artabro/wire/core/Paths.php
2024-08-27 11:35:37 +02:00

207 lines
9.4 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php namespace ProcessWire;
/**
* ProcessWire configuration paths and URLs
*
* #pw-headline Configuration paths and URLs (Paths class)
* #pw-summary Maintains lists of file paths or URLs, primarily used by the ProcessWire $config->paths and $urls API variables.
* #pw-summary-paths-only These properties are only useful when accessed from `$config->paths` as they are not HTTP accessible as URLs.
* #pw-summary-urls-only These properties apply only to the `$urls` or `$config->urls`. Do not use them with `$config->paths`.
* #pw-summary-pagination These properties apply only to the `$urls` or `$config->urls` and only when pagination is active for the current request.
* #pw-var $urls
*
* #pw-body =
* The Paths class is used by `$config->paths` and `$config->urls` (or just `$urls`). The `$config->paths` refers to server disk paths
* while `$config->urls` refers to web server URLs. All of the same properties are present on both, though several properties
* are only useful on one or the other (as outlined below). You can access a path or URL like this:
* ~~~~~
* $path = $config->paths->templates; // i.e. /path/to/htdocs/site/templates/
* $url = $config->urls->templates; // i.e. /site/templates/
* ~~~~~
* The `$config->urls` property can also be accessed more directly via the `$urls` API variable (in PW 3.x+):
* ~~~~~
* $url = $urls->templates; // i.e. /site/templates/
* ~~~~~
* For `$config->urls` (or `$urls`), if you prepend `http` to any of the property names (making it camelCase) it will
* return the full http/https URL rather then the relative URL:
* ~~~~~
* $httpUrl = $config->urls->httpTemplates; // i.e. https://domain.com/site/templates/
* $httpUrl = $urls->httpTemplates; // same as above
* ~~~~~
* You may optionally add your own properties as well. If you add a path/url without a leading slash “/” it is assumed to
* be relative to the `root` property. If it has a leading slash, then it is absolute.
* ~~~~~
* // add new urls properties
* $urls->set('css', 'site/templates/css/'); // relative to site root
* $urls->set('uikit', '/uikit/dist/'); // absolute
*
* // get properties that were set
* echo $urls->get('css'); // i.e. /site/templates/css/
* echo $urls->get('uikit'); // i.e. /uikit/dist/
* echo $urls->get('httpCss'); // i.e. https://domain.com/site/templates/css/
* echo $urls->get('httpUikit'); // i.e. https://domain.com/uikit/dist/
* echo $urls->httpUikit; // same as above (using get method call is optional for any of these)
* ~~~~~
* Do not set `http` properties directly, as they are dynamically generated from `urls` properties at runtime upon request.
*
* In the examples on this page, you can replace the `$urls` variable with `$config->paths` if you need to get the server path
* instead of a URL. As indicated earlier, `$urls` can aso be accessed at the more verbose `$config->urls` if you prefer.
*
* > Please note in the property/method descriptions below that use the placeholder `$urls` refers to either `$config->paths` or
* `$config->urls` (or the shorter alias `$urls`). So `$urls->files` (for example) in the definitions below can refer to either
* `$config->paths->files` or `$config->urls->files` (or the shorter alias `$urls->files`). We use `$urls` here because its
* just the shortest option for example purposes.
*
* #pw-body
*
* ProcessWire 3.x, Copyright 2022 by Ryan Cramer
* https://processwire.com
*
* This file is licensed under the MIT license
* https://processwire.com/about/license/mit/
*
* @property string $root Site root: / (or subdirectory if site not at domain root)
* @property string $templates Site templates: /site/templates/
* @property string $fieldTemplates Site field templates /site/templates/fields/ #pw-group-paths-only
* @property string $adminTemplates Admin theme template files: /wire/templates-admin/ or /site/templates-admin/ #pw-internal
* @property string $modules Core modules: /wire/modules/
* @property string $siteModules Site-specific modules: /site/modules/
* @property string $core ProcessWire core files: /wire/core/
* @property string $site ProcessWire site files /site/
* @property string $assets Site-specific assets: /site/assets/
* @property string $cache Site-specific cache: /site/assets/cache/ #pw-group-paths-only
* @property string $logs Site-specific logs: /site/assets/logs/ #pw-group-paths-only
* @property string $files Site-specific files: /site/assets/files/
* @property string $tmp Temporary files: /site/assets/tmp/ #pw-group-paths-only
* @property string $sessions Session files: /site/assets/sessions/ #pw-group-paths-only
* @property string $classes Site-specific class files: /site/classes/ #pw-group-paths-only
*
* The following properties are only in $config->urls
* ==================================================
* @property string $admin Admin URL #pw-group-urls-only
* @property string|null $next URL to next pagination of current page, when applicable (populated by MarkupPagerNav, after render) #pw-group-urls-only #pw-group-pagination
* @property string|null $prev URL to previous pagination of current page, when applicable (populated by MarkupPagerNav, after render) #pw-group-urls-only #pw-group-pagination
*
* The following are in $config->urls and equivalent to previously mentioned properties, but include scheme + host
* ===============================================================================================================
* @property-read string $httpRoot Full http/https URL to site root (i.e. https://domain.com/). #pw-group-urls-only
* @property-read string $httpTemplates Full http/https URL to site templates (i.e. https://domain.com/site/templates/). #pw-group-urls-only
* @property-read string $httpAdminTemplates Full http/https URL to admin templates. #pw-internal
* @property-read string $httpModules Full http/https URL to core (wire) modules. #pw-group-urls-only
* @property-read string $httpSiteModules Full http/https URL to site modules. #pw-group-urls-only
* @property-read string $httpAssets Full http/https URL to site assets (i.e. https://domain.com/site/assets/). #pw-group-urls-only
* @property-read string $httpFiles Full http/https URL to site assets files (i.e. https://domain.com/site/assets/files/). #pw-group-urls-only
* @property-read string $httpNext Full http/https URL to next pagination of current page (when applicable). #pw-group-urls-only #pw-group-pagination
* @property-read string $httpPrev Full http/https URL to prev pagination of current page (when applicable). #pw-group-urls-only #pw-group-pagination
*
* The "http" may be optionally prepended to any property accessed from $config->urls (including those you add yourself).
*
*/
class Paths extends WireData {
/**
* Cached root
*
* @var string
*
*/
protected $_root = '';
/**
* Construct the Paths
*
* @param string $root Path of the root that will be used as a base for stored paths.
*
*/
public function __construct($root) {
$this->_root = $root;
$this->useFuel(false);
}
/**
* Given a path, normalize it to "/" style directory separators if they aren't already
*
* #pw-internal
*
* @static
* @param string $path
* @return string
*
*/
public static function normalizeSeparators($path) {
if(DIRECTORY_SEPARATOR == '/') return $path;
$path = str_replace(DIRECTORY_SEPARATOR, '/', $path);
return $path;
}
/**
* Set a new path/URL location
*
* #pw-group-methods
*
* @param string $key
* @param mixed $value If the first character of the provided path is a slash, then that specific path will be used without modification.
* If the first character is anything other than a slash, then the 'root' variable will be prepended to the path.
* @return Paths|WireData
*
*/
public function set($key, $value) {
if(DIRECTORY_SEPARATOR != '/') $value = self::normalizeSeparators($value);
if($key == 'root') {
$this->_root = $value;
return $this;
}
return parent::set($key, $value);
}
/**
* Return the requested path or URL (functionally the same as direct access)
*
* #pw-group-methods
*
* @param object|string $key
* @return mixed|null|string The requested path variable
*
*/
public function get($key) {
static $_http = null;
if($key === 'root') return $this->_root;
$http = '';
$altKey = '';
if(is_object($key)) {
$key = "$key";
} else if(strpos($key, 'http') === 0) {
if(is_null($_http)) {
$scheme = $this->wire()->input->scheme;
if(!$scheme) $scheme = 'http';
$httpHost = $this->wire()->config->httpHost;
if($httpHost) $_http = "$scheme://$httpHost";
}
$http = $_http;
$key = substr($key, 4); // httpTemplates => Templates
$altKey = $key; // no lowercase conversion (useful for keys like module names, i.e. 'ProcessPageEdit')
$key[0] = strtolower($key[0]); // first character lowercase: Templates => templates
}
if($key === 'root') {
$value = $http . $this->_root;
} else {
$value = parent::get($key);
if($value === null || !strlen($value)) {
if($altKey) $value = parent::get($altKey);
if(empty($value)) return $value;
}
$pos = strpos($value, '//');
if($pos !== false && ($pos === 0 || ($pos > 0 && $value[$pos-1] === ':'))) {
// fully qualified URL
} else if($value[0] == '/' || (DIRECTORY_SEPARATOR != '/' && $value[1] == ':')) {
// path specifies its own root
$value = $http . $value;
} else {
// path needs root prepended
$value = $http . $this->_root . $value;
}
}
return $value;
}
}