Extending on @Stephen's answer, here is a way to get around that issue without duplicating main.php
and without modifying it directly.
What I did was create a _ss_environment.php
file which is added early on in the loading process of Silverstripe.
_ss_environment.php
global $url;
$url = $_GET['raw_url'];
if (isset($_GET['url']))
{
unset($_GET['url']);
}
// IIS includes get variables in url
$i = strpos($url, '?');
if($i !== false)
{
$url = substr($url, 0, $i);
}
.htaccess
RewriteCond %{REQUEST_URI} ^(.*)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !\.php$
RewriteRule .* framework/main.php?raw_url=%1 [QSA]
So here is what is happening:
- The
.htaccess
is now using raw_url
instead of url
-
_ss_environment.php
is being called early in the loading process, setting the global $url
variable that main.php
normally sets. This is set with raw_url
rather than url
.
- To prevent
main.php
to just override it again when it sees your url
query string parameter, it is unset (Silverstripe seems to reset this later as far as my test is concerned).
- Lastly is a little block of code that
main.php
would normally run if $_GET['url']
is set, copied as-is for apparent support in IIS. (If you don't use IIS, you likely won't need it.)
This has a few benefits:
- No update to
main.php
allows upgrading Silverstripe slightly easier in the future
- Runs the minimal amount of code needed to "trick" Silverstripe into thinking it is running normally.
The one obvious drawback to any solution for changing away form the url
query string parameter is if anything looks at the parameter directly. With how Silverstripe works, it is more likely that code uses the $url
global variable or the Director
class rather than looking at the query string for the current URL.
I tested this on a 3.1 site by doing the changes I mentioned and:
- Creating a controller called
TestController
-
In the init
function of the controller, I am running the following:
var_dump($_GET['url']);
var_dump($this->getRequest()->getVars());
- Visited
/TestController?url=abc123
, saw the value of both dumps have "abc123" as the value for the URL parameter.
- Navigated to a few other custom pages on the site to make sure they were still working (no issues that I saw)
Unfortunately, I haven't been able to find documentation for the order of inclusion in regards to _config.php
and _ss_environment.php
. However, after browsing through the code, I have worked out it is this:
I could probably go on however I think this gives a pretty good picture of what is going on. I don't really see a way around not using the _ss_environment.php
file. Nothing else gets included early enough that you can hook into without modifying core code.