From 85a951584edb166ad2fa5f67bc2cd6db863146c1 Mon Sep 17 00:00:00 2001 From: Ingo Schommer Date: Tue, 3 Oct 2017 00:30:24 +1300 Subject: [PATCH] Update main.php path to support framework in vendor --- .../01_Installation/03_Windows.md | 2 +- .../01_Installation/05_Common_Problems.md | 5 ++- .../How_To/Configure_Lighttpd.md | 14 +++---- .../01_Installation/How_To/Configure_Nginx.md | 4 +- .../How_To/Setup_Nginx_and_HHVM.md | 2 +- .../04_Directory_Structure.md | 38 +++++++++-------- .../14_Files/03_File_Security.md | 39 +++++++++--------- .../16_Execution_Pipeline/index.md | 10 ++--- docs/en/02_Developer_Guides/17_CLI/index.md | 8 ++-- docs/en/04_Changelogs/4.0.0.md | 37 ++++++++++++++++- docs/en/_images/modules_folder.jpg | Bin 28307 -> 0 bytes src/Dev/Install/DatabaseAdapterRegistry.php | 26 ++++++++---- src/Dev/Install/Installer.php | 23 ++++++++--- src/includes/autoload.php | 6 +-- 14 files changed, 136 insertions(+), 78 deletions(-) delete mode 100644 docs/en/_images/modules_folder.jpg diff --git a/docs/en/00_Getting_Started/01_Installation/03_Windows.md b/docs/en/00_Getting_Started/01_Installation/03_Windows.md index 2427611d4..3cddfb1dd 100644 --- a/docs/en/00_Getting_Started/01_Installation/03_Windows.md +++ b/docs/en/00_Getting_Started/01_Installation/03_Windows.md @@ -62,7 +62,7 @@ control. 3. Apache rewrite (mod_rewrite) isn't working and it's installed (prior to SilverStripe 3.1.11) -Due to some changes to `mod_dir` in [Apache 2.4](http://httpd.apache.org/docs/current/mod/mod_dir.html#DirectoryCheckHandler) (precedence of handlers), index.php gets added to the URLs as soon as you navigate to the homepage of your site. Further requests are then handled by index.php rather than `mod_rewrite` (framework/main.php). To fix this place the following within the `mod_rewrite` section of your .htaccess file: +Due to some changes to `mod_dir` in [Apache 2.4](http://httpd.apache.org/docs/current/mod/mod_dir.html#DirectoryCheckHandler) (precedence of handlers), index.php gets added to the URLs as soon as you navigate to the homepage of your site. Further requests are then handled by index.php rather than `mod_rewrite` (`main.php`). To fix this place the following within the `mod_rewrite` section of your .htaccess file: ``` diff --git a/docs/en/00_Getting_Started/01_Installation/05_Common_Problems.md b/docs/en/00_Getting_Started/01_Installation/05_Common_Problems.md index 781bf916d..6b2d318e5 100644 --- a/docs/en/00_Getting_Started/01_Installation/05_Common_Problems.md +++ b/docs/en/00_Getting_Started/01_Installation/05_Common_Problems.md @@ -22,7 +22,10 @@ On "live" environments, the `?isDev=1` solution is preferred, as it means that y ## mod_rewrite isn't working but it's installed (prior to SilverStripe 3.1.11) -Due to some changes to `mod_dir` in [Apache 2.4](http://httpd.apache.org/docs/current/mod/mod_dir.html#DirectoryCheckHandler) (precedence of handlers), index.php gets added to the URLs as soon as you navigate to the homepage of your site. Further requests are then handled by index.php rather than `mod_rewrite` (framework/main.php). To fix this place the following within the `mod_rewrite` section of your .htaccess file: +Due to some changes to `mod_dir` in [Apache 2.4](http://httpd.apache.org/docs/current/mod/mod_dir.html#DirectoryCheckHandler) +(precedence of handlers), index.php gets added to the URLs as soon as you navigate to the homepage of your site. +Further requests are then handled by index.php rather than `mod_rewrite` (`main.php`). +To fix this place the following within the `mod_rewrite` section of your .htaccess file: ``` diff --git a/docs/en/00_Getting_Started/01_Installation/How_To/Configure_Lighttpd.md b/docs/en/00_Getting_Started/01_Installation/How_To/Configure_Lighttpd.md index afa9917ac..5d60a35d6 100644 --- a/docs/en/00_Getting_Started/01_Installation/How_To/Configure_Lighttpd.md +++ b/docs/en/00_Getting_Started/01_Installation/How_To/Configure_Lighttpd.md @@ -15,7 +15,7 @@ Silverstripe. Replace "yoursite.com" and "/home/yoursite/public_html/" below. static-file.exclude-extensions += ( ".ss" ) # Deny access to SilverStripe command-line interface - $HTTP["url"] =~ "^/framework/cli-script.php" { + $HTTP["url"] =~ "^/vendor/silverstripe/framework/cli-script.php" { url.access-deny = ( "" ) } @@ -27,11 +27,11 @@ Silverstripe. Replace "yoursite.com" and "/home/yoursite/public_html/" below. # Rewrite URLs so they are nicer url.rewrite-once = ( "^/.*\.[A-Za-z0-9]+.*?$" => "$0", - "^/(.*?)(\?|$)(.*)" => "/framework/main.php?url=$1&$3" + "^/(.*?)(\?|$)(.*)" => "/vendor/silverstripe/framework/main.php?url=$1&$3" ) # Show SilverStripe error page - server.error-handler-404 = "/framework/main.php" + server.error-handler-404 = "/vendor/silverstripe/framework/main.php" } @@ -53,14 +53,14 @@ of Silverstripe on the same host, you can use something like this (be warned, it url.rewrite-once = ( "(?i)(/copy1/.*\.([A-Za-z0-9]+))(.*?)$" => "$0", "(?i)(/copy2/.*\.([A-Za-z0-9]+))(.*?)$" => "$0", - "^/copy1/(.*?)(\?|$)(.*)" => "/copy1/framework/main.php?url=$1&$3", - "^/copy2/(.*?)(\?|$)(.*)" => "/copy2/framework/main.php?url=$1&$3" + "^/copy1/(.*?)(\?|$)(.*)" => "/copy1/vendor/silverstripe/framework/main.php?url=$1&$3", + "^/copy2/(.*?)(\?|$)(.*)" => "/copy2/vendor/silverstripe/framework/main.php?url=$1&$3" ) $HTTP["url"] =~ "^/copy1/" { - server.error-handler-404 = "/copy1/framework/main.php" + server.error-handler-404 = "/copy1/vendor/silverstripe/framework/main.php" } $HTTP["url"] =~ "^/copy2/" { - server.error-handler-404 = "/copy2/framework/main.php" + server.error-handler-404 = "/copy2/vendor/silverstripe/framework/main.php" } } diff --git a/docs/en/00_Getting_Started/01_Installation/How_To/Configure_Nginx.md b/docs/en/00_Getting_Started/01_Installation/How_To/Configure_Nginx.md index 86d6e5247..d9a247f82 100644 --- a/docs/en/00_Getting_Started/01_Installation/How_To/Configure_Nginx.md +++ b/docs/en/00_Getting_Started/01_Installation/How_To/Configure_Nginx.md @@ -30,7 +30,7 @@ But enough of the disclaimer, on to the actual configuration — typically in `n } location / { - try_files $uri /framework/main.php?url=$uri&$query_string; + try_files $uri vendor/silverstripe/framework/main.php?url=$uri&$query_string; } error_page 404 /assets/error-404.html; @@ -41,7 +41,7 @@ But enough of the disclaimer, on to the actual configuration — typically in `n deny all; } sendfile on; - try_files $uri /framework/main.php?url=$uri&$query_string; + try_files $uri vendor/silverstripe/framework/main.php?url=$uri&$query_string; } location ~ /framework/.*(main|rpc|tiny_mce_gzip)\.php$ { diff --git a/docs/en/00_Getting_Started/01_Installation/How_To/Setup_Nginx_and_HHVM.md b/docs/en/00_Getting_Started/01_Installation/How_To/Setup_Nginx_and_HHVM.md index f8763baa4..f5b93a7c7 100644 --- a/docs/en/00_Getting_Started/01_Installation/How_To/Setup_Nginx_and_HHVM.md +++ b/docs/en/00_Getting_Started/01_Installation/How_To/Setup_Nginx_and_HHVM.md @@ -48,7 +48,7 @@ Create `/etc/nginx/silverstripe.conf` and add this configuration: fastcgi_buffers 4 32k; location / { - try_files $uri /framework/main.php?url=$uri&$query_string; + try_files $uri /vendor/silverstripe/framework/main.php?url=$uri&$query_string; } error_page 404 /assets/error-404.html; diff --git a/docs/en/00_Getting_Started/04_Directory_Structure.md b/docs/en/00_Getting_Started/04_Directory_Structure.md index f53f85fa8..5a827d2b1 100644 --- a/docs/en/00_Getting_Started/04_Directory_Structure.md +++ b/docs/en/00_Getting_Started/04_Directory_Structure.md @@ -9,9 +9,9 @@ directories is meaningful to its logic. Directory | Description --------- | ----------- -`assets/` | Contains images and other files uploaded via the SilverStripe CMS. You can also place your own content inside it, and link to it from within the content area of the CMS. -`cms/` | Contains all the files that form the CMS area of your site. It’s structure is similar to the mysite/ directory, so if you find something interesting, it should be easy enough to look inside and see how it was built. -`framework/` | The framework that builds both your own site and as the CMS that powers it. You’ll be utilising files in this directory often, both directly and indirectly. +`assets/` | Images and other files uploaded via the SilverStripe CMS. You can also place your own content inside it, and link to it from within the content area of the CMS. +`resources/`| Public files from modules (added automatically) +`vendor/` | SilverStripe modules and other supporting libraries (the framework is in `vendor/silverstripe/framework`) ## Custom Code Structure @@ -46,20 +46,22 @@ on folder and file naming in SilverStripe core modules. See [themes](/developer_guides/templates/themes) -## Module Structure {#module_structure} +## Module Structure {#module_structure} -Modules are currently top-level folders that have a `_config.php` file or a `_config/` directory present. -They should follow the same conventions as posed in "Custom Site Structure" +Modules are commonly stored as composer packages in the `vendor/` folder. +They need to have a `_config.php` file or a `_config/` directory present, +and should follow the same conventions as posed in "Custom Site Structure". Example Forum: | Directory | Description | | --------- | ----------- | - | `forum/` | This directory contains all of your code that defines your website. | - | `forum/code` | PHP code for model and controller (subdirectories are optional) | + | `vendor/silverstripe/blog/`| This directory contains all of your code that defines your website. | + | `vendor/silverstripe/blog/code` | PHP code for model and controller (subdirectories are optional) | | ... | ... | -![](../_images/modules_folder.jpg) +Note: Before SilverStripe 4.x, modules were living as top-level folders in the webroot itself. +Some modules might not have been upgraded to support placement in `vendor/` ### Module documentation @@ -68,7 +70,7 @@ plain text files inside a 'docs' folder located in the module folder. These file can be written with the Markdown syntax (See [Contributing Documentation](/contributing/documentation)) and include media such as images or videos. -Inside the docs folder, developers should organise the markdown files into each +Inside the `docs/` folder, developers should organise the markdown files into each separate language they wish to write documentation for (usually just `en`). Inside each languages' subfolder, developers then have freedom to create whatever structure they wish for organising the documentation they wish. @@ -77,14 +79,14 @@ Example Forum Documentation: | Directory | Description | | --------- | ----------- | - | `forum/docs` | The docs folder will be picked up by the documentation viewer. | - | `forum/docs/_manifest_exclude` | Empty file to signify that SilverStripe does not need to load classes from this folder | - | `forum/docs/en/` | English documentation | - | `forum/docs/en/index.md` | Documentation homepage. Should provide an introduction and links to remaining docs | - | `forum/docs/en/Getting_Started.md` | Documentation page. Naming convention is Uppercase and underscores. | - | `forum/docs/en/_images/` | Folder to store any images or media | - | `forum/docs/en/Some_Topic/` | You can organise documentation into nested folders. Naming convention is Uppercase and underscores. | -|`forum/docs/en/04_Some_Topic/00_Getting_Started.md`|Structure is created by use of numbered prefixes. This applies to nested folders and documentations pages, index.md should not have a prefix.| + | `blog/docs` | | + | `blog/docs/_manifest_exclude` | Empty file to signify that SilverStripe does not need to load classes from this folder | + | `blog/docs/en/` | English documentation | + | `blog/docs/en/index.md` | Documentation homepage. Should provide an introduction and links to remaining docs | + | `blog/docs/en/Getting_Started.md` | Documentation page. Naming convention is Uppercase and underscores. | + | `blog/docs/en/_images/` | Folder to store any images or media | + | `blog/docs/en/Some_Topic/` | You can organise documentation into nested folders. Naming convention is Uppercase and underscores. | + | `blog/docs/en/04_Some_Topic/00_Getting_Started.md`|Structure is created by use of numbered prefixes. This applies to nested folders and documentations pages, index.md should not have a prefix.| ## Autoloading diff --git a/docs/en/02_Developer_Guides/14_Files/03_File_Security.md b/docs/en/02_Developer_Guides/14_Files/03_File_Security.md index 30a18757e..660f39b5e 100644 --- a/docs/en/02_Developer_Guides/14_Files/03_File_Security.md +++ b/docs/en/02_Developer_Guides/14_Files/03_File_Security.md @@ -344,25 +344,25 @@ The extension can also be globally disabled by removing it at the root level: If the default server configuration is not appropriate for your specific environment, then you can further customise the .htaccess or web.config by editing one or more of the below: -* `Assets_HTAccess.ss`: Template for public permissions on the Apache server. -* `Assets_WebConfig.ss`: Template for public permissions on the IIS server. -* `Protected_HTAccess.ss`: Template for the protected store on the Apache server (should deny all requests). -* `Protected_WebConfig.ss`: Template for the protected store on the IIS server (should deny all requests). +* `PublicAssetAdapter_HTAccess.ss`: Template for public permissions on the Apache server. +* `PublicAssetAdapter_WebConfig.ss`: Template for public permissions on the IIS server. +* `ProtectedAssetAdapter_HTAccess.ss`: Template for the protected store on the Apache server (should deny all requests). +* `ProtectedAssetAdapter_WebConfig.ss`: Template for the protected store on the IIS server (should deny all requests). Each of these files will be regenerated on ?flush, so it is important to ensure that these files are overridden at the template level, not via manually generated configuration files. #### Configuring Web Server: Apache server -In order to ensure that public files are served correctly, you should check that your ./assets -.htaccess bypasses PHP requests for files that do exist. The default template -(declared by `Assets_HTAccess.ss`) has the following section, which may be customised in your project: +In order to ensure that public files are served correctly, you should check that your `assets/.htaccess` +bypasses PHP requests for files that do exist. The default template +(declared by `PublicAssetAdapter_HTAccess.ss`) has the following section, which may be customised in your project: ``` - # Non existant files passed to requesthandler - RewriteCond %{REQUEST_URI} ^(.*)$ - RewriteCond %{REQUEST_FILENAME} !-f - RewriteRule .* ../framework/main.php?url=%1 [QSA] +# Non existant files passed to requesthandler +RewriteCond %{REQUEST_URI} ^(.*)$ +RewriteCond %{REQUEST_FILENAME} !-f +RewriteRule .* ../vendor/silverstripe/framework/main.php?url=%1 [QSA] ``` You will need to ensure that your core apache configuration has the necessary `AllowOverride` @@ -377,13 +377,14 @@ while ensuring non-existent files are processed via the Framework. The default rule for IIS is as below (only partial configuration displayed): ``` - - - - - - - + + + + + + + + ``` You will need to make sure that the `allowOverride` property of your root web.config is not set @@ -401,6 +402,6 @@ dynamic requests are processed via the Framework: ``` location ^~ /assets/ { sendfile on; - try_files $uri /framework/main.php?url=$uri&$query_string; + try_files $uri vendor/silverstripe/framework/main.php?url=$uri&$query_string; } ``` diff --git a/docs/en/02_Developer_Guides/16_Execution_Pipeline/index.md b/docs/en/02_Developer_Guides/16_Execution_Pipeline/index.md index b7f808895..f43de804b 100644 --- a/docs/en/02_Developer_Guides/16_Execution_Pipeline/index.md +++ b/docs/en/02_Developer_Guides/16_Execution_Pipeline/index.md @@ -54,12 +54,12 @@ If no file can be directly matched, control is handed off to `framework/main.php RewriteRule silverstripe-cache(/|$) - [F,L,NC] RewriteRule composer\.(json|lock) - [F,L,NC] - # Process through SilverStripe if no file with the requested name exists. - # Pass through the original path as a query parameter, and retain the existing parameters. + # Non existant files passed to requesthandler + # Try finding the module in the vendor folder first RewriteCond %{REQUEST_URI} ^(.*)$ RewriteCond %{REQUEST_FILENAME} !-f - RewriteRule .* framework/main.php?url=%1 [QSA] - + RewriteRule .* ../vendor/silverstripe/framework/main.php?url=%1 [QSA] + # If requesting the main script directly, rewrite to the installer RewriteCond %{REQUEST_URI} ^(.*)/framework/main.php$ RewriteCond %{REQUEST_FILENAME} !-f @@ -86,7 +86,7 @@ tasks silently in the background. [configuration file](/getting_started/environment_management) in the webroot. * Sets constants based on the filesystem structure (e.g. `BASE_URL`, `BASE_PATH` and `TEMP_FOLDER`) -All requests go through `framework/main.php`, which sets up the core [Kernel](api:SilverStripe\Core\Kernel) and [HTTPApplication](api:SilverStripe\Control\HTTPApplication) +All requests go through `main.php`, which sets up the core [Kernel](api:SilverStripe\Core\Kernel) and [HTTPApplication](api:SilverStripe\Control\HTTPApplication) objects. See [/developer_guides/execution_pipeline/app_object_and_kernel] for details on this. The main process follows: diff --git a/docs/en/02_Developer_Guides/17_CLI/index.md b/docs/en/02_Developer_Guides/17_CLI/index.md index 67ce6319b..2e0b227c5 100644 --- a/docs/en/02_Developer_Guides/17_CLI/index.md +++ b/docs/en/02_Developer_Guides/17_CLI/index.md @@ -6,12 +6,12 @@ SilverStripe can call [Controllers](../controllers) through a command line inter web browser. This functionality can be used to automate tasks with cron jobs, run unit tests, or anything else that needs to interface over the command line. -The main entry point for any command line execution is `framework/cli-script.php`. For example, to run a database -rebuild from the command line, use this command: +The main entry point for any command line execution is `cli-script.php` in the framework module. +For example, to run a database rebuild from the command line, use this command: ```bash cd your-webroot/ - php framework/cli-script.php dev/build + php vendor/bin/framework/cli-script.php dev/build ```
@@ -159,4 +159,4 @@ The following will run `MyTask` every minute. ```bash * * * * * /your/site/folder/sake dev/tasks/MyTask -``` \ No newline at end of file +``` diff --git a/docs/en/04_Changelogs/4.0.0.md b/docs/en/04_Changelogs/4.0.0.md index 0c5859b90..2aa9109f0 100644 --- a/docs/en/04_Changelogs/4.0.0.md +++ b/docs/en/04_Changelogs/4.0.0.md @@ -64,8 +64,7 @@ guide developers in preparing existing 3.x code for compatibility with 4.0 [intervention/image](https://github.com/intervention/image) library to power manipualations. * Dependencies can managed via [recipe-plugin](https://github.com/silverstripe/recipe-plugin). See [recipe-core](https://github.com/silverstripe/recipe-core) and [recipe-cms](https://github.com/silverstripe/recipe-cms) as examples. * Authentication has been upgraded to a modular approach using re-usable interfaces and easier to hook in to LoginHandlers. -* Support for modules installed in vendor folder. See [/developer_guides/extending/how_tos/publish_a_module](the - module publishing guide) for more information. +* Core modules are installed in the `vendor/` folder by default (other modules can opt-in, see [guide](/developer_guides/extending/how_tos/publish_a_module)) ## Upgrading @@ -78,6 +77,14 @@ some automated processes that users can run to This section describes the processes which every project upgrading to 4.0 should follow. This should be followed as a standard first point of upgrade. +#### Upgrade your rewrite rules + +The location of SilverStripe's "entry file" has changed. Your project and server environment will need +to adjust the path to this file from `framework/main.php` to `vendor/silverstripe/framework/main.php`. +If you are running Apache, adjust your `.htaccess` file. For other webservers, +please consult the [installation guides](getting_started/installation/). + + #### Upgrade references to renamed and namespaced classes Nearly all core PHP classes have been namespaced. For example, `DataObject` is now called `SilverStripe\ORM\DataObject`. @@ -285,6 +292,32 @@ To ensure consistency, we've also deprecated support for path constants: * `THIRDPARTY_DIR` and `THIRDPARTY_PATH` * `CMS_DIR` and `CMS_PATH` * `THEMES_DIR` and `THEMES_PATH` + +#### Adapt tooling to modules in vendor folder + +SilverStripe modules can now be installed like any other composer package: In the `vendor/` folder +instead of the webroot. Modules need to opt in to this behaviour after they've ensured +that no hardcoded path references exist (see "Upgrade module paths in file references"). + +All core modules have been moved over already: + +```diff +-framework/ +-cms/ +... ++vendor/silverstripe/framework ++vendor/silverstripe/cms +``` + +Since the `vendor/` folder isn't publicly accessible, modules need to declare +which files need to be exposed via the new [vendor-plugin](https://github.com/silverstripe/vendor-plugin) +(e.g. images or CSS/JS files). These files will be either symlinked or copied into a new `resources/` +folder automatically on `composer install`. + +If your deployment process relies on `composer install` on the production environment, +and this environment supports symlinks, you don't need to change anything. +If you deploy release archives, either ensure those archives can correctly extract symlinks, +or explicitly switch to the "copy" mode to avoid symlinks. ### API Specific Upgrades diff --git a/docs/en/_images/modules_folder.jpg b/docs/en/_images/modules_folder.jpg deleted file mode 100644 index 2a49224a4ed1fd2eeca6dc9d7e64dece505ff124..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28307 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 diff --git a/src/Dev/Install/DatabaseAdapterRegistry.php b/src/Dev/Install/DatabaseAdapterRegistry.php index b4bb6c358..4af6c7505 100644 --- a/src/Dev/Install/DatabaseAdapterRegistry.php +++ b/src/Dev/Install/DatabaseAdapterRegistry.php @@ -110,26 +110,36 @@ class DatabaseAdapterRegistry } /** - * Detects all _register_database.php files and invokes them + * Detects all _register_database.php files and invokes them. + * Searches through vendor/ folder only, + * does not support "legacy" folder location in webroot */ public static function autodiscover() { - foreach (glob(__DIR__ . '/../../../../*', GLOB_ONLYDIR) as $directory) { - if (file_exists($directory . '/_register_database.php')) { - include_once($directory . '/_register_database.php'); + // Search through all composer packages in vendor + foreach (glob(BASE_PATH . '/vendor/*', GLOB_ONLYDIR) as $vendor) { + foreach (glob($vendor . '/*', GLOB_ONLYDIR) as $directory) { + if (file_exists($directory . '/_register_database.php')) { + include_once($directory . '/_register_database.php'); + } } } } /** * Detects all _configure_database.php files and invokes them - * Called by ConfigureFromEnv.php + * Called by ConfigureFromEnv.php. + * Searches through vendor/ folder only, + * does not support "legacy" folder location in webroot */ public static function autoconfigure() { - foreach (glob(__DIR__ . '/../../../../*', GLOB_ONLYDIR) as $directory) { - if (file_exists($directory . '/_configure_database.php')) { - include_once($directory . '/_configure_database.php'); + // Search through all composer packages in vendor + foreach (glob(BASE_PATH . '/vendor/*', GLOB_ONLYDIR) as $vendor) { + foreach (glob($vendor . '/*', GLOB_ONLYDIR) as $directory) { + if (file_exists($directory . '/_configure_database.php')) { + include_once($directory . '/_configure_database.php'); + } } } } diff --git a/src/Dev/Install/Installer.php b/src/Dev/Install/Installer.php index 303a6bfe2..e6b374008 100644 --- a/src/Dev/Install/Installer.php +++ b/src/Dev/Install/Installer.php @@ -438,16 +438,26 @@ ErrorDocument 500 /assets/error-500.html $baseClause $cgiClause + # Deny access to vendor, unless you're requesting main.php + RewriteCond %{REQUEST_URI} !^/vendor/silverstripe/framework/main\.php + RewriteRule ^vendor(/|$) - [F,L,NC]s + + # Deny access to potentially sensitive files and folders + RewriteRule ^\.env - [F,L,NC] + RewriteRule silverstripe-cache(/|$) - [F,L,NC] + RewriteRule composer\.(json|lock) - [F,L,NC] + RewriteRule (error|silverstripe|debug)\.log - [F,L,NC] + # Deny access to potentially sensitive files and folders - RewriteRule ^vendor(/|$) - [F,L,NC] RewriteRule silverstripe-cache(/|$) - [F,L,NC] RewriteRule composer\.(json|lock) - [F,L,NC] # Process through SilverStripe if no file with the requested name exists. - # Pass through the original path as a query parameter, and retain the existing parameters. - RewriteCond %{REQUEST_URI} ^(.*)$ - RewriteCond %{REQUEST_FILENAME} !-f - RewriteRule .* framework/main.php?url=%1 [QSA] + # Pass through the original path as a query parameter, and retain the existing parameters. + # Try finding framework in the vendor folder first + RewriteCond %{REQUEST_URI} ^(.*)$ + RewriteCond %{REQUEST_FILENAME} !-f + RewriteRule .* vendor/silverstripe/framework/main.php?url=%1 [QSA] TEXT; @@ -502,8 +512,9 @@ TEXT; + - + diff --git a/src/includes/autoload.php b/src/includes/autoload.php index 67baec014..e82557e65 100644 --- a/src/includes/autoload.php +++ b/src/includes/autoload.php @@ -5,11 +5,9 @@ call_user_func(function () { $candidates = [ // module in vendor __DIR__ . '/../../../../autoload.php', - // module in webroot + // module itself is webroot (usually during CI installs) __DIR__ . '/../../vendor/autoload.php', - // module in webroot - __DIR__ . '/../../../vendor/autoload.php', - // module is webroot (usually during CI installs) + // fallback getcwd() . '/vendor/autoload.php', ]; foreach ($candidates as $candidate) {