mirror of
https://github.com/processwire/processwire.git
synced 2025-08-13 18:24:57 +02:00
Add $config->setLocation(), $config->setPath() and $config->setUrl() methods to allow runtime modification of system paths/URLs.
This commit is contained in:
@@ -218,6 +218,149 @@ class Config extends WireData {
|
||||
return $for === '' ? $this->urls : $this->url($for);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a directory to a named location, updates $config->paths and $config->urls for it
|
||||
*
|
||||
* - Paths relative to PW installation root should omit the leading slash, i.e. use `site/templates/` and NOT `/site/templates/`.
|
||||
*
|
||||
* - If specifying just the `$dir` argument, it updates both `$config->paths` and `$config->urls` for it.
|
||||
*
|
||||
* - If specifying both `$dir` and `$url` arguments, then `$dir` refers to `$config->paths` and `$url` refers to `$config->urls`.
|
||||
*
|
||||
* - The `$for` argument can be: `cache`, `logs`, `files`, `tmp`, `templates`, or one of your own. Other named locations may
|
||||
* also work, but since they can potentially be used before PW’s “ready” state, they may not be reliable.
|
||||
*
|
||||
* - **Warning:** anything that changes a system URL may make the URL no longer have the protection of the root .htaccess file.
|
||||
* As a result, if you modify system URLs for anything on a live server, you should also update your .htaccess file to
|
||||
* reflect your changes (while leaving existing rules for original URL in place).
|
||||
*
|
||||
* The following example would be in /site/init.php or /site/ready.php (or equivalent module method). In this example we
|
||||
* are changing the location (path and URL) of our /site/templates/ to use a new version of the files in /site/dev-templates/
|
||||
* so that we can test them out with user 'karen', while all other users on the site get our regular templates.
|
||||
* ~~~~~
|
||||
* // change templates path and URL to /site/dev-templates/ when user name is 'karen'
|
||||
* if($user->name == 'karen') {
|
||||
* $config->setLocation('templates', 'site/dev-templates/');
|
||||
* }
|
||||
* ~~~~~
|
||||
*
|
||||
* @param string $for Named location from `$config->paths` or `$config->urls`, one of: `cache`, `logs`, `files`, `tmp`, `templates`, or your own.
|
||||
* @param string $dir Directory or URL to the location. Should be either a path or URL relative to current installation root (recommended),
|
||||
* or an absolute disk path that resolves somewhere in current installation root. If specifying an absolute path outside of the installation
|
||||
* root, then you’ll also want to provide the $url argument since PW won’t know it. You may also specify a blank string for this argument
|
||||
* if you only want to set the $url argument.
|
||||
* @param string|bool $url If the $dir argument represents both the path and URL relative to site root, you can omit this argument.
|
||||
* If path and URL cannot be derived from one another, or you only want to modify the $url (leaving $dir blank), you
|
||||
* can specify the URL in this argument. Specify boolean false if you only want to set the $dir (path) and not detect the $url from it.
|
||||
* @return self
|
||||
* @throws WireException If request cannot be accommodated
|
||||
* @since 3.0.141
|
||||
*
|
||||
*/
|
||||
public function setLocation($for, $dir, $url = '') {
|
||||
|
||||
if($for === 'root') throw new WireException('Root path can only be changed at boot');
|
||||
|
||||
if(!empty($dir)) {
|
||||
$rootPath = $this->paths->get('root');
|
||||
|
||||
// make sure path uses unix-style slashes
|
||||
$dir = Paths::normalizeSeparators($dir);
|
||||
|
||||
// if given path is inclusive of root path, make path relative to site root
|
||||
if(strpos($dir, $rootPath) === 0) $dir = substr($dir, strlen($rootPath));
|
||||
|
||||
// ensure trailing slash
|
||||
if(substr($dir, -1) !== '/') $dir .= '/';
|
||||
}
|
||||
|
||||
// now determine the URL to set
|
||||
if($url === false) {
|
||||
// arguments say to skip setting URL
|
||||
} else if(empty($url)) {
|
||||
// URL and path are the same relative to site root
|
||||
if(!empty($dir)) $url = $dir;
|
||||
} else {
|
||||
// given a custom URL
|
||||
$rootUrl = $this->urls->get('root');
|
||||
// if URL begins at PW installation root, remove the root part of the URL
|
||||
if(strpos($url, $rootUrl) === 0) $url = substr($url, strlen($rootUrl));
|
||||
// ensure trailing slash
|
||||
if(substr($url, -1) !== '/' && strpos($url, '?') === false && strpos($url, '#') === false) $url .= '/';
|
||||
}
|
||||
|
||||
if(!empty($path)) $this->paths->set($for, $dir);
|
||||
if(!empty($url)) $this->urls->set($for, $url);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change or set just the server disk path for the named location (leaving URL as-is)
|
||||
*
|
||||
* - If you want to update both disk path and URL at the same time, or if URL and path are going to be the same relative to
|
||||
* installation root, use the `setLocation()` method instead.
|
||||
*
|
||||
* - Paths relative to PW installation root should omit the leading slash, i.e. use `site/templates/` and NOT `/site/templates/`.
|
||||
*
|
||||
* - The `$for` argument can be: `cache`, `logs`, `files`, `tmp`, `templates`, or one of your own. Other named locations may
|
||||
* also work, but since they can potentially be used before PW’s “ready” state, they may not be reliable.
|
||||
*
|
||||
* @param string $for Named location from `$config->paths`, one of: `cache`, `logs`, `files`, `tmp`, `templates`, or your own.
|
||||
* @param string $path Path relative to PW installation root (no leading slash), or absolute path if not.
|
||||
* @return self
|
||||
* @throws WireException
|
||||
* @since 3.0.141
|
||||
*
|
||||
*/
|
||||
public function setPath($for, $path) {
|
||||
return $this->setLocation($for, $path, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change or set just the URL for the named location (leaving server disk path as-is)
|
||||
*
|
||||
* - If you want to update both disk path and URL at the same time, or if URL and path are going to be the same relative to
|
||||
* installation root, use the `setLocation()` method instead.
|
||||
*
|
||||
* - Paths relative to PW installation root should omit the leading slash, i.e. use `site/templates/` and NOT `/site/templates/`.
|
||||
*
|
||||
* - The `$for` argument can be: `cache`, `logs`, `files`, `tmp`, `templates`, or one of your own. Other named locations may
|
||||
* also work, but since they can potentially be used before PW’s “ready” state, they may not be reliable.
|
||||
*
|
||||
* - **Warning:** anything that changes a system URL may make the URL no longer have the protection of the root .htaccess file.
|
||||
* As a result, if you modify system URLs for anything on a live server, you should also update your .htaccess file to
|
||||
* reflect your changes (while leaving existing rules for original URL in place).
|
||||
*
|
||||
* The following examples would go in /site/ready.php.
|
||||
*
|
||||
* Let’s say we created a symbolic link in our web root `/tiedostot/` (Finnish for “files”) that points to /site/assets/files/.
|
||||
* We want all of our file URLs to appear as “/tiedostot/1234/img.jpg” rather than “/site/assets/files/1234/img.jpg”. We would
|
||||
* change the URL for ProcessWire’s `$config->urls->files` to point there like this example below. (Please also see warning above)
|
||||
* ~~~~~
|
||||
* if($page->template != 'admin') {
|
||||
* $config->setUrl('files', 'tiedostot/');
|
||||
* }
|
||||
* ~~~~~
|
||||
* In this next example, we are changing all of our file URLs on the front-end to point a cookieless subdomain that maps all
|
||||
* requests to the root path of https://files.domain.com to /site/assets/files/. The example works for CDNs as well.
|
||||
* ~~~~~
|
||||
* if($page->template != 'admin) {
|
||||
* $config->setUrl('files', 'https://files.domain.com/');
|
||||
* }
|
||||
* ~~~~~
|
||||
*
|
||||
* @param string $for Named location from `$config->urls`, one of: `cache`, `logs`, `files`, `tmp`, `templates`, or your own.
|
||||
* @param string $url URL relative to PW installation root (no leading slash) or absolute URL if not (optionally including scheme and domain).
|
||||
* @return self
|
||||
* @throws WireException
|
||||
* @since 3.0.141
|
||||
*
|
||||
*/
|
||||
public function setUrl($for, $url) {
|
||||
return $this->setLocation($for, '', $url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get disk path for requested resource or module
|
||||
*
|
||||
|
Reference in New Issue
Block a user