mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Merge branch '5.2' into 5
# Conflicts: # src/Core/ClassInfo.php # src/ORM/FieldType/DBForeignKey.php
This commit is contained in:
commit
dcace43183
22
.github/workflows/add-prs-to-project.yml
vendored
Normal file
22
.github/workflows/add-prs-to-project.yml
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
name: Add new PRs to github project
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request_target:
|
||||||
|
types:
|
||||||
|
- opened
|
||||||
|
- ready_for_review
|
||||||
|
|
||||||
|
permissions: {}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
addprtoproject:
|
||||||
|
name: Add PR to GitHub Project
|
||||||
|
# Only run on the silverstripe account
|
||||||
|
if: github.repository_owner == 'silverstripe'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Add PR to github project
|
||||||
|
uses: silverstripe/gha-add-pr-to-project@v1
|
||||||
|
with:
|
||||||
|
app_id: ${{ vars.PROJECT_PERMISSIONS_APP_ID }}
|
||||||
|
private_key: ${{ secrets.PROJECT_PERMISSIONS_APP_PRIVATE_KEY }}
|
@ -116,7 +116,7 @@ class ContentNegotiator
|
|||||||
*/
|
*/
|
||||||
public static function process(HTTPResponse $response)
|
public static function process(HTTPResponse $response)
|
||||||
{
|
{
|
||||||
if (!self::enabled_for($response)) {
|
if (!ContentNegotiator::enabled_for($response)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -573,7 +573,7 @@ class Controller extends RequestHandler implements TemplateGlobalProvider
|
|||||||
{
|
{
|
||||||
// Ensure this controller has a valid session
|
// Ensure this controller has a valid session
|
||||||
$this->getRequest()->getSession();
|
$this->getRequest()->getSession();
|
||||||
array_unshift(self::$controller_stack, $this);
|
array_unshift(Controller::$controller_stack, $this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -581,8 +581,8 @@ class Controller extends RequestHandler implements TemplateGlobalProvider
|
|||||||
*/
|
*/
|
||||||
public function popCurrent()
|
public function popCurrent()
|
||||||
{
|
{
|
||||||
if ($this === self::$controller_stack[0]) {
|
if ($this === Controller::$controller_stack[0]) {
|
||||||
array_shift(self::$controller_stack);
|
array_shift(Controller::$controller_stack);
|
||||||
} else {
|
} else {
|
||||||
$class = static::class;
|
$class = static::class;
|
||||||
user_error(
|
user_error(
|
||||||
@ -693,7 +693,7 @@ class Controller extends RequestHandler implements TemplateGlobalProvider
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Normlise trailing slash
|
// Normlise trailing slash
|
||||||
$shouldHaveTrailingSlash = self::config()->uninherited('add_trailing_slash');
|
$shouldHaveTrailingSlash = Controller::config()->uninherited('add_trailing_slash');
|
||||||
if ($shouldHaveTrailingSlash
|
if ($shouldHaveTrailingSlash
|
||||||
&& !str_ends_with($url, '/')
|
&& !str_ends_with($url, '/')
|
||||||
&& !preg_match('/^(.*)\.([^\/]*)$/', Director::makeRelative($url))
|
&& !preg_match('/^(.*)\.([^\/]*)$/', Director::makeRelative($url))
|
||||||
|
@ -31,7 +31,7 @@ class Cookie
|
|||||||
* Must be "Strict", "Lax", or "None"
|
* Must be "Strict", "Lax", or "None"
|
||||||
* @config
|
* @config
|
||||||
*/
|
*/
|
||||||
private static string $default_samesite = self::SAMESITE_LAX;
|
private static string $default_samesite = Cookie::SAMESITE_LAX;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch the current instance of the cookie backend.
|
* Fetch the current instance of the cookie backend.
|
||||||
@ -67,7 +67,7 @@ class Cookie
|
|||||||
$secure = false,
|
$secure = false,
|
||||||
$httpOnly = true
|
$httpOnly = true
|
||||||
) {
|
) {
|
||||||
return self::get_inst()->set($name, $value, $expiry, $path, $domain, $secure, $httpOnly);
|
return Cookie::get_inst()->set($name, $value, $expiry, $path, $domain, $secure, $httpOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -80,7 +80,7 @@ class Cookie
|
|||||||
*/
|
*/
|
||||||
public static function get($name, $includeUnsent = true)
|
public static function get($name, $includeUnsent = true)
|
||||||
{
|
{
|
||||||
return self::get_inst()->get($name, $includeUnsent);
|
return Cookie::get_inst()->get($name, $includeUnsent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -92,7 +92,7 @@ class Cookie
|
|||||||
*/
|
*/
|
||||||
public static function get_all($includeUnsent = true)
|
public static function get_all($includeUnsent = true)
|
||||||
{
|
{
|
||||||
return self::get_inst()->getAll($includeUnsent);
|
return Cookie::get_inst()->getAll($includeUnsent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -104,7 +104,7 @@ class Cookie
|
|||||||
*/
|
*/
|
||||||
public static function force_expiry($name, $path = null, $domain = null, $secure = false, $httpOnly = true)
|
public static function force_expiry($name, $path = null, $domain = null, $secure = false, $httpOnly = true)
|
||||||
{
|
{
|
||||||
return self::get_inst()->forceExpiry($name, $path, $domain, $secure, $httpOnly);
|
return Cookie::get_inst()->forceExpiry($name, $path, $domain, $secure, $httpOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -116,14 +116,14 @@ class Cookie
|
|||||||
public static function validateSameSite(string $sameSite): void
|
public static function validateSameSite(string $sameSite): void
|
||||||
{
|
{
|
||||||
$validValues = [
|
$validValues = [
|
||||||
self::SAMESITE_STRICT,
|
Cookie::SAMESITE_STRICT,
|
||||||
self::SAMESITE_LAX,
|
Cookie::SAMESITE_LAX,
|
||||||
self::SAMESITE_NONE,
|
Cookie::SAMESITE_NONE,
|
||||||
];
|
];
|
||||||
if (!in_array($sameSite, $validValues)) {
|
if (!in_array($sameSite, $validValues)) {
|
||||||
throw new LogicException('Cookie samesite must be "Strict", "Lax", or "None"');
|
throw new LogicException('Cookie samesite must be "Strict", "Lax", or "None"');
|
||||||
}
|
}
|
||||||
if ($sameSite === self::SAMESITE_NONE && !Director::is_https(self::getRequest())) {
|
if ($sameSite === Cookie::SAMESITE_NONE && !Director::is_https(Cookie::getRequest())) {
|
||||||
Injector::inst()->get(LoggerInterface::class)->warning('Cookie samesite cannot be "None" for non-https requests.');
|
Injector::inst()->get(LoggerInterface::class)->warning('Cookie samesite cannot be "None" for non-https requests.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -238,7 +238,7 @@ class Director implements TemplateGlobalProvider
|
|||||||
|
|
||||||
// Ensure URL is properly made relative.
|
// Ensure URL is properly made relative.
|
||||||
// Example: url passed is "/ss31/my-page" (prefixed with BASE_URL), this should be changed to "my-page"
|
// Example: url passed is "/ss31/my-page" (prefixed with BASE_URL), this should be changed to "my-page"
|
||||||
$url = self::makeRelative($url);
|
$url = Director::makeRelative($url);
|
||||||
if (strpos($url ?? '', '?') !== false) {
|
if (strpos($url ?? '', '?') !== false) {
|
||||||
list($url, $getVarsEncoded) = explode('?', $url ?? '', 2);
|
list($url, $getVarsEncoded) = explode('?', $url ?? '', 2);
|
||||||
parse_str($getVarsEncoded ?? '', $newVars['_GET']);
|
parse_str($getVarsEncoded ?? '', $newVars['_GET']);
|
||||||
@ -371,7 +371,7 @@ class Director implements TemplateGlobalProvider
|
|||||||
*/
|
*/
|
||||||
public static function get_current_page()
|
public static function get_current_page()
|
||||||
{
|
{
|
||||||
return self::$current_page ? self::$current_page : Controller::curr();
|
return Director::$current_page ? Director::$current_page : Controller::curr();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -381,7 +381,7 @@ class Director implements TemplateGlobalProvider
|
|||||||
*/
|
*/
|
||||||
public static function set_current_page($page)
|
public static function set_current_page($page)
|
||||||
{
|
{
|
||||||
self::$current_page = $page;
|
Director::$current_page = $page;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -394,7 +394,7 @@ class Director implements TemplateGlobalProvider
|
|||||||
* - REQUEST - Resolve this path to the current url (i.e. behaves as though no `<base>` tag is provided in a html document)
|
* - REQUEST - Resolve this path to the current url (i.e. behaves as though no `<base>` tag is provided in a html document)
|
||||||
* - ROOT - Treat this as though it was an absolute path, and append it to the protocol and hostname.
|
* - ROOT - Treat this as though it was an absolute path, and append it to the protocol and hostname.
|
||||||
*/
|
*/
|
||||||
public static function absoluteURL(string $url, string $relativeParent = self::BASE): string|bool
|
public static function absoluteURL(string $url, string $relativeParent = Director::BASE): string|bool
|
||||||
{
|
{
|
||||||
// Check if there is already a protocol given
|
// Check if there is already a protocol given
|
||||||
if (preg_match('/^http(s?):\/\//', $url ?? '')) {
|
if (preg_match('/^http(s?):\/\//', $url ?? '')) {
|
||||||
@ -404,14 +404,14 @@ class Director implements TemplateGlobalProvider
|
|||||||
// Absolute urls without protocol are added
|
// Absolute urls without protocol are added
|
||||||
// E.g. //google.com -> http://google.com
|
// E.g. //google.com -> http://google.com
|
||||||
if (strpos($url ?? '', '//') === 0) {
|
if (strpos($url ?? '', '//') === 0) {
|
||||||
return Controller::normaliseTrailingSlash(self::protocol() . substr($url ?? '', 2));
|
return Controller::normaliseTrailingSlash(Director::protocol() . substr($url ?? '', 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine method for mapping the parent to this relative url
|
// Determine method for mapping the parent to this relative url
|
||||||
if ($relativeParent === self::ROOT || self::is_root_relative_url($url)) {
|
if ($relativeParent === Director::ROOT || Director::is_root_relative_url($url)) {
|
||||||
// Root relative urls always should be evaluated relative to the root
|
// Root relative urls always should be evaluated relative to the root
|
||||||
$parent = self::protocolAndHost();
|
$parent = Director::protocolAndHost();
|
||||||
} elseif ($relativeParent === self::REQUEST) {
|
} elseif ($relativeParent === Director::REQUEST) {
|
||||||
// Request relative urls rely on the REQUEST_URI param (old default behaviour)
|
// Request relative urls rely on the REQUEST_URI param (old default behaviour)
|
||||||
if (!isset($_SERVER['REQUEST_URI'])) {
|
if (!isset($_SERVER['REQUEST_URI'])) {
|
||||||
return false;
|
return false;
|
||||||
@ -419,7 +419,7 @@ class Director implements TemplateGlobalProvider
|
|||||||
$parent = dirname($_SERVER['REQUEST_URI'] . 'x');
|
$parent = dirname($_SERVER['REQUEST_URI'] . 'x');
|
||||||
} else {
|
} else {
|
||||||
// Default to respecting site base_url
|
// Default to respecting site base_url
|
||||||
$parent = self::absoluteBaseURL();
|
$parent = Director::absoluteBaseURL();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map empty urls to relative slash and join to base
|
// Map empty urls to relative slash and join to base
|
||||||
@ -489,7 +489,7 @@ class Director implements TemplateGlobalProvider
|
|||||||
public static function host(HTTPRequest $request = null)
|
public static function host(HTTPRequest $request = null)
|
||||||
{
|
{
|
||||||
// Check if overridden by alternate_base_url
|
// Check if overridden by alternate_base_url
|
||||||
if ($baseURL = self::config()->get('alternate_base_url')) {
|
if ($baseURL = static::config()->get('alternate_base_url')) {
|
||||||
$baseURL = Injector::inst()->convertServiceProperty($baseURL);
|
$baseURL = Injector::inst()->convertServiceProperty($baseURL);
|
||||||
$host = static::parseHost($baseURL);
|
$host = static::parseHost($baseURL);
|
||||||
if ($host) {
|
if ($host) {
|
||||||
@ -508,7 +508,7 @@ class Director implements TemplateGlobalProvider
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check base url
|
// Check base url
|
||||||
if ($baseURL = self::config()->uninherited('default_base_url')) {
|
if ($baseURL = static::config()->uninherited('default_base_url')) {
|
||||||
$baseURL = Injector::inst()->convertServiceProperty($baseURL);
|
$baseURL = Injector::inst()->convertServiceProperty($baseURL);
|
||||||
$host = static::parseHost($baseURL);
|
$host = static::parseHost($baseURL);
|
||||||
if ($host) {
|
if ($host) {
|
||||||
@ -566,7 +566,7 @@ class Director implements TemplateGlobalProvider
|
|||||||
*/
|
*/
|
||||||
public static function protocol(HTTPRequest $request = null)
|
public static function protocol(HTTPRequest $request = null)
|
||||||
{
|
{
|
||||||
return (self::is_https($request)) ? 'https://' : 'http://';
|
return (Director::is_https($request)) ? 'https://' : 'http://';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -578,7 +578,7 @@ class Director implements TemplateGlobalProvider
|
|||||||
public static function is_https(HTTPRequest $request = null)
|
public static function is_https(HTTPRequest $request = null)
|
||||||
{
|
{
|
||||||
// Check override from alternate_base_url
|
// Check override from alternate_base_url
|
||||||
if ($baseURL = self::config()->uninherited('alternate_base_url')) {
|
if ($baseURL = static::config()->uninherited('alternate_base_url')) {
|
||||||
$baseURL = Injector::inst()->convertServiceProperty($baseURL);
|
$baseURL = Injector::inst()->convertServiceProperty($baseURL);
|
||||||
$protocol = parse_url($baseURL ?? '', PHP_URL_SCHEME);
|
$protocol = parse_url($baseURL ?? '', PHP_URL_SCHEME);
|
||||||
if ($protocol) {
|
if ($protocol) {
|
||||||
@ -593,7 +593,7 @@ class Director implements TemplateGlobalProvider
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check default_base_url
|
// Check default_base_url
|
||||||
if ($baseURL = self::config()->uninherited('default_base_url')) {
|
if ($baseURL = static::config()->uninherited('default_base_url')) {
|
||||||
$baseURL = Injector::inst()->convertServiceProperty($baseURL);
|
$baseURL = Injector::inst()->convertServiceProperty($baseURL);
|
||||||
$protocol = parse_url($baseURL ?? '', PHP_URL_SCHEME);
|
$protocol = parse_url($baseURL ?? '', PHP_URL_SCHEME);
|
||||||
if ($protocol) {
|
if ($protocol) {
|
||||||
@ -612,7 +612,7 @@ class Director implements TemplateGlobalProvider
|
|||||||
public static function baseURL()
|
public static function baseURL()
|
||||||
{
|
{
|
||||||
// Check override base_url
|
// Check override base_url
|
||||||
$alternate = self::config()->get('alternate_base_url');
|
$alternate = static::config()->get('alternate_base_url');
|
||||||
if ($alternate) {
|
if ($alternate) {
|
||||||
$alternate = Injector::inst()->convertServiceProperty($alternate);
|
$alternate = Injector::inst()->convertServiceProperty($alternate);
|
||||||
return rtrim(parse_url($alternate ?? '', PHP_URL_PATH) ?? '', '/') . '/';
|
return rtrim(parse_url($alternate ?? '', PHP_URL_PATH) ?? '', '/') . '/';
|
||||||
@ -659,8 +659,8 @@ class Director implements TemplateGlobalProvider
|
|||||||
*/
|
*/
|
||||||
public static function publicFolder()
|
public static function publicFolder()
|
||||||
{
|
{
|
||||||
$folder = self::baseFolder();
|
$folder = Director::baseFolder();
|
||||||
$publicDir = self::publicDir();
|
$publicDir = Director::publicDir();
|
||||||
if ($publicDir) {
|
if ($publicDir) {
|
||||||
return Path::join($folder, $publicDir);
|
return Path::join($folder, $publicDir);
|
||||||
}
|
}
|
||||||
@ -694,7 +694,7 @@ class Director implements TemplateGlobalProvider
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remove base folder or url
|
// Remove base folder or url
|
||||||
foreach ([self::publicFolder(), self::baseFolder(), self::baseURL()] as $base) {
|
foreach ([Director::publicFolder(), Director::baseFolder(), Director::baseURL()] as $base) {
|
||||||
// Ensure single / doesn't break comparison (unless it would make base empty)
|
// Ensure single / doesn't break comparison (unless it would make base empty)
|
||||||
$base = rtrim($base ?? '', '\\/') ?: $base;
|
$base = rtrim($base ?? '', '\\/') ?: $base;
|
||||||
if (stripos($url ?? '', $base ?? '') === 0) {
|
if (stripos($url ?? '', $base ?? '') === 0) {
|
||||||
@ -827,7 +827,7 @@ class Director implements TemplateGlobalProvider
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Relative urls always are site urls
|
// Relative urls always are site urls
|
||||||
return self::is_relative_url($url);
|
return Director::is_relative_url($url);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -840,20 +840,20 @@ class Director implements TemplateGlobalProvider
|
|||||||
public static function getAbsFile($file)
|
public static function getAbsFile($file)
|
||||||
{
|
{
|
||||||
// If already absolute
|
// If already absolute
|
||||||
if (self::is_absolute($file)) {
|
if (Director::is_absolute($file)) {
|
||||||
return $file;
|
return $file;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If path is relative to public folder search there first
|
// If path is relative to public folder search there first
|
||||||
if (self::publicDir()) {
|
if (Director::publicDir()) {
|
||||||
$path = Path::join(self::publicFolder(), $file);
|
$path = Path::join(Director::publicFolder(), $file);
|
||||||
if (file_exists($path ?? '')) {
|
if (file_exists($path ?? '')) {
|
||||||
return $path;
|
return $path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default to base folder
|
// Default to base folder
|
||||||
return Path::join(self::baseFolder(), $file);
|
return Path::join(Director::baseFolder(), $file);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -877,9 +877,9 @@ class Director implements TemplateGlobalProvider
|
|||||||
*/
|
*/
|
||||||
public static function absoluteBaseURL()
|
public static function absoluteBaseURL()
|
||||||
{
|
{
|
||||||
$baseURL = self::absoluteURL(
|
$baseURL = Director::absoluteURL(
|
||||||
self::baseURL(),
|
Director::baseURL(),
|
||||||
self::ROOT
|
Director::ROOT
|
||||||
);
|
);
|
||||||
return Controller::normaliseTrailingSlash($baseURL);
|
return Controller::normaliseTrailingSlash($baseURL);
|
||||||
}
|
}
|
||||||
@ -986,7 +986,7 @@ class Director implements TemplateGlobalProvider
|
|||||||
*/
|
*/
|
||||||
public static function is_ajax(HTTPRequest $request = null)
|
public static function is_ajax(HTTPRequest $request = null)
|
||||||
{
|
{
|
||||||
$request = self::currentRequest($request);
|
$request = Director::currentRequest($request);
|
||||||
if ($request) {
|
if ($request) {
|
||||||
return $request->isAjax();
|
return $request->isAjax();
|
||||||
}
|
}
|
||||||
@ -1054,7 +1054,7 @@ class Director implements TemplateGlobalProvider
|
|||||||
*/
|
*/
|
||||||
public static function isLive()
|
public static function isLive()
|
||||||
{
|
{
|
||||||
return self::get_environment_type() === 'live';
|
return Director::get_environment_type() === 'live';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1065,7 +1065,7 @@ class Director implements TemplateGlobalProvider
|
|||||||
*/
|
*/
|
||||||
public static function isDev()
|
public static function isDev()
|
||||||
{
|
{
|
||||||
return self::get_environment_type() === 'dev';
|
return Director::get_environment_type() === 'dev';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1076,7 +1076,7 @@ class Director implements TemplateGlobalProvider
|
|||||||
*/
|
*/
|
||||||
public static function isTest()
|
public static function isTest()
|
||||||
{
|
{
|
||||||
return self::get_environment_type() === 'test';
|
return Director::get_environment_type() === 'test';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -104,10 +104,10 @@ class Email extends SymfonyEmail
|
|||||||
{
|
{
|
||||||
$addresses = [];
|
$addresses = [];
|
||||||
$config = (array) static::config()->get($configKey);
|
$config = (array) static::config()->get($configKey);
|
||||||
$addresses = self::convertConfigToAddreses($config);
|
$addresses = Email::convertConfigToAddreses($config);
|
||||||
$env = Environment::getEnv($envKey);
|
$env = Environment::getEnv($envKey);
|
||||||
if ($env) {
|
if ($env) {
|
||||||
$addresses = array_merge($addresses, self::convertConfigToAddreses($env));
|
$addresses = array_merge($addresses, Email::convertConfigToAddreses($env));
|
||||||
}
|
}
|
||||||
return $addresses;
|
return $addresses;
|
||||||
}
|
}
|
||||||
@ -403,7 +403,7 @@ class Email extends SymfonyEmail
|
|||||||
}
|
}
|
||||||
|
|
||||||
return ThemeResourceLoader::inst()->findTemplate(
|
return ThemeResourceLoader::inst()->findTemplate(
|
||||||
SSViewer::get_templates_by_class(static::class, '', self::class),
|
SSViewer::get_templates_by_class(static::class, '', Email::class),
|
||||||
SSViewer::get_themes()
|
SSViewer::get_themes()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -226,7 +226,7 @@ class HTTP
|
|||||||
*/
|
*/
|
||||||
public static function RAW_setGetVar($varname, $varvalue, $currentURL = null)
|
public static function RAW_setGetVar($varname, $varvalue, $currentURL = null)
|
||||||
{
|
{
|
||||||
$url = self::setGetVar($varname, $varvalue, $currentURL);
|
$url = HTTP::setGetVar($varname, $varvalue, $currentURL);
|
||||||
return Convert::xml2raw($url);
|
return Convert::xml2raw($url);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,7 +268,7 @@ class HTTP
|
|||||||
*/
|
*/
|
||||||
public static function getLinksIn($content)
|
public static function getLinksIn($content)
|
||||||
{
|
{
|
||||||
return self::findByTagAndAttribute($content, ["a" => "href"]);
|
return HTTP::findByTagAndAttribute($content, ["a" => "href"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -278,7 +278,7 @@ class HTTP
|
|||||||
*/
|
*/
|
||||||
public static function getImagesIn($content)
|
public static function getImagesIn($content)
|
||||||
{
|
{
|
||||||
return self::findByTagAndAttribute($content, ["img" => "src"]);
|
return HTTP::findByTagAndAttribute($content, ["img" => "src"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -850,7 +850,7 @@ class HTTPRequest implements ArrayAccess
|
|||||||
*/
|
*/
|
||||||
public function setHttpMethod($method)
|
public function setHttpMethod($method)
|
||||||
{
|
{
|
||||||
if (!self::isValidHttpMethod($method)) {
|
if (!HTTPRequest::isValidHttpMethod($method)) {
|
||||||
throw new \InvalidArgumentException('HTTPRequest::setHttpMethod: Invalid HTTP method');
|
throw new \InvalidArgumentException('HTTPRequest::setHttpMethod: Invalid HTTP method');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,7 +174,7 @@ class HTTPResponse
|
|||||||
*/
|
*/
|
||||||
public function setStatusCode($code, $description = null)
|
public function setStatusCode($code, $description = null)
|
||||||
{
|
{
|
||||||
if (isset(self::$status_codes[$code])) {
|
if (isset(HTTPResponse::$status_codes[$code])) {
|
||||||
$this->statusCode = $code;
|
$this->statusCode = $code;
|
||||||
} else {
|
} else {
|
||||||
throw new InvalidArgumentException("Unrecognised HTTP status code '$code'");
|
throw new InvalidArgumentException("Unrecognised HTTP status code '$code'");
|
||||||
@ -183,7 +183,7 @@ class HTTPResponse
|
|||||||
if ($description) {
|
if ($description) {
|
||||||
$this->statusDescription = $description;
|
$this->statusDescription = $description;
|
||||||
} else {
|
} else {
|
||||||
$this->statusDescription = self::$status_codes[$code];
|
$this->statusDescription = HTTPResponse::$status_codes[$code];
|
||||||
}
|
}
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -320,7 +320,7 @@ class HTTPResponse
|
|||||||
|
|
||||||
public function redirect(string $dest, int $code = 302): static
|
public function redirect(string $dest, int $code = 302): static
|
||||||
{
|
{
|
||||||
if (!in_array($code, self::$redirect_codes)) {
|
if (!in_array($code, HTTPResponse::$redirect_codes)) {
|
||||||
trigger_error("Invalid HTTP redirect code {$code}", E_USER_WARNING);
|
trigger_error("Invalid HTTP redirect code {$code}", E_USER_WARNING);
|
||||||
$code = 302;
|
$code = 302;
|
||||||
}
|
}
|
||||||
@ -439,7 +439,7 @@ EOT
|
|||||||
*/
|
*/
|
||||||
public function isRedirect()
|
public function isRedirect()
|
||||||
{
|
{
|
||||||
return in_array($this->getStatusCode(), self::$redirect_codes);
|
return in_array($this->getStatusCode(), HTTPResponse::$redirect_codes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -68,20 +68,20 @@ class HTTPCacheControlMiddleware implements HTTPMiddleware, Resettable
|
|||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $stateDirectives = [
|
protected $stateDirectives = [
|
||||||
self::STATE_DISABLED => [
|
HTTPCacheControlMiddleware::STATE_DISABLED => [
|
||||||
'no-cache' => true,
|
'no-cache' => true,
|
||||||
'no-store' => true,
|
'no-store' => true,
|
||||||
'must-revalidate' => true,
|
'must-revalidate' => true,
|
||||||
],
|
],
|
||||||
self::STATE_PRIVATE => [
|
HTTPCacheControlMiddleware::STATE_PRIVATE => [
|
||||||
'private' => true,
|
'private' => true,
|
||||||
'must-revalidate' => true,
|
'must-revalidate' => true,
|
||||||
],
|
],
|
||||||
self::STATE_PUBLIC => [
|
HTTPCacheControlMiddleware::STATE_PUBLIC => [
|
||||||
'public' => true,
|
'public' => true,
|
||||||
'must-revalidate' => true,
|
'must-revalidate' => true,
|
||||||
],
|
],
|
||||||
self::STATE_ENABLED => [
|
HTTPCacheControlMiddleware::STATE_ENABLED => [
|
||||||
'no-cache' => true,
|
'no-cache' => true,
|
||||||
'must-revalidate' => true,
|
'must-revalidate' => true,
|
||||||
]
|
]
|
||||||
@ -93,7 +93,7 @@ class HTTPCacheControlMiddleware implements HTTPMiddleware, Resettable
|
|||||||
* @config
|
* @config
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private static $defaultState = self::STATE_ENABLED;
|
private static $defaultState = HTTPCacheControlMiddleware::STATE_ENABLED;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Current state
|
* Current state
|
||||||
@ -307,7 +307,7 @@ class HTTPCacheControlMiddleware implements HTTPMiddleware, Resettable
|
|||||||
*/
|
*/
|
||||||
protected function applyChangeLevel($level, $force)
|
protected function applyChangeLevel($level, $force)
|
||||||
{
|
{
|
||||||
$forcingLevel = $level + ($force ? self::LEVEL_FORCED : 0);
|
$forcingLevel = $level + ($force ? HTTPCacheControlMiddleware::LEVEL_FORCED : 0);
|
||||||
if ($forcingLevel < $this->getForcingLevel()) {
|
if ($forcingLevel < $this->getForcingLevel()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -465,7 +465,7 @@ class HTTPCacheControlMiddleware implements HTTPMiddleware, Resettable
|
|||||||
public function setNoStore($noStore = true)
|
public function setNoStore($noStore = true)
|
||||||
{
|
{
|
||||||
// Affect all non-disabled states
|
// Affect all non-disabled states
|
||||||
$applyTo = [self::STATE_ENABLED, self::STATE_PRIVATE, self::STATE_PUBLIC];
|
$applyTo = [HTTPCacheControlMiddleware::STATE_ENABLED, HTTPCacheControlMiddleware::STATE_PRIVATE, HTTPCacheControlMiddleware::STATE_PUBLIC];
|
||||||
if ($noStore) {
|
if ($noStore) {
|
||||||
$this->setStateDirective($applyTo, 'no-store');
|
$this->setStateDirective($applyTo, 'no-store');
|
||||||
$this->removeStateDirective($applyTo, 'max-age');
|
$this->removeStateDirective($applyTo, 'max-age');
|
||||||
@ -486,7 +486,7 @@ class HTTPCacheControlMiddleware implements HTTPMiddleware, Resettable
|
|||||||
public function setNoCache($noCache = true)
|
public function setNoCache($noCache = true)
|
||||||
{
|
{
|
||||||
// Affect all non-disabled states
|
// Affect all non-disabled states
|
||||||
$applyTo = [self::STATE_ENABLED, self::STATE_PRIVATE, self::STATE_PUBLIC];
|
$applyTo = [HTTPCacheControlMiddleware::STATE_ENABLED, HTTPCacheControlMiddleware::STATE_PRIVATE, HTTPCacheControlMiddleware::STATE_PUBLIC];
|
||||||
if ($noCache) {
|
if ($noCache) {
|
||||||
$this->setStateDirective($applyTo, 'no-cache');
|
$this->setStateDirective($applyTo, 'no-cache');
|
||||||
$this->removeStateDirective($applyTo, 'max-age');
|
$this->removeStateDirective($applyTo, 'max-age');
|
||||||
@ -509,7 +509,7 @@ class HTTPCacheControlMiddleware implements HTTPMiddleware, Resettable
|
|||||||
public function setMaxAge($age)
|
public function setMaxAge($age)
|
||||||
{
|
{
|
||||||
// Affect all non-disabled states
|
// Affect all non-disabled states
|
||||||
$applyTo = [self::STATE_ENABLED, self::STATE_PRIVATE, self::STATE_PUBLIC];
|
$applyTo = [HTTPCacheControlMiddleware::STATE_ENABLED, HTTPCacheControlMiddleware::STATE_PRIVATE, HTTPCacheControlMiddleware::STATE_PUBLIC];
|
||||||
$this->setStateDirective($applyTo, 'max-age', $age);
|
$this->setStateDirective($applyTo, 'max-age', $age);
|
||||||
if ($age) {
|
if ($age) {
|
||||||
$this->removeStateDirective($applyTo, 'no-cache');
|
$this->removeStateDirective($applyTo, 'no-cache');
|
||||||
@ -529,7 +529,7 @@ class HTTPCacheControlMiddleware implements HTTPMiddleware, Resettable
|
|||||||
public function setSharedMaxAge($age)
|
public function setSharedMaxAge($age)
|
||||||
{
|
{
|
||||||
// Affect all non-disabled states
|
// Affect all non-disabled states
|
||||||
$applyTo = [self::STATE_ENABLED, self::STATE_PRIVATE, self::STATE_PUBLIC];
|
$applyTo = [HTTPCacheControlMiddleware::STATE_ENABLED, HTTPCacheControlMiddleware::STATE_PRIVATE, HTTPCacheControlMiddleware::STATE_PUBLIC];
|
||||||
$this->setStateDirective($applyTo, 's-maxage', $age);
|
$this->setStateDirective($applyTo, 's-maxage', $age);
|
||||||
if ($age) {
|
if ($age) {
|
||||||
$this->removeStateDirective($applyTo, 'no-cache');
|
$this->removeStateDirective($applyTo, 'no-cache');
|
||||||
@ -547,7 +547,7 @@ class HTTPCacheControlMiddleware implements HTTPMiddleware, Resettable
|
|||||||
*/
|
*/
|
||||||
public function setMustRevalidate($mustRevalidate = true)
|
public function setMustRevalidate($mustRevalidate = true)
|
||||||
{
|
{
|
||||||
$applyTo = [self::STATE_ENABLED, self::STATE_PRIVATE, self::STATE_PUBLIC];
|
$applyTo = [HTTPCacheControlMiddleware::STATE_ENABLED, HTTPCacheControlMiddleware::STATE_PRIVATE, HTTPCacheControlMiddleware::STATE_PUBLIC];
|
||||||
$this->setStateDirective($applyTo, 'must-revalidate', $mustRevalidate);
|
$this->setStateDirective($applyTo, 'must-revalidate', $mustRevalidate);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -569,8 +569,8 @@ class HTTPCacheControlMiddleware implements HTTPMiddleware, Resettable
|
|||||||
public function enableCache($force = false, $maxAge = null)
|
public function enableCache($force = false, $maxAge = null)
|
||||||
{
|
{
|
||||||
// Only execute this if its forcing level is high enough
|
// Only execute this if its forcing level is high enough
|
||||||
if ($this->applyChangeLevel(self::LEVEL_ENABLED, $force)) {
|
if ($this->applyChangeLevel(HTTPCacheControlMiddleware::LEVEL_ENABLED, $force)) {
|
||||||
$this->setState(self::STATE_ENABLED);
|
$this->setState(HTTPCacheControlMiddleware::STATE_ENABLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_null($maxAge)) {
|
if (!is_null($maxAge)) {
|
||||||
@ -600,8 +600,8 @@ class HTTPCacheControlMiddleware implements HTTPMiddleware, Resettable
|
|||||||
public function disableCache($force = false)
|
public function disableCache($force = false)
|
||||||
{
|
{
|
||||||
// Only execute this if its forcing level is high enough
|
// Only execute this if its forcing level is high enough
|
||||||
if ($this->applyChangeLevel(self::LEVEL_DISABLED, $force)) {
|
if ($this->applyChangeLevel(HTTPCacheControlMiddleware::LEVEL_DISABLED, $force)) {
|
||||||
$this->setState(self::STATE_DISABLED);
|
$this->setState(HTTPCacheControlMiddleware::STATE_DISABLED);
|
||||||
}
|
}
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -620,8 +620,8 @@ class HTTPCacheControlMiddleware implements HTTPMiddleware, Resettable
|
|||||||
public function privateCache($force = false)
|
public function privateCache($force = false)
|
||||||
{
|
{
|
||||||
// Only execute this if its forcing level is high enough
|
// Only execute this if its forcing level is high enough
|
||||||
if ($this->applyChangeLevel(self::LEVEL_PRIVATE, $force)) {
|
if ($this->applyChangeLevel(HTTPCacheControlMiddleware::LEVEL_PRIVATE, $force)) {
|
||||||
$this->setState(self::STATE_PRIVATE);
|
$this->setState(HTTPCacheControlMiddleware::STATE_PRIVATE);
|
||||||
}
|
}
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -641,8 +641,8 @@ class HTTPCacheControlMiddleware implements HTTPMiddleware, Resettable
|
|||||||
public function publicCache($force = false, $maxAge = null)
|
public function publicCache($force = false, $maxAge = null)
|
||||||
{
|
{
|
||||||
// Only execute this if its forcing level is high enough
|
// Only execute this if its forcing level is high enough
|
||||||
if ($this->applyChangeLevel(self::LEVEL_PUBLIC, $force)) {
|
if ($this->applyChangeLevel(HTTPCacheControlMiddleware::LEVEL_PUBLIC, $force)) {
|
||||||
$this->setState(self::STATE_PUBLIC);
|
$this->setState(HTTPCacheControlMiddleware::STATE_PUBLIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_null($maxAge)) {
|
if (!is_null($maxAge)) {
|
||||||
|
@ -130,7 +130,7 @@ class RequestHandler extends ViewableData
|
|||||||
/**
|
/**
|
||||||
* Handles URL requests.
|
* Handles URL requests.
|
||||||
*
|
*
|
||||||
* - ViewableData::handleRequest() iterates through each rule in {@link self::$url_handlers}.
|
* - ViewableData::handleRequest() iterates through each rule in {@link RequestHandler::$url_handlers}.
|
||||||
* - If the rule matches, the named method will be called.
|
* - If the rule matches, the named method will be called.
|
||||||
* - If there is still more URL to be processed, then handleRequest()
|
* - If there is still more URL to be processed, then handleRequest()
|
||||||
* is called on the object that that method returns.
|
* is called on the object that that method returns.
|
||||||
@ -445,7 +445,7 @@ class RequestHandler extends ViewableData
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Check that the given action is allowed to be called from a URL.
|
* Check that the given action is allowed to be called from a URL.
|
||||||
* It will interrogate {@link self::$allowed_actions} to determine this.
|
* It will interrogate {@link RequestHandler::$allowed_actions} to determine this.
|
||||||
*
|
*
|
||||||
* @param string $action
|
* @param string $action
|
||||||
* @return bool
|
* @return bool
|
||||||
|
@ -235,7 +235,7 @@ class Session
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Funny business detected!
|
// Funny business detected!
|
||||||
if (self::config()->get('strict_user_agent_check') && isset($this->data['HTTP_USER_AGENT'])) {
|
if (static::config()->get('strict_user_agent_check') && isset($this->data['HTTP_USER_AGENT'])) {
|
||||||
if ($this->data['HTTP_USER_AGENT'] !== $this->userAgent($request)) {
|
if ($this->data['HTTP_USER_AGENT'] !== $this->userAgent($request)) {
|
||||||
$this->clearAll();
|
$this->clearAll();
|
||||||
$this->restart($request);
|
$this->restart($request);
|
||||||
|
@ -44,7 +44,7 @@ class IPUtils
|
|||||||
$method = substr_count($requestIP ?? '', ':') > 1 ? 'checkIP6' : 'checkIP4';
|
$method = substr_count($requestIP ?? '', ':') > 1 ? 'checkIP6' : 'checkIP4';
|
||||||
|
|
||||||
foreach ($ips as $ip) {
|
foreach ($ips as $ip) {
|
||||||
if (self::$method($requestIP, trim($ip ?? ''))) {
|
if (IPUtils::$method($requestIP, trim($ip ?? ''))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -140,7 +140,7 @@ abstract class BaseKernel implements Kernel
|
|||||||
*/
|
*/
|
||||||
protected function bootPHP()
|
protected function bootPHP()
|
||||||
{
|
{
|
||||||
if ($this->getEnvironment() === self::LIVE) {
|
if ($this->getEnvironment() === BaseKernel::LIVE) {
|
||||||
// limited to fatal errors and warnings in live mode
|
// limited to fatal errors and warnings in live mode
|
||||||
error_reporting(E_ALL & ~(E_DEPRECATED | E_STRICT | E_NOTICE));
|
error_reporting(E_ALL & ~(E_DEPRECATED | E_STRICT | E_NOTICE));
|
||||||
} else {
|
} else {
|
||||||
@ -263,7 +263,7 @@ abstract class BaseKernel implements Kernel
|
|||||||
return $env;
|
return $env;
|
||||||
}
|
}
|
||||||
|
|
||||||
return self::LIVE;
|
return BaseKernel::LIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract public function boot($flush = false);
|
abstract public function boot($flush = false);
|
||||||
@ -431,7 +431,7 @@ abstract class BaseKernel implements Kernel
|
|||||||
|
|
||||||
public function setEnvironment($environment)
|
public function setEnvironment($environment)
|
||||||
{
|
{
|
||||||
if (!in_array($environment, [self::DEV, self::TEST, self::LIVE, null])) {
|
if (!in_array($environment, [BaseKernel::DEV, BaseKernel::TEST, BaseKernel::LIVE, null])) {
|
||||||
throw new InvalidArgumentException(
|
throw new InvalidArgumentException(
|
||||||
"Director::set_environment_type passed '$environment'. It should be passed dev, test, or live"
|
"Director::set_environment_type passed '$environment'. It should be passed dev, test, or live"
|
||||||
);
|
);
|
||||||
|
@ -84,7 +84,7 @@ class ClassInfo implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function hasTable($tableName)
|
public static function hasTable($tableName)
|
||||||
{
|
{
|
||||||
$cache = self::getCache();
|
$cache = ClassInfo::getCache();
|
||||||
$configData = serialize(DB::getConfig());
|
$configData = serialize(DB::getConfig());
|
||||||
$cacheKey = 'tableList_' . md5($configData);
|
$cacheKey = 'tableList_' . md5($configData);
|
||||||
$tableList = $cache->get($cacheKey) ?? [];
|
$tableList = $cache->get($cacheKey) ?? [];
|
||||||
@ -103,13 +103,13 @@ class ClassInfo implements Flushable
|
|||||||
|
|
||||||
public static function reset_db_cache()
|
public static function reset_db_cache()
|
||||||
{
|
{
|
||||||
self::getCache()->clear();
|
ClassInfo::getCache()->clear();
|
||||||
self::$_cache_ancestry = [];
|
ClassInfo::$_cache_ancestry = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function flush()
|
public static function flush()
|
||||||
{
|
{
|
||||||
self::reset_db_cache();
|
ClassInfo::reset_db_cache();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -126,7 +126,7 @@ class ClassInfo implements Flushable
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
$class = self::class_name($class);
|
$class = ClassInfo::class_name($class);
|
||||||
if ($includeUnbacked) {
|
if ($includeUnbacked) {
|
||||||
$table = DataObject::getSchema()->tableName($class);
|
$table = DataObject::getSchema()->tableName($class);
|
||||||
$classes = DB::get_schema()->enumValuesForField($table, 'ClassName');
|
$classes = DB::get_schema()->enumValuesForField($table, 'ClassName');
|
||||||
@ -150,10 +150,10 @@ class ClassInfo implements Flushable
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get all classes
|
// Get all classes
|
||||||
$class = self::class_name($nameOrObject);
|
$class = ClassInfo::class_name($nameOrObject);
|
||||||
$classes = array_merge(
|
$classes = array_merge(
|
||||||
self::ancestry($class),
|
ClassInfo::ancestry($class),
|
||||||
self::subclassesFor($class)
|
ClassInfo::subclassesFor($class)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Filter by table
|
// Filter by table
|
||||||
@ -190,7 +190,7 @@ class ClassInfo implements Flushable
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get class names
|
// Get class names
|
||||||
$className = self::class_name($nameOrObject);
|
$className = ClassInfo::class_name($nameOrObject);
|
||||||
$lowerClassName = strtolower($className ?? '');
|
$lowerClassName = strtolower($className ?? '');
|
||||||
|
|
||||||
// Merge with descendants
|
// Merge with descendants
|
||||||
@ -204,7 +204,7 @@ class ClassInfo implements Flushable
|
|||||||
/**
|
/**
|
||||||
* Convert a class name in any case and return it as it was defined in PHP
|
* Convert a class name in any case and return it as it was defined in PHP
|
||||||
*
|
*
|
||||||
* eg: self::class_name('dataobJEct'); //returns 'DataObject'
|
* eg: ClassInfo::class_name('dataobJEct'); //returns 'DataObject'
|
||||||
*
|
*
|
||||||
* @param string|object $nameOrObject The classname or object you want to normalise
|
* @param string|object $nameOrObject The classname or object you want to normalise
|
||||||
* @throws \ReflectionException
|
* @throws \ReflectionException
|
||||||
@ -246,23 +246,23 @@ class ClassInfo implements Flushable
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
$class = self::class_name($nameOrObject);
|
$class = ClassInfo::class_name($nameOrObject);
|
||||||
|
|
||||||
$lowerClass = strtolower($class ?? '');
|
$lowerClass = strtolower($class ?? '');
|
||||||
|
|
||||||
$cacheKey = $lowerClass . '_' . (string)$tablesOnly;
|
$cacheKey = $lowerClass . '_' . (string)$tablesOnly;
|
||||||
$parent = $class;
|
$parent = $class;
|
||||||
if (!isset(self::$_cache_ancestry[$cacheKey])) {
|
if (!isset(ClassInfo::$_cache_ancestry[$cacheKey])) {
|
||||||
$ancestry = [];
|
$ancestry = [];
|
||||||
do {
|
do {
|
||||||
if (!$tablesOnly || DataObject::getSchema()->classHasTable($parent)) {
|
if (!$tablesOnly || DataObject::getSchema()->classHasTable($parent)) {
|
||||||
$ancestry[strtolower($parent)] = $parent;
|
$ancestry[strtolower($parent)] = $parent;
|
||||||
}
|
}
|
||||||
} while ($parent = get_parent_class($parent ?? ''));
|
} while ($parent = get_parent_class($parent ?? ''));
|
||||||
self::$_cache_ancestry[$cacheKey] = array_reverse($ancestry ?? []);
|
ClassInfo::$_cache_ancestry[$cacheKey] = array_reverse($ancestry ?? []);
|
||||||
}
|
}
|
||||||
|
|
||||||
return self::$_cache_ancestry[$cacheKey];
|
return ClassInfo::$_cache_ancestry[$cacheKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -285,7 +285,7 @@ class ClassInfo implements Flushable
|
|||||||
public static function classImplements($className, $interfaceName)
|
public static function classImplements($className, $interfaceName)
|
||||||
{
|
{
|
||||||
$lowerClassName = strtolower($className ?? '');
|
$lowerClassName = strtolower($className ?? '');
|
||||||
$implementors = self::implementorsOf($interfaceName);
|
$implementors = ClassInfo::implementorsOf($interfaceName);
|
||||||
return isset($implementors[$lowerClassName]);
|
return isset($implementors[$lowerClassName]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -348,22 +348,22 @@ class ClassInfo implements Flushable
|
|||||||
$lClass = strtolower($class ?? '');
|
$lClass = strtolower($class ?? '');
|
||||||
$lMethod = strtolower($method ?? '');
|
$lMethod = strtolower($method ?? '');
|
||||||
$lCompclass = strtolower($compclass ?? '');
|
$lCompclass = strtolower($compclass ?? '');
|
||||||
if (!isset(self::$_cache_methods[$lClass])) {
|
if (!isset(ClassInfo::$_cache_methods[$lClass])) {
|
||||||
self::$_cache_methods[$lClass] = [];
|
ClassInfo::$_cache_methods[$lClass] = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!array_key_exists($lMethod, self::$_cache_methods[$lClass] ?? [])) {
|
if (!array_key_exists($lMethod, ClassInfo::$_cache_methods[$lClass] ?? [])) {
|
||||||
self::$_cache_methods[$lClass][$lMethod] = false;
|
ClassInfo::$_cache_methods[$lClass][$lMethod] = false;
|
||||||
|
|
||||||
$classRef = new ReflectionClass($class);
|
$classRef = new ReflectionClass($class);
|
||||||
|
|
||||||
if ($classRef->hasMethod($method)) {
|
if ($classRef->hasMethod($method)) {
|
||||||
$methodRef = $classRef->getMethod($method);
|
$methodRef = $classRef->getMethod($method);
|
||||||
self::$_cache_methods[$lClass][$lMethod] = $methodRef->getDeclaringClass()->getName();
|
ClassInfo::$_cache_methods[$lClass][$lMethod] = $methodRef->getDeclaringClass()->getName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return strtolower(self::$_cache_methods[$lClass][$lMethod] ?? '') === $lCompclass;
|
return strtolower(ClassInfo::$_cache_methods[$lClass][$lMethod] ?? '') === $lCompclass;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -573,7 +573,7 @@ class ClassInfo implements Flushable
|
|||||||
bool $includeBaseClass = false
|
bool $includeBaseClass = false
|
||||||
): array {
|
): array {
|
||||||
// get class names
|
// get class names
|
||||||
$baseClass = self::class_name($baseClassOrObject);
|
$baseClass = ClassInfo::class_name($baseClassOrObject);
|
||||||
|
|
||||||
// get a list of all subclasses for a given class
|
// get a list of all subclasses for a given class
|
||||||
$classes = ClassInfo::subclassesFor($baseClass, $includeBaseClass);
|
$classes = ClassInfo::subclassesFor($baseClass, $includeBaseClass);
|
||||||
|
@ -79,7 +79,7 @@ abstract class Config
|
|||||||
public static function nest()
|
public static function nest()
|
||||||
{
|
{
|
||||||
// Clone current config and nest
|
// Clone current config and nest
|
||||||
$new = self::inst()->nest();
|
$new = Config::inst()->nest();
|
||||||
ConfigLoader::inst()->pushManifest($new);
|
ConfigLoader::inst()->pushManifest($new);
|
||||||
return $new;
|
return $new;
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ class ConfigLoader
|
|||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
* @var self
|
* @var ConfigLoader
|
||||||
*/
|
*/
|
||||||
private static $instance;
|
private static $instance;
|
||||||
|
|
||||||
@ -22,11 +22,11 @@ class ConfigLoader
|
|||||||
protected $manifests = [];
|
protected $manifests = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return self
|
* @return ConfigLoader
|
||||||
*/
|
*/
|
||||||
public static function inst()
|
public static function inst()
|
||||||
{
|
{
|
||||||
return self::$instance ? self::$instance : self::$instance = new static();
|
return ConfigLoader::$instance ? ConfigLoader::$instance : ConfigLoader::$instance = new static();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -37,7 +37,7 @@ class ConfigLoader
|
|||||||
*/
|
*/
|
||||||
public function getManifest()
|
public function getManifest()
|
||||||
{
|
{
|
||||||
if ($this !== self::$instance) {
|
if ($this !== ConfigLoader::$instance) {
|
||||||
throw new BadMethodCallException(
|
throw new BadMethodCallException(
|
||||||
"Non-current config manifest cannot be accessed. Please call ->activate() first"
|
"Non-current config manifest cannot be accessed. Please call ->activate() first"
|
||||||
);
|
);
|
||||||
|
@ -36,7 +36,7 @@ class Convert
|
|||||||
*/
|
*/
|
||||||
public static function raw2att($val)
|
public static function raw2att($val)
|
||||||
{
|
{
|
||||||
return self::raw2xml($val);
|
return Convert::raw2xml($val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -49,7 +49,7 @@ class Convert
|
|||||||
*/
|
*/
|
||||||
public static function raw2htmlatt($val)
|
public static function raw2htmlatt($val)
|
||||||
{
|
{
|
||||||
return self::raw2att($val);
|
return Convert::raw2att($val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -68,13 +68,13 @@ class Convert
|
|||||||
{
|
{
|
||||||
if (is_array($val)) {
|
if (is_array($val)) {
|
||||||
foreach ($val as $k => $v) {
|
foreach ($val as $k => $v) {
|
||||||
$val[$k] = self::raw2htmlname($v);
|
$val[$k] = Convert::raw2htmlname($v);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $val;
|
return $val;
|
||||||
}
|
}
|
||||||
|
|
||||||
return self::raw2att($val);
|
return Convert::raw2att($val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -93,7 +93,7 @@ class Convert
|
|||||||
{
|
{
|
||||||
if (is_array($val)) {
|
if (is_array($val)) {
|
||||||
foreach ($val as $k => $v) {
|
foreach ($val as $k => $v) {
|
||||||
$val[$k] = self::raw2htmlid($v);
|
$val[$k] = Convert::raw2htmlid($v);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $val;
|
return $val;
|
||||||
@ -122,7 +122,7 @@ class Convert
|
|||||||
{
|
{
|
||||||
if (is_array($val)) {
|
if (is_array($val)) {
|
||||||
foreach ($val as $k => $v) {
|
foreach ($val as $k => $v) {
|
||||||
$val[$k] = self::raw2xml($v);
|
$val[$k] = Convert::raw2xml($v);
|
||||||
}
|
}
|
||||||
return $val;
|
return $val;
|
||||||
}
|
}
|
||||||
@ -142,7 +142,7 @@ class Convert
|
|||||||
{
|
{
|
||||||
if (is_array($val)) {
|
if (is_array($val)) {
|
||||||
foreach ($val as $k => $v) {
|
foreach ($val as $k => $v) {
|
||||||
$val[$k] = self::raw2js($v);
|
$val[$k] = Convert::raw2js($v);
|
||||||
}
|
}
|
||||||
return $val;
|
return $val;
|
||||||
}
|
}
|
||||||
@ -171,7 +171,7 @@ class Convert
|
|||||||
{
|
{
|
||||||
if (is_array($val)) {
|
if (is_array($val)) {
|
||||||
foreach ($val as $k => $v) {
|
foreach ($val as $k => $v) {
|
||||||
$val[$k] = self::raw2sql($v, $quoted);
|
$val[$k] = Convert::raw2sql($v, $quoted);
|
||||||
}
|
}
|
||||||
return $val;
|
return $val;
|
||||||
}
|
}
|
||||||
@ -211,14 +211,14 @@ class Convert
|
|||||||
{
|
{
|
||||||
if (is_array($val)) {
|
if (is_array($val)) {
|
||||||
foreach ($val as $k => $v) {
|
foreach ($val as $k => $v) {
|
||||||
$val[$k] = self::xml2raw($v);
|
$val[$k] = Convert::xml2raw($v);
|
||||||
}
|
}
|
||||||
return $val;
|
return $val;
|
||||||
}
|
}
|
||||||
|
|
||||||
// More complex text needs to use html2raw instead
|
// More complex text needs to use html2raw instead
|
||||||
if (strpos($val ?? '', '<') !== false) {
|
if (strpos($val ?? '', '<') !== false) {
|
||||||
return self::html2raw($val);
|
return Convert::html2raw($val);
|
||||||
}
|
}
|
||||||
|
|
||||||
return html_entity_decode($val ?? '', ENT_QUOTES, 'UTF-8');
|
return html_entity_decode($val ?? '', ENT_QUOTES, 'UTF-8');
|
||||||
|
@ -224,7 +224,7 @@ class Environment
|
|||||||
// Parse name-value pairs
|
// Parse name-value pairs
|
||||||
$envVars = parse_ini_string($string ?? '') ?: [];
|
$envVars = parse_ini_string($string ?? '') ?: [];
|
||||||
foreach ($envVars as $name => $value) {
|
foreach ($envVars as $name => $value) {
|
||||||
self::setEnv($name, $value);
|
Environment::setEnv($name, $value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,7 +262,7 @@ class Injector implements ContainerInterface
|
|||||||
public static function nest()
|
public static function nest()
|
||||||
{
|
{
|
||||||
// Clone current injector and nest
|
// Clone current injector and nest
|
||||||
$new = clone self::inst();
|
$new = clone Injector::inst();
|
||||||
InjectorLoader::inst()->pushManifest($new);
|
InjectorLoader::inst()->pushManifest($new);
|
||||||
return $new;
|
return $new;
|
||||||
}
|
}
|
||||||
@ -597,7 +597,7 @@ class Injector implements ContainerInterface
|
|||||||
|
|
||||||
// If we're dealing with a DataObject singleton without specific constructor params, pass through Singleton
|
// If we're dealing with a DataObject singleton without specific constructor params, pass through Singleton
|
||||||
// flag as second argument
|
// flag as second argument
|
||||||
if ((!$type || $type !== self::PROTOTYPE)
|
if ((!$type || $type !== Injector::PROTOTYPE)
|
||||||
&& empty($constructorParams)
|
&& empty($constructorParams)
|
||||||
&& is_subclass_of($class, DataObject::class)) {
|
&& is_subclass_of($class, DataObject::class)) {
|
||||||
$constructorParams = [null, DataObject::CREATE_SINGLETON];
|
$constructorParams = [null, DataObject::CREATE_SINGLETON];
|
||||||
@ -651,7 +651,7 @@ class Injector implements ContainerInterface
|
|||||||
$type = isset($spec['type']) ? $spec['type'] : null;
|
$type = isset($spec['type']) ? $spec['type'] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($id && (!$type || $type !== self::PROTOTYPE)) {
|
if ($id && (!$type || $type !== Injector::PROTOTYPE)) {
|
||||||
// this ABSOLUTELY must be set before the object is injected.
|
// this ABSOLUTELY must be set before the object is injected.
|
||||||
// This prevents circular reference errors down the line
|
// This prevents circular reference errors down the line
|
||||||
$this->serviceCache[$id] = $object;
|
$this->serviceCache[$id] = $object;
|
||||||
@ -1006,16 +1006,16 @@ class Injector implements ContainerInterface
|
|||||||
|
|
||||||
// Check if we are getting a prototype or singleton
|
// Check if we are getting a prototype or singleton
|
||||||
$type = $asSingleton
|
$type = $asSingleton
|
||||||
? (isset($spec['type']) ? $spec['type'] : self::SINGLETON)
|
? (isset($spec['type']) ? $spec['type'] : Injector::SINGLETON)
|
||||||
: self::PROTOTYPE;
|
: Injector::PROTOTYPE;
|
||||||
|
|
||||||
// Return existing instance for singletons
|
// Return existing instance for singletons
|
||||||
if ($type === self::SINGLETON && isset($this->serviceCache[$name])) {
|
if ($type === Injector::SINGLETON && isset($this->serviceCache[$name])) {
|
||||||
return $this->serviceCache[$name];
|
return $this->serviceCache[$name];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update constructor args
|
// Update constructor args
|
||||||
if ($type === self::PROTOTYPE && $constructorArgs) {
|
if ($type === Injector::PROTOTYPE && $constructorArgs) {
|
||||||
// Passed in args are expected to already be normalised (no service references)
|
// Passed in args are expected to already be normalised (no service references)
|
||||||
$spec['constructor'] = $constructorArgs;
|
$spec['constructor'] = $constructorArgs;
|
||||||
} else {
|
} else {
|
||||||
|
@ -13,7 +13,7 @@ class InjectorLoader
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
* @var self
|
* @var InjectorLoader
|
||||||
*/
|
*/
|
||||||
private static $instance;
|
private static $instance;
|
||||||
|
|
||||||
@ -23,11 +23,11 @@ class InjectorLoader
|
|||||||
protected $manifests = [];
|
protected $manifests = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return self
|
* @return InjectorLoader
|
||||||
*/
|
*/
|
||||||
public static function inst()
|
public static function inst()
|
||||||
{
|
{
|
||||||
return self::$instance ? self::$instance : self::$instance = new static();
|
return InjectorLoader::$instance ? InjectorLoader::$instance : InjectorLoader::$instance = new static();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -38,13 +38,13 @@ class InjectorLoader
|
|||||||
*/
|
*/
|
||||||
public function getManifest()
|
public function getManifest()
|
||||||
{
|
{
|
||||||
if ($this !== self::$instance) {
|
if ($this !== InjectorLoader::$instance) {
|
||||||
throw new BadMethodCallException(
|
throw new BadMethodCallException(
|
||||||
"Non-current injector manifest cannot be accessed. Please call ->activate() first"
|
"Non-current injector manifest cannot be accessed. Please call ->activate() first"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (empty($this->manifests)) {
|
if (empty($this->manifests)) {
|
||||||
throw new BadMethodCallException(self::NO_MANIFESTS_AVAILABLE);
|
throw new BadMethodCallException(InjectorLoader::NO_MANIFESTS_AVAILABLE);
|
||||||
}
|
}
|
||||||
return $this->manifests[count($this->manifests) - 1];
|
return $this->manifests[count($this->manifests) - 1];
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ class ClassLoader
|
|||||||
*/
|
*/
|
||||||
public static function inst()
|
public static function inst()
|
||||||
{
|
{
|
||||||
return self::$instance ? self::$instance : self::$instance = new static();
|
return ClassLoader::$instance ? ClassLoader::$instance : ClassLoader::$instance = new static();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -41,7 +41,7 @@ class ManifestFileFinder extends FileFinder
|
|||||||
$inVendor = $this->isInsideVendor($basename, $pathname, $depth);
|
$inVendor = $this->isInsideVendor($basename, $pathname, $depth);
|
||||||
if ($inVendor) {
|
if ($inVendor) {
|
||||||
// Skip nested vendor folders (e.g. vendor/silverstripe/framework/vendor)
|
// Skip nested vendor folders (e.g. vendor/silverstripe/framework/vendor)
|
||||||
if ($depth == 4 && basename($pathname ?? '') === self::VENDOR_DIR) {
|
if ($depth == 4 && basename($pathname ?? '') === ManifestFileFinder::VENDOR_DIR) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +82,7 @@ class ManifestFileFinder extends FileFinder
|
|||||||
public function isInsideVendor($basename, $pathname, $depth)
|
public function isInsideVendor($basename, $pathname, $depth)
|
||||||
{
|
{
|
||||||
$base = basename($this->upLevels($pathname, $depth - 1) ?? '');
|
$base = basename($this->upLevels($pathname, $depth - 1) ?? '');
|
||||||
return $base === self::VENDOR_DIR;
|
return $base === ManifestFileFinder::VENDOR_DIR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -170,12 +170,12 @@ class ManifestFileFinder extends FileFinder
|
|||||||
}
|
}
|
||||||
|
|
||||||
// True if config file exists
|
// True if config file exists
|
||||||
if (file_exists($pathname . '/' . self::CONFIG_FILE)) {
|
if (file_exists($pathname . '/' . ManifestFileFinder::CONFIG_FILE)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// True if config dir exists
|
// True if config dir exists
|
||||||
if (file_exists($pathname . '/' . self::CONFIG_DIR)) {
|
if (file_exists($pathname . '/' . ManifestFileFinder::CONFIG_DIR)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,9 +207,9 @@ class ManifestFileFinder extends FileFinder
|
|||||||
*/
|
*/
|
||||||
protected function getIgnoredDirs()
|
protected function getIgnoredDirs()
|
||||||
{
|
{
|
||||||
$ignored = [self::LANG_DIR, 'node_modules'];
|
$ignored = [ManifestFileFinder::LANG_DIR, 'node_modules'];
|
||||||
if ($this->getOption('ignore_tests')) {
|
if ($this->getOption('ignore_tests')) {
|
||||||
$ignored[] = self::TESTS_DIR;
|
$ignored[] = ManifestFileFinder::TESTS_DIR;
|
||||||
}
|
}
|
||||||
return $ignored;
|
return $ignored;
|
||||||
}
|
}
|
||||||
@ -229,7 +229,7 @@ class ManifestFileFinder extends FileFinder
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if manifest-ignored is present
|
// Check if manifest-ignored is present
|
||||||
if (file_exists($pathname . '/' . self::EXCLUDE_FILE)) {
|
if (file_exists($pathname . '/' . ManifestFileFinder::EXCLUDE_FILE)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ namespace SilverStripe\Core\Manifest;
|
|||||||
class ModuleLoader
|
class ModuleLoader
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var self
|
* @var ModuleLoader
|
||||||
*/
|
*/
|
||||||
private static $instance;
|
private static $instance;
|
||||||
|
|
||||||
@ -18,11 +18,11 @@ class ModuleLoader
|
|||||||
protected $manifests = [];
|
protected $manifests = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return self
|
* @return ModuleLoader
|
||||||
*/
|
*/
|
||||||
public static function inst()
|
public static function inst()
|
||||||
{
|
{
|
||||||
return self::$instance ? self::$instance : self::$instance = new static();
|
return ModuleLoader::$instance ? ModuleLoader::$instance : ModuleLoader::$instance = new static();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -241,7 +241,7 @@ class ModuleManifest
|
|||||||
);
|
);
|
||||||
|
|
||||||
if ($project) {
|
if ($project) {
|
||||||
$sorter->setVariable(self::PROJECT_KEY, $project);
|
$sorter->setVariable(ModuleManifest::PROJECT_KEY, $project);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->modules = $sorter->getSortedList();
|
$this->modules = $sorter->getSortedList();
|
||||||
|
@ -175,7 +175,7 @@ class VersionProvider
|
|||||||
*/
|
*/
|
||||||
public function getModules()
|
public function getModules()
|
||||||
{
|
{
|
||||||
$modules = Config::inst()->get(self::class, 'modules');
|
$modules = Config::inst()->get(VersionProvider::class, 'modules');
|
||||||
return !empty($modules) ? $modules : ['silverstripe/framework' => 'Framework'];
|
return !empty($modules) ? $modules : ['silverstripe/framework' => 'Framework'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,9 +53,9 @@ class Path
|
|||||||
{
|
{
|
||||||
$path = trim(Convert::slashes($path) ?? '');
|
$path = trim(Convert::slashes($path) ?? '');
|
||||||
if ($relative) {
|
if ($relative) {
|
||||||
return trim($path ?? '', self::TRIM_CHARS ?? '');
|
return trim($path ?? '', Path::TRIM_CHARS ?? '');
|
||||||
} else {
|
} else {
|
||||||
return rtrim($path ?? '', self::TRIM_CHARS ?? '');
|
return rtrim($path ?? '', Path::TRIM_CHARS ?? '');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ class Backtrace
|
|||||||
*/
|
*/
|
||||||
public static function filtered_backtrace($ignoredFunctions = null)
|
public static function filtered_backtrace($ignoredFunctions = null)
|
||||||
{
|
{
|
||||||
return self::filter_backtrace(debug_backtrace(), $ignoredFunctions);
|
return Backtrace::filter_backtrace(debug_backtrace(), $ignoredFunctions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -70,7 +70,7 @@ class Backtrace
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while ($bt && in_array(self::full_func_name($bt[0]), $defaultIgnoredFunctions ?? [])) {
|
while ($bt && in_array(Backtrace::full_func_name($bt[0]), $defaultIgnoredFunctions ?? [])) {
|
||||||
array_shift($bt);
|
array_shift($bt);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +82,7 @@ class Backtrace
|
|||||||
if (!empty($frame['class'])) {
|
if (!empty($frame['class'])) {
|
||||||
foreach ($ignoredArgs as $fnSpec) {
|
foreach ($ignoredArgs as $fnSpec) {
|
||||||
if (is_array($fnSpec)
|
if (is_array($fnSpec)
|
||||||
&& self::matchesFilterableClass($frame['class'], $fnSpec[0])
|
&& Backtrace::matchesFilterableClass($frame['class'], $fnSpec[0])
|
||||||
&& $frame['function'] == $fnSpec[1]
|
&& $frame['function'] == $fnSpec[1]
|
||||||
) {
|
) {
|
||||||
$match = true;
|
$match = true;
|
||||||
@ -115,7 +115,7 @@ class Backtrace
|
|||||||
public static function backtrace($returnVal = false, $ignoreAjax = false, $ignoredFunctions = null)
|
public static function backtrace($returnVal = false, $ignoreAjax = false, $ignoredFunctions = null)
|
||||||
{
|
{
|
||||||
$plainText = Director::is_cli() || (Director::is_ajax() && !$ignoreAjax);
|
$plainText = Director::is_cli() || (Director::is_ajax() && !$ignoreAjax);
|
||||||
$result = self::get_rendered_backtrace(debug_backtrace(), $plainText, $ignoredFunctions);
|
$result = Backtrace::get_rendered_backtrace(debug_backtrace(), $plainText, $ignoredFunctions);
|
||||||
if ($returnVal) {
|
if ($returnVal) {
|
||||||
return $result;
|
return $result;
|
||||||
} else {
|
} else {
|
||||||
@ -176,11 +176,11 @@ class Backtrace
|
|||||||
if (empty($bt)) {
|
if (empty($bt)) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
$bt = self::filter_backtrace($bt, $ignoredFunctions);
|
$bt = Backtrace::filter_backtrace($bt, $ignoredFunctions);
|
||||||
$result = ($plainText) ? '' : '<ul>';
|
$result = ($plainText) ? '' : '<ul>';
|
||||||
foreach ($bt as $item) {
|
foreach ($bt as $item) {
|
||||||
if ($plainText) {
|
if ($plainText) {
|
||||||
$result .= self::full_func_name($item, true) . "\n";
|
$result .= Backtrace::full_func_name($item, true) . "\n";
|
||||||
if (isset($item['line']) && isset($item['file'])) {
|
if (isset($item['line']) && isset($item['file'])) {
|
||||||
$result .= basename($item['file'] ?? '') . ":$item[line]\n";
|
$result .= basename($item['file'] ?? '') . ":$item[line]\n";
|
||||||
}
|
}
|
||||||
@ -189,7 +189,7 @@ class Backtrace
|
|||||||
if ($item['function'] == 'user_error') {
|
if ($item['function'] == 'user_error') {
|
||||||
$name = $item['args'][0];
|
$name = $item['args'][0];
|
||||||
} else {
|
} else {
|
||||||
$name = self::full_func_name($item, true);
|
$name = Backtrace::full_func_name($item, true);
|
||||||
}
|
}
|
||||||
$result .= "<li><b>" . htmlentities($name ?? '', ENT_COMPAT, 'UTF-8') . "</b>\n<br />\n";
|
$result .= "<li><b>" . htmlentities($name ?? '', ENT_COMPAT, 'UTF-8') . "</b>\n<br />\n";
|
||||||
$result .= isset($item['file']) ? htmlentities(basename($item['file']), ENT_COMPAT, 'UTF-8') : '';
|
$result .= isset($item['file']) ? htmlentities(basename($item['file']), ENT_COMPAT, 'UTF-8') : '';
|
||||||
|
@ -23,7 +23,7 @@ abstract class BulkLoader extends ViewableData
|
|||||||
/**
|
/**
|
||||||
* Each row in the imported dataset should map to one instance
|
* Each row in the imported dataset should map to one instance
|
||||||
* of this class (with optional property translation
|
* of this class (with optional property translation
|
||||||
* through {@self::$columnMaps}.
|
* through {@BulkLoader::$columnMaps}.
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
@ -144,17 +144,17 @@ abstract class BulkLoader extends ViewableData
|
|||||||
/**
|
/**
|
||||||
* Determine whether this bulk loader should respect create/edit/delete permissions.
|
* Determine whether this bulk loader should respect create/edit/delete permissions.
|
||||||
*/
|
*/
|
||||||
public function setCheckPermissions(bool $value): self
|
public function setCheckPermissions(bool $value): BulkLoader
|
||||||
{
|
{
|
||||||
$this->checkPermissions = $value;
|
$this->checkPermissions = $value;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Load the given file via {@link self::processAll()} and {@link self::processRecord()}.
|
* Load the given file via {@link BulkLoader::processAll()} and {@link BulkLoader::processRecord()}.
|
||||||
* Optionally truncates (clear) the table before it imports.
|
* Optionally truncates (clear) the table before it imports.
|
||||||
*
|
*
|
||||||
* @return BulkLoader_Result See {@link self::processAll()}
|
* @return BulkLoader_Result See {@link BulkLoader::processAll()}
|
||||||
*/
|
*/
|
||||||
public function load($filepath)
|
public function load($filepath)
|
||||||
{
|
{
|
||||||
@ -190,7 +190,7 @@ abstract class BulkLoader extends ViewableData
|
|||||||
* it through a UI.
|
* it through a UI.
|
||||||
*
|
*
|
||||||
* @param string $filepath Absolute path to the file we're importing
|
* @param string $filepath Absolute path to the file we're importing
|
||||||
* @return array See {@link self::processAll()}
|
* @return array See {@link BulkLoader::processAll()}
|
||||||
*/
|
*/
|
||||||
abstract public function preview($filepath);
|
abstract public function preview($filepath);
|
||||||
|
|
||||||
@ -208,7 +208,7 @@ abstract class BulkLoader extends ViewableData
|
|||||||
/**
|
/**
|
||||||
* Process a single record from the file.
|
* Process a single record from the file.
|
||||||
*
|
*
|
||||||
* @param array $record An map of the data, keyed by the header field defined in {@link self::$columnMap}
|
* @param array $record An map of the data, keyed by the header field defined in {@link BulkLoader::$columnMap}
|
||||||
* @param array $columnMap
|
* @param array $columnMap
|
||||||
* @param $result BulkLoader_Result (passed as reference)
|
* @param $result BulkLoader_Result (passed as reference)
|
||||||
* @param boolean $preview
|
* @param boolean $preview
|
||||||
@ -286,7 +286,7 @@ abstract class BulkLoader extends ViewableData
|
|||||||
* so this is mainly a customization method.
|
* so this is mainly a customization method.
|
||||||
*
|
*
|
||||||
* @param mixed $val
|
* @param mixed $val
|
||||||
* @param string $fieldName Name of the field as specified in the array-values for {@link self::$columnMap}.
|
* @param string $fieldName Name of the field as specified in the array-values for {@link BulkLoader::$columnMap}.
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
protected function isNullValue($val, $fieldName = null)
|
protected function isNullValue($val, $fieldName = null)
|
||||||
|
@ -37,13 +37,13 @@ class CLI
|
|||||||
*/
|
*/
|
||||||
public static function text($text, $fgColour = null, $bgColour = null, $bold = false)
|
public static function text($text, $fgColour = null, $bgColour = null, $bold = false)
|
||||||
{
|
{
|
||||||
if (!self::supports_colour()) {
|
if (!CLI::supports_colour()) {
|
||||||
return $text;
|
return $text;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($fgColour || $bgColour || $bold) {
|
if ($fgColour || $bgColour || $bold) {
|
||||||
$prefix = self::start_colour($fgColour, $bgColour, $bold);
|
$prefix = CLI::start_colour($fgColour, $bgColour, $bold);
|
||||||
$suffix = self::end_colour();
|
$suffix = CLI::end_colour();
|
||||||
} else {
|
} else {
|
||||||
$prefix = $suffix = "";
|
$prefix = $suffix = "";
|
||||||
}
|
}
|
||||||
@ -62,7 +62,7 @@ class CLI
|
|||||||
*/
|
*/
|
||||||
public static function start_colour($fgColour = null, $bgColour = null, $bold = false)
|
public static function start_colour($fgColour = null, $bgColour = null, $bold = false)
|
||||||
{
|
{
|
||||||
if (!self::supports_colour()) {
|
if (!CLI::supports_colour()) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
$colours = [
|
$colours = [
|
||||||
@ -98,6 +98,6 @@ class CLI
|
|||||||
*/
|
*/
|
||||||
public static function end_colour()
|
public static function end_colour()
|
||||||
{
|
{
|
||||||
return self::supports_colour() ? "\033[0m" : "";
|
return CLI::supports_colour() ? "\033[0m" : "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,10 +43,10 @@ class CliDebugView extends DebugView
|
|||||||
*/
|
*/
|
||||||
public function renderError($httpRequest, $errno, $errstr, $errfile, $errline)
|
public function renderError($httpRequest, $errno, $errstr, $errfile, $errline)
|
||||||
{
|
{
|
||||||
if (!isset(self::$error_types[$errno])) {
|
if (!isset(CliDebugView::$error_types[$errno])) {
|
||||||
$errorTypeTitle = "UNKNOWN TYPE, ERRNO $errno";
|
$errorTypeTitle = "UNKNOWN TYPE, ERRNO $errno";
|
||||||
} else {
|
} else {
|
||||||
$errorTypeTitle = self::$error_types[$errno]['title'];
|
$errorTypeTitle = CliDebugView::$error_types[$errno]['title'];
|
||||||
}
|
}
|
||||||
$output = CLI::text("ERROR [" . $errorTypeTitle . "]: $errstr\nIN $httpRequest\n", "red", null, true);
|
$output = CLI::text("ERROR [" . $errorTypeTitle . "]: $errstr\nIN $httpRequest\n", "red", null, true);
|
||||||
$output .= CLI::text("Line $errline in $errfile\n\n", "red");
|
$output .= CLI::text("Line $errline in $errfile\n\n", "red");
|
||||||
@ -67,7 +67,7 @@ class CliDebugView extends DebugView
|
|||||||
foreach ($lines as $offset => $line) {
|
foreach ($lines as $offset => $line) {
|
||||||
$output .= ($offset == $errline) ? "* " : " ";
|
$output .= ($offset == $errline) ? "* " : " ";
|
||||||
$output .= str_pad("$offset:", 5);
|
$output .= str_pad("$offset:", 5);
|
||||||
$output .= wordwrap($line ?? '', self::config()->columns ?? 0, "\n ");
|
$output .= wordwrap($line ?? '', static::config()->columns ?? 0, "\n ");
|
||||||
}
|
}
|
||||||
$output .= "\n";
|
$output .= "\n";
|
||||||
|
|
||||||
@ -90,7 +90,7 @@ class CliDebugView extends DebugView
|
|||||||
|
|
||||||
public function renderParagraph($text)
|
public function renderParagraph($text)
|
||||||
{
|
{
|
||||||
return wordwrap($text ?? '', self::config()->columns ?? 0) . "\n\n";
|
return wordwrap($text ?? '', static::config()->columns ?? 0) . "\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -103,10 +103,10 @@ class CliDebugView extends DebugView
|
|||||||
*/
|
*/
|
||||||
public function renderInfo($title, $subtitle, $description = null)
|
public function renderInfo($title, $subtitle, $description = null)
|
||||||
{
|
{
|
||||||
$output = wordwrap(strtoupper($title ?? ''), self::config()->columns ?? 0) . "\n";
|
$output = wordwrap(strtoupper($title ?? ''), static::config()->columns ?? 0) . "\n";
|
||||||
$output .= wordwrap($subtitle ?? '', self::config()->columns ?? 0) . "\n";
|
$output .= wordwrap($subtitle ?? '', static::config()->columns ?? 0) . "\n";
|
||||||
$output .= str_repeat('-', min(self::config()->columns, max(strlen($title ?? ''), strlen($subtitle ?? ''))) ?? 0) . "\n";
|
$output .= str_repeat('-', min(static::config()->columns, max(strlen($title ?? ''), strlen($subtitle ?? ''))) ?? 0) . "\n";
|
||||||
$output .= wordwrap($description ?? '', self::config()->columns ?? 0) . "\n\n";
|
$output .= wordwrap($description ?? '', static::config()->columns ?? 0) . "\n\n";
|
||||||
|
|
||||||
return $output;
|
return $output;
|
||||||
}
|
}
|
||||||
@ -114,17 +114,17 @@ class CliDebugView extends DebugView
|
|||||||
public function renderVariable($val, $caller)
|
public function renderVariable($val, $caller)
|
||||||
{
|
{
|
||||||
$output = PHP_EOL;
|
$output = PHP_EOL;
|
||||||
$output .= CLI::text(str_repeat('=', self::config()->columns ?? 0), 'green');
|
$output .= CLI::text(str_repeat('=', static::config()->columns ?? 0), 'green');
|
||||||
$output .= PHP_EOL;
|
$output .= PHP_EOL;
|
||||||
$output .= CLI::text($this->formatCaller($caller), 'blue', null, true);
|
$output .= CLI::text($this->formatCaller($caller), 'blue', null, true);
|
||||||
$output .= PHP_EOL . PHP_EOL;
|
$output .= PHP_EOL . PHP_EOL;
|
||||||
if (is_string($val)) {
|
if (is_string($val)) {
|
||||||
$output .= wordwrap($val ?? '', self::config()->columns ?? 0);
|
$output .= wordwrap($val ?? '', static::config()->columns ?? 0);
|
||||||
} else {
|
} else {
|
||||||
$output .= var_export($val, true);
|
$output .= var_export($val, true);
|
||||||
}
|
}
|
||||||
$output .= PHP_EOL;
|
$output .= PHP_EOL;
|
||||||
$output .= CLI::text(str_repeat('=', self::config()->columns ?? 0), 'green');
|
$output .= CLI::text(str_repeat('=', static::config()->columns ?? 0), 'green');
|
||||||
$output .= PHP_EOL;
|
$output .= PHP_EOL;
|
||||||
|
|
||||||
return $output;
|
return $output;
|
||||||
@ -184,7 +184,7 @@ class CliDebugView extends DebugView
|
|||||||
|
|
||||||
// Format text
|
// Format text
|
||||||
if (is_string($val)) {
|
if (is_string($val)) {
|
||||||
return wordwrap($val ?? '', self::config()->columns ?? 0);
|
return wordwrap($val ?? '', static::config()->columns ?? 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Other
|
// Other
|
||||||
|
@ -325,7 +325,7 @@ class CsvBulkLoader extends BulkLoader
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Find an existing objects based on one or more uniqueness columns
|
* Find an existing objects based on one or more uniqueness columns
|
||||||
* specified via {@link self::$duplicateChecks}.
|
* specified via {@link CsvBulkLoader::$duplicateChecks}.
|
||||||
*
|
*
|
||||||
* @param array $record CSV data column
|
* @param array $record CSV data column
|
||||||
* @param array $columnMap
|
* @param array $columnMap
|
||||||
@ -380,7 +380,7 @@ class CsvBulkLoader extends BulkLoader
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine whether any loaded files should be parsed with a
|
* Determine whether any loaded files should be parsed with a
|
||||||
* header-row (otherwise we rely on {@link self::$columnMap}.
|
* header-row (otherwise we rely on {@link CsvBulkLoader::$columnMap}.
|
||||||
*
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
|
@ -102,8 +102,8 @@ class Debug
|
|||||||
*/
|
*/
|
||||||
public static function dump($val, HTTPRequest $request = null)
|
public static function dump($val, HTTPRequest $request = null)
|
||||||
{
|
{
|
||||||
echo self::create_debug_view($request)
|
echo Debug::create_debug_view($request)
|
||||||
->renderVariable($val, self::caller());
|
->renderVariable($val, Debug::caller());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -214,7 +214,7 @@ class DebugView
|
|||||||
*/
|
*/
|
||||||
public function renderError($httpRequest, $errno, $errstr, $errfile, $errline)
|
public function renderError($httpRequest, $errno, $errstr, $errfile, $errline)
|
||||||
{
|
{
|
||||||
$errorType = isset(self::$error_types[$errno]) ? self::$error_types[$errno] : self::$unknown_error;
|
$errorType = isset(DebugView::$error_types[$errno]) ? DebugView::$error_types[$errno] : DebugView::$unknown_error;
|
||||||
$httpRequestEnt = htmlentities($httpRequest ?? '', ENT_COMPAT, 'UTF-8');
|
$httpRequestEnt = htmlentities($httpRequest ?? '', ENT_COMPAT, 'UTF-8');
|
||||||
if (filter_var(ini_get('html_errors'), FILTER_VALIDATE_BOOL)) {
|
if (filter_var(ini_get('html_errors'), FILTER_VALIDATE_BOOL)) {
|
||||||
$errstr = strip_tags($errstr ?? '');
|
$errstr = strip_tags($errstr ?? '');
|
||||||
@ -308,7 +308,7 @@ class DebugView
|
|||||||
$output = '<pre style="background-color:#ccc;padding:5px;font-size:14px;line-height:18px;">';
|
$output = '<pre style="background-color:#ccc;padding:5px;font-size:14px;line-height:18px;">';
|
||||||
$output .= "<span style=\"font-size: 12px;color:#666;\">" . $this->formatCaller($caller) . " - </span>\n";
|
$output .= "<span style=\"font-size: 12px;color:#666;\">" . $this->formatCaller($caller) . " - </span>\n";
|
||||||
if (is_string($val)) {
|
if (is_string($val)) {
|
||||||
$output .= wordwrap($val ?? '', self::config()->columns ?? 0);
|
$output .= wordwrap($val ?? '', static::config()->columns ?? 0);
|
||||||
} else {
|
} else {
|
||||||
$output .= var_export($val, true);
|
$output .= var_export($val, true);
|
||||||
}
|
}
|
||||||
|
@ -111,14 +111,14 @@ class Deprecation
|
|||||||
*/
|
*/
|
||||||
public static function withNoReplacement(callable $func)
|
public static function withNoReplacement(callable $func)
|
||||||
{
|
{
|
||||||
if (self::$insideWithNoReplacement) {
|
if (Deprecation::$insideWithNoReplacement) {
|
||||||
return $func();
|
return $func();
|
||||||
}
|
}
|
||||||
self::$insideWithNoReplacement = true;
|
Deprecation::$insideWithNoReplacement = true;
|
||||||
try {
|
try {
|
||||||
return $func();
|
return $func();
|
||||||
} finally {
|
} finally {
|
||||||
self::$insideWithNoReplacement = false;
|
Deprecation::$insideWithNoReplacement = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,7 +138,7 @@ class Deprecation
|
|||||||
}
|
}
|
||||||
$newLevel = $level;
|
$newLevel = $level;
|
||||||
// handle closures inside withNoReplacement()
|
// handle closures inside withNoReplacement()
|
||||||
if (self::$insideWithNoReplacement
|
if (Deprecation::$insideWithNoReplacement
|
||||||
&& substr($backtrace[$newLevel]['function'], -strlen('{closure}')) === '{closure}'
|
&& substr($backtrace[$newLevel]['function'], -strlen('{closure}')) === '{closure}'
|
||||||
) {
|
) {
|
||||||
$newLevel = $newLevel + 2;
|
$newLevel = $newLevel + 2;
|
||||||
@ -184,7 +184,7 @@ class Deprecation
|
|||||||
*/
|
*/
|
||||||
public static function isTriggeringError(): bool
|
public static function isTriggeringError(): bool
|
||||||
{
|
{
|
||||||
return self::$isTriggeringError;
|
return Deprecation::$isTriggeringError;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -195,7 +195,7 @@ class Deprecation
|
|||||||
*/
|
*/
|
||||||
public static function setShouldShowForHttp(bool $value): void
|
public static function setShouldShowForHttp(bool $value): void
|
||||||
{
|
{
|
||||||
self::$shouldShowForHttp = $value;
|
Deprecation::$shouldShowForHttp = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -206,7 +206,7 @@ class Deprecation
|
|||||||
*/
|
*/
|
||||||
public static function setShouldShowForCli(bool $value): void
|
public static function setShouldShowForCli(bool $value): void
|
||||||
{
|
{
|
||||||
self::$shouldShowForCli = $value;
|
Deprecation::$shouldShowForCli = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -217,9 +217,9 @@ class Deprecation
|
|||||||
{
|
{
|
||||||
if (Environment::hasEnv('SS_DEPRECATION_SHOW_HTTP')) {
|
if (Environment::hasEnv('SS_DEPRECATION_SHOW_HTTP')) {
|
||||||
$envVar = Environment::getEnv('SS_DEPRECATION_SHOW_HTTP');
|
$envVar = Environment::getEnv('SS_DEPRECATION_SHOW_HTTP');
|
||||||
return self::varAsBoolean($envVar);
|
return Deprecation::varAsBoolean($envVar);
|
||||||
}
|
}
|
||||||
return self::$shouldShowForHttp;
|
return Deprecation::$shouldShowForHttp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -230,34 +230,34 @@ class Deprecation
|
|||||||
{
|
{
|
||||||
if (Environment::hasEnv('SS_DEPRECATION_SHOW_CLI')) {
|
if (Environment::hasEnv('SS_DEPRECATION_SHOW_CLI')) {
|
||||||
$envVar = Environment::getEnv('SS_DEPRECATION_SHOW_CLI');
|
$envVar = Environment::getEnv('SS_DEPRECATION_SHOW_CLI');
|
||||||
return self::varAsBoolean($envVar);
|
return Deprecation::varAsBoolean($envVar);
|
||||||
}
|
}
|
||||||
return self::$shouldShowForCli;
|
return Deprecation::$shouldShowForCli;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function outputNotices(): void
|
public static function outputNotices(): void
|
||||||
{
|
{
|
||||||
if (!self::isEnabled()) {
|
if (!Deprecation::isEnabled()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$count = 0;
|
$count = 0;
|
||||||
$origCount = count(self::$userErrorMessageBuffer);
|
$origCount = count(Deprecation::$userErrorMessageBuffer);
|
||||||
while ($origCount > $count) {
|
while ($origCount > $count) {
|
||||||
$count++;
|
$count++;
|
||||||
$arr = array_shift(self::$userErrorMessageBuffer);
|
$arr = array_shift(Deprecation::$userErrorMessageBuffer);
|
||||||
$message = $arr['message'];
|
$message = $arr['message'];
|
||||||
$calledInsideWithNoReplacement = $arr['calledInsideWithNoReplacement'];
|
$calledInsideWithNoReplacement = $arr['calledInsideWithNoReplacement'];
|
||||||
if ($calledInsideWithNoReplacement && !self::$showNoReplacementNotices) {
|
if ($calledInsideWithNoReplacement && !Deprecation::$showNoReplacementNotices) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
self::$isTriggeringError = true;
|
Deprecation::$isTriggeringError = true;
|
||||||
user_error($message, E_USER_DEPRECATED);
|
user_error($message, E_USER_DEPRECATED);
|
||||||
self::$isTriggeringError = false;
|
Deprecation::$isTriggeringError = false;
|
||||||
}
|
}
|
||||||
// Make absolutely sure the buffer is empty - array_shift seems to leave an item in the array
|
// Make absolutely sure the buffer is empty - array_shift seems to leave an item in the array
|
||||||
// if we're not using numeric keys.
|
// if we're not using numeric keys.
|
||||||
self::$userErrorMessageBuffer = [];
|
Deprecation::$userErrorMessageBuffer = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -278,17 +278,17 @@ class Deprecation
|
|||||||
// calls something else that calls Deprecation::notice()
|
// calls something else that calls Deprecation::notice()
|
||||||
try {
|
try {
|
||||||
$data = null;
|
$data = null;
|
||||||
if ($scope === self::SCOPE_CONFIG) {
|
if ($scope === Deprecation::SCOPE_CONFIG) {
|
||||||
// Deprecated config set via yaml will only be shown in the browser when using ?flush=1
|
// Deprecated config set via yaml will only be shown in the browser when using ?flush=1
|
||||||
// It will not show in CLI when running dev/build flush=1
|
// It will not show in CLI when running dev/build flush=1
|
||||||
$data = [
|
$data = [
|
||||||
'key' => sha1($string),
|
'key' => sha1($string),
|
||||||
'message' => $string,
|
'message' => $string,
|
||||||
'calledInsideWithNoReplacement' => self::$insideWithNoReplacement
|
'calledInsideWithNoReplacement' => Deprecation::$insideWithNoReplacement
|
||||||
];
|
];
|
||||||
} else {
|
} else {
|
||||||
if (!self::isEnabled()) {
|
if (!Deprecation::isEnabled()) {
|
||||||
// Do not add to self::$userErrorMessageBuffer, as the backtrace is too expensive
|
// Do not add to Deprecation::$userErrorMessageBuffer, as the backtrace is too expensive
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,7 +298,7 @@ class Deprecation
|
|||||||
// Get the calling scope
|
// Get the calling scope
|
||||||
if ($scope == Deprecation::SCOPE_METHOD) {
|
if ($scope == Deprecation::SCOPE_METHOD) {
|
||||||
$backtrace = debug_backtrace(0);
|
$backtrace = debug_backtrace(0);
|
||||||
$caller = self::get_called_method_from_trace($backtrace, 1);
|
$caller = Deprecation::get_called_method_from_trace($backtrace, 1);
|
||||||
} elseif ($scope == Deprecation::SCOPE_CLASS) {
|
} elseif ($scope == Deprecation::SCOPE_CLASS) {
|
||||||
$backtrace = debug_backtrace(0);
|
$backtrace = debug_backtrace(0);
|
||||||
$caller = isset($backtrace[1]['class']) ? $backtrace[1]['class'] : '(unknown)';
|
$caller = isset($backtrace[1]['class']) ? $backtrace[1]['class'] : '(unknown)';
|
||||||
@ -310,8 +310,8 @@ class Deprecation
|
|||||||
$string .= ".";
|
$string .= ".";
|
||||||
}
|
}
|
||||||
|
|
||||||
$level = self::$insideWithNoReplacement ? 4 : 2;
|
$level = Deprecation::$insideWithNoReplacement ? 4 : 2;
|
||||||
$string .= " Called from " . self::get_called_method_from_trace($backtrace, $level) . '.';
|
$string .= " Called from " . Deprecation::get_called_method_from_trace($backtrace, $level) . '.';
|
||||||
|
|
||||||
if ($caller) {
|
if ($caller) {
|
||||||
$string = $caller . ' is deprecated.' . ($string ? ' ' . $string : '');
|
$string = $caller . ' is deprecated.' . ($string ? ' ' . $string : '');
|
||||||
@ -319,22 +319,22 @@ class Deprecation
|
|||||||
$data = [
|
$data = [
|
||||||
'key' => sha1($string),
|
'key' => sha1($string),
|
||||||
'message' => $string,
|
'message' => $string,
|
||||||
'calledInsideWithNoReplacement' => self::$insideWithNoReplacement
|
'calledInsideWithNoReplacement' => Deprecation::$insideWithNoReplacement
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
if ($data && !array_key_exists($data['key'], self::$userErrorMessageBuffer)) {
|
if ($data && !array_key_exists($data['key'], Deprecation::$userErrorMessageBuffer)) {
|
||||||
// Store de-duplicated data in a buffer to be outputted when outputNotices() is called
|
// Store de-duplicated data in a buffer to be outputted when outputNotices() is called
|
||||||
self::$userErrorMessageBuffer[$data['key']] = $data;
|
Deprecation::$userErrorMessageBuffer[$data['key']] = $data;
|
||||||
|
|
||||||
// Use a shutdown function rather than immediately calling user_error() so that notices
|
// Use a shutdown function rather than immediately calling user_error() so that notices
|
||||||
// do not interfere with setting session varibles i.e. headers already sent error
|
// do not interfere with setting session varibles i.e. headers already sent error
|
||||||
// it also means the deprecation notices appear below all phpunit output in CI
|
// it also means the deprecation notices appear below all phpunit output in CI
|
||||||
// which is far nicer than having it spliced between phpunit output
|
// which is far nicer than having it spliced between phpunit output
|
||||||
if (!self::$haveSetShutdownFunction && self::isEnabled()) {
|
if (!Deprecation::$haveSetShutdownFunction && Deprecation::isEnabled()) {
|
||||||
register_shutdown_function(function () {
|
register_shutdown_function(function () {
|
||||||
self::outputNotices();
|
Deprecation::outputNotices();
|
||||||
});
|
});
|
||||||
self::$haveSetShutdownFunction = true;
|
Deprecation::$haveSetShutdownFunction = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (BadMethodCallException $e) {
|
} catch (BadMethodCallException $e) {
|
||||||
|
@ -96,10 +96,10 @@ class DatabaseAdapterRegistry implements Flushable
|
|||||||
|
|
||||||
// set default fields if none are defined already
|
// set default fields if none are defined already
|
||||||
if (!isset($config['fields'])) {
|
if (!isset($config['fields'])) {
|
||||||
$config['fields'] = self::$default_fields;
|
$config['fields'] = DatabaseAdapterRegistry::$default_fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
self::$adapters[$config['class']] = $config;
|
DatabaseAdapterRegistry::$adapters[$config['class']] = $config;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -109,7 +109,7 @@ class DatabaseAdapterRegistry implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function unregister($class)
|
public static function unregister($class)
|
||||||
{
|
{
|
||||||
unset(self::$adapters[$class]);
|
unset(DatabaseAdapterRegistry::$adapters[$class]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -204,7 +204,7 @@ class DatabaseAdapterRegistry implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function get_adapters()
|
public static function get_adapters()
|
||||||
{
|
{
|
||||||
return self::$adapters;
|
return DatabaseAdapterRegistry::$adapters;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -215,8 +215,8 @@ class DatabaseAdapterRegistry implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function get_adapter($class)
|
public static function get_adapter($class)
|
||||||
{
|
{
|
||||||
if (isset(self::$adapters[$class])) {
|
if (isset(DatabaseAdapterRegistry::$adapters[$class])) {
|
||||||
return self::$adapters[$class];
|
return DatabaseAdapterRegistry::$adapters[$class];
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -228,7 +228,7 @@ class DatabaseAdapterRegistry implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function get_default_fields()
|
public static function get_default_fields()
|
||||||
{
|
{
|
||||||
return self::$default_fields;
|
return DatabaseAdapterRegistry::$default_fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -206,7 +206,7 @@ abstract class SapphireTest extends TestCase implements TestOnly
|
|||||||
*/
|
*/
|
||||||
protected static function is_running_test()
|
protected static function is_running_test()
|
||||||
{
|
{
|
||||||
return self::$is_running_test;
|
return SapphireTest::$is_running_test;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -216,7 +216,7 @@ abstract class SapphireTest extends TestCase implements TestOnly
|
|||||||
*/
|
*/
|
||||||
protected static function set_is_running_test($bool)
|
protected static function set_is_running_test($bool)
|
||||||
{
|
{
|
||||||
self::$is_running_test = $bool;
|
SapphireTest::$is_running_test = $bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -661,7 +661,7 @@ abstract class SapphireTest extends TestCase implements TestOnly
|
|||||||
public static function assertListContains($matches, SS_List $list, $message = '')
|
public static function assertListContains($matches, SS_List $list, $message = '')
|
||||||
{
|
{
|
||||||
if (!is_array($matches)) {
|
if (!is_array($matches)) {
|
||||||
throw self::createInvalidArgumentException(
|
throw SapphireTest::createInvalidArgumentException(
|
||||||
1,
|
1,
|
||||||
'array'
|
'array'
|
||||||
);
|
);
|
||||||
@ -699,7 +699,7 @@ abstract class SapphireTest extends TestCase implements TestOnly
|
|||||||
public static function assertListNotContains($matches, SS_List $list, $message = '')
|
public static function assertListNotContains($matches, SS_List $list, $message = '')
|
||||||
{
|
{
|
||||||
if (!is_array($matches)) {
|
if (!is_array($matches)) {
|
||||||
throw self::createInvalidArgumentException(
|
throw SapphireTest::createInvalidArgumentException(
|
||||||
1,
|
1,
|
||||||
'array'
|
'array'
|
||||||
);
|
);
|
||||||
@ -739,7 +739,7 @@ abstract class SapphireTest extends TestCase implements TestOnly
|
|||||||
public static function assertListEquals($matches, SS_List $list, $message = '')
|
public static function assertListEquals($matches, SS_List $list, $message = '')
|
||||||
{
|
{
|
||||||
if (!is_array($matches)) {
|
if (!is_array($matches)) {
|
||||||
throw self::createInvalidArgumentException(
|
throw SapphireTest::createInvalidArgumentException(
|
||||||
1,
|
1,
|
||||||
'array'
|
'array'
|
||||||
);
|
);
|
||||||
@ -770,7 +770,7 @@ abstract class SapphireTest extends TestCase implements TestOnly
|
|||||||
public static function assertListAllMatch($match, SS_List $list, $message = '')
|
public static function assertListAllMatch($match, SS_List $list, $message = '')
|
||||||
{
|
{
|
||||||
if (!is_array($match)) {
|
if (!is_array($match)) {
|
||||||
throw self::createInvalidArgumentException(
|
throw SapphireTest::createInvalidArgumentException(
|
||||||
1,
|
1,
|
||||||
'array'
|
'array'
|
||||||
);
|
);
|
||||||
|
@ -11,7 +11,7 @@ class TestKernel extends CoreKernel
|
|||||||
{
|
{
|
||||||
public function __construct($basePath)
|
public function __construct($basePath)
|
||||||
{
|
{
|
||||||
$this->setEnvironment(self::DEV);
|
$this->setEnvironment(TestKernel::DEV);
|
||||||
parent::__construct($basePath);
|
parent::__construct($basePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ class TestKernel extends CoreKernel
|
|||||||
*/
|
*/
|
||||||
public function reset()
|
public function reset()
|
||||||
{
|
{
|
||||||
$this->setEnvironment(self::DEV);
|
$this->setEnvironment(TestKernel::DEV);
|
||||||
$this->bootPHP();
|
$this->bootPHP();
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ class RelationValidationService implements Resettable
|
|||||||
|
|
||||||
public static function reset(): void
|
public static function reset(): void
|
||||||
{
|
{
|
||||||
$service = self::singleton();
|
$service = RelationValidationService::singleton();
|
||||||
$service->clearErrors();
|
$service->clearErrors();
|
||||||
$service->ignoreConfig = false;
|
$service->ignoreConfig = false;
|
||||||
}
|
}
|
||||||
@ -98,7 +98,7 @@ class RelationValidationService implements Resettable
|
|||||||
*/
|
*/
|
||||||
public function validateRelations(): array
|
public function validateRelations(): array
|
||||||
{
|
{
|
||||||
self::reset();
|
RelationValidationService::reset();
|
||||||
$classes = ClassInfo::subclassesFor(DataObject::class);
|
$classes = ClassInfo::subclassesFor(DataObject::class);
|
||||||
|
|
||||||
return $this->validateClasses($classes);
|
return $this->validateClasses($classes);
|
||||||
@ -139,7 +139,7 @@ class RelationValidationService implements Resettable
|
|||||||
*/
|
*/
|
||||||
public function inspectClasses(array $classes): array
|
public function inspectClasses(array $classes): array
|
||||||
{
|
{
|
||||||
self::reset();
|
RelationValidationService::reset();
|
||||||
$this->ignoreConfig = true;
|
$this->ignoreConfig = true;
|
||||||
|
|
||||||
return $this->validateClasses($classes);
|
return $this->validateClasses($classes);
|
||||||
|
@ -48,7 +48,7 @@ class ConfirmedPasswordField extends FormField
|
|||||||
/**
|
/**
|
||||||
* Allow empty fields when entering the password for the first time
|
* Allow empty fields when entering the password for the first time
|
||||||
* If this is set to true then a random password may be generated if the field is empty
|
* If this is set to true then a random password may be generated if the field is empty
|
||||||
* depending on the value of $self::generateRandomPasswordOnEmtpy
|
* depending on the value of $ConfirmedPasswordField::generateRandomPasswordOnEmtpy
|
||||||
*
|
*
|
||||||
* @var boolean
|
* @var boolean
|
||||||
*/
|
*/
|
||||||
|
@ -278,7 +278,7 @@ class Form extends ViewableData implements HasRequestHandler
|
|||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
RequestHandler $controller = null,
|
RequestHandler $controller = null,
|
||||||
$name = self::DEFAULT_NAME,
|
$name = Form::DEFAULT_NAME,
|
||||||
FieldList $fields = null,
|
FieldList $fields = null,
|
||||||
FieldList $actions = null,
|
FieldList $actions = null,
|
||||||
Validator $validator = null
|
Validator $validator = null
|
||||||
@ -348,7 +348,7 @@ class Form extends ViewableData implements HasRequestHandler
|
|||||||
// load data in from previous submission upon error
|
// load data in from previous submission upon error
|
||||||
$data = $this->getSessionData();
|
$data = $this->getSessionData();
|
||||||
if (isset($data)) {
|
if (isset($data)) {
|
||||||
$this->loadDataFrom($data, self::MERGE_AS_INTERNAL_VALUE);
|
$this->loadDataFrom($data, Form::MERGE_AS_INTERNAL_VALUE);
|
||||||
}
|
}
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -536,7 +536,7 @@ class Form extends ViewableData implements HasRequestHandler
|
|||||||
*/
|
*/
|
||||||
protected function setupDefaultClasses()
|
protected function setupDefaultClasses()
|
||||||
{
|
{
|
||||||
$defaultClasses = self::config()->get('default_classes');
|
$defaultClasses = static::config()->get('default_classes');
|
||||||
if ($defaultClasses) {
|
if ($defaultClasses) {
|
||||||
foreach ($defaultClasses as $class) {
|
foreach ($defaultClasses as $class) {
|
||||||
$this->addExtraClass($class);
|
$this->addExtraClass($class);
|
||||||
@ -560,7 +560,7 @@ class Form extends ViewableData implements HasRequestHandler
|
|||||||
* in which case the default form behaviour will kick in.
|
* in which case the default form behaviour will kick in.
|
||||||
*
|
*
|
||||||
* @param $callback
|
* @param $callback
|
||||||
* @return self
|
* @return Form
|
||||||
*/
|
*/
|
||||||
public function setValidationResponseCallback($callback)
|
public function setValidationResponseCallback($callback)
|
||||||
{
|
{
|
||||||
@ -954,12 +954,12 @@ class Form extends ViewableData implements HasRequestHandler
|
|||||||
if ($fields = $this->fields->dataFields()) {
|
if ($fields = $this->fields->dataFields()) {
|
||||||
foreach ($fields as $field) {
|
foreach ($fields as $field) {
|
||||||
if ($field instanceof FileField) {
|
if ($field instanceof FileField) {
|
||||||
return self::ENC_TYPE_MULTIPART;
|
return Form::ENC_TYPE_MULTIPART;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return self::ENC_TYPE_URLENCODED;
|
return Form::ENC_TYPE_URLENCODED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1343,7 +1343,7 @@ class Form extends ViewableData implements HasRequestHandler
|
|||||||
|
|
||||||
// Handle the backwards compatible case of passing "true" as the second argument
|
// Handle the backwards compatible case of passing "true" as the second argument
|
||||||
if ($mergeStrategy === true) {
|
if ($mergeStrategy === true) {
|
||||||
$mergeStrategy = self::MERGE_CLEAR_MISSING;
|
$mergeStrategy = Form::MERGE_CLEAR_MISSING;
|
||||||
} elseif ($mergeStrategy === false) {
|
} elseif ($mergeStrategy === false) {
|
||||||
$mergeStrategy = 0;
|
$mergeStrategy = 0;
|
||||||
}
|
}
|
||||||
@ -1359,9 +1359,9 @@ class Form extends ViewableData implements HasRequestHandler
|
|||||||
|
|
||||||
// Using the `MERGE_AS_INTERNAL_VALUE` or `MERGE_AS_SUBMITTED_VALUE` flags users can explicitly specify which
|
// Using the `MERGE_AS_INTERNAL_VALUE` or `MERGE_AS_SUBMITTED_VALUE` flags users can explicitly specify which
|
||||||
// `setValue` method to use.
|
// `setValue` method to use.
|
||||||
if (($mergeStrategy & self::MERGE_AS_INTERNAL_VALUE) == self::MERGE_AS_INTERNAL_VALUE) {
|
if (($mergeStrategy & Form::MERGE_AS_INTERNAL_VALUE) == Form::MERGE_AS_INTERNAL_VALUE) {
|
||||||
$submitted = false;
|
$submitted = false;
|
||||||
} elseif (($mergeStrategy & self::MERGE_AS_SUBMITTED_VALUE) == self::MERGE_AS_SUBMITTED_VALUE) {
|
} elseif (($mergeStrategy & Form::MERGE_AS_SUBMITTED_VALUE) == Form::MERGE_AS_SUBMITTED_VALUE) {
|
||||||
$submitted = true;
|
$submitted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1455,10 +1455,10 @@ class Form extends ViewableData implements HasRequestHandler
|
|||||||
// save to the field if either a value is given, or loading of blank/undefined values is forced
|
// save to the field if either a value is given, or loading of blank/undefined values is forced
|
||||||
$setValue = false;
|
$setValue = false;
|
||||||
if ($exists) {
|
if ($exists) {
|
||||||
if ($val != false || ($mergeStrategy & self::MERGE_IGNORE_FALSEISH) != self::MERGE_IGNORE_FALSEISH) {
|
if ($val != false || ($mergeStrategy & Form::MERGE_IGNORE_FALSEISH) != Form::MERGE_IGNORE_FALSEISH) {
|
||||||
$setValue = true;
|
$setValue = true;
|
||||||
}
|
}
|
||||||
} elseif (($mergeStrategy & self::MERGE_CLEAR_MISSING) == self::MERGE_CLEAR_MISSING) {
|
} elseif (($mergeStrategy & Form::MERGE_CLEAR_MISSING) == Form::MERGE_CLEAR_MISSING) {
|
||||||
$setValue = true;
|
$setValue = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ interface FormFactory
|
|||||||
* Custom factories may support more advanced parameters.
|
* Custom factories may support more advanced parameters.
|
||||||
* @return Form
|
* @return Form
|
||||||
*/
|
*/
|
||||||
public function getForm(RequestHandler $controller = null, $name = self::DEFAULT_NAME, $context = []);
|
public function getForm(RequestHandler $controller = null, $name = FormFactory::DEFAULT_NAME, $context = []);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return list of mandatory context keys
|
* Return list of mandatory context keys
|
||||||
|
@ -238,7 +238,7 @@ class FormField extends RequestHandler
|
|||||||
* or simply be a block of stand-alone content. As with 'Custom',
|
* or simply be a block of stand-alone content. As with 'Custom',
|
||||||
* the component property is mandatory if this is assigned.
|
* the component property is mandatory if this is assigned.
|
||||||
*
|
*
|
||||||
* Each value has an equivalent constant, e.g. {@link self::SCHEMA_DATA_TYPE_STRING}.
|
* Each value has an equivalent constant, e.g. {@link FormField::SCHEMA_DATA_TYPE_STRING}.
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
@ -333,7 +333,7 @@ class FormField extends RequestHandler
|
|||||||
$this->setName($name);
|
$this->setName($name);
|
||||||
|
|
||||||
if ($title === null) {
|
if ($title === null) {
|
||||||
$this->title = self::name_to_label($name);
|
$this->title = FormField::name_to_label($name);
|
||||||
} else {
|
} else {
|
||||||
$this->title = $title;
|
$this->title = $title;
|
||||||
}
|
}
|
||||||
@ -1566,7 +1566,7 @@ class FormField extends RequestHandler
|
|||||||
* @param Tip|null $tip
|
* @param Tip|null $tip
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function setTitleTip(?Tip $tip): self
|
public function setTitleTip(?Tip $tip): FormField
|
||||||
{
|
{
|
||||||
$this->titleTip = $tip;
|
$this->titleTip = $tip;
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -567,11 +567,11 @@ class GridField extends FormField
|
|||||||
|
|
||||||
// Continue looping if any placeholders exist
|
// Continue looping if any placeholders exist
|
||||||
while (array_filter($content ?? [], function ($value) {
|
while (array_filter($content ?? [], function ($value) {
|
||||||
return preg_match(self::FRAGMENT_REGEX ?? '', $value ?? '');
|
return preg_match(GridField::FRAGMENT_REGEX ?? '', $value ?? '');
|
||||||
})) {
|
})) {
|
||||||
foreach ($content as $contentKey => $contentValue) {
|
foreach ($content as $contentKey => $contentValue) {
|
||||||
// Skip if this specific content has no placeholders
|
// Skip if this specific content has no placeholders
|
||||||
if (!preg_match_all(self::FRAGMENT_REGEX ?? '', $contentValue ?? '', $matches)) {
|
if (!preg_match_all(GridField::FRAGMENT_REGEX ?? '', $contentValue ?? '', $matches)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
foreach ($matches[1] as $match) {
|
foreach ($matches[1] as $match) {
|
||||||
@ -587,7 +587,7 @@ class GridField extends FormField
|
|||||||
// If the fragment still has a fragment definition in it, when we should defer
|
// If the fragment still has a fragment definition in it, when we should defer
|
||||||
// this item until later.
|
// this item until later.
|
||||||
|
|
||||||
if (preg_match(self::FRAGMENT_REGEX ?? '', $fragment ?? '', $matches)) {
|
if (preg_match(GridField::FRAGMENT_REGEX ?? '', $fragment ?? '', $matches)) {
|
||||||
if (isset($fragmentDeferred[$contentKey]) && $fragmentDeferred[$contentKey] > 5) {
|
if (isset($fragmentDeferred[$contentKey]) && $fragmentDeferred[$contentKey] > 5) {
|
||||||
throw new LogicException(sprintf(
|
throw new LogicException(sprintf(
|
||||||
'GridField HTML fragment "%s" and "%s" appear to have a circular dependency.',
|
'GridField HTML fragment "%s" and "%s" appear to have a circular dependency.',
|
||||||
|
@ -285,7 +285,7 @@ class GridFieldDetailForm extends AbstractGridFieldComponent implements GridFiel
|
|||||||
* database, and the record has a CMSEditLink method, then the system will redirect to the
|
* database, and the record has a CMSEditLink method, then the system will redirect to the
|
||||||
* URL returned by that method.
|
* URL returned by that method.
|
||||||
*/
|
*/
|
||||||
public function setRedirectMissingRecords(bool $redirectMissingRecords): self
|
public function setRedirectMissingRecords(bool $redirectMissingRecords): GridFieldDetailForm
|
||||||
{
|
{
|
||||||
$this->redirectMissingRecords = $redirectMissingRecords;
|
$this->redirectMissingRecords = $redirectMissingRecords;
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -92,7 +92,7 @@ class GridFieldFilterHeader extends AbstractGridFieldComponent implements GridFi
|
|||||||
return $this->searchField;
|
return $this->searchField;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setSearchField(string $field): self
|
public function setSearchField(string $field): GridFieldFilterHeader
|
||||||
{
|
{
|
||||||
$this->searchField = $field;
|
$this->searchField = $field;
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -25,14 +25,14 @@ class GridState_Data
|
|||||||
|
|
||||||
public function __get($name)
|
public function __get($name)
|
||||||
{
|
{
|
||||||
return $this->getData($name, new self());
|
return $this->getData($name, new GridState_Data());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __call($name, $arguments)
|
public function __call($name, $arguments)
|
||||||
{
|
{
|
||||||
// Assume first parameter is default value
|
// Assume first parameter is default value
|
||||||
if (empty($arguments)) {
|
if (empty($arguments)) {
|
||||||
$default = new self();
|
$default = new GridState_Data();
|
||||||
} else {
|
} else {
|
||||||
$default = $arguments[0];
|
$default = $arguments[0];
|
||||||
}
|
}
|
||||||
@ -72,7 +72,7 @@ class GridState_Data
|
|||||||
$this->data[$name] = $default;
|
$this->data[$name] = $default;
|
||||||
} else {
|
} else {
|
||||||
if (is_array($this->data[$name])) {
|
if (is_array($this->data[$name])) {
|
||||||
$this->data[$name] = new self($this->data[$name]);
|
$this->data[$name] = new GridState_Data($this->data[$name]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,11 +81,11 @@ abstract class HTMLEditorConfig
|
|||||||
return static::get_active();
|
return static::get_active();
|
||||||
}
|
}
|
||||||
// Create new instance if unconfigured
|
// Create new instance if unconfigured
|
||||||
if (!isset(self::$configs[$identifier])) {
|
if (!isset(HTMLEditorConfig::$configs[$identifier])) {
|
||||||
self::$configs[$identifier] = static::create();
|
HTMLEditorConfig::$configs[$identifier] = static::create();
|
||||||
self::$configs[$identifier]->setOption('editorIdentifier', $identifier);
|
HTMLEditorConfig::$configs[$identifier]->setOption('editorIdentifier', $identifier);
|
||||||
}
|
}
|
||||||
return self::$configs[$identifier];
|
return HTMLEditorConfig::$configs[$identifier];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -98,10 +98,10 @@ abstract class HTMLEditorConfig
|
|||||||
public static function set_config($identifier, HTMLEditorConfig $config = null)
|
public static function set_config($identifier, HTMLEditorConfig $config = null)
|
||||||
{
|
{
|
||||||
if ($config) {
|
if ($config) {
|
||||||
self::$configs[$identifier] = $config;
|
HTMLEditorConfig::$configs[$identifier] = $config;
|
||||||
self::$configs[$identifier]->setOption('editorIdentifier', $identifier);
|
HTMLEditorConfig::$configs[$identifier]->setOption('editorIdentifier', $identifier);
|
||||||
} else {
|
} else {
|
||||||
unset(self::$configs[$identifier]);
|
unset(HTMLEditorConfig::$configs[$identifier]);
|
||||||
}
|
}
|
||||||
return $config;
|
return $config;
|
||||||
}
|
}
|
||||||
@ -136,7 +136,7 @@ abstract class HTMLEditorConfig
|
|||||||
*/
|
*/
|
||||||
public static function set_active_identifier($identifier)
|
public static function set_active_identifier($identifier)
|
||||||
{
|
{
|
||||||
self::$current = $identifier;
|
HTMLEditorConfig::$current = $identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -147,7 +147,7 @@ abstract class HTMLEditorConfig
|
|||||||
*/
|
*/
|
||||||
public static function get_active_identifier()
|
public static function get_active_identifier()
|
||||||
{
|
{
|
||||||
$identifier = self::$current ?: static::config()->get('default_config');
|
$identifier = HTMLEditorConfig::$current ?: static::config()->get('default_config');
|
||||||
return $identifier;
|
return $identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,8 +158,8 @@ abstract class HTMLEditorConfig
|
|||||||
*/
|
*/
|
||||||
public static function get_active()
|
public static function get_active()
|
||||||
{
|
{
|
||||||
$identifier = self::get_active_identifier();
|
$identifier = HTMLEditorConfig::get_active_identifier();
|
||||||
return self::get($identifier);
|
return HTMLEditorConfig::get($identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -184,7 +184,7 @@ abstract class HTMLEditorConfig
|
|||||||
{
|
{
|
||||||
$configs = [];
|
$configs = [];
|
||||||
|
|
||||||
foreach (self::$configs as $identifier => $config) {
|
foreach (HTMLEditorConfig::$configs as $identifier => $config) {
|
||||||
$configs[$identifier] = $config->getOption('friendly_name');
|
$configs[$identifier] = $config->getOption('friendly_name');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -740,7 +740,7 @@ class TinyMCEConfig extends HTMLEditorConfig implements i18nEntityProvider
|
|||||||
private function initImageSizePresets(array &$settings): void
|
private function initImageSizePresets(array &$settings): void
|
||||||
{
|
{
|
||||||
if (empty($settings['image_size_presets'])) {
|
if (empty($settings['image_size_presets'])) {
|
||||||
$settings['image_size_presets'] = self::config()->get('image_size_presets');
|
$settings['image_size_presets'] = static::config()->get('image_size_presets');
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($settings['image_size_presets'] as &$preset) {
|
foreach ($settings['image_size_presets'] as &$preset) {
|
||||||
@ -755,7 +755,7 @@ class TinyMCEConfig extends HTMLEditorConfig implements i18nEntityProvider
|
|||||||
);
|
);
|
||||||
} elseif (empty($preset['text']) && isset($preset['width'])) {
|
} elseif (empty($preset['text']) && isset($preset['width'])) {
|
||||||
$preset['text'] = _t(
|
$preset['text'] = _t(
|
||||||
self::class . '.PIXEL_WIDTH',
|
TinyMCEConfig::class . '.PIXEL_WIDTH',
|
||||||
'{width} pixels',
|
'{width} pixels',
|
||||||
$preset
|
$preset
|
||||||
);
|
);
|
||||||
@ -945,7 +945,7 @@ class TinyMCEConfig extends HTMLEditorConfig implements i18nEntityProvider
|
|||||||
* @param string $folderName
|
* @param string $folderName
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function setFolderName(string $folderName): self
|
public function setFolderName(string $folderName): TinyMCEConfig
|
||||||
{
|
{
|
||||||
$folder = Folder::find_or_make($folderName);
|
$folder = Folder::find_or_make($folderName);
|
||||||
$folderID = $folder ? $folder->ID : null;
|
$folderID = $folder ? $folder->ID : null;
|
||||||
@ -956,9 +956,9 @@ class TinyMCEConfig extends HTMLEditorConfig implements i18nEntityProvider
|
|||||||
public function provideI18nEntities()
|
public function provideI18nEntities()
|
||||||
{
|
{
|
||||||
$entities = [
|
$entities = [
|
||||||
self::class . '.PIXEL_WIDTH' => '{width} pixels',
|
TinyMCEConfig::class . '.PIXEL_WIDTH' => '{width} pixels',
|
||||||
];
|
];
|
||||||
foreach (self::config()->get('image_size_presets') as $preset) {
|
foreach (static::config()->get('image_size_presets') as $preset) {
|
||||||
if (empty($preset['i18n']) || empty($preset['text'])) {
|
if (empty($preset['i18n']) || empty($preset['text'])) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ class HTMLReadonlyField extends ReadonlyField
|
|||||||
'ValueEntities' => 'HTMLFragment',
|
'ValueEntities' => 'HTMLFragment',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $schemaDataType = self::SCHEMA_DATA_TYPE_STRUCTURAL;
|
protected $schemaDataType = HTMLReadonlyField::SCHEMA_DATA_TYPE_STRUCTURAL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
|
@ -17,7 +17,7 @@ class HeaderField extends DatalessField
|
|||||||
*/
|
*/
|
||||||
protected $headingLevel = 2;
|
protected $headingLevel = 2;
|
||||||
|
|
||||||
protected $schemaDataType = self::SCHEMA_DATA_TYPE_STRUCTURAL;
|
protected $schemaDataType = HeaderField::SCHEMA_DATA_TYPE_STRUCTURAL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
|
@ -26,7 +26,7 @@ class LiteralField extends DatalessField
|
|||||||
*/
|
*/
|
||||||
protected $content;
|
protected $content;
|
||||||
|
|
||||||
protected $schemaDataType = self::SCHEMA_DATA_TYPE_STRUCTURAL;
|
protected $schemaDataType = LiteralField::SCHEMA_DATA_TYPE_STRUCTURAL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
|
@ -67,7 +67,7 @@ abstract class SingleSelectField extends SelectField
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param boolean $bool
|
* @param boolean $bool
|
||||||
* @return self Self reference
|
* @return SingleSelectField Self reference
|
||||||
*/
|
*/
|
||||||
public function setHasEmptyDefault($bool)
|
public function setHasEmptyDefault($bool)
|
||||||
{
|
{
|
||||||
|
@ -78,7 +78,7 @@ class TextField extends FormField implements TippableFieldInterface
|
|||||||
* @param Tip|null $tip The Tip to apply, or null to remove an existing one
|
* @param Tip|null $tip The Tip to apply, or null to remove an existing one
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function setTip(?Tip $tip = null): self
|
public function setTip(?Tip $tip = null): TextField
|
||||||
{
|
{
|
||||||
$this->tip = $tip;
|
$this->tip = $tip;
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ class Tip
|
|||||||
|
|
||||||
private const DEFAULT_ICON = 'lamp';
|
private const DEFAULT_ICON = 'lamp';
|
||||||
|
|
||||||
private const DEFAULT_IMPORTANCE_LEVEL = self::IMPORTANCE_LEVELS['NORMAL'];
|
private const DEFAULT_IMPORTANCE_LEVEL = Tip::IMPORTANCE_LEVELS['NORMAL'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string The icon that should be used on the Tip button
|
* @var string The icon that should be used on the Tip button
|
||||||
@ -46,8 +46,8 @@ class Tip
|
|||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
string $message,
|
string $message,
|
||||||
string $importance_level = self::DEFAULT_IMPORTANCE_LEVEL,
|
string $importance_level = Tip::DEFAULT_IMPORTANCE_LEVEL,
|
||||||
string $icon = self::DEFAULT_ICON
|
string $icon = Tip::DEFAULT_ICON
|
||||||
) {
|
) {
|
||||||
$this->setMessage($message);
|
$this->setMessage($message);
|
||||||
$this->setIcon($icon);
|
$this->setIcon($icon);
|
||||||
@ -81,9 +81,9 @@ class Tip
|
|||||||
* @return Tip
|
* @return Tip
|
||||||
* @throws InvalidArgumentException
|
* @throws InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
public function setImportanceLevel(string $importance_level): self
|
public function setImportanceLevel(string $importance_level): Tip
|
||||||
{
|
{
|
||||||
if (!in_array($importance_level, self::IMPORTANCE_LEVELS ?? [])) {
|
if (!in_array($importance_level, Tip::IMPORTANCE_LEVELS ?? [])) {
|
||||||
throw new InvalidArgumentException(
|
throw new InvalidArgumentException(
|
||||||
'Provided importance level must be defined in Tip::IMPORTANCE_LEVELS'
|
'Provided importance level must be defined in Tip::IMPORTANCE_LEVELS'
|
||||||
);
|
);
|
||||||
@ -106,7 +106,7 @@ class Tip
|
|||||||
* @param string $icon
|
* @param string $icon
|
||||||
* @return Tip
|
* @return Tip
|
||||||
*/
|
*/
|
||||||
public function setIcon(string $icon): self
|
public function setIcon(string $icon): Tip
|
||||||
{
|
{
|
||||||
$this->icon = $icon;
|
$this->icon = $icon;
|
||||||
|
|
||||||
@ -125,7 +125,7 @@ class Tip
|
|||||||
* @param string $message
|
* @param string $message
|
||||||
* @return Tip
|
* @return Tip
|
||||||
*/
|
*/
|
||||||
public function setMessage(string $message): self
|
public function setMessage(string $message): Tip
|
||||||
{
|
{
|
||||||
$this->message = $message;
|
$this->message = $message;
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ use SilverStripe\ORM\Hierarchy\MarkedSet;
|
|||||||
*/
|
*/
|
||||||
class TreeDropdownField extends FormField implements HasOneRelationFieldInterface
|
class TreeDropdownField extends FormField implements HasOneRelationFieldInterface
|
||||||
{
|
{
|
||||||
protected $schemaDataType = self::SCHEMA_DATA_TYPE_SINGLESELECT;
|
protected $schemaDataType = TreeDropdownField::SCHEMA_DATA_TYPE_SINGLESELECT;
|
||||||
|
|
||||||
protected $schemaComponent = 'TreeDropdownField';
|
protected $schemaComponent = 'TreeDropdownField';
|
||||||
|
|
||||||
@ -561,7 +561,7 @@ class TreeDropdownField extends FormField implements HasOneRelationFieldInterfac
|
|||||||
} else {
|
} else {
|
||||||
// Return basic html
|
// Return basic html
|
||||||
$html = $markingSet->renderChildren(
|
$html = $markingSet->renderChildren(
|
||||||
[self::class . '_HTML', 'type' => 'Includes'],
|
[TreeDropdownField::class . '_HTML', 'type' => 'Includes'],
|
||||||
$customised
|
$customised
|
||||||
);
|
);
|
||||||
return HTTPResponse::create()
|
return HTTPResponse::create()
|
||||||
@ -894,10 +894,10 @@ class TreeDropdownField extends FormField implements HasOneRelationFieldInterfac
|
|||||||
protected function getCacheKey()
|
protected function getCacheKey()
|
||||||
{
|
{
|
||||||
$target = $this->getSourceObject();
|
$target = $this->getSourceObject();
|
||||||
if (!isset(self::$cacheKeyCache[$target])) {
|
if (!isset(TreeDropdownField::$cacheKeyCache[$target])) {
|
||||||
self::$cacheKeyCache[$target] = DataList::create($target)->max('LastEdited');
|
TreeDropdownField::$cacheKeyCache[$target] = DataList::create($target)->max('LastEdited');
|
||||||
}
|
}
|
||||||
return self::$cacheKeyCache[$target];
|
return TreeDropdownField::$cacheKeyCache[$target];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSchemaDataDefaults()
|
public function getSchemaDataDefaults()
|
||||||
@ -917,7 +917,7 @@ class TreeDropdownField extends FormField implements HasOneRelationFieldInterfac
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param boolean $bool
|
* @param boolean $bool
|
||||||
* @return self Self reference
|
* @return TreeDropdownField Self reference
|
||||||
*/
|
*/
|
||||||
public function setHasEmptyDefault($bool)
|
public function setHasEmptyDefault($bool)
|
||||||
{
|
{
|
||||||
|
@ -82,7 +82,7 @@ class ArrayLib
|
|||||||
*/
|
*/
|
||||||
public static function array_values_recursive($array)
|
public static function array_values_recursive($array)
|
||||||
{
|
{
|
||||||
return self::flatten($array, false);
|
return ArrayLib::flatten($array, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -146,7 +146,7 @@ class ArrayLib
|
|||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
foreach ($haystack as $obj) {
|
foreach ($haystack as $obj) {
|
||||||
if (self::in_array_recursive($needle, $obj, $strict)) {
|
if (ArrayLib::in_array_recursive($needle, $obj, $strict)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@ class DBQueryBuilder
|
|||||||
// Skip items in the stack trace that originate from these classes or their subclasses,
|
// Skip items in the stack trace that originate from these classes or their subclasses,
|
||||||
// we want to know what called these instead
|
// we want to know what called these instead
|
||||||
$baseClasses = [
|
$baseClasses = [
|
||||||
self::class,
|
DBQueryBuilder::class,
|
||||||
DataQuery::class,
|
DataQuery::class,
|
||||||
SQLExpression::class,
|
SQLExpression::class,
|
||||||
DB::class,
|
DB::class,
|
||||||
|
@ -234,9 +234,9 @@ abstract class Database
|
|||||||
$sql = DB::inline_parameters($sql, $parameters);
|
$sql = DB::inline_parameters($sql, $parameters);
|
||||||
} elseif (strtolower($_REQUEST['showqueries'] ?? '') === 'whitelist') {
|
} elseif (strtolower($_REQUEST['showqueries'] ?? '') === 'whitelist') {
|
||||||
$displaySql = false;
|
$displaySql = false;
|
||||||
foreach (self::$whitelist_array as $query => $searchType) {
|
foreach (Database::$whitelist_array as $query => $searchType) {
|
||||||
$fullQuery = ($searchType === self::FULL_QUERY && $query === $sql);
|
$fullQuery = ($searchType === Database::FULL_QUERY && $query === $sql);
|
||||||
$partialQuery = ($searchType === self::PARTIAL_QUERY && mb_strpos($sql ?? '', $query ?? '') !== false);
|
$partialQuery = ($searchType === Database::PARTIAL_QUERY && mb_strpos($sql ?? '', $query ?? '') !== false);
|
||||||
if (!$fullQuery && !$partialQuery) {
|
if (!$fullQuery && !$partialQuery) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -277,7 +277,7 @@ abstract class Database
|
|||||||
*/
|
*/
|
||||||
public static function setWhitelistQueryArray($whitelistArray)
|
public static function setWhitelistQueryArray($whitelistArray)
|
||||||
{
|
{
|
||||||
self::$whitelist_array = $whitelistArray;
|
Database::$whitelist_array = $whitelistArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -287,7 +287,7 @@ abstract class Database
|
|||||||
*/
|
*/
|
||||||
public static function getWhitelistQueryArray()
|
public static function getWhitelistQueryArray()
|
||||||
{
|
{
|
||||||
return self::$whitelist_array;
|
return Database::$whitelist_array;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -47,7 +47,7 @@ class MySQLQueryBuilder extends DBQueryBuilder
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($limit['limit'] === null) {
|
if ($limit['limit'] === null) {
|
||||||
$limit['limit'] = self::MAX_ROWS;
|
$limit['limit'] = MySQLQueryBuilder::MAX_ROWS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Format the array limit, given an optional start key
|
// Format the array limit, given an optional start key
|
||||||
|
@ -23,8 +23,8 @@ class MySQLSchemaManager extends DBSchemaManager
|
|||||||
{
|
{
|
||||||
$fieldSchemas = $indexSchemas = "";
|
$fieldSchemas = $indexSchemas = "";
|
||||||
|
|
||||||
if (!empty($options[self::ID])) {
|
if (!empty($options[MySQLSchemaManager::ID])) {
|
||||||
$addOptions = $options[self::ID];
|
$addOptions = $options[MySQLSchemaManager::ID];
|
||||||
} else {
|
} else {
|
||||||
$addOptions = "ENGINE=InnoDB";
|
$addOptions = "ENGINE=InnoDB";
|
||||||
}
|
}
|
||||||
@ -97,7 +97,7 @@ class MySQLSchemaManager extends DBSchemaManager
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$dbID = self::ID;
|
$dbID = MySQLSchemaManager::ID;
|
||||||
if ($alteredOptions && isset($alteredOptions[$dbID])) {
|
if ($alteredOptions && isset($alteredOptions[$dbID])) {
|
||||||
$this->query(sprintf("ALTER TABLE \"%s\" %s", $tableName, $alteredOptions[$dbID]));
|
$this->query(sprintf("ALTER TABLE \"%s\" %s", $tableName, $alteredOptions[$dbID]));
|
||||||
$this->alterationMessage(
|
$this->alterationMessage(
|
||||||
@ -232,7 +232,7 @@ class MySQLSchemaManager extends DBSchemaManager
|
|||||||
// MySQL 8.0.17 stopped reporting the width attribute for integers
|
// MySQL 8.0.17 stopped reporting the width attribute for integers
|
||||||
// https://github.com/silverstripe/silverstripe-framework/issues/9453
|
// https://github.com/silverstripe/silverstripe-framework/issues/9453
|
||||||
// Note: MariaDB did not change its behaviour
|
// Note: MariaDB did not change its behaviour
|
||||||
$forceWidth = Config::inst()->get(self::class, 'schema_use_int_width');
|
$forceWidth = Config::inst()->get(MySQLSchemaManager::class, 'schema_use_int_width');
|
||||||
if ($forceWidth !== null) {
|
if ($forceWidth !== null) {
|
||||||
return $forceWidth;
|
return $forceWidth;
|
||||||
}
|
}
|
||||||
@ -256,11 +256,11 @@ class MySQLSchemaManager extends DBSchemaManager
|
|||||||
|
|
||||||
if ($field['Collation'] && $field['Collation'] != 'NULL') {
|
if ($field['Collation'] && $field['Collation'] != 'NULL') {
|
||||||
// Cache collation info to cut down on database traffic
|
// Cache collation info to cut down on database traffic
|
||||||
if (!isset(self::$_cache_collation_info[$field['Collation']])) {
|
if (!isset(MySQLSchemaManager::$_cache_collation_info[$field['Collation']])) {
|
||||||
self::$_cache_collation_info[$field['Collation']]
|
MySQLSchemaManager::$_cache_collation_info[$field['Collation']]
|
||||||
= $this->query("SHOW COLLATION LIKE '{$field['Collation']}'")->record();
|
= $this->query("SHOW COLLATION LIKE '{$field['Collation']}'")->record();
|
||||||
}
|
}
|
||||||
$collInfo = self::$_cache_collation_info[$field['Collation']];
|
$collInfo = MySQLSchemaManager::$_cache_collation_info[$field['Collation']];
|
||||||
$fieldSpec .= " character set $collInfo[Charset] collate $field[Collation]";
|
$fieldSpec .= " character set $collInfo[Charset] collate $field[Collation]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ class MySQLiConnector extends DBConnector
|
|||||||
dirname($parameters['ssl_ca'] ?? ''),
|
dirname($parameters['ssl_ca'] ?? ''),
|
||||||
array_key_exists('ssl_cipher', $parameters ?? [])
|
array_key_exists('ssl_cipher', $parameters ?? [])
|
||||||
? $parameters['ssl_cipher']
|
? $parameters['ssl_cipher']
|
||||||
: self::config()->get('ssl_cipher_default')
|
: static::config()->get('ssl_cipher_default')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ class NullDatabase extends Database
|
|||||||
/**
|
/**
|
||||||
* @param string $msg
|
* @param string $msg
|
||||||
*/
|
*/
|
||||||
public function setErrorMessage(string $msg): self
|
public function setErrorMessage(string $msg): NullDatabase
|
||||||
{
|
{
|
||||||
$this->errorMessage = $msg;
|
$this->errorMessage = $msg;
|
||||||
return $this;
|
return $this;
|
||||||
@ -43,7 +43,7 @@ class NullDatabase extends Database
|
|||||||
/**
|
/**
|
||||||
* @param string $msg
|
* @param string $msg
|
||||||
*/
|
*/
|
||||||
public function setQueryErrorMessage(string $msg): self
|
public function setQueryErrorMessage(string $msg): NullDatabase
|
||||||
{
|
{
|
||||||
$this->queryErrorMessage = $msg;
|
$this->queryErrorMessage = $msg;
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -84,7 +84,7 @@ class DB
|
|||||||
*/
|
*/
|
||||||
public static function set_conn(Database $connection, $name = 'default')
|
public static function set_conn(Database $connection, $name = 'default')
|
||||||
{
|
{
|
||||||
self::$connections[$name] = $connection;
|
DB::$connections[$name] = $connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -96,8 +96,8 @@ class DB
|
|||||||
*/
|
*/
|
||||||
public static function get_conn($name = 'default')
|
public static function get_conn($name = 'default')
|
||||||
{
|
{
|
||||||
if (isset(self::$connections[$name])) {
|
if (isset(DB::$connections[$name])) {
|
||||||
return self::$connections[$name];
|
return DB::$connections[$name];
|
||||||
}
|
}
|
||||||
|
|
||||||
// lazy connect
|
// lazy connect
|
||||||
@ -118,7 +118,7 @@ class DB
|
|||||||
*/
|
*/
|
||||||
public static function get_schema($name = 'default')
|
public static function get_schema($name = 'default')
|
||||||
{
|
{
|
||||||
$connection = self::get_conn($name);
|
$connection = DB::get_conn($name);
|
||||||
if ($connection) {
|
if ($connection) {
|
||||||
return $connection->getSchemaManager();
|
return $connection->getSchemaManager();
|
||||||
}
|
}
|
||||||
@ -136,7 +136,7 @@ class DB
|
|||||||
*/
|
*/
|
||||||
public static function build_sql(SQLExpression $expression, &$parameters, $name = 'default')
|
public static function build_sql(SQLExpression $expression, &$parameters, $name = 'default')
|
||||||
{
|
{
|
||||||
$connection = self::get_conn($name);
|
$connection = DB::get_conn($name);
|
||||||
if ($connection) {
|
if ($connection) {
|
||||||
return $connection->getQueryBuilder()->buildSQL($expression, $parameters);
|
return $connection->getQueryBuilder()->buildSQL($expression, $parameters);
|
||||||
} else {
|
} else {
|
||||||
@ -154,7 +154,7 @@ class DB
|
|||||||
*/
|
*/
|
||||||
public static function get_connector($name = 'default')
|
public static function get_connector($name = 'default')
|
||||||
{
|
{
|
||||||
$connection = self::get_conn($name);
|
$connection = DB::get_conn($name);
|
||||||
if ($connection) {
|
if ($connection) {
|
||||||
return $connection->getConnector();
|
return $connection->getConnector();
|
||||||
}
|
}
|
||||||
@ -187,7 +187,7 @@ class DB
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Validate name
|
// Validate name
|
||||||
if ($name && !self::valid_alternative_database_name($name)) {
|
if ($name && !DB::valid_alternative_database_name($name)) {
|
||||||
throw new InvalidArgumentException(sprintf(
|
throw new InvalidArgumentException(sprintf(
|
||||||
'Invalid alternative database name: "%s"',
|
'Invalid alternative database name: "%s"',
|
||||||
$name
|
$name
|
||||||
@ -200,9 +200,9 @@ class DB
|
|||||||
}
|
}
|
||||||
$request = Injector::inst()->get(HTTPRequest::class);
|
$request = Injector::inst()->get(HTTPRequest::class);
|
||||||
if ($name) {
|
if ($name) {
|
||||||
$request->getSession()->set(self::ALT_DB_KEY, $name);
|
$request->getSession()->set(DB::ALT_DB_KEY, $name);
|
||||||
} else {
|
} else {
|
||||||
$request->getSession()->clear(self::ALT_DB_KEY);
|
$request->getSession()->clear(DB::ALT_DB_KEY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,8 +231,8 @@ class DB
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$name = $request->getSession()->get(self::ALT_DB_KEY);
|
$name = $request->getSession()->get(DB::ALT_DB_KEY);
|
||||||
if (self::valid_alternative_database_name($name)) {
|
if (DB::valid_alternative_database_name($name)) {
|
||||||
return $name;
|
return $name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,7 +271,7 @@ class DB
|
|||||||
public static function connect($databaseConfig, $label = 'default')
|
public static function connect($databaseConfig, $label = 'default')
|
||||||
{
|
{
|
||||||
// This is used by the "testsession" module to test up a test session using an alternative name
|
// This is used by the "testsession" module to test up a test session using an alternative name
|
||||||
if ($name = self::get_alternative_database_name()) {
|
if ($name = DB::get_alternative_database_name()) {
|
||||||
$databaseConfig['database'] = $name;
|
$databaseConfig['database'] = $name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,14 +279,14 @@ class DB
|
|||||||
throw new InvalidArgumentException("DB::connect: Not passed a valid database config");
|
throw new InvalidArgumentException("DB::connect: Not passed a valid database config");
|
||||||
}
|
}
|
||||||
|
|
||||||
self::$connection_attempted = true;
|
DB::$connection_attempted = true;
|
||||||
|
|
||||||
$dbClass = $databaseConfig['type'];
|
$dbClass = $databaseConfig['type'];
|
||||||
|
|
||||||
// Using Injector->create allows us to use registered configurations
|
// Using Injector->create allows us to use registered configurations
|
||||||
// which may or may not map to explicit objects
|
// which may or may not map to explicit objects
|
||||||
$conn = Injector::inst()->create($dbClass);
|
$conn = Injector::inst()->create($dbClass);
|
||||||
self::set_conn($conn, $label);
|
DB::set_conn($conn, $label);
|
||||||
$conn->connect($databaseConfig);
|
$conn->connect($databaseConfig);
|
||||||
|
|
||||||
return $conn;
|
return $conn;
|
||||||
@ -323,7 +323,7 @@ class DB
|
|||||||
*/
|
*/
|
||||||
public static function connection_attempted()
|
public static function connection_attempted()
|
||||||
{
|
{
|
||||||
return self::$connection_attempted;
|
return DB::$connection_attempted;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -334,9 +334,9 @@ class DB
|
|||||||
*/
|
*/
|
||||||
public static function query($sql, $errorLevel = E_USER_ERROR)
|
public static function query($sql, $errorLevel = E_USER_ERROR)
|
||||||
{
|
{
|
||||||
self::$lastQuery = $sql;
|
DB::$lastQuery = $sql;
|
||||||
|
|
||||||
return self::get_conn()->query($sql, $errorLevel);
|
return DB::get_conn()->query($sql, $errorLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -426,9 +426,9 @@ class DB
|
|||||||
*/
|
*/
|
||||||
public static function prepared_query($sql, $parameters, $errorLevel = E_USER_ERROR)
|
public static function prepared_query($sql, $parameters, $errorLevel = E_USER_ERROR)
|
||||||
{
|
{
|
||||||
self::$lastQuery = $sql;
|
DB::$lastQuery = $sql;
|
||||||
|
|
||||||
return self::get_conn()->preparedQuery($sql, $parameters, $errorLevel);
|
return DB::get_conn()->preparedQuery($sql, $parameters, $errorLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -473,8 +473,8 @@ class DB
|
|||||||
*/
|
*/
|
||||||
public static function manipulate($manipulation)
|
public static function manipulate($manipulation)
|
||||||
{
|
{
|
||||||
self::$lastQuery = $manipulation;
|
DB::$lastQuery = $manipulation;
|
||||||
self::get_conn()->manipulate($manipulation);
|
DB::get_conn()->manipulate($manipulation);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -485,7 +485,7 @@ class DB
|
|||||||
*/
|
*/
|
||||||
public static function get_generated_id($table)
|
public static function get_generated_id($table)
|
||||||
{
|
{
|
||||||
return self::get_conn()->getGeneratedID($table);
|
return DB::get_conn()->getGeneratedID($table);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -495,7 +495,7 @@ class DB
|
|||||||
*/
|
*/
|
||||||
public static function is_active()
|
public static function is_active()
|
||||||
{
|
{
|
||||||
return ($conn = self::get_conn()) && $conn->isActive();
|
return ($conn = DB::get_conn()) && $conn->isActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -508,7 +508,7 @@ class DB
|
|||||||
*/
|
*/
|
||||||
public static function create_database($database)
|
public static function create_database($database)
|
||||||
{
|
{
|
||||||
return self::get_conn()->selectDatabase($database, true);
|
return DB::get_conn()->selectDatabase($database, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -531,7 +531,7 @@ class DB
|
|||||||
$options = null,
|
$options = null,
|
||||||
$advancedOptions = null
|
$advancedOptions = null
|
||||||
) {
|
) {
|
||||||
return self::get_schema()->createTable($table, $fields, $indexes, $options, $advancedOptions);
|
return DB::get_schema()->createTable($table, $fields, $indexes, $options, $advancedOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -542,7 +542,7 @@ class DB
|
|||||||
*/
|
*/
|
||||||
public static function create_field($table, $field, $spec)
|
public static function create_field($table, $field, $spec)
|
||||||
{
|
{
|
||||||
return self::get_schema()->createField($table, $field, $spec);
|
return DB::get_schema()->createField($table, $field, $spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -568,7 +568,7 @@ class DB
|
|||||||
$options = null,
|
$options = null,
|
||||||
$extensions = null
|
$extensions = null
|
||||||
) {
|
) {
|
||||||
self::get_schema()->requireTable($table, $fieldSchema, $indexSchema, $hasAutoIncPK, $options, $extensions);
|
DB::get_schema()->requireTable($table, $fieldSchema, $indexSchema, $hasAutoIncPK, $options, $extensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -580,7 +580,7 @@ class DB
|
|||||||
*/
|
*/
|
||||||
public static function require_field($table, $field, $spec)
|
public static function require_field($table, $field, $spec)
|
||||||
{
|
{
|
||||||
self::get_schema()->requireField($table, $field, $spec);
|
DB::get_schema()->requireField($table, $field, $spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -592,7 +592,7 @@ class DB
|
|||||||
*/
|
*/
|
||||||
public static function require_index($table, $index, $spec)
|
public static function require_index($table, $index, $spec)
|
||||||
{
|
{
|
||||||
self::get_schema()->requireIndex($table, $index, $spec);
|
DB::get_schema()->requireIndex($table, $index, $spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -602,7 +602,7 @@ class DB
|
|||||||
*/
|
*/
|
||||||
public static function dont_require_table($table)
|
public static function dont_require_table($table)
|
||||||
{
|
{
|
||||||
self::get_schema()->dontRequireTable($table);
|
DB::get_schema()->dontRequireTable($table);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -613,7 +613,7 @@ class DB
|
|||||||
*/
|
*/
|
||||||
public static function dont_require_field($table, $fieldName)
|
public static function dont_require_field($table, $fieldName)
|
||||||
{
|
{
|
||||||
self::get_schema()->dontRequireField($table, $fieldName);
|
DB::get_schema()->dontRequireField($table, $fieldName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -624,7 +624,7 @@ class DB
|
|||||||
*/
|
*/
|
||||||
public static function check_and_repair_table($table)
|
public static function check_and_repair_table($table)
|
||||||
{
|
{
|
||||||
return self::get_schema()->checkAndRepairTable($table);
|
return DB::get_schema()->checkAndRepairTable($table);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -634,7 +634,7 @@ class DB
|
|||||||
*/
|
*/
|
||||||
public static function affected_rows()
|
public static function affected_rows()
|
||||||
{
|
{
|
||||||
return self::get_conn()->affectedRows();
|
return DB::get_conn()->affectedRows();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -645,7 +645,7 @@ class DB
|
|||||||
*/
|
*/
|
||||||
public static function table_list()
|
public static function table_list()
|
||||||
{
|
{
|
||||||
return self::get_schema()->tableList();
|
return DB::get_schema()->tableList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -657,7 +657,7 @@ class DB
|
|||||||
*/
|
*/
|
||||||
public static function field_list($table)
|
public static function field_list($table)
|
||||||
{
|
{
|
||||||
return self::get_schema()->fieldList($table);
|
return DB::get_schema()->fieldList($table);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -667,7 +667,7 @@ class DB
|
|||||||
*/
|
*/
|
||||||
public static function quiet($quiet = true)
|
public static function quiet($quiet = true)
|
||||||
{
|
{
|
||||||
self::get_schema()->quiet($quiet);
|
DB::get_schema()->quiet($quiet);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -678,6 +678,6 @@ class DB
|
|||||||
*/
|
*/
|
||||||
public static function alteration_message($message, $type = "")
|
public static function alteration_message($message, $type = "")
|
||||||
{
|
{
|
||||||
self::get_schema()->alterationMessage($message, $type);
|
DB::get_schema()->alterationMessage($message, $type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -343,10 +343,10 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
*/
|
*/
|
||||||
public static function getSchema()
|
public static function getSchema()
|
||||||
{
|
{
|
||||||
if (is_null(self::$schema)) {
|
if (is_null(DataObject::$schema)) {
|
||||||
self::$schema = Injector::inst()->get(DataObjectSchema::class);
|
DataObject::$schema = Injector::inst()->get(DataObjectSchema::class);
|
||||||
}
|
}
|
||||||
return self::$schema;
|
return DataObject::$schema;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -358,7 +358,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
* left as the default by regular users.
|
* left as the default by regular users.
|
||||||
* @param array $queryParams List of DataQuery params necessary to lazy load, or load related objects.
|
* @param array $queryParams List of DataQuery params necessary to lazy load, or load related objects.
|
||||||
*/
|
*/
|
||||||
public function __construct($record = [], $creationType = self::CREATE_OBJECT, $queryParams = [])
|
public function __construct($record = [], $creationType = DataObject::CREATE_OBJECT, $queryParams = [])
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
@ -372,7 +372,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
if (!is_bool($creationType)) {
|
if (!is_bool($creationType)) {
|
||||||
user_error('Creation type is neither boolean (old isSingleton arg) nor integer (new arg), please review your code', E_USER_WARNING);
|
user_error('Creation type is neither boolean (old isSingleton arg) nor integer (new arg), please review your code', E_USER_WARNING);
|
||||||
}
|
}
|
||||||
$creationType = $creationType ? self::CREATE_SINGLETON : self::CREATE_OBJECT;
|
$creationType = $creationType ? DataObject::CREATE_SINGLETON : DataObject::CREATE_OBJECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set query params on the DataObject to tell the lazy loading mechanism the context the object creation context
|
// Set query params on the DataObject to tell the lazy loading mechanism the context the object creation context
|
||||||
@ -383,13 +383,13 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
|
|
||||||
switch ($creationType) {
|
switch ($creationType) {
|
||||||
// Hydrate a record
|
// Hydrate a record
|
||||||
case self::CREATE_HYDRATED:
|
case DataObject::CREATE_HYDRATED:
|
||||||
case self::CREATE_MEMORY_HYDRATED:
|
case DataObject::CREATE_MEMORY_HYDRATED:
|
||||||
$this->hydrate($record, $creationType === self::CREATE_HYDRATED);
|
$this->hydrate($record, $creationType === DataObject::CREATE_HYDRATED);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Create a new object, using the constructor argument as the initial content
|
// Create a new object, using the constructor argument as the initial content
|
||||||
case self::CREATE_OBJECT:
|
case DataObject::CREATE_OBJECT:
|
||||||
if ($record instanceof stdClass) {
|
if ($record instanceof stdClass) {
|
||||||
$record = (array)$record;
|
$record = (array)$record;
|
||||||
}
|
}
|
||||||
@ -429,7 +429,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case self::CREATE_SINGLETON:
|
case DataObject::CREATE_SINGLETON:
|
||||||
// No setting happens for a singleton
|
// No setting happens for a singleton
|
||||||
$this->record['ID'] = 0;
|
$this->record['ID'] = 0;
|
||||||
$this->record['ClassName'] = static::class;
|
$this->record['ClassName'] = static::class;
|
||||||
@ -722,7 +722,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
public function setClassName($className)
|
public function setClassName($className)
|
||||||
{
|
{
|
||||||
$className = trim($className ?? '');
|
$className = trim($className ?? '');
|
||||||
if (!$className || !is_subclass_of($className, self::class)) {
|
if (!$className || !is_subclass_of($className, DataObject::class)) {
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -750,14 +750,14 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
*/
|
*/
|
||||||
public function newClassInstance($newClassName)
|
public function newClassInstance($newClassName)
|
||||||
{
|
{
|
||||||
if (!is_subclass_of($newClassName, self::class)) {
|
if (!is_subclass_of($newClassName, DataObject::class)) {
|
||||||
throw new InvalidArgumentException("$newClassName is not a valid subclass of DataObject");
|
throw new InvalidArgumentException("$newClassName is not a valid subclass of DataObject");
|
||||||
}
|
}
|
||||||
|
|
||||||
$originalClass = $this->ClassName;
|
$originalClass = $this->ClassName;
|
||||||
|
|
||||||
/** @var DataObject $newInstance */
|
/** @var DataObject $newInstance */
|
||||||
$newInstance = Injector::inst()->create($newClassName, $this->record, self::CREATE_MEMORY_HYDRATED);
|
$newInstance = Injector::inst()->create($newClassName, $this->record, DataObject::CREATE_MEMORY_HYDRATED);
|
||||||
|
|
||||||
// Modify ClassName
|
// Modify ClassName
|
||||||
if ($newClassName != $originalClass) {
|
if ($newClassName != $originalClass) {
|
||||||
@ -777,7 +777,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
{
|
{
|
||||||
parent::defineMethods();
|
parent::defineMethods();
|
||||||
|
|
||||||
if (static::class === self::class) {
|
if (static::class === DataObject::class) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1299,7 +1299,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load the default values in from the self::$defaults array.
|
* Load the default values in from the DataObject::$defaults array.
|
||||||
* Will traverse the defaults of the current class and all its parent classes.
|
* Will traverse the defaults of the current class and all its parent classes.
|
||||||
* Called by the constructor when creating new records.
|
* Called by the constructor when creating new records.
|
||||||
*
|
*
|
||||||
@ -1335,7 +1335,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($class == self::class) {
|
if ($class == DataObject::class) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1496,7 +1496,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
$this->prepareManipulationTable($baseTable, $now, true, $manipulation, $this->baseClass());
|
$this->prepareManipulationTable($baseTable, $now, true, $manipulation, $this->baseClass());
|
||||||
DB::manipulate($manipulation);
|
DB::manipulate($manipulation);
|
||||||
|
|
||||||
$this->changed['ID'] = self::CHANGE_VALUE;
|
$this->changed['ID'] = DataObject::CHANGE_VALUE;
|
||||||
$this->record['ID'] = DB::get_generated_id($baseTable);
|
$this->record['ID'] = DB::get_generated_id($baseTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1823,7 +1823,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
$joinID = $this->getField($joinField);
|
$joinID = $this->getField($joinField);
|
||||||
|
|
||||||
// Extract class name for polymorphic relations
|
// Extract class name for polymorphic relations
|
||||||
if ($class === self::class) {
|
if ($class === DataObject::class) {
|
||||||
$class = $this->getField($componentName . 'Class');
|
$class = $this->getField($componentName . 'Class');
|
||||||
if (empty($class)) {
|
if (empty($class)) {
|
||||||
return null;
|
return null;
|
||||||
@ -1906,7 +1906,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
$this->setField($joinField, $item ? $item->ID : null);
|
$this->setField($joinField, $item ? $item->ID : null);
|
||||||
// Update Class (Polymorphic has_one)
|
// Update Class (Polymorphic has_one)
|
||||||
// Extract class name for polymorphic relations
|
// Extract class name for polymorphic relations
|
||||||
if ($class === self::class) {
|
if ($class === DataObject::class) {
|
||||||
$this->setField($componentName . 'Class', $item ? get_class($item) : null);
|
$this->setField($componentName . 'Class', $item ? get_class($item) : null);
|
||||||
}
|
}
|
||||||
} elseif ($class = $schema->belongsToComponent(static::class, $componentName)) {
|
} elseif ($class = $schema->belongsToComponent(static::class, $componentName)) {
|
||||||
@ -2085,7 +2085,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
// If relation is polymorphic, do not infer recriprocal relationship
|
// If relation is polymorphic, do not infer recriprocal relationship
|
||||||
if ($class === self::class) {
|
if ($class === DataObject::class) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (!is_a($this, $class ?? '', true)) {
|
if (!is_a($this, $class ?? '', true)) {
|
||||||
@ -2448,7 +2448,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
if ($fields->fieldByName($generalSearch) || $fields->dataFieldByName($generalSearch)) {
|
if ($fields->fieldByName($generalSearch) || $fields->dataFieldByName($generalSearch)) {
|
||||||
throw new LogicException('General search field name must be unique.');
|
throw new LogicException('General search field name must be unique.');
|
||||||
}
|
}
|
||||||
$fields->unshift(HiddenField::create($generalSearch, _t(self::class . '.GENERALSEARCH', 'General Search')));
|
$fields->unshift(HiddenField::create($generalSearch, _t(DataObject::class . '.GENERALSEARCH', 'General Search')));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $fields;
|
return $fields;
|
||||||
@ -2810,7 +2810,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
* @param int $changeLevel The strictness of what is defined as change. Defaults to strict
|
* @param int $changeLevel The strictness of what is defined as change. Defaults to strict
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getChangedFields($databaseFieldsOnly = false, $changeLevel = self::CHANGE_STRICT)
|
public function getChangedFields($databaseFieldsOnly = false, $changeLevel = DataObject::CHANGE_STRICT)
|
||||||
{
|
{
|
||||||
$changedFields = [];
|
$changedFields = [];
|
||||||
|
|
||||||
@ -2821,15 +2821,15 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (is_object($v) && method_exists($v, 'isChanged') && $v->isChanged()) {
|
if (is_object($v) && method_exists($v, 'isChanged') && $v->isChanged()) {
|
||||||
$this->changed[$k] = self::CHANGE_VALUE;
|
$this->changed[$k] = DataObject::CHANGE_VALUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If change was forced, then derive change data from $this->record
|
// If change was forced, then derive change data from $this->record
|
||||||
if ($this->changeForced && $changeLevel <= self::CHANGE_STRICT) {
|
if ($this->changeForced && $changeLevel <= DataObject::CHANGE_STRICT) {
|
||||||
$changed = array_combine(
|
$changed = array_combine(
|
||||||
array_keys($this->record ?? []),
|
array_keys($this->record ?? []),
|
||||||
array_fill(0, count($this->record ?? []), self::CHANGE_STRICT)
|
array_fill(0, count($this->record ?? []), DataObject::CHANGE_STRICT)
|
||||||
);
|
);
|
||||||
unset($changed['Version']);
|
unset($changed['Version']);
|
||||||
} else {
|
} else {
|
||||||
@ -2846,7 +2846,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Filter the list to those of a certain change level
|
// Filter the list to those of a certain change level
|
||||||
if ($changeLevel > self::CHANGE_STRICT) {
|
if ($changeLevel > DataObject::CHANGE_STRICT) {
|
||||||
if ($fields) {
|
if ($fields) {
|
||||||
foreach ($fields as $name => $level) {
|
foreach ($fields as $name => $level) {
|
||||||
if ($level < $changeLevel) {
|
if ($level < $changeLevel) {
|
||||||
@ -2877,7 +2877,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
* @param int $changeLevel See {@link getChangedFields()}
|
* @param int $changeLevel See {@link getChangedFields()}
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function isChanged($fieldName = null, $changeLevel = self::CHANGE_STRICT)
|
public function isChanged($fieldName = null, $changeLevel = DataObject::CHANGE_STRICT)
|
||||||
{
|
{
|
||||||
$fields = $fieldName ? [$fieldName] : true;
|
$fields = $fieldName ? [$fieldName] : true;
|
||||||
$changed = $this->getChangedFields($fields, $changeLevel);
|
$changed = $this->getChangedFields($fields, $changeLevel);
|
||||||
@ -2965,13 +2965,13 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
// if a field is not existing or has strictly changed
|
// if a field is not existing or has strictly changed
|
||||||
if (!array_key_exists($fieldName, $this->original ?? []) || $this->original[$fieldName] !== $val) {
|
if (!array_key_exists($fieldName, $this->original ?? []) || $this->original[$fieldName] !== $val) {
|
||||||
// At the very least, the type has changed
|
// At the very least, the type has changed
|
||||||
$this->changed[$fieldName] = self::CHANGE_STRICT;
|
$this->changed[$fieldName] = DataObject::CHANGE_STRICT;
|
||||||
|
|
||||||
if ((!array_key_exists($fieldName, $this->original ?? []) && $val)
|
if ((!array_key_exists($fieldName, $this->original ?? []) && $val)
|
||||||
|| (array_key_exists($fieldName, $this->original ?? []) && $this->original[$fieldName] != $val)
|
|| (array_key_exists($fieldName, $this->original ?? []) && $this->original[$fieldName] != $val)
|
||||||
) {
|
) {
|
||||||
// Value has changed as well, not just the type
|
// Value has changed as well, not just the type
|
||||||
$this->changed[$fieldName] = self::CHANGE_VALUE;
|
$this->changed[$fieldName] = DataObject::CHANGE_VALUE;
|
||||||
}
|
}
|
||||||
// Value has been restored to its original, remove any record of the change
|
// Value has been restored to its original, remove any record of the change
|
||||||
} elseif (isset($this->changed[$fieldName])) {
|
} elseif (isset($this->changed[$fieldName])) {
|
||||||
@ -3366,7 +3366,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
* @param string|array $filter A filter to be inserted into the WHERE clause.
|
* @param string|array $filter A filter to be inserted into the WHERE clause.
|
||||||
* Supports parameterised queries. See SQLSelect::addWhere() for syntax examples.
|
* Supports parameterised queries. See SQLSelect::addWhere() for syntax examples.
|
||||||
* @param string|array|null $sort Passed to DataList::sort()
|
* @param string|array|null $sort Passed to DataList::sort()
|
||||||
* BY clause. If omitted, self::$default_sort will be used.
|
* BY clause. If omitted, DataObject::$default_sort will be used.
|
||||||
* @param string $join Deprecated 3.0 Join clause. Use leftJoin($table, $joinClause) instead.
|
* @param string $join Deprecated 3.0 Join clause. Use leftJoin($table, $joinClause) instead.
|
||||||
* @param string|array $limit A limit expression to be inserted into the LIMIT clause.
|
* @param string|array $limit A limit expression to be inserted into the LIMIT clause.
|
||||||
* @param string $containerClass The container class to return the results in.
|
* @param string $containerClass The container class to return the results in.
|
||||||
@ -3384,14 +3384,14 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
// Validate arguments
|
// Validate arguments
|
||||||
if ($callerClass == null) {
|
if ($callerClass == null) {
|
||||||
$callerClass = get_called_class();
|
$callerClass = get_called_class();
|
||||||
if ($callerClass === self::class) {
|
if ($callerClass === DataObject::class) {
|
||||||
throw new InvalidArgumentException('Call <classname>::get() instead of DataObject::get()');
|
throw new InvalidArgumentException('Call <classname>::get() instead of DataObject::get()');
|
||||||
}
|
}
|
||||||
if ($filter || $sort || $join || $limit || ($containerClass !== DataList::class)) {
|
if ($filter || $sort || $join || $limit || ($containerClass !== DataList::class)) {
|
||||||
throw new InvalidArgumentException('If calling <classname>::get() then you shouldn\'t pass any other'
|
throw new InvalidArgumentException('If calling <classname>::get() then you shouldn\'t pass any other'
|
||||||
. ' arguments');
|
. ' arguments');
|
||||||
}
|
}
|
||||||
} elseif ($callerClass === self::class) {
|
} elseif ($callerClass === DataObject::class) {
|
||||||
throw new InvalidArgumentException('DataObject::get() cannot query non-subclass DataObject directly');
|
throw new InvalidArgumentException('DataObject::get() cannot query non-subclass DataObject directly');
|
||||||
}
|
}
|
||||||
if ($join) {
|
if ($join) {
|
||||||
@ -3446,7 +3446,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Validate class
|
// Validate class
|
||||||
if ($callerClass === self::class) {
|
if ($callerClass === DataObject::class) {
|
||||||
throw new InvalidArgumentException('DataObject::get_one() cannot query non-subclass DataObject directly');
|
throw new InvalidArgumentException('DataObject::get_one() cannot query non-subclass DataObject directly');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3457,7 +3457,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
$cacheKey = md5(serialize($cacheComponents));
|
$cacheKey = md5(serialize($cacheComponents));
|
||||||
|
|
||||||
$item = null;
|
$item = null;
|
||||||
if (!$cache || !isset(self::$_cache_get_one[$callerClass][$cacheKey])) {
|
if (!$cache || !isset(DataObject::$_cache_get_one[$callerClass][$cacheKey])) {
|
||||||
$dl = DataObject::get($callerClass);
|
$dl = DataObject::get($callerClass);
|
||||||
if (!empty($filter)) {
|
if (!empty($filter)) {
|
||||||
$dl = $dl->where($filter);
|
$dl = $dl->where($filter);
|
||||||
@ -3468,15 +3468,15 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
$item = $dl->first();
|
$item = $dl->first();
|
||||||
|
|
||||||
if ($cache) {
|
if ($cache) {
|
||||||
self::$_cache_get_one[$callerClass][$cacheKey] = $item;
|
DataObject::$_cache_get_one[$callerClass][$cacheKey] = $item;
|
||||||
if (!self::$_cache_get_one[$callerClass][$cacheKey]) {
|
if (!DataObject::$_cache_get_one[$callerClass][$cacheKey]) {
|
||||||
self::$_cache_get_one[$callerClass][$cacheKey] = false;
|
DataObject::$_cache_get_one[$callerClass][$cacheKey] = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($cache) {
|
if ($cache) {
|
||||||
return self::$_cache_get_one[$callerClass][$cacheKey] ?: null;
|
return DataObject::$_cache_get_one[$callerClass][$cacheKey] ?: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $item;
|
return $item;
|
||||||
@ -3492,15 +3492,15 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
*/
|
*/
|
||||||
public function flushCache($persistent = true)
|
public function flushCache($persistent = true)
|
||||||
{
|
{
|
||||||
if (static::class == self::class) {
|
if (static::class == DataObject::class) {
|
||||||
self::$_cache_get_one = [];
|
DataObject::$_cache_get_one = [];
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
$classes = ClassInfo::ancestry(static::class);
|
$classes = ClassInfo::ancestry(static::class);
|
||||||
foreach ($classes as $class) {
|
foreach ($classes as $class) {
|
||||||
if (isset(self::$_cache_get_one[$class])) {
|
if (isset(DataObject::$_cache_get_one[$class])) {
|
||||||
unset(self::$_cache_get_one[$class]);
|
unset(DataObject::$_cache_get_one[$class]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3516,8 +3516,8 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
*/
|
*/
|
||||||
public static function flush_and_destroy_cache()
|
public static function flush_and_destroy_cache()
|
||||||
{
|
{
|
||||||
if (self::$_cache_get_one) {
|
if (DataObject::$_cache_get_one) {
|
||||||
foreach (self::$_cache_get_one as $class => $items) {
|
foreach (DataObject::$_cache_get_one as $class => $items) {
|
||||||
if (is_array($items)) {
|
if (is_array($items)) {
|
||||||
foreach ($items as $item) {
|
foreach ($items as $item) {
|
||||||
if ($item) {
|
if ($item) {
|
||||||
@ -3527,7 +3527,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self::$_cache_get_one = [];
|
DataObject::$_cache_get_one = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -3538,8 +3538,8 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
DBEnum::flushCache();
|
DBEnum::flushCache();
|
||||||
ClassInfo::reset_db_cache();
|
ClassInfo::reset_db_cache();
|
||||||
static::getSchema()->reset();
|
static::getSchema()->reset();
|
||||||
self::$_cache_get_one = [];
|
DataObject::$_cache_get_one = [];
|
||||||
self::$_cache_field_labels = [];
|
DataObject::$_cache_field_labels = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -3567,7 +3567,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Validate class
|
// Validate class
|
||||||
if ($class === self::class) {
|
if ($class === DataObject::class) {
|
||||||
throw new InvalidArgumentException('DataObject::get_by_id() cannot query non-subclass DataObject directly');
|
throw new InvalidArgumentException('DataObject::get_by_id() cannot query non-subclass DataObject directly');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3670,7 +3670,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
$table = $schema->tableName(static::class);
|
$table = $schema->tableName(static::class);
|
||||||
$fields = $schema->databaseFields(static::class, false);
|
$fields = $schema->databaseFields(static::class, false);
|
||||||
$indexes = $schema->databaseIndexes(static::class, false);
|
$indexes = $schema->databaseIndexes(static::class, false);
|
||||||
$extensions = self::database_extensions(static::class);
|
$extensions = DataObject::database_extensions(static::class);
|
||||||
|
|
||||||
if (empty($table)) {
|
if (empty($table)) {
|
||||||
throw new LogicException(
|
throw new LogicException(
|
||||||
@ -3679,7 +3679,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($fields) {
|
if ($fields) {
|
||||||
$hasAutoIncPK = get_parent_class($this ?? '') === self::class;
|
$hasAutoIncPK = get_parent_class($this ?? '') === DataObject::class;
|
||||||
DB::require_table(
|
DB::require_table(
|
||||||
$table,
|
$table,
|
||||||
$fields,
|
$fields,
|
||||||
@ -3911,7 +3911,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
* between data object being required in the search interface.
|
* between data object being required in the search interface.
|
||||||
*
|
*
|
||||||
* Generates labels based on name of the field itself, if no static property
|
* Generates labels based on name of the field itself, if no static property
|
||||||
* {@link self::field_labels} exists.
|
* {@link DataObject::field_labels} exists.
|
||||||
*
|
*
|
||||||
* @uses $field_labels
|
* @uses $field_labels
|
||||||
* @uses FormField::name_to_label()
|
* @uses FormField::name_to_label()
|
||||||
@ -3924,7 +3924,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
{
|
{
|
||||||
$cacheKey = static::class . '_' . $includerelations;
|
$cacheKey = static::class . '_' . $includerelations;
|
||||||
|
|
||||||
if (!isset(self::$_cache_field_labels[$cacheKey])) {
|
if (!isset(DataObject::$_cache_field_labels[$cacheKey])) {
|
||||||
$customLabels = $this->config()->get('field_labels');
|
$customLabels = $this->config()->get('field_labels');
|
||||||
$autoLabels = [];
|
$autoLabels = [];
|
||||||
|
|
||||||
@ -3970,10 +3970,10 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
|
|
||||||
$labels = array_merge((array)$autoLabels, (array)$customLabels);
|
$labels = array_merge((array)$autoLabels, (array)$customLabels);
|
||||||
$this->extend('updateFieldLabels', $labels);
|
$this->extend('updateFieldLabels', $labels);
|
||||||
self::$_cache_field_labels[$cacheKey] = $labels;
|
DataObject::$_cache_field_labels[$cacheKey] = $labels;
|
||||||
}
|
}
|
||||||
|
|
||||||
return self::$_cache_field_labels[$cacheKey];
|
return DataObject::$_cache_field_labels[$cacheKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -4092,7 +4092,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
public static function disable_subclass_access()
|
public static function disable_subclass_access()
|
||||||
{
|
{
|
||||||
Deprecation::notice('5.2.0', 'Will be removed without equivalent functionality');
|
Deprecation::notice('5.2.0', 'Will be removed without equivalent functionality');
|
||||||
self::$subclass_access = false;
|
DataObject::$subclass_access = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -4101,7 +4101,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
public static function enable_subclass_access()
|
public static function enable_subclass_access()
|
||||||
{
|
{
|
||||||
Deprecation::notice('5.2.0', 'Will be removed without equivalent functionality');
|
Deprecation::notice('5.2.0', 'Will be removed without equivalent functionality');
|
||||||
self::$subclass_access = true;
|
DataObject::$subclass_access = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------------------------//
|
||||||
|
@ -206,9 +206,9 @@ class DataObjectSchema
|
|||||||
if (!is_int($options)) {
|
if (!is_int($options)) {
|
||||||
throw new InvalidArgumentException("Invalid options " . var_export($options, true));
|
throw new InvalidArgumentException("Invalid options " . var_export($options, true));
|
||||||
}
|
}
|
||||||
$uninherited = ($options & self::UNINHERITED) === self::UNINHERITED;
|
$uninherited = ($options & DataObjectSchema::UNINHERITED) === DataObjectSchema::UNINHERITED;
|
||||||
$dbOnly = ($options & self::DB_ONLY) === self::DB_ONLY;
|
$dbOnly = ($options & DataObjectSchema::DB_ONLY) === DataObjectSchema::DB_ONLY;
|
||||||
$includeClass = ($options & self::INCLUDE_CLASS) === self::INCLUDE_CLASS;
|
$includeClass = ($options & DataObjectSchema::INCLUDE_CLASS) === DataObjectSchema::INCLUDE_CLASS;
|
||||||
|
|
||||||
// Walk class hierarchy
|
// Walk class hierarchy
|
||||||
$db = [];
|
$db = [];
|
||||||
@ -513,7 +513,7 @@ class DataObjectSchema
|
|||||||
}
|
}
|
||||||
// Handle has_one which handles multiple reciprocal has_many relations
|
// Handle has_one which handles multiple reciprocal has_many relations
|
||||||
$hasOneClass = $spec['class'];
|
$hasOneClass = $spec['class'];
|
||||||
if (($spec[self::HAS_ONE_MULTI_RELATIONAL] ?? false) === true) {
|
if (($spec[DataObjectSchema::HAS_ONE_MULTI_RELATIONAL] ?? false) === true) {
|
||||||
$compositeFields[$fieldName] = 'PolymorphicRelationAwareForeignKey';
|
$compositeFields[$fieldName] = 'PolymorphicRelationAwareForeignKey';
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -577,7 +577,7 @@ class DataObjectSchema
|
|||||||
}
|
}
|
||||||
$this->defaultDatabaseIndexes[$class] = [];
|
$this->defaultDatabaseIndexes[$class] = [];
|
||||||
|
|
||||||
$fieldSpecs = $this->fieldSpecs($class, self::UNINHERITED);
|
$fieldSpecs = $this->fieldSpecs($class, DataObjectSchema::UNINHERITED);
|
||||||
foreach ($fieldSpecs as $field => $spec) {
|
foreach ($fieldSpecs as $field => $spec) {
|
||||||
/** @var DBField $fieldObj */
|
/** @var DBField $fieldObj */
|
||||||
$fieldObj = Injector::inst()->create($spec, $field);
|
$fieldObj = Injector::inst()->create($spec, $field);
|
||||||
@ -651,7 +651,7 @@ class DataObjectSchema
|
|||||||
list ($table, $column) = $this->parseSortColumn(trim($value ?? ''));
|
list ($table, $column) = $this->parseSortColumn(trim($value ?? ''));
|
||||||
$table = trim($table ?? '', '"');
|
$table = trim($table ?? '', '"');
|
||||||
$column = trim($column ?? '', '"');
|
$column = trim($column ?? '', '"');
|
||||||
if ($table && strtolower($table ?? '') !== strtolower(self::tableName($class) ?? '')) {
|
if ($table && strtolower($table ?? '') !== strtolower(DataObjectSchema::tableName($class) ?? '')) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ($this->databaseField($class, $column, false)) {
|
if ($this->databaseField($class, $column, false)) {
|
||||||
@ -945,7 +945,7 @@ class DataObjectSchema
|
|||||||
}
|
}
|
||||||
|
|
||||||
$spec = $hasOnes[$component];
|
$spec = $hasOnes[$component];
|
||||||
return ($spec[self::HAS_ONE_MULTI_RELATIONAL] ?? false) === true;
|
return ($spec[DataObjectSchema::HAS_ONE_MULTI_RELATIONAL] ?? false) === true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1280,7 +1280,7 @@ class DataObjectSchema
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (($spec[self::HAS_ONE_MULTI_RELATIONAL] ?? false) === true
|
if (($spec[DataObjectSchema::HAS_ONE_MULTI_RELATIONAL] ?? false) === true
|
||||||
&& $spec['class'] !== DataObject::class
|
&& $spec['class'] !== DataObject::class
|
||||||
) {
|
) {
|
||||||
throw new InvalidArgumentException(
|
throw new InvalidArgumentException(
|
||||||
|
@ -743,7 +743,7 @@ class DataQuery
|
|||||||
$schema = DataObject::getSchema();
|
$schema = DataObject::getSchema();
|
||||||
|
|
||||||
// If the query is a DataQuery, make sure all manipulators, joins, etc are applied
|
// If the query is a DataQuery, make sure all manipulators, joins, etc are applied
|
||||||
if ($query instanceof self) {
|
if ($query instanceof DataQuery) {
|
||||||
$cteDataClass = $query->dataClass();
|
$cteDataClass = $query->dataClass();
|
||||||
$query = $query->query();
|
$query = $query->query();
|
||||||
// DataQuery wants to select ALL columns by default,
|
// DataQuery wants to select ALL columns by default,
|
||||||
|
@ -59,7 +59,7 @@ class EagerLoadedList extends ViewableData implements Relation, SS_List, Filtera
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Nested eager-loaded data which applies to relations on records contained in this list
|
* Nested eager-loaded data which applies to relations on records contained in this list
|
||||||
* @var array<int,self|DataObject>
|
* @var array<int,EagerLoadedList|DataObject>
|
||||||
*/
|
*/
|
||||||
private array $eagerLoadedData = [];
|
private array $eagerLoadedData = [];
|
||||||
|
|
||||||
@ -148,7 +148,7 @@ class EagerLoadedList extends ViewableData implements Relation, SS_List, Filtera
|
|||||||
*
|
*
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function addEagerLoadedData(string $relation, int $id, self|DataObject $data): static
|
public function addEagerLoadedData(string $relation, int $id, EagerLoadedList|DataObject $data): static
|
||||||
{
|
{
|
||||||
$this->eagerLoadedData[$id][$relation] = $data;
|
$this->eagerLoadedData[$id][$relation] = $data;
|
||||||
return $this;
|
return $this;
|
||||||
@ -856,7 +856,7 @@ class EagerLoadedList extends ViewableData implements Relation, SS_List, Filtera
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$data = $this->eagerLoadedData[$id][$relationName];
|
$data = $this->eagerLoadedData[$id][$relationName];
|
||||||
if (!($data instanceof self)) {
|
if (!($data instanceof EagerLoadedList)) {
|
||||||
// There's no clean way to get the rows back out of DataObject records,
|
// There's no clean way to get the rows back out of DataObject records,
|
||||||
// and if it's not a DataObject then we don't know how to handle it,
|
// and if it's not a DataObject then we don't know how to handle it,
|
||||||
// so fall back to a new DB query
|
// so fall back to a new DB query
|
||||||
|
@ -45,7 +45,7 @@ class DBDate extends DBField
|
|||||||
$value = $this->parseDate($value);
|
$value = $this->parseDate($value);
|
||||||
if ($value === false) {
|
if ($value === false) {
|
||||||
throw new InvalidArgumentException(
|
throw new InvalidArgumentException(
|
||||||
"Invalid date: '$value'. Use " . self::ISO_DATE . " to prevent this error."
|
"Invalid date: '$value'. Use " . DBDate::ISO_DATE . " to prevent this error."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
$this->value = $value;
|
$this->value = $value;
|
||||||
@ -254,7 +254,7 @@ class DBDate extends DBField
|
|||||||
*/
|
*/
|
||||||
public function getISOFormat()
|
public function getISOFormat()
|
||||||
{
|
{
|
||||||
return self::ISO_DATE;
|
return DBDate::ISO_DATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -543,7 +543,7 @@ class DBDate extends DBField
|
|||||||
*/
|
*/
|
||||||
public function IsToday()
|
public function IsToday()
|
||||||
{
|
{
|
||||||
return $this->Format(self::ISO_DATE) === DBDatetime::now()->Format(self::ISO_DATE);
|
return $this->Format(DBDate::ISO_DATE) === DBDatetime::now()->Format(DBDate::ISO_DATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -559,7 +559,7 @@ class DBDate extends DBField
|
|||||||
* @param string $adjustment PHP strtotime style
|
* @param string $adjustment PHP strtotime style
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function modify(string $adjustment): self
|
public function modify(string $adjustment): DBDate
|
||||||
{
|
{
|
||||||
$modifiedTime = strtotime($adjustment ?? '', $this->getTimestamp());
|
$modifiedTime = strtotime($adjustment ?? '', $this->getTimestamp());
|
||||||
return $this->setValue($modifiedTime);
|
return $this->setValue($modifiedTime);
|
||||||
@ -572,7 +572,7 @@ class DBDate extends DBField
|
|||||||
*/
|
*/
|
||||||
public function URLDate()
|
public function URLDate()
|
||||||
{
|
{
|
||||||
return rawurlencode($this->Format(self::ISO_DATE, self::ISO_LOCALE) ?? '');
|
return rawurlencode($this->Format(DBDate::ISO_DATE, DBDate::ISO_LOCALE) ?? '');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function scaffoldFormField($title = null, $params = null)
|
public function scaffoldFormField($title = null, $params = null)
|
||||||
@ -600,7 +600,7 @@ class DBDate extends DBField
|
|||||||
// Validate date
|
// Validate date
|
||||||
if (!checkdate($month ?? 0, $day ?? 0, $year ?? 0)) {
|
if (!checkdate($month ?? 0, $day ?? 0, $year ?? 0)) {
|
||||||
throw new InvalidArgumentException(
|
throw new InvalidArgumentException(
|
||||||
"Invalid date: '$value'. Use " . self::ISO_DATE . " to prevent this error."
|
"Invalid date: '$value'. Use " . DBDate::ISO_DATE . " to prevent this error."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -623,7 +623,7 @@ class DBDate extends DBField
|
|||||||
$matches
|
$matches
|
||||||
)) {
|
)) {
|
||||||
throw new InvalidArgumentException(
|
throw new InvalidArgumentException(
|
||||||
"Invalid date: '$value'. Use " . self::ISO_DATE . " to prevent this error."
|
"Invalid date: '$value'. Use " . DBDate::ISO_DATE . " to prevent this error."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -638,7 +638,7 @@ class DBDate extends DBField
|
|||||||
}
|
}
|
||||||
if ($parts[0] < 1000 && (int)$parts[0] !== 0) {
|
if ($parts[0] < 1000 && (int)$parts[0] !== 0) {
|
||||||
throw new InvalidArgumentException(
|
throw new InvalidArgumentException(
|
||||||
"Invalid date: '$value'. Use " . self::ISO_DATE . " to prevent this error."
|
"Invalid date: '$value'. Use " . DBDate::ISO_DATE . " to prevent this error."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
$parts[] = $matches['time'];
|
$parts[] = $matches['time'];
|
||||||
|
@ -58,7 +58,7 @@ class DBDatetime extends DBDate implements TemplateGlobalProvider
|
|||||||
* @param bool $immutable
|
* @param bool $immutable
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function setImmutable(bool $immutable): self
|
public function setImmutable(bool $immutable): DBDatetime
|
||||||
{
|
{
|
||||||
$this->immutable = $immutable;
|
$this->immutable = $immutable;
|
||||||
|
|
||||||
@ -172,7 +172,7 @@ class DBDatetime extends DBDate implements TemplateGlobalProvider
|
|||||||
*/
|
*/
|
||||||
public function URLDatetime()
|
public function URLDatetime()
|
||||||
{
|
{
|
||||||
return rawurlencode($this->Format(self::ISO_DATETIME, self::ISO_LOCALE) ?? '');
|
return rawurlencode($this->Format(DBDatetime::ISO_DATETIME, DBDatetime::ISO_LOCALE) ?? '');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function scaffoldFormField($title = null, $params = null)
|
public function scaffoldFormField($title = null, $params = null)
|
||||||
@ -208,7 +208,7 @@ class DBDatetime extends DBDate implements TemplateGlobalProvider
|
|||||||
*/
|
*/
|
||||||
public static function now()
|
public static function now()
|
||||||
{
|
{
|
||||||
$time = self::$mock_now ? self::$mock_now->Value : time();
|
$time = DBDatetime::$mock_now ? DBDatetime::$mock_now->Value : time();
|
||||||
|
|
||||||
/** @var DBDatetime $now */
|
/** @var DBDatetime $now */
|
||||||
$now = DBField::create_field('Datetime', $time);
|
$now = DBField::create_field('Datetime', $time);
|
||||||
@ -233,7 +233,7 @@ class DBDatetime extends DBDate implements TemplateGlobalProvider
|
|||||||
throw new InvalidArgumentException('DBDatetime::set_mock_now(): Wrong format: ' . $value);
|
throw new InvalidArgumentException('DBDatetime::set_mock_now(): Wrong format: ' . $value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self::$mock_now = $datetime;
|
DBDatetime::$mock_now = $datetime;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -242,7 +242,7 @@ class DBDatetime extends DBDate implements TemplateGlobalProvider
|
|||||||
*/
|
*/
|
||||||
public static function clear_mock_now()
|
public static function clear_mock_now()
|
||||||
{
|
{
|
||||||
self::$mock_now = null;
|
DBDatetime::$mock_now = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -255,14 +255,14 @@ class DBDatetime extends DBDate implements TemplateGlobalProvider
|
|||||||
*/
|
*/
|
||||||
public static function withFixedNow($time, $callback)
|
public static function withFixedNow($time, $callback)
|
||||||
{
|
{
|
||||||
$original = self::$mock_now;
|
$original = DBDatetime::$mock_now;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
self::set_mock_now($time);
|
DBDatetime::set_mock_now($time);
|
||||||
|
|
||||||
return $callback();
|
return $callback();
|
||||||
} finally {
|
} finally {
|
||||||
self::$mock_now = $original;
|
DBDatetime::$mock_now = $original;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -324,6 +324,6 @@ class DBDatetime extends DBDate implements TemplateGlobalProvider
|
|||||||
*/
|
*/
|
||||||
public function getISOFormat()
|
public function getISOFormat()
|
||||||
{
|
{
|
||||||
return self::ISO_DATETIME;
|
return DBDatetime::ISO_DATETIME;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ class DBEnum extends DBString
|
|||||||
*/
|
*/
|
||||||
public static function flushCache()
|
public static function flushCache()
|
||||||
{
|
{
|
||||||
self::$enum_cache = [];
|
DBEnum::$enum_cache = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -209,13 +209,13 @@ class DBEnum extends DBString
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the table level cache exists
|
// Ensure the table level cache exists
|
||||||
if (empty(self::$enum_cache[$table])) {
|
if (empty(DBEnum::$enum_cache[$table])) {
|
||||||
self::$enum_cache[$table] = [];
|
DBEnum::$enum_cache[$table] = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check existing cache
|
// Check existing cache
|
||||||
if (!empty(self::$enum_cache[$table][$name])) {
|
if (!empty(DBEnum::$enum_cache[$table][$name])) {
|
||||||
return self::$enum_cache[$table][$name];
|
return DBEnum::$enum_cache[$table][$name];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get all enum values
|
// Get all enum values
|
||||||
@ -226,7 +226,7 @@ class DBEnum extends DBString
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Cache and return
|
// Cache and return
|
||||||
self::$enum_cache[$table][$name] = $enumValues;
|
DBEnum::$enum_cache[$table][$name] = $enumValues;
|
||||||
return $enumValues;
|
return $enumValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -540,7 +540,7 @@ abstract class DBField extends ViewableData implements DBIndexable
|
|||||||
"DBField::saveInto() Called on a nameless '" . static::class . "' object"
|
"DBField::saveInto() Called on a nameless '" . static::class . "' object"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if ($this->value instanceof self) {
|
if ($this->value instanceof DBField) {
|
||||||
$this->value->saveInto($dataObject);
|
$this->value->saveInto($dataObject);
|
||||||
} else {
|
} else {
|
||||||
$dataObject->__set($fieldName, $this->value);
|
$dataObject->__set($fieldName, $this->value);
|
||||||
|
@ -237,6 +237,6 @@ abstract class DBString extends DBField
|
|||||||
*/
|
*/
|
||||||
public function defaultEllipsis(): string
|
public function defaultEllipsis(): string
|
||||||
{
|
{
|
||||||
return _t(self::class . '.ELLIPSIS', '…');
|
return _t(DBString::class . '.ELLIPSIS', '…');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -174,7 +174,7 @@ class DBTime extends DBField
|
|||||||
*/
|
*/
|
||||||
public function getISOFormat()
|
public function getISOFormat()
|
||||||
{
|
{
|
||||||
return self::ISO_TIME;
|
return DBTime::ISO_TIME;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -474,7 +474,7 @@ abstract class SearchFilter
|
|||||||
} elseif (in_array('nocase', $modifiers ?? [])) {
|
} elseif (in_array('nocase', $modifiers ?? [])) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
$sensitive = self::config()->get('default_case_sensitive');
|
$sensitive = SearchFilter::config()->get('default_case_sensitive');
|
||||||
if ($sensitive !== null) {
|
if ($sensitive !== null) {
|
||||||
return $sensitive;
|
return $sensitive;
|
||||||
}
|
}
|
||||||
@ -488,13 +488,13 @@ abstract class SearchFilter
|
|||||||
*/
|
*/
|
||||||
protected function getCaseSensitiveByCollation(): ?bool
|
protected function getCaseSensitiveByCollation(): ?bool
|
||||||
{
|
{
|
||||||
if (!self::$caseSensitiveByCollation) {
|
if (!SearchFilter::$caseSensitiveByCollation) {
|
||||||
if (!DB::is_active()) {
|
if (!DB::is_active()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
self::$caseSensitiveByCollation = DB::query("SELECT 'CASE' = 'case'")->record() === 0;
|
SearchFilter::$caseSensitiveByCollation = DB::query("SELECT 'CASE' = 'case'")->record() === 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return self::$caseSensitiveByCollation;
|
return SearchFilter::$caseSensitiveByCollation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -298,9 +298,9 @@ class Hierarchy extends DataExtension
|
|||||||
|
|
||||||
// cached call
|
// cached call
|
||||||
if ($cache) {
|
if ($cache) {
|
||||||
if (isset(self::$cache_numChildren[$baseClass][$cacheType][$id])) {
|
if (isset(Hierarchy::$cache_numChildren[$baseClass][$cacheType][$id])) {
|
||||||
return self::$cache_numChildren[$baseClass][$cacheType][$id];
|
return Hierarchy::$cache_numChildren[$baseClass][$cacheType][$id];
|
||||||
} elseif (isset(self::$cache_numChildren[$baseClass][$cacheType]['_complete'])) {
|
} elseif (isset(Hierarchy::$cache_numChildren[$baseClass][$cacheType]['_complete'])) {
|
||||||
// If the cache is complete and we didn't find our ID in the cache, it means this object is childless.
|
// If the cache is complete and we didn't find our ID in the cache, it means this object is childless.
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -311,7 +311,7 @@ class Hierarchy extends DataExtension
|
|||||||
|
|
||||||
// Save if caching
|
// Save if caching
|
||||||
if ($cache) {
|
if ($cache) {
|
||||||
self::$cache_numChildren[$baseClass][$cacheType][$id] = $numChildren;
|
Hierarchy::$cache_numChildren[$baseClass][$cacheType][$id] = $numChildren;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $numChildren;
|
return $numChildren;
|
||||||
@ -333,7 +333,7 @@ class Hierarchy extends DataExtension
|
|||||||
if (empty($options['numChildrenMethod']) || $options['numChildrenMethod'] === 'numChildren') {
|
if (empty($options['numChildrenMethod']) || $options['numChildrenMethod'] === 'numChildren') {
|
||||||
$idList = is_array($recordList) ? $recordList :
|
$idList = is_array($recordList) ? $recordList :
|
||||||
($recordList instanceof DataList ? $recordList->column('ID') : null);
|
($recordList instanceof DataList ? $recordList->column('ID') : null);
|
||||||
self::prepopulate_numchildren_cache($this->getHierarchyBaseClass(), $idList);
|
Hierarchy::prepopulate_numchildren_cache($this->getHierarchyBaseClass(), $idList);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->owner->extend('onPrepopulateTreeDataCache', $recordList, $options);
|
$this->owner->extend('onPrepopulateTreeDataCache', $recordList, $options);
|
||||||
@ -384,11 +384,11 @@ class Hierarchy extends DataExtension
|
|||||||
$query->setGroupBy([Convert::symbol2sql("ParentID")]);
|
$query->setGroupBy([Convert::symbol2sql("ParentID")]);
|
||||||
|
|
||||||
$numChildren = $query->execute()->map();
|
$numChildren = $query->execute()->map();
|
||||||
self::$cache_numChildren[$baseClass]['numChildren'] = $numChildren;
|
Hierarchy::$cache_numChildren[$baseClass]['numChildren'] = $numChildren;
|
||||||
if (!$idList) {
|
if (!$idList) {
|
||||||
// If all objects are being cached, mark this cache as complete
|
// If all objects are being cached, mark this cache as complete
|
||||||
// to avoid counting children of childless object.
|
// to avoid counting children of childless object.
|
||||||
self::$cache_numChildren[$baseClass]['numChildren']['_complete'] = true;
|
Hierarchy::$cache_numChildren[$baseClass]['numChildren']['_complete'] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -416,7 +416,7 @@ class Hierarchy extends DataExtension
|
|||||||
{
|
{
|
||||||
$ancestry = ClassInfo::ancestry($this->owner);
|
$ancestry = ClassInfo::ancestry($this->owner);
|
||||||
$ancestorClass = array_shift($ancestry);
|
$ancestorClass = array_shift($ancestry);
|
||||||
while ($ancestorClass && !ViewableData::has_extension($ancestorClass, self::class)) {
|
while ($ancestorClass && !ViewableData::has_extension($ancestorClass, Hierarchy::class)) {
|
||||||
$ancestorClass = array_shift($ancestry);
|
$ancestorClass = array_shift($ancestry);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -575,6 +575,6 @@ class Hierarchy extends DataExtension
|
|||||||
public function flushCache()
|
public function flushCache()
|
||||||
{
|
{
|
||||||
$this->owner->_cache_children = null;
|
$this->owner->_cache_children = null;
|
||||||
self::$cache_numChildren = [];
|
Hierarchy::$cache_numChildren = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -275,7 +275,7 @@ class MarkedSet
|
|||||||
if (!$template) {
|
if (!$template) {
|
||||||
$template = [
|
$template = [
|
||||||
'type' => 'Includes',
|
'type' => 'Includes',
|
||||||
self::class . '_HTML'
|
MarkedSet::class . '_HTML'
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
$tree = $this->getSubtree($this->rootNode, 0);
|
$tree = $this->getSubtree($this->rootNode, 0);
|
||||||
|
@ -54,7 +54,7 @@ abstract class ListDecorator extends ViewableData implements SS_List, Sortable,
|
|||||||
* @param TListA<TA> $list
|
* @param TListA<TA> $list
|
||||||
* @return static<TListA, TA>
|
* @return static<TListA, TA>
|
||||||
*/
|
*/
|
||||||
public function setList(SS_List&Sortable&Filterable&Limitable $list): self
|
public function setList(SS_List&Sortable&Filterable&Limitable $list): ListDecorator
|
||||||
{
|
{
|
||||||
$this->list = $list;
|
$this->list = $list;
|
||||||
$this->failover = $this->list;
|
$this->failover = $this->list;
|
||||||
|
@ -241,7 +241,7 @@ abstract class SQLConditionalExpression extends SQLExpression
|
|||||||
foreach ($this->from as $key => $tableClause) {
|
foreach ($this->from as $key => $tableClause) {
|
||||||
if (is_array($tableClause)) {
|
if (is_array($tableClause)) {
|
||||||
$table = '"' . $tableClause['table'] . '"';
|
$table = '"' . $tableClause['table'] . '"';
|
||||||
} elseif (is_string($tableClause) && preg_match(self::getJoinRegex(), $tableClause ?? '', $matches)) {
|
} elseif (is_string($tableClause) && preg_match(SQLConditionalExpression::getJoinRegex(), $tableClause ?? '', $matches)) {
|
||||||
$table = $matches[1];
|
$table = $matches[1];
|
||||||
} else {
|
} else {
|
||||||
$table = $tableClause;
|
$table = $tableClause;
|
||||||
@ -341,7 +341,7 @@ abstract class SQLConditionalExpression extends SQLExpression
|
|||||||
// Remove the regular FROM tables out so we only deal with the JOINs
|
// Remove the regular FROM tables out so we only deal with the JOINs
|
||||||
$regularTables = [];
|
$regularTables = [];
|
||||||
foreach ($from as $alias => $tableClause) {
|
foreach ($from as $alias => $tableClause) {
|
||||||
if (is_string($tableClause) && !preg_match(self::getJoinRegex(), $tableClause)) {
|
if (is_string($tableClause) && !preg_match(SQLConditionalExpression::getJoinRegex(), $tableClause)) {
|
||||||
$regularTables[$alias] = $tableClause;
|
$regularTables[$alias] = $tableClause;
|
||||||
unset($from[$alias]);
|
unset($from[$alias]);
|
||||||
}
|
}
|
||||||
|
@ -560,7 +560,7 @@ class SQLSelect extends SQLConditionalExpression
|
|||||||
*/
|
*/
|
||||||
public function addUnion(SQLSelect $query, ?string $type = null): static
|
public function addUnion(SQLSelect $query, ?string $type = null): static
|
||||||
{
|
{
|
||||||
if ($type && $type !== self::UNION_ALL && $type !== self::UNION_DISTINCT) {
|
if ($type && $type !== SQLSelect::UNION_ALL && $type !== SQLSelect::UNION_DISTINCT) {
|
||||||
throw new LogicException('Union $type must be one of the constants UNION_ALL or UNION_DISTINCT.');
|
throw new LogicException('Union $type must be one of the constants UNION_ALL or UNION_DISTINCT.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ class FulltextSearchable extends DataExtension
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self::$searchable_classes = $searchableClasses;
|
FulltextSearchable::$searchable_classes = $searchableClasses;
|
||||||
if (class_exists("SilverStripe\\CMS\\Controllers\\ContentController")) {
|
if (class_exists("SilverStripe\\CMS\\Controllers\\ContentController")) {
|
||||||
ContentController::add_extension("SilverStripe\\CMS\\Search\\ContentControllerSearchExtension");
|
ContentController::add_extension("SilverStripe\\CMS\\Search\\ContentControllerSearchExtension");
|
||||||
}
|
}
|
||||||
@ -120,6 +120,6 @@ class FulltextSearchable extends DataExtension
|
|||||||
*/
|
*/
|
||||||
public static function get_searchable_classes()
|
public static function get_searchable_classes()
|
||||||
{
|
{
|
||||||
return self::$searchable_classes;
|
return FulltextSearchable::$searchable_classes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ class SearchContext
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* A key value pair of values that should be searched for.
|
* A key value pair of values that should be searched for.
|
||||||
* The keys should match the field names specified in {@link self::$fields}.
|
* The keys should match the field names specified in {@link SearchContext::$fields}.
|
||||||
* Usually these values come from a submitted searchform
|
* Usually these values come from a submitted searchform
|
||||||
* in the form of a $_REQUEST object.
|
* in the form of a $_REQUEST object.
|
||||||
* CAUTION: All values should be treated as insecure client input.
|
* CAUTION: All values should be treated as insecure client input.
|
||||||
|
@ -73,7 +73,7 @@ class ValidationResult
|
|||||||
* Bool values will be treated as plain text flag.
|
* Bool values will be treated as plain text flag.
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function addError($message, $messageType = self::TYPE_ERROR, $code = null, $cast = self::CAST_TEXT)
|
public function addError($message, $messageType = ValidationResult::TYPE_ERROR, $code = null, $cast = ValidationResult::CAST_TEXT)
|
||||||
{
|
{
|
||||||
return $this->addFieldError(null, $message, $messageType, $code, $cast);
|
return $this->addFieldError(null, $message, $messageType, $code, $cast);
|
||||||
}
|
}
|
||||||
@ -94,9 +94,9 @@ class ValidationResult
|
|||||||
public function addFieldError(
|
public function addFieldError(
|
||||||
$fieldName,
|
$fieldName,
|
||||||
$message,
|
$message,
|
||||||
$messageType = self::TYPE_ERROR,
|
$messageType = ValidationResult::TYPE_ERROR,
|
||||||
$code = null,
|
$code = null,
|
||||||
$cast = self::CAST_TEXT
|
$cast = ValidationResult::CAST_TEXT
|
||||||
) {
|
) {
|
||||||
$this->isValid = false;
|
$this->isValid = false;
|
||||||
return $this->addFieldMessage($fieldName, $message, $messageType, $code, $cast);
|
return $this->addFieldMessage($fieldName, $message, $messageType, $code, $cast);
|
||||||
@ -114,7 +114,7 @@ class ValidationResult
|
|||||||
* Bool values will be treated as plain text flag.
|
* Bool values will be treated as plain text flag.
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function addMessage($message, $messageType = self::TYPE_ERROR, $code = null, $cast = self::CAST_TEXT)
|
public function addMessage($message, $messageType = ValidationResult::TYPE_ERROR, $code = null, $cast = ValidationResult::CAST_TEXT)
|
||||||
{
|
{
|
||||||
return $this->addFieldMessage(null, $message, $messageType, $code, $cast);
|
return $this->addFieldMessage(null, $message, $messageType, $code, $cast);
|
||||||
}
|
}
|
||||||
@ -135,15 +135,15 @@ class ValidationResult
|
|||||||
public function addFieldMessage(
|
public function addFieldMessage(
|
||||||
$fieldName,
|
$fieldName,
|
||||||
$message,
|
$message,
|
||||||
$messageType = self::TYPE_ERROR,
|
$messageType = ValidationResult::TYPE_ERROR,
|
||||||
$code = null,
|
$code = null,
|
||||||
$cast = self::CAST_TEXT
|
$cast = ValidationResult::CAST_TEXT
|
||||||
) {
|
) {
|
||||||
if ($code && is_numeric($code)) {
|
if ($code && is_numeric($code)) {
|
||||||
throw new InvalidArgumentException("Don't use a numeric code '$code'. Use a string.");
|
throw new InvalidArgumentException("Don't use a numeric code '$code'. Use a string.");
|
||||||
}
|
}
|
||||||
if (is_bool($cast)) {
|
if (is_bool($cast)) {
|
||||||
$cast = $cast ? self::CAST_TEXT : self::CAST_HTML;
|
$cast = $cast ? ValidationResult::CAST_TEXT : ValidationResult::CAST_HTML;
|
||||||
}
|
}
|
||||||
$metadata = [
|
$metadata = [
|
||||||
'message' => $message,
|
'message' => $message,
|
||||||
|
@ -43,7 +43,7 @@ class BasicAuth
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @config
|
* @config
|
||||||
* @var Boolean Flag set by {@link self::protect_entire_site()}
|
* @var Boolean Flag set by {@link BasicAuth::protect_entire_site()}
|
||||||
*/
|
*/
|
||||||
private static $entire_site_protected = false;
|
private static $entire_site_protected = false;
|
||||||
|
|
||||||
@ -187,7 +187,7 @@ class BasicAuth
|
|||||||
* of the permission codes a user has.
|
* of the permission codes a user has.
|
||||||
* @param string $message
|
* @param string $message
|
||||||
*/
|
*/
|
||||||
public static function protect_entire_site($protect = true, $code = self::AUTH_PERMISSION, $message = null)
|
public static function protect_entire_site($protect = true, $code = BasicAuth::AUTH_PERMISSION, $message = null)
|
||||||
{
|
{
|
||||||
static::config()
|
static::config()
|
||||||
->set('entire_site_protected', $protect)
|
->set('entire_site_protected', $protect)
|
||||||
@ -214,11 +214,11 @@ class BasicAuth
|
|||||||
// Check if site is protected
|
// Check if site is protected
|
||||||
if ($config->get('entire_site_protected')) {
|
if ($config->get('entire_site_protected')) {
|
||||||
$permissionCode = $config->get('entire_site_protected_code');
|
$permissionCode = $config->get('entire_site_protected_code');
|
||||||
} elseif (Environment::getEnv(self::USE_BASIC_AUTH)) {
|
} elseif (Environment::getEnv(BasicAuth::USE_BASIC_AUTH)) {
|
||||||
// Convert legacy 1 / true to ADMIN permissions
|
// Convert legacy 1 / true to ADMIN permissions
|
||||||
$permissionCode = Environment::getEnv(self::USE_BASIC_AUTH);
|
$permissionCode = Environment::getEnv(BasicAuth::USE_BASIC_AUTH);
|
||||||
if (!is_string($permissionCode) || is_numeric($permissionCode)) {
|
if (!is_string($permissionCode) || is_numeric($permissionCode)) {
|
||||||
$permissionCode = self::AUTH_PERMISSION;
|
$permissionCode = BasicAuth::AUTH_PERMISSION;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Not enabled
|
// Not enabled
|
||||||
|
@ -368,7 +368,7 @@ class Storage
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the URL registered by {@see self::setSuccessUrl} as a success redirect target
|
* Returns the URL registered by {@see Storage::setSuccessUrl} as a success redirect target
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
@ -391,7 +391,7 @@ class Storage
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the URL registered by {@see self::setFailureUrl} as a success redirect target
|
* Returns the URL registered by {@see Storage::setFailureUrl} as a success redirect target
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
|
@ -147,7 +147,7 @@ class InheritedPermissions implements PermissionChecker, MemberCacheFlusher
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($memberIDs && is_array($memberIDs)) {
|
if ($memberIDs && is_array($memberIDs)) {
|
||||||
foreach ([self::VIEW, self::EDIT, self::DELETE] as $type) {
|
foreach ([InheritedPermissions::VIEW, InheritedPermissions::EDIT, InheritedPermissions::DELETE] as $type) {
|
||||||
foreach ($memberIDs as $memberID) {
|
foreach ($memberIDs as $memberID) {
|
||||||
$key = $this->generateCacheKey($type, $memberID);
|
$key = $this->generateCacheKey($type, $memberID);
|
||||||
$this->cacheService->delete($key);
|
$this->cacheService->delete($key);
|
||||||
@ -215,13 +215,13 @@ class InheritedPermissions implements PermissionChecker, MemberCacheFlusher
|
|||||||
public function prePopulatePermissionCache($permission = 'edit', $ids = [])
|
public function prePopulatePermissionCache($permission = 'edit', $ids = [])
|
||||||
{
|
{
|
||||||
switch ($permission) {
|
switch ($permission) {
|
||||||
case self::EDIT:
|
case InheritedPermissions::EDIT:
|
||||||
$this->canEditMultiple($ids, Security::getCurrentUser(), false);
|
$this->canEditMultiple($ids, Security::getCurrentUser(), false);
|
||||||
break;
|
break;
|
||||||
case self::VIEW:
|
case InheritedPermissions::VIEW:
|
||||||
$this->canViewMultiple($ids, Security::getCurrentUser(), false);
|
$this->canViewMultiple($ids, Security::getCurrentUser(), false);
|
||||||
break;
|
break;
|
||||||
case self::DELETE:
|
case InheritedPermissions::DELETE:
|
||||||
$this->canDeleteMultiple($ids, Security::getCurrentUser(), false);
|
$this->canDeleteMultiple($ids, Security::getCurrentUser(), false);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -265,7 +265,7 @@ class InheritedPermissions implements PermissionChecker, MemberCacheFlusher
|
|||||||
// Validate member permission
|
// Validate member permission
|
||||||
// Only VIEW allows anonymous (Anyone) permissions
|
// Only VIEW allows anonymous (Anyone) permissions
|
||||||
$memberID = $member ? (int)$member->ID : 0;
|
$memberID = $member ? (int)$member->ID : 0;
|
||||||
if (!$memberID && $type !== self::VIEW) {
|
if (!$memberID && $type !== InheritedPermissions::VIEW) {
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -374,10 +374,10 @@ class InheritedPermissions implements PermissionChecker, MemberCacheFlusher
|
|||||||
. " OR (\"$typeField\" = ? AND \"$memberJoinTable\".\"{$baseTable}ID\" IS NOT NULL)"
|
. " OR (\"$typeField\" = ? AND \"$memberJoinTable\".\"{$baseTable}ID\" IS NOT NULL)"
|
||||||
. ")"
|
. ")"
|
||||||
=> [
|
=> [
|
||||||
self::ANYONE,
|
InheritedPermissions::ANYONE,
|
||||||
self::LOGGED_IN_USERS,
|
InheritedPermissions::LOGGED_IN_USERS,
|
||||||
self::ONLY_THESE_USERS,
|
InheritedPermissions::ONLY_THESE_USERS,
|
||||||
self::ONLY_THESE_MEMBERS,
|
InheritedPermissions::ONLY_THESE_MEMBERS,
|
||||||
]
|
]
|
||||||
])
|
])
|
||||||
->leftJoin(
|
->leftJoin(
|
||||||
@ -393,7 +393,7 @@ class InheritedPermissions implements PermissionChecker, MemberCacheFlusher
|
|||||||
} else {
|
} else {
|
||||||
// Only view pages with ViewType = Anyone if not logged in
|
// Only view pages with ViewType = Anyone if not logged in
|
||||||
$uninheritedPermissions = $stageRecords
|
$uninheritedPermissions = $stageRecords
|
||||||
->filter($typeField, self::ANYONE)
|
->filter($typeField, InheritedPermissions::ANYONE)
|
||||||
->column('ID');
|
->column('ID');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -406,7 +406,7 @@ class InheritedPermissions implements PermissionChecker, MemberCacheFlusher
|
|||||||
// We group these and run a batch permission check on all parents. This gives us the result
|
// We group these and run a batch permission check on all parents. This gives us the result
|
||||||
// of whether the user has permission to edit this object.
|
// of whether the user has permission to edit this object.
|
||||||
$groupedByParent = [];
|
$groupedByParent = [];
|
||||||
$potentiallyInherited = $stageRecords->filter($typeField, self::INHERIT)
|
$potentiallyInherited = $stageRecords->filter($typeField, InheritedPermissions::INHERIT)
|
||||||
->orderBy("\"{$baseTable}\".\"ID\"")
|
->orderBy("\"{$baseTable}\".\"ID\"")
|
||||||
->dataQuery()
|
->dataQuery()
|
||||||
->query()
|
->query()
|
||||||
@ -456,7 +456,7 @@ class InheritedPermissions implements PermissionChecker, MemberCacheFlusher
|
|||||||
public function canEditMultiple($ids, Member $member = null, $useCached = true)
|
public function canEditMultiple($ids, Member $member = null, $useCached = true)
|
||||||
{
|
{
|
||||||
return $this->batchPermissionCheck(
|
return $this->batchPermissionCheck(
|
||||||
self::EDIT,
|
InheritedPermissions::EDIT,
|
||||||
$ids,
|
$ids,
|
||||||
$member,
|
$member,
|
||||||
$this->getGlobalEditPermissions(),
|
$this->getGlobalEditPermissions(),
|
||||||
@ -472,7 +472,7 @@ class InheritedPermissions implements PermissionChecker, MemberCacheFlusher
|
|||||||
*/
|
*/
|
||||||
public function canViewMultiple($ids, Member $member = null, $useCached = true)
|
public function canViewMultiple($ids, Member $member = null, $useCached = true)
|
||||||
{
|
{
|
||||||
return $this->batchPermissionCheck(self::VIEW, $ids, $member, [], $useCached);
|
return $this->batchPermissionCheck(InheritedPermissions::VIEW, $ids, $member, [], $useCached);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -559,7 +559,7 @@ class InheritedPermissions implements PermissionChecker, MemberCacheFlusher
|
|||||||
{
|
{
|
||||||
// No ID: Check default permission
|
// No ID: Check default permission
|
||||||
if (!$id) {
|
if (!$id) {
|
||||||
return $this->checkDefaultPermissions(self::DELETE, $member);
|
return $this->checkDefaultPermissions(InheritedPermissions::DELETE, $member);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Regular canEdit logic is handled by canEditMultiple
|
// Regular canEdit logic is handled by canEditMultiple
|
||||||
@ -581,7 +581,7 @@ class InheritedPermissions implements PermissionChecker, MemberCacheFlusher
|
|||||||
{
|
{
|
||||||
// No ID: Check default permission
|
// No ID: Check default permission
|
||||||
if (!$id) {
|
if (!$id) {
|
||||||
return $this->checkDefaultPermissions(self::EDIT, $member);
|
return $this->checkDefaultPermissions(InheritedPermissions::EDIT, $member);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Regular canEdit logic is handled by canEditMultiple
|
// Regular canEdit logic is handled by canEditMultiple
|
||||||
@ -603,7 +603,7 @@ class InheritedPermissions implements PermissionChecker, MemberCacheFlusher
|
|||||||
{
|
{
|
||||||
// No ID: Check default permission
|
// No ID: Check default permission
|
||||||
if (!$id) {
|
if (!$id) {
|
||||||
return $this->checkDefaultPermissions(self::VIEW, $member);
|
return $this->checkDefaultPermissions(InheritedPermissions::VIEW, $member);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Regular canView logic is handled by canViewMultiple
|
// Regular canView logic is handled by canViewMultiple
|
||||||
@ -626,11 +626,11 @@ class InheritedPermissions implements PermissionChecker, MemberCacheFlusher
|
|||||||
protected function getPermissionField($type)
|
protected function getPermissionField($type)
|
||||||
{
|
{
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
case self::DELETE:
|
case InheritedPermissions::DELETE:
|
||||||
// Delete uses edit type - Drop through
|
// Delete uses edit type - Drop through
|
||||||
case self::EDIT:
|
case InheritedPermissions::EDIT:
|
||||||
return 'CanEditType';
|
return 'CanEditType';
|
||||||
case self::VIEW:
|
case InheritedPermissions::VIEW:
|
||||||
return 'CanViewType';
|
return 'CanViewType';
|
||||||
default:
|
default:
|
||||||
throw new InvalidArgumentException("Invalid argument type $type");
|
throw new InvalidArgumentException("Invalid argument type $type");
|
||||||
@ -661,11 +661,11 @@ class InheritedPermissions implements PermissionChecker, MemberCacheFlusher
|
|||||||
protected function getGroupJoinTable($type)
|
protected function getGroupJoinTable($type)
|
||||||
{
|
{
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
case self::DELETE:
|
case InheritedPermissions::DELETE:
|
||||||
// Delete uses edit type - Drop through
|
// Delete uses edit type - Drop through
|
||||||
case self::EDIT:
|
case InheritedPermissions::EDIT:
|
||||||
return $this->getEditorGroupsTable();
|
return $this->getEditorGroupsTable();
|
||||||
case self::VIEW:
|
case InheritedPermissions::VIEW:
|
||||||
return $this->getViewerGroupsTable();
|
return $this->getViewerGroupsTable();
|
||||||
default:
|
default:
|
||||||
throw new InvalidArgumentException("Invalid argument type $type");
|
throw new InvalidArgumentException("Invalid argument type $type");
|
||||||
@ -682,11 +682,11 @@ class InheritedPermissions implements PermissionChecker, MemberCacheFlusher
|
|||||||
protected function getMemberJoinTable($type)
|
protected function getMemberJoinTable($type)
|
||||||
{
|
{
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
case self::DELETE:
|
case InheritedPermissions::DELETE:
|
||||||
// Delete uses edit type - Drop through
|
// Delete uses edit type - Drop through
|
||||||
case self::EDIT:
|
case InheritedPermissions::EDIT:
|
||||||
return $this->getEditorMembersTable();
|
return $this->getEditorMembersTable();
|
||||||
case self::VIEW:
|
case InheritedPermissions::VIEW:
|
||||||
return $this->getViewerMembersTable();
|
return $this->getViewerMembersTable();
|
||||||
default:
|
default:
|
||||||
throw new InvalidArgumentException("Invalid argument type $type");
|
throw new InvalidArgumentException("Invalid argument type $type");
|
||||||
@ -707,11 +707,11 @@ class InheritedPermissions implements PermissionChecker, MemberCacheFlusher
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
case self::VIEW:
|
case InheritedPermissions::VIEW:
|
||||||
return $defaultPermissions->canView($member);
|
return $defaultPermissions->canView($member);
|
||||||
case self::EDIT:
|
case InheritedPermissions::EDIT:
|
||||||
return $defaultPermissions->canEdit($member);
|
return $defaultPermissions->canEdit($member);
|
||||||
case self::DELETE:
|
case InheritedPermissions::DELETE:
|
||||||
return $defaultPermissions->canDelete($member);
|
return $defaultPermissions->canDelete($member);
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
@ -23,7 +23,7 @@ class LogoutForm extends Form
|
|||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
RequestHandler $controller = null,
|
RequestHandler $controller = null,
|
||||||
$name = self::DEFAULT_NAME,
|
$name = LogoutForm::DEFAULT_NAME,
|
||||||
FieldList $fields = null,
|
FieldList $fields = null,
|
||||||
FieldList $actions = null,
|
FieldList $actions = null,
|
||||||
Validator $validator = null
|
Validator $validator = null
|
||||||
|
@ -478,7 +478,7 @@ class Member extends DataObject
|
|||||||
public function regenerateTempID()
|
public function regenerateTempID()
|
||||||
{
|
{
|
||||||
$generator = new RandomGenerator();
|
$generator = new RandomGenerator();
|
||||||
$lifetime = self::config()->get('temp_id_lifetime');
|
$lifetime = static::config()->get('temp_id_lifetime');
|
||||||
$this->TempIDHash = $generator->randomToken('sha1');
|
$this->TempIDHash = $generator->randomToken('sha1');
|
||||||
$this->TempIDExpired = $lifetime
|
$this->TempIDExpired = $lifetime
|
||||||
? date('Y-m-d H:i:s', strtotime(DBDatetime::now()->getValue()) + $lifetime)
|
? date('Y-m-d H:i:s', strtotime(DBDatetime::now()->getValue()) + $lifetime)
|
||||||
@ -565,7 +565,7 @@ class Member extends DataObject
|
|||||||
public function validateAutoLoginToken($autologinToken)
|
public function validateAutoLoginToken($autologinToken)
|
||||||
{
|
{
|
||||||
$hash = $this->encryptWithUserSettings($autologinToken);
|
$hash = $this->encryptWithUserSettings($autologinToken);
|
||||||
$member = self::member_from_autologinhash($hash, false);
|
$member = Member::member_from_autologinhash($hash, false);
|
||||||
|
|
||||||
return (bool)$member;
|
return (bool)$member;
|
||||||
}
|
}
|
||||||
@ -1615,7 +1615,7 @@ class Member extends DataObject
|
|||||||
protected function encryptPassword()
|
protected function encryptPassword()
|
||||||
{
|
{
|
||||||
// reset salt so that it gets regenerated - this will invalidate any persistent login cookies
|
// reset salt so that it gets regenerated - this will invalidate any persistent login cookies
|
||||||
// or other information encrypted with this Member's settings (see self::encryptWithUserSettings)
|
// or other information encrypted with this Member's settings (see Member::encryptWithUserSettings)
|
||||||
$this->Salt = '';
|
$this->Salt = '';
|
||||||
|
|
||||||
// Password was changed: encrypt the password according the settings
|
// Password was changed: encrypt the password according the settings
|
||||||
@ -1650,13 +1650,13 @@ class Member extends DataObject
|
|||||||
*/
|
*/
|
||||||
public function registerFailedLogin()
|
public function registerFailedLogin()
|
||||||
{
|
{
|
||||||
$lockOutAfterCount = self::config()->get('lock_out_after_incorrect_logins');
|
$lockOutAfterCount = static::config()->get('lock_out_after_incorrect_logins');
|
||||||
if ($lockOutAfterCount) {
|
if ($lockOutAfterCount) {
|
||||||
// Keep a tally of the number of failed log-ins so that we can lock people out
|
// Keep a tally of the number of failed log-ins so that we can lock people out
|
||||||
++$this->FailedLoginCount;
|
++$this->FailedLoginCount;
|
||||||
|
|
||||||
if ($this->FailedLoginCount >= $lockOutAfterCount) {
|
if ($this->FailedLoginCount >= $lockOutAfterCount) {
|
||||||
$lockoutMins = self::config()->get('lock_out_delay_mins');
|
$lockoutMins = static::config()->get('lock_out_delay_mins');
|
||||||
$this->LockedOutUntil = date('Y-m-d H:i:s', DBDatetime::now()->getTimestamp() + $lockoutMins * 60);
|
$this->LockedOutUntil = date('Y-m-d H:i:s', DBDatetime::now()->getTimestamp() + $lockoutMins * 60);
|
||||||
$this->FailedLoginCount = 0;
|
$this->FailedLoginCount = 0;
|
||||||
}
|
}
|
||||||
@ -1670,7 +1670,7 @@ class Member extends DataObject
|
|||||||
*/
|
*/
|
||||||
public function registerSuccessfulLogin()
|
public function registerSuccessfulLogin()
|
||||||
{
|
{
|
||||||
if (self::config()->get('lock_out_after_incorrect_logins')) {
|
if (static::config()->get('lock_out_after_incorrect_logins')) {
|
||||||
// Forgive all past login failures
|
// Forgive all past login failures
|
||||||
$this->FailedLoginCount = 0;
|
$this->FailedLoginCount = 0;
|
||||||
$this->LockedOutUntil = null;
|
$this->LockedOutUntil = null;
|
||||||
@ -1714,7 +1714,7 @@ class Member extends DataObject
|
|||||||
public function generateRandomPassword(int $length = 0): string
|
public function generateRandomPassword(int $length = 0): string
|
||||||
{
|
{
|
||||||
$password = '';
|
$password = '';
|
||||||
$validator = self::password_validator();
|
$validator = Member::password_validator();
|
||||||
if ($length && $validator && $length < $validator->getMinLength()) {
|
if ($length && $validator && $length < $validator->getMinLength()) {
|
||||||
throw new InvalidArgumentException('length argument is less than password validator minLength');
|
throw new InvalidArgumentException('length argument is less than password validator minLength');
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,7 @@ class MemberLoginForm extends BaseLoginForm
|
|||||||
if (isset($logoutAction)) {
|
if (isset($logoutAction)) {
|
||||||
$this->setFormAction($logoutAction);
|
$this->setFormAction($logoutAction);
|
||||||
}
|
}
|
||||||
$this->setValidator(RequiredFields::create(self::config()->get('required_fields')));
|
$this->setValidator(RequiredFields::create(static::config()->get('required_fields')));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -225,6 +225,6 @@ class MemberLoginForm extends BaseLoginForm
|
|||||||
*/
|
*/
|
||||||
public function getAuthenticatorName()
|
public function getAuthenticatorName()
|
||||||
{
|
{
|
||||||
return _t(self::class . '.AUTHENTICATORNAME', "E-mail & Password");
|
return _t(MemberLoginForm::class . '.AUTHENTICATORNAME', "E-mail & Password");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ abstract class PasswordEncryptor
|
|||||||
*/
|
*/
|
||||||
public static function get_encryptors()
|
public static function get_encryptors()
|
||||||
{
|
{
|
||||||
return Config::inst()->get(self::class, 'encryptors');
|
return Config::inst()->get(PasswordEncryptor::class, 'encryptors');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -38,7 +38,7 @@ abstract class PasswordEncryptor
|
|||||||
*/
|
*/
|
||||||
public static function create_for_algorithm($algorithm)
|
public static function create_for_algorithm($algorithm)
|
||||||
{
|
{
|
||||||
$encryptors = self::get_encryptors();
|
$encryptors = PasswordEncryptor::get_encryptors();
|
||||||
if (!isset($encryptors[$algorithm])) {
|
if (!isset($encryptors[$algorithm])) {
|
||||||
throw new PasswordEncryptor_NotFoundException(
|
throw new PasswordEncryptor_NotFoundException(
|
||||||
sprintf('No implementation found for "%s"', $algorithm)
|
sprintf('No implementation found for "%s"', $algorithm)
|
||||||
|
@ -30,7 +30,7 @@ class PasswordEncryptor_Blowfish extends PasswordEncryptor
|
|||||||
*/
|
*/
|
||||||
public static function set_cost($cost)
|
public static function set_cost($cost)
|
||||||
{
|
{
|
||||||
self::$cost = max(min(31, $cost), 4);
|
PasswordEncryptor_Blowfish::$cost = max(min(31, $cost), 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -40,7 +40,7 @@ class PasswordEncryptor_Blowfish extends PasswordEncryptor
|
|||||||
*/
|
*/
|
||||||
public static function get_cost()
|
public static function get_cost()
|
||||||
{
|
{
|
||||||
return self::$cost;
|
return PasswordEncryptor_Blowfish::$cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function encrypt($password, $salt = null, $member = null)
|
public function encrypt($password, $salt = null, $member = null)
|
||||||
@ -153,7 +153,7 @@ class PasswordEncryptor_Blowfish extends PasswordEncryptor
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* self::$cost param is forced to be two digits with leading zeroes for ints 4-9
|
* PasswordEncryptor_Blowfish::$cost param is forced to be two digits with leading zeroes for ints 4-9
|
||||||
*
|
*
|
||||||
* @param string $password
|
* @param string $password
|
||||||
* @param Member $member
|
* @param Member $member
|
||||||
@ -162,7 +162,7 @@ class PasswordEncryptor_Blowfish extends PasswordEncryptor
|
|||||||
public function salt($password, $member = null)
|
public function salt($password, $member = null)
|
||||||
{
|
{
|
||||||
$generator = new RandomGenerator();
|
$generator = new RandomGenerator();
|
||||||
return sprintf('%02d', self::$cost) . '$' . substr($generator->randomToken('sha1') ?? '', 0, 22);
|
return sprintf('%02d', PasswordEncryptor_Blowfish::$cost) . '$' . substr($generator->randomToken('sha1') ?? '', 0, 22);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function check($hash, $password, $salt = null, $member = null)
|
public function check($hash, $password, $salt = null, $member = null)
|
||||||
|
@ -122,7 +122,7 @@ class Permission extends DataObject implements TemplateGlobalProvider, Resettabl
|
|||||||
$member = Security::getCurrentUser();
|
$member = Security::getCurrentUser();
|
||||||
}
|
}
|
||||||
|
|
||||||
return self::checkMember($member, $code, $arg, $strict);
|
return Permission::checkMember($member, $code, $arg, $strict);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -136,7 +136,7 @@ class Permission extends DataObject implements TemplateGlobalProvider, Resettabl
|
|||||||
*/
|
*/
|
||||||
public static function reset()
|
public static function reset()
|
||||||
{
|
{
|
||||||
self::$cache_permissions = [];
|
Permission::$cache_permissions = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -173,12 +173,12 @@ class Permission extends DataObject implements TemplateGlobalProvider, Resettabl
|
|||||||
|
|
||||||
if ($arg == 'any') {
|
if ($arg == 'any') {
|
||||||
// Cache the permissions in memory
|
// Cache the permissions in memory
|
||||||
if (!isset(self::$cache_permissions[$memberID])) {
|
if (!isset(Permission::$cache_permissions[$memberID])) {
|
||||||
self::$cache_permissions[$memberID] = self::permissions_for_member($memberID);
|
Permission::$cache_permissions[$memberID] = Permission::permissions_for_member($memberID);
|
||||||
}
|
}
|
||||||
foreach ($code as $permCode) {
|
foreach ($code as $permCode) {
|
||||||
if ($permCode === 'CMS_ACCESS') {
|
if ($permCode === 'CMS_ACCESS') {
|
||||||
foreach (self::$cache_permissions[$memberID] as $perm) {
|
foreach (Permission::$cache_permissions[$memberID] as $perm) {
|
||||||
//if they have admin rights OR they have an explicit access to the CMS then give permission
|
//if they have admin rights OR they have an explicit access to the CMS then give permission
|
||||||
if (($adminImpliesAll && $perm == 'ADMIN') || substr($perm ?? '', 0, 11) === 'CMS_ACCESS_') {
|
if (($adminImpliesAll && $perm == 'ADMIN') || substr($perm ?? '', 0, 11) === 'CMS_ACCESS_') {
|
||||||
return true;
|
return true;
|
||||||
@ -196,7 +196,7 @@ class Permission extends DataObject implements TemplateGlobalProvider, Resettabl
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Multiple $code values - return true if at least one matches, ie, intersection exists
|
// Multiple $code values - return true if at least one matches, ie, intersection exists
|
||||||
return (bool)array_intersect($code ?? [], self::$cache_permissions[$memberID]);
|
return (bool)array_intersect($code ?? [], Permission::$cache_permissions[$memberID]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Code filters
|
// Code filters
|
||||||
@ -207,7 +207,7 @@ class Permission extends DataObject implements TemplateGlobalProvider, Resettabl
|
|||||||
|
|
||||||
// The following code should only be used if you're not using the "any" arg. This is kind
|
// The following code should only be used if you're not using the "any" arg. This is kind
|
||||||
// of obsolete functionality and could possibly be deprecated.
|
// of obsolete functionality and could possibly be deprecated.
|
||||||
$groupParams = self::groupList($memberID);
|
$groupParams = Permission::groupList($memberID);
|
||||||
if (empty($groupParams)) {
|
if (empty($groupParams)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -245,7 +245,7 @@ class Permission extends DataObject implements TemplateGlobalProvider, Resettabl
|
|||||||
array_merge(
|
array_merge(
|
||||||
$codeParams,
|
$codeParams,
|
||||||
$adminParams,
|
$adminParams,
|
||||||
[self::GRANT_PERMISSION],
|
[Permission::GRANT_PERMISSION],
|
||||||
$groupParams,
|
$groupParams,
|
||||||
$argParams
|
$argParams
|
||||||
)
|
)
|
||||||
@ -264,7 +264,7 @@ class Permission extends DataObject implements TemplateGlobalProvider, Resettabl
|
|||||||
\"Code\" IN ($codeClause) AND
|
\"Code\" IN ($codeClause) AND
|
||||||
\"Type\" = ?
|
\"Type\" = ?
|
||||||
)",
|
)",
|
||||||
array_merge($codeParams, [self::GRANT_PERMISSION])
|
array_merge($codeParams, [Permission::GRANT_PERMISSION])
|
||||||
)->value();
|
)->value();
|
||||||
|
|
||||||
if (!$hasPermission) {
|
if (!$hasPermission) {
|
||||||
@ -283,7 +283,7 @@ class Permission extends DataObject implements TemplateGlobalProvider, Resettabl
|
|||||||
*/
|
*/
|
||||||
public static function permissions_for_member($memberID)
|
public static function permissions_for_member($memberID)
|
||||||
{
|
{
|
||||||
$groupList = self::groupList($memberID);
|
$groupList = Permission::groupList($memberID);
|
||||||
|
|
||||||
if ($groupList) {
|
if ($groupList) {
|
||||||
$groupCSV = implode(", ", $groupList);
|
$groupCSV = implode(", ", $groupList);
|
||||||
@ -291,7 +291,7 @@ class Permission extends DataObject implements TemplateGlobalProvider, Resettabl
|
|||||||
$allowed = array_unique(DB::query("
|
$allowed = array_unique(DB::query("
|
||||||
SELECT \"Code\"
|
SELECT \"Code\"
|
||||||
FROM \"Permission\"
|
FROM \"Permission\"
|
||||||
WHERE \"Type\" = " . self::GRANT_PERMISSION . " AND \"GroupID\" IN ($groupCSV)
|
WHERE \"Type\" = " . Permission::GRANT_PERMISSION . " AND \"GroupID\" IN ($groupCSV)
|
||||||
|
|
||||||
UNION
|
UNION
|
||||||
|
|
||||||
@ -305,7 +305,7 @@ class Permission extends DataObject implements TemplateGlobalProvider, Resettabl
|
|||||||
$denied = array_unique(DB::query("
|
$denied = array_unique(DB::query("
|
||||||
SELECT \"Code\"
|
SELECT \"Code\"
|
||||||
FROM \"Permission\"
|
FROM \"Permission\"
|
||||||
WHERE \"Type\" = " . self::DENY_PERMISSION . " AND \"GroupID\" IN ($groupCSV)
|
WHERE \"Type\" = " . Permission::DENY_PERMISSION . " AND \"GroupID\" IN ($groupCSV)
|
||||||
")->column() ?? []);
|
")->column() ?? []);
|
||||||
|
|
||||||
return array_diff($allowed ?? [], $denied);
|
return array_diff($allowed ?? [], $denied);
|
||||||
@ -384,7 +384,7 @@ class Permission extends DataObject implements TemplateGlobalProvider, Resettabl
|
|||||||
$perm->Code = $code;
|
$perm->Code = $code;
|
||||||
}
|
}
|
||||||
|
|
||||||
$perm->Type = self::GRANT_PERMISSION;
|
$perm->Type = Permission::GRANT_PERMISSION;
|
||||||
|
|
||||||
// Arg component
|
// Arg component
|
||||||
switch ($arg) {
|
switch ($arg) {
|
||||||
@ -426,7 +426,7 @@ class Permission extends DataObject implements TemplateGlobalProvider, Resettabl
|
|||||||
$perm->Code = $code;
|
$perm->Code = $code;
|
||||||
}
|
}
|
||||||
|
|
||||||
$perm->Type = self::DENY_PERMISSION;
|
$perm->Type = Permission::DENY_PERMISSION;
|
||||||
|
|
||||||
// Arg component
|
// Arg component
|
||||||
switch ($arg) {
|
switch ($arg) {
|
||||||
@ -456,7 +456,7 @@ class Permission extends DataObject implements TemplateGlobalProvider, Resettabl
|
|||||||
*/
|
*/
|
||||||
public static function get_members_by_permission($code)
|
public static function get_members_by_permission($code)
|
||||||
{
|
{
|
||||||
$toplevelGroups = self::get_groups_by_permission($code);
|
$toplevelGroups = Permission::get_groups_by_permission($code);
|
||||||
if (!$toplevelGroups) {
|
if (!$toplevelGroups) {
|
||||||
return new ArrayList();
|
return new ArrayList();
|
||||||
}
|
}
|
||||||
|
@ -217,9 +217,9 @@ class RememberLoginHash extends DataObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (static::getLogoutAcrossDevices()) {
|
if (static::getLogoutAcrossDevices()) {
|
||||||
self::get()->filter(['MemberID' => $member->ID])->removeAll();
|
RememberLoginHash::get()->filter(['MemberID' => $member->ID])->removeAll();
|
||||||
} elseif ($alcDevice) {
|
} elseif ($alcDevice) {
|
||||||
self::get()->filter([
|
RememberLoginHash::get()->filter([
|
||||||
'MemberID' => $member->ID,
|
'MemberID' => $member->ID,
|
||||||
'DeviceID' => $alcDevice
|
'DeviceID' => $alcDevice
|
||||||
])->removeAll();
|
])->removeAll();
|
||||||
|
@ -306,7 +306,7 @@ class Security extends Controller implements TemplateGlobalProvider
|
|||||||
*/
|
*/
|
||||||
public static function permissionFailure($controller = null, $messageSet = null): HTTPResponse
|
public static function permissionFailure($controller = null, $messageSet = null): HTTPResponse
|
||||||
{
|
{
|
||||||
self::set_ignore_disallowed_actions(true);
|
Security::set_ignore_disallowed_actions(true);
|
||||||
|
|
||||||
// Parse raw message / escape type
|
// Parse raw message / escape type
|
||||||
$parseMessage = function ($message) {
|
$parseMessage = function ($message) {
|
||||||
@ -437,7 +437,7 @@ class Security extends Controller implements TemplateGlobalProvider
|
|||||||
*/
|
*/
|
||||||
public static function setCurrentUser($currentUser = null)
|
public static function setCurrentUser($currentUser = null)
|
||||||
{
|
{
|
||||||
self::$currentUser = $currentUser;
|
Security::$currentUser = $currentUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -445,7 +445,7 @@ class Security extends Controller implements TemplateGlobalProvider
|
|||||||
*/
|
*/
|
||||||
public static function getCurrentUser()
|
public static function getCurrentUser()
|
||||||
{
|
{
|
||||||
return self::$currentUser;
|
return Security::$currentUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1049,7 +1049,7 @@ class Security extends Controller implements TemplateGlobalProvider
|
|||||||
{
|
{
|
||||||
// Fall back to the default encryption algorithm
|
// Fall back to the default encryption algorithm
|
||||||
if (!$algorithm) {
|
if (!$algorithm) {
|
||||||
$algorithm = self::config()->get('password_encryption_algorithm');
|
$algorithm = static::config()->get('password_encryption_algorithm');
|
||||||
}
|
}
|
||||||
|
|
||||||
$encryptor = PasswordEncryptor::create_for_algorithm($algorithm);
|
$encryptor = PasswordEncryptor::create_for_algorithm($algorithm);
|
||||||
@ -1074,12 +1074,12 @@ class Security extends Controller implements TemplateGlobalProvider
|
|||||||
public static function database_is_ready()
|
public static function database_is_ready()
|
||||||
{
|
{
|
||||||
// Used for unit tests
|
// Used for unit tests
|
||||||
if (self::$force_database_is_ready !== null) {
|
if (Security::$force_database_is_ready !== null) {
|
||||||
return self::$force_database_is_ready;
|
return Security::$force_database_is_ready;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self::$database_is_ready) {
|
if (Security::$database_is_ready) {
|
||||||
return self::$database_is_ready;
|
return Security::$database_is_ready;
|
||||||
}
|
}
|
||||||
|
|
||||||
$requiredClasses = ClassInfo::dataClassesFor(Member::class);
|
$requiredClasses = ClassInfo::dataClassesFor(Member::class);
|
||||||
@ -1115,7 +1115,7 @@ class Security extends Controller implements TemplateGlobalProvider
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self::$database_is_ready = true;
|
Security::$database_is_ready = true;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1125,8 +1125,8 @@ class Security extends Controller implements TemplateGlobalProvider
|
|||||||
*/
|
*/
|
||||||
public static function clear_database_is_ready()
|
public static function clear_database_is_ready()
|
||||||
{
|
{
|
||||||
self::$database_is_ready = null;
|
Security::$database_is_ready = null;
|
||||||
self::$force_database_is_ready = null;
|
Security::$force_database_is_ready = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1136,7 +1136,7 @@ class Security extends Controller implements TemplateGlobalProvider
|
|||||||
*/
|
*/
|
||||||
public static function force_database_is_ready($isReady)
|
public static function force_database_is_ready($isReady)
|
||||||
{
|
{
|
||||||
self::$force_database_is_ready = $isReady;
|
Security::$force_database_is_ready = $isReady;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1165,12 +1165,12 @@ class Security extends Controller implements TemplateGlobalProvider
|
|||||||
*/
|
*/
|
||||||
public static function set_ignore_disallowed_actions($flag)
|
public static function set_ignore_disallowed_actions($flag)
|
||||||
{
|
{
|
||||||
self::$ignore_disallowed_actions = $flag;
|
Security::$ignore_disallowed_actions = $flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function ignore_disallowed_actions()
|
public static function ignore_disallowed_actions()
|
||||||
{
|
{
|
||||||
return self::$ignore_disallowed_actions;
|
return Security::$ignore_disallowed_actions;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1182,7 +1182,7 @@ class Security extends Controller implements TemplateGlobalProvider
|
|||||||
*/
|
*/
|
||||||
public static function login_url()
|
public static function login_url()
|
||||||
{
|
{
|
||||||
return Controller::join_links(Director::baseURL(), self::config()->get('login_url'));
|
return Controller::join_links(Director::baseURL(), static::config()->get('login_url'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1195,7 +1195,7 @@ class Security extends Controller implements TemplateGlobalProvider
|
|||||||
*/
|
*/
|
||||||
public static function logout_url()
|
public static function logout_url()
|
||||||
{
|
{
|
||||||
$logoutUrl = Controller::join_links(Director::baseURL(), self::config()->get('logout_url'));
|
$logoutUrl = Controller::join_links(Director::baseURL(), static::config()->get('logout_url'));
|
||||||
return SecurityToken::inst()->addToUrl($logoutUrl);
|
return SecurityToken::inst()->addToUrl($logoutUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1208,7 +1208,7 @@ class Security extends Controller implements TemplateGlobalProvider
|
|||||||
*/
|
*/
|
||||||
public static function lost_password_url()
|
public static function lost_password_url()
|
||||||
{
|
{
|
||||||
return Controller::join_links(Director::baseURL(), self::config()->get('lost_password_url'));
|
return Controller::join_links(Director::baseURL(), static::config()->get('lost_password_url'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -66,7 +66,7 @@ class SecurityToken implements TemplateGlobalProvider
|
|||||||
*/
|
*/
|
||||||
public function __construct($name = null)
|
public function __construct($name = null)
|
||||||
{
|
{
|
||||||
$this->name = $name ?: self::get_default_name();
|
$this->name = $name ?: SecurityToken::get_default_name();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -76,11 +76,11 @@ class SecurityToken implements TemplateGlobalProvider
|
|||||||
*/
|
*/
|
||||||
public static function inst()
|
public static function inst()
|
||||||
{
|
{
|
||||||
if (!self::$inst) {
|
if (!SecurityToken::$inst) {
|
||||||
self::$inst = new SecurityToken();
|
SecurityToken::$inst = new SecurityToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
return self::$inst;
|
return SecurityToken::$inst;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -89,8 +89,8 @@ class SecurityToken implements TemplateGlobalProvider
|
|||||||
*/
|
*/
|
||||||
public static function disable()
|
public static function disable()
|
||||||
{
|
{
|
||||||
self::$enabled = false;
|
SecurityToken::$enabled = false;
|
||||||
self::$inst = new NullSecurityToken();
|
SecurityToken::$inst = new NullSecurityToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -98,8 +98,8 @@ class SecurityToken implements TemplateGlobalProvider
|
|||||||
*/
|
*/
|
||||||
public static function enable()
|
public static function enable()
|
||||||
{
|
{
|
||||||
self::$enabled = true;
|
SecurityToken::$enabled = true;
|
||||||
self::$inst = new SecurityToken();
|
SecurityToken::$inst = new SecurityToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -107,7 +107,7 @@ class SecurityToken implements TemplateGlobalProvider
|
|||||||
*/
|
*/
|
||||||
public static function is_enabled()
|
public static function is_enabled()
|
||||||
{
|
{
|
||||||
return self::$enabled;
|
return SecurityToken::$enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -115,7 +115,7 @@ class SecurityToken implements TemplateGlobalProvider
|
|||||||
*/
|
*/
|
||||||
public static function get_default_name()
|
public static function get_default_name()
|
||||||
{
|
{
|
||||||
return self::$default_name;
|
return SecurityToken::$default_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,7 +27,7 @@ class SudoModeService implements SudoModeServiceInterface
|
|||||||
|
|
||||||
public function check(Session $session): bool
|
public function check(Session $session): bool
|
||||||
{
|
{
|
||||||
$lastActivated = $session->get(self::SUDO_MODE_SESSION_KEY);
|
$lastActivated = $session->get(SudoModeService::SUDO_MODE_SESSION_KEY);
|
||||||
// Not activated at all
|
// Not activated at all
|
||||||
if (!$lastActivated) {
|
if (!$lastActivated) {
|
||||||
return false;
|
return false;
|
||||||
@ -41,7 +41,7 @@ class SudoModeService implements SudoModeServiceInterface
|
|||||||
|
|
||||||
public function activate(Session $session): bool
|
public function activate(Session $session): bool
|
||||||
{
|
{
|
||||||
$session->set(self::SUDO_MODE_SESSION_KEY, DBDatetime::now()->getTimestamp());
|
$session->set(SudoModeService::SUDO_MODE_SESSION_KEY, DBDatetime::now()->getTimestamp());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ class EmbedContainer implements Embeddable
|
|||||||
return $this->options;
|
return $this->options;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setOptions(array $options): self
|
public function setOptions(array $options): EmbedContainer
|
||||||
{
|
{
|
||||||
$this->options = $options;
|
$this->options = $options;
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -31,21 +31,21 @@ class HtmlDiff
|
|||||||
{
|
{
|
||||||
// Get HTML chunks even if we're going to escape it later
|
// Get HTML chunks even if we're going to escape it later
|
||||||
// The diff algorithm sees "<span>some" as a single piece rather than "<span>" and "some" being separate
|
// The diff algorithm sees "<span>some" as a single piece rather than "<span>" and "some" being separate
|
||||||
$from = self::explodeToHtmlChunks($from);
|
$from = HtmlDiff::explodeToHtmlChunks($from);
|
||||||
$to = self::explodeToHtmlChunks($to);
|
$to = HtmlDiff::explodeToHtmlChunks($to);
|
||||||
|
|
||||||
// Diff the chunks
|
// Diff the chunks
|
||||||
$differ = self::getDiffer();
|
$differ = HtmlDiff::getDiffer();
|
||||||
$diff = $differ->diffToArray($from, $to);
|
$diff = $differ->diffToArray($from, $to);
|
||||||
|
|
||||||
// If we aren't escaping the HTML, convert the first diff into clean HTML blocks and then run a new diff
|
// If we aren't escaping the HTML, convert the first diff into clean HTML blocks and then run a new diff
|
||||||
// on the blocks to get an end result that doesn't have broken HTML
|
// on the blocks to get an end result that doesn't have broken HTML
|
||||||
if (!$escape) {
|
if (!$escape) {
|
||||||
$diifAsBlocks = self::convertDiffToHtmlBlocks($diff);
|
$diifAsBlocks = HtmlDiff::convertDiffToHtmlBlocks($diff);
|
||||||
$diff = $differ->diffToArray($diifAsBlocks[self::OLD_VAL], $diifAsBlocks[self::NEW_VAL]);
|
$diff = $differ->diffToArray($diifAsBlocks[HtmlDiff::OLD_VAL], $diifAsBlocks[HtmlDiff::NEW_VAL]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$diff = self::createFinalDiffBlocks($diff, $escape);
|
$diff = HtmlDiff::createFinalDiffBlocks($diff, $escape);
|
||||||
|
|
||||||
// Take the diff and slap the appropriate <ins> and <del> tags in place
|
// Take the diff and slap the appropriate <ins> and <del> tags in place
|
||||||
$content = '';
|
$content = '';
|
||||||
@ -76,7 +76,7 @@ class HtmlDiff
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return self::cleanHTML($content);
|
return HtmlDiff::cleanHTML($content);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -94,7 +94,7 @@ class HtmlDiff
|
|||||||
foreach ($diff as $edit) {
|
foreach ($diff as $edit) {
|
||||||
list($value, $type) = $edit;
|
list($value, $type) = $edit;
|
||||||
$isClosingTag = !$escaped && str_starts_with($value, '</');
|
$isClosingTag = !$escaped && str_starts_with($value, '</');
|
||||||
$isOpeningNonVoidTag = !$escaped && self::isOpeningNonVoidTag($value);
|
$isOpeningNonVoidTag = !$escaped && HtmlDiff::isOpeningNonVoidTag($value);
|
||||||
|
|
||||||
// If we were building a DIFFERENT type of block, or we've run out of open tags and are closing something
|
// If we were building a DIFFERENT type of block, or we've run out of open tags and are closing something
|
||||||
// earlier in the chain, close the previous block and start a new one
|
// earlier in the chain, close the previous block and start a new one
|
||||||
@ -139,8 +139,8 @@ class HtmlDiff
|
|||||||
*/
|
*/
|
||||||
private static function convertDiffToHtmlBlocks(array $diff): array
|
private static function convertDiffToHtmlBlocks(array $diff): array
|
||||||
{
|
{
|
||||||
$openTagsInBlock[self::OLD_VAL] = $openTagsInBlock[self::NEW_VAL] = 0;
|
$openTagsInBlock[HtmlDiff::OLD_VAL] = $openTagsInBlock[HtmlDiff::NEW_VAL] = 0;
|
||||||
$htmlBlocks[self::OLD_VAL] = $htmlBlocks[self::NEW_VAL] = [];
|
$htmlBlocks[HtmlDiff::OLD_VAL] = $htmlBlocks[HtmlDiff::NEW_VAL] = [];
|
||||||
|
|
||||||
foreach ($diff as $edit) {
|
foreach ($diff as $edit) {
|
||||||
list($value, $type) = $edit;
|
list($value, $type) = $edit;
|
||||||
@ -149,16 +149,16 @@ class HtmlDiff
|
|||||||
if ($value === '') {
|
if ($value === '') {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
self::addToHtmlBlocks($htmlBlocks, $openTagsInBlock, self::OLD_VAL, false, $value);
|
HtmlDiff::addToHtmlBlocks($htmlBlocks, $openTagsInBlock, HtmlDiff::OLD_VAL, false, $value);
|
||||||
self::addToHtmlBlocks($htmlBlocks, $openTagsInBlock, self::NEW_VAL, false, $value);
|
HtmlDiff::addToHtmlBlocks($htmlBlocks, $openTagsInBlock, HtmlDiff::NEW_VAL, false, $value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Differ::ADDED:
|
case Differ::ADDED:
|
||||||
self::addToHtmlBlocks($htmlBlocks, $openTagsInBlock, self::NEW_VAL, true, $value);
|
HtmlDiff::addToHtmlBlocks($htmlBlocks, $openTagsInBlock, HtmlDiff::NEW_VAL, true, $value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Differ::REMOVED:
|
case Differ::REMOVED:
|
||||||
self::addToHtmlBlocks($htmlBlocks, $openTagsInBlock, self::OLD_VAL, true, $value);
|
HtmlDiff::addToHtmlBlocks($htmlBlocks, $openTagsInBlock, HtmlDiff::OLD_VAL, true, $value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -186,7 +186,7 @@ class HtmlDiff
|
|||||||
$htmlBlocks[$oldOrNew][] = $value;
|
$htmlBlocks[$oldOrNew][] = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($canAddTagsToBlock && self::isOpeningNonVoidTag($value)) {
|
if ($canAddTagsToBlock && HtmlDiff::isOpeningNonVoidTag($value)) {
|
||||||
// If we're mid block or explicitly looking for new tags, we should add any new non-void tags to the block
|
// If we're mid block or explicitly looking for new tags, we should add any new non-void tags to the block
|
||||||
$openTagsInBlock[$oldOrNew]++;
|
$openTagsInBlock[$oldOrNew]++;
|
||||||
} elseif ($alreadyMidBlock && str_starts_with($value, '</')) {
|
} elseif ($alreadyMidBlock && str_starts_with($value, '</')) {
|
||||||
@ -254,13 +254,13 @@ class HtmlDiff
|
|||||||
* This cleans code if possible, using an instance of HTMLCleaner
|
* This cleans code if possible, using an instance of HTMLCleaner
|
||||||
*
|
*
|
||||||
* @param ?HTMLCleaner $cleaner Optional instance of a HTMLCleaner class to
|
* @param ?HTMLCleaner $cleaner Optional instance of a HTMLCleaner class to
|
||||||
* use, overriding self::$html_cleaner_class
|
* use, overriding HtmlDiff::$html_cleaner_class
|
||||||
*/
|
*/
|
||||||
private static function cleanHTML(string $content, ?HTMLCleaner $cleaner = null): string
|
private static function cleanHTML(string $content, ?HTMLCleaner $cleaner = null): string
|
||||||
{
|
{
|
||||||
if (!$cleaner) {
|
if (!$cleaner) {
|
||||||
if (self::$html_cleaner_class && class_exists(self::$html_cleaner_class)) {
|
if (HtmlDiff::$html_cleaner_class && class_exists(HtmlDiff::$html_cleaner_class)) {
|
||||||
$cleaner = Injector::inst()->create(self::$html_cleaner_class);
|
$cleaner = Injector::inst()->create(HtmlDiff::$html_cleaner_class);
|
||||||
} else {
|
} else {
|
||||||
//load cleaner if the dependent class is available
|
//load cleaner if the dependent class is available
|
||||||
$cleaner = HTMLCleaner::inst();
|
$cleaner = HTMLCleaner::inst();
|
||||||
@ -284,9 +284,9 @@ class HtmlDiff
|
|||||||
|
|
||||||
private static function getDiffer(): Differ
|
private static function getDiffer(): Differ
|
||||||
{
|
{
|
||||||
if (!self::$differ) {
|
if (!HtmlDiff::$differ) {
|
||||||
self::$differ = new Differ();
|
HtmlDiff::$differ = new Differ();
|
||||||
}
|
}
|
||||||
return self::$differ;
|
return HtmlDiff::$differ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ class SQLFormatter
|
|||||||
protected function addNewlines($sql, $useHtmlFormatting = false)
|
protected function addNewlines($sql, $useHtmlFormatting = false)
|
||||||
{
|
{
|
||||||
$eol = PHP_EOL;
|
$eol = PHP_EOL;
|
||||||
foreach (self::$newline_before_tokens as $token) {
|
foreach (SQLFormatter::$newline_before_tokens as $token) {
|
||||||
$breakToken = ($useHtmlFormatting) ? "<br />$eol" : $eol;
|
$breakToken = ($useHtmlFormatting) ? "<br />$eol" : $eol;
|
||||||
$sql = preg_replace('/[^\n](' . $token . ')/', $breakToken . '$1', $sql ?? '');
|
$sql = preg_replace('/[^\n](' . $token . ')/', $breakToken . '$1', $sql ?? '');
|
||||||
}
|
}
|
||||||
|
@ -58,11 +58,11 @@ class ShortcodeParser
|
|||||||
*/
|
*/
|
||||||
public static function get($identifier = 'default')
|
public static function get($identifier = 'default')
|
||||||
{
|
{
|
||||||
if (!array_key_exists($identifier, self::$instances)) {
|
if (!array_key_exists($identifier, ShortcodeParser::$instances)) {
|
||||||
self::$instances[$identifier] = static::create();
|
ShortcodeParser::$instances[$identifier] = static::create();
|
||||||
}
|
}
|
||||||
|
|
||||||
return self::$instances[$identifier];
|
return ShortcodeParser::$instances[$identifier];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -72,7 +72,7 @@ class ShortcodeParser
|
|||||||
*/
|
*/
|
||||||
public static function get_active()
|
public static function get_active()
|
||||||
{
|
{
|
||||||
return static::get(self::$active_instance);
|
return static::get(ShortcodeParser::$active_instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -82,7 +82,7 @@ class ShortcodeParser
|
|||||||
*/
|
*/
|
||||||
public static function set_active($identifier)
|
public static function set_active($identifier)
|
||||||
{
|
{
|
||||||
self::$active_instance = (string) $identifier;
|
ShortcodeParser::$active_instance = (string) $identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------------------------
|
||||||
@ -192,7 +192,7 @@ class ShortcodeParser
|
|||||||
if ($content === false) {
|
if ($content === false) {
|
||||||
if (ShortcodeParser::$error_behavior == ShortcodeParser::ERROR) {
|
if (ShortcodeParser::$error_behavior == ShortcodeParser::ERROR) {
|
||||||
throw new \InvalidArgumentException('Unknown shortcode tag ' . $tag['open']);
|
throw new \InvalidArgumentException('Unknown shortcode tag ' . $tag['open']);
|
||||||
} elseif (self::$error_behavior == self::WARN && $isHTMLAllowed) {
|
} elseif (ShortcodeParser::$error_behavior == ShortcodeParser::WARN && $isHTMLAllowed) {
|
||||||
$content = '<strong class="warning">' . $tag['text'] . '</strong>';
|
$content = '<strong class="warning">' . $tag['text'] . '</strong>';
|
||||||
} elseif (ShortcodeParser::$error_behavior == ShortcodeParser::STRIP) {
|
} elseif (ShortcodeParser::$error_behavior == ShortcodeParser::STRIP) {
|
||||||
return '';
|
return '';
|
||||||
@ -271,7 +271,7 @@ class ShortcodeParser
|
|||||||
|
|
||||||
protected static function attrrx()
|
protected static function attrrx()
|
||||||
{
|
{
|
||||||
return '/' . self::$attrrx . '/xS';
|
return '/' . ShortcodeParser::$attrrx . '/xS';
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static $tagrx = '
|
protected static $tagrx = '
|
||||||
@ -296,7 +296,7 @@ class ShortcodeParser
|
|||||||
|
|
||||||
protected static function tagrx()
|
protected static function tagrx()
|
||||||
{
|
{
|
||||||
return '/' . sprintf(self::$tagrx, self::$attrrx) . '/xS';
|
return '/' . sprintf(ShortcodeParser::$tagrx, ShortcodeParser::$attrrx) . '/xS';
|
||||||
}
|
}
|
||||||
|
|
||||||
const WARN = 'warn';
|
const WARN = 'warn';
|
||||||
@ -304,7 +304,7 @@ class ShortcodeParser
|
|||||||
const LEAVE = 'leave';
|
const LEAVE = 'leave';
|
||||||
const ERROR = 'error';
|
const ERROR = 'error';
|
||||||
|
|
||||||
public static $error_behavior = self::LEAVE;
|
public static $error_behavior = ShortcodeParser::LEAVE;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -380,7 +380,7 @@ class ShortcodeParser
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($err) {
|
if ($err) {
|
||||||
if (self::$error_behavior == self::ERROR) {
|
if (ShortcodeParser::$error_behavior == ShortcodeParser::ERROR) {
|
||||||
throw new \Exception($err);
|
throw new \Exception($err);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -407,9 +407,9 @@ class ShortcodeParser
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Step 3: remove any tags that don't have handlers registered
|
// Step 3: remove any tags that don't have handlers registered
|
||||||
// Only do this if self::$error_behavior == self::LEAVE
|
// Only do this if ShortcodeParser::$error_behavior == ShortcodeParser::LEAVE
|
||||||
// This is optional but speeds things up.
|
// This is optional but speeds things up.
|
||||||
if (self::$error_behavior == self::LEAVE) {
|
if (ShortcodeParser::$error_behavior == ShortcodeParser::LEAVE) {
|
||||||
foreach ($tags as $i => $tag) {
|
foreach ($tags as $i => $tag) {
|
||||||
if (empty($this->shortcodes[$tag['open']])) {
|
if (empty($this->shortcodes[$tag['open']])) {
|
||||||
unset($tags[$i]);
|
unset($tags[$i]);
|
||||||
@ -497,7 +497,7 @@ class ShortcodeParser
|
|||||||
$tags = $this->extractTags($content);
|
$tags = $this->extractTags($content);
|
||||||
|
|
||||||
if ($tags) {
|
if ($tags) {
|
||||||
$markerClass = self::$marker_class;
|
$markerClass = ShortcodeParser::$marker_class;
|
||||||
|
|
||||||
$content = $this->replaceTagsWithText($content, $tags, function ($idx, $tag) use ($markerClass) {
|
$content = $this->replaceTagsWithText($content, $tags, function ($idx, $tag) use ($markerClass) {
|
||||||
return '<img class="' . $markerClass . '" data-tagid="' . $idx . '" />';
|
return '<img class="' . $markerClass . '" data-tagid="' . $idx . '" />';
|
||||||
@ -522,7 +522,7 @@ class ShortcodeParser
|
|||||||
do {
|
do {
|
||||||
$parent = $parent->parentNode;
|
$parent = $parent->parentNode;
|
||||||
} while ($parent instanceof DOMElement &&
|
} while ($parent instanceof DOMElement &&
|
||||||
!in_array(strtolower($parent->tagName ?? ''), self::$block_level_elements)
|
!in_array(strtolower($parent->tagName ?? ''), ShortcodeParser::$block_level_elements)
|
||||||
);
|
);
|
||||||
|
|
||||||
$node->setAttribute('data-parentid', count($parents ?? []));
|
$node->setAttribute('data-parentid', count($parents ?? []));
|
||||||
@ -566,14 +566,14 @@ class ShortcodeParser
|
|||||||
protected function moveMarkerToCompliantHome($node, $parent, $location)
|
protected function moveMarkerToCompliantHome($node, $parent, $location)
|
||||||
{
|
{
|
||||||
// Move before block parent
|
// Move before block parent
|
||||||
if ($location == self::BEFORE) {
|
if ($location == ShortcodeParser::BEFORE) {
|
||||||
if (isset($parent->parentNode)) {
|
if (isset($parent->parentNode)) {
|
||||||
$parent->parentNode->insertBefore($node, $parent);
|
$parent->parentNode->insertBefore($node, $parent);
|
||||||
}
|
}
|
||||||
} elseif ($location == self::AFTER) {
|
} elseif ($location == ShortcodeParser::AFTER) {
|
||||||
// Move after block parent
|
// Move after block parent
|
||||||
$this->insertAfter($node, $parent);
|
$this->insertAfter($node, $parent);
|
||||||
} elseif ($location == self::SPLIT) {
|
} elseif ($location == ShortcodeParser::SPLIT) {
|
||||||
// Split parent at node
|
// Split parent at node
|
||||||
$at = $node;
|
$at = $node;
|
||||||
$splitee = $node->parentNode;
|
$splitee = $node->parentNode;
|
||||||
@ -593,9 +593,9 @@ class ShortcodeParser
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->insertAfter($node, $parent);
|
$this->insertAfter($node, $parent);
|
||||||
} elseif ($location == self::INLINE) {
|
} elseif ($location == ShortcodeParser::INLINE) {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
if (in_array(strtolower($node->tagName ?? ''), self::$block_level_elements)) {
|
if (in_array(strtolower($node->tagName ?? ''), ShortcodeParser::$block_level_elements)) {
|
||||||
user_error(
|
user_error(
|
||||||
'Requested to insert block tag ' . $node->tagName . ' inline - probably this will break HTML compliance',
|
'Requested to insert block tag ' . $node->tagName . ' inline - probably this will break HTML compliance',
|
||||||
E_USER_WARNING
|
E_USER_WARNING
|
||||||
@ -661,7 +661,7 @@ class ShortcodeParser
|
|||||||
|
|
||||||
// Now parse the result into a DOM
|
// Now parse the result into a DOM
|
||||||
if (!$htmlvalue->isValid()) {
|
if (!$htmlvalue->isValid()) {
|
||||||
if (self::$error_behavior == self::ERROR) {
|
if (ShortcodeParser::$error_behavior == ShortcodeParser::ERROR) {
|
||||||
throw new \Exception('Couldn\'t decode HTML when processing short codes');
|
throw new \Exception('Couldn\'t decode HTML when processing short codes');
|
||||||
} else {
|
} else {
|
||||||
$continue = false;
|
$continue = false;
|
||||||
@ -674,7 +674,7 @@ class ShortcodeParser
|
|||||||
$this->replaceAttributeTagsWithContent($htmlvalue);
|
$this->replaceAttributeTagsWithContent($htmlvalue);
|
||||||
|
|
||||||
// Find all the element scoped shortcode markers
|
// Find all the element scoped shortcode markers
|
||||||
$shortcodes = $htmlvalue->query('//img[@class="' . self::$marker_class . '"]');
|
$shortcodes = $htmlvalue->query('//img[@class="' . ShortcodeParser::$marker_class . '"]');
|
||||||
|
|
||||||
// Find the parents. Do this before DOM modification, since SPLIT might cause parents to move otherwise
|
// Find the parents. Do this before DOM modification, since SPLIT might cause parents to move otherwise
|
||||||
$parents = $this->findParentsForMarkers($shortcodes);
|
$parents = $this->findParentsForMarkers($shortcodes);
|
||||||
@ -691,19 +691,19 @@ class ShortcodeParser
|
|||||||
$class = $tag['attrs']['class'];
|
$class = $tag['attrs']['class'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$location = self::INLINE;
|
$location = ShortcodeParser::INLINE;
|
||||||
if ($class == 'left' || $class == 'right') {
|
if ($class == 'left' || $class == 'right') {
|
||||||
$location = self::BEFORE;
|
$location = ShortcodeParser::BEFORE;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Below code disabled due to https://github.com/silverstripe/silverstripe-framework/issues/5987
|
* Below code disabled due to https://github.com/silverstripe/silverstripe-framework/issues/5987
|
||||||
if ($class == 'center' || $class == 'leftAlone') {
|
if ($class == 'center' || $class == 'leftAlone') {
|
||||||
$location = self::SPLIT;
|
$location = ShortcodeParser::SPLIT;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!$parent) {
|
if (!$parent) {
|
||||||
if ($location !== self::INLINE) {
|
if ($location !== ShortcodeParser::INLINE) {
|
||||||
throw new \RuntimeException(
|
throw new \RuntimeException(
|
||||||
"Parent block for shortcode couldn't be found, but location wasn't INLINE"
|
"Parent block for shortcode couldn't be found, but location wasn't INLINE"
|
||||||
);
|
);
|
||||||
@ -722,7 +722,7 @@ class ShortcodeParser
|
|||||||
$content = preg_replace_callback(
|
$content = preg_replace_callback(
|
||||||
// Not a general-case parser; assumes that the HTML generated in replaceElementTagsWithMarkers()
|
// Not a general-case parser; assumes that the HTML generated in replaceElementTagsWithMarkers()
|
||||||
// hasn't been heavily modified
|
// hasn't been heavily modified
|
||||||
'/<img[^>]+class="' . preg_quote(self::$marker_class) . '"[^>]+data-tagid="([^"]+)"[^>]*>/i',
|
'/<img[^>]+class="' . preg_quote(ShortcodeParser::$marker_class) . '"[^>]+data-tagid="([^"]+)"[^>]*>/i',
|
||||||
function ($matches) use ($tags, $parser) {
|
function ($matches) use ($tags, $parser) {
|
||||||
$tag = $tags[$matches[1]];
|
$tag = $tags[$matches[1]];
|
||||||
return $parser->getShortcodeReplacementText($tag);
|
return $parser->getShortcodeReplacementText($tag);
|
||||||
|
@ -31,7 +31,7 @@ class Requirements implements Flushable
|
|||||||
{
|
{
|
||||||
$disabled = Config::inst()->get(static::class, 'disable_flush_combined');
|
$disabled = Config::inst()->get(static::class, 'disable_flush_combined');
|
||||||
if (!$disabled) {
|
if (!$disabled) {
|
||||||
self::delete_all_combined_files();
|
Requirements::delete_all_combined_files();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ class Requirements implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function set_combined_files_enabled($enable)
|
public static function set_combined_files_enabled($enable)
|
||||||
{
|
{
|
||||||
self::backend()->setCombinedFilesEnabled($enable);
|
Requirements::backend()->setCombinedFilesEnabled($enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -52,7 +52,7 @@ class Requirements implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function get_combined_files_enabled()
|
public static function get_combined_files_enabled()
|
||||||
{
|
{
|
||||||
return self::backend()->getCombinedFilesEnabled();
|
return Requirements::backend()->getCombinedFilesEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -62,7 +62,7 @@ class Requirements implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function set_combined_files_folder($folder)
|
public static function set_combined_files_folder($folder)
|
||||||
{
|
{
|
||||||
self::backend()->setCombinedFilesFolder($folder);
|
Requirements::backend()->setCombinedFilesFolder($folder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -75,7 +75,7 @@ class Requirements implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function set_suffix_requirements($var)
|
public static function set_suffix_requirements($var)
|
||||||
{
|
{
|
||||||
self::backend()->setSuffixRequirements($var);
|
Requirements::backend()->setSuffixRequirements($var);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -85,7 +85,7 @@ class Requirements implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function get_suffix_requirements()
|
public static function get_suffix_requirements()
|
||||||
{
|
{
|
||||||
return self::backend()->getSuffixRequirements();
|
return Requirements::backend()->getSuffixRequirements();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -101,10 +101,10 @@ class Requirements implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function backend()
|
public static function backend()
|
||||||
{
|
{
|
||||||
if (!self::$backend) {
|
if (!Requirements::$backend) {
|
||||||
self::$backend = Requirements_Backend::create();
|
Requirements::$backend = Requirements_Backend::create();
|
||||||
}
|
}
|
||||||
return self::$backend;
|
return Requirements::$backend;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -114,7 +114,7 @@ class Requirements implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function set_backend(Requirements_Backend $backend)
|
public static function set_backend(Requirements_Backend $backend)
|
||||||
{
|
{
|
||||||
self::$backend = $backend;
|
Requirements::$backend = $backend;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -128,7 +128,7 @@ class Requirements implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function javascript($file, $options = [])
|
public static function javascript($file, $options = [])
|
||||||
{
|
{
|
||||||
self::backend()->javascript($file, $options);
|
Requirements::backend()->javascript($file, $options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -139,7 +139,7 @@ class Requirements implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function customScript($script, $uniquenessID = null)
|
public static function customScript($script, $uniquenessID = null)
|
||||||
{
|
{
|
||||||
self::backend()->customScript($script, $uniquenessID);
|
Requirements::backend()->customScript($script, $uniquenessID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -154,7 +154,7 @@ class Requirements implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function customScriptWithAttributes(string $script, array $options = [], string|int|null $uniquenessID = null)
|
public static function customScriptWithAttributes(string $script, array $options = [], string|int|null $uniquenessID = null)
|
||||||
{
|
{
|
||||||
self::backend()->customScriptWithAttributes($script, $options, $uniquenessID);
|
Requirements::backend()->customScriptWithAttributes($script, $options, $uniquenessID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -164,7 +164,7 @@ class Requirements implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function get_custom_scripts()
|
public static function get_custom_scripts()
|
||||||
{
|
{
|
||||||
return self::backend()->getCustomScripts();
|
return Requirements::backend()->getCustomScripts();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -175,7 +175,7 @@ class Requirements implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function customCSS($script, $uniquenessID = null)
|
public static function customCSS($script, $uniquenessID = null)
|
||||||
{
|
{
|
||||||
self::backend()->customCSS($script, $uniquenessID);
|
Requirements::backend()->customCSS($script, $uniquenessID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -186,7 +186,7 @@ class Requirements implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function insertHeadTags($html, $uniquenessID = null)
|
public static function insertHeadTags($html, $uniquenessID = null)
|
||||||
{
|
{
|
||||||
self::backend()->insertHeadTags($html, $uniquenessID);
|
Requirements::backend()->insertHeadTags($html, $uniquenessID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -199,7 +199,7 @@ class Requirements implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function javascriptTemplate($file, $vars, $uniquenessID = null)
|
public static function javascriptTemplate($file, $vars, $uniquenessID = null)
|
||||||
{
|
{
|
||||||
self::backend()->javascriptTemplate($file, $vars, $uniquenessID);
|
Requirements::backend()->javascriptTemplate($file, $vars, $uniquenessID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -214,7 +214,7 @@ class Requirements implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function css($file, $media = null, $options = [])
|
public static function css($file, $media = null, $options = [])
|
||||||
{
|
{
|
||||||
self::backend()->css($file, $media, $options);
|
Requirements::backend()->css($file, $media, $options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -230,7 +230,7 @@ class Requirements implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function themedCSS($name, $media = null)
|
public static function themedCSS($name, $media = null)
|
||||||
{
|
{
|
||||||
self::backend()->themedCSS($name, $media);
|
Requirements::backend()->themedCSS($name, $media);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -246,7 +246,7 @@ class Requirements implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function themedJavascript($name, $type = null)
|
public static function themedJavascript($name, $type = null)
|
||||||
{
|
{
|
||||||
self::backend()->themedJavascript($name, $type);
|
Requirements::backend()->themedJavascript($name, $type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -259,7 +259,7 @@ class Requirements implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function clear($fileOrID = null)
|
public static function clear($fileOrID = null)
|
||||||
{
|
{
|
||||||
self::backend()->clear($fileOrID);
|
Requirements::backend()->clear($fileOrID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -267,7 +267,7 @@ class Requirements implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function restore()
|
public static function restore()
|
||||||
{
|
{
|
||||||
self::backend()->restore();
|
Requirements::backend()->restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -285,7 +285,7 @@ class Requirements implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function block($fileOrID)
|
public static function block($fileOrID)
|
||||||
{
|
{
|
||||||
self::backend()->block($fileOrID);
|
Requirements::backend()->block($fileOrID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -295,7 +295,7 @@ class Requirements implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function unblock($fileOrID)
|
public static function unblock($fileOrID)
|
||||||
{
|
{
|
||||||
self::backend()->unblock($fileOrID);
|
Requirements::backend()->unblock($fileOrID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -303,7 +303,7 @@ class Requirements implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function unblock_all()
|
public static function unblock_all()
|
||||||
{
|
{
|
||||||
self::backend()->unblockAll();
|
Requirements::backend()->unblockAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -317,7 +317,7 @@ class Requirements implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function includeInHTML($content)
|
public static function includeInHTML($content)
|
||||||
{
|
{
|
||||||
return self::backend()->includeInHTML($content);
|
return Requirements::backend()->includeInHTML($content);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -328,7 +328,7 @@ class Requirements implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function include_in_response(HTTPResponse $response)
|
public static function include_in_response(HTTPResponse $response)
|
||||||
{
|
{
|
||||||
self::backend()->includeInResponse($response);
|
Requirements::backend()->includeInResponse($response);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -345,7 +345,7 @@ class Requirements implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function add_i18n_javascript($langDir, $return = false)
|
public static function add_i18n_javascript($langDir, $return = false)
|
||||||
{
|
{
|
||||||
return self::backend()->add_i18n_javascript($langDir, $return);
|
return Requirements::backend()->add_i18n_javascript($langDir, $return);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -399,7 +399,7 @@ class Requirements implements Flushable
|
|||||||
if (is_string($options)) {
|
if (is_string($options)) {
|
||||||
throw new InvalidArgumentException("Invalid $options");
|
throw new InvalidArgumentException("Invalid $options");
|
||||||
}
|
}
|
||||||
self::backend()->combineFiles($combinedFileName, $files, $options);
|
Requirements::backend()->combineFiles($combinedFileName, $files, $options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -411,7 +411,7 @@ class Requirements implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function get_combine_files()
|
public static function get_combine_files()
|
||||||
{
|
{
|
||||||
return self::backend()->getCombinedFiles();
|
return Requirements::backend()->getCombinedFiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -420,7 +420,7 @@ class Requirements implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function delete_all_combined_files()
|
public static function delete_all_combined_files()
|
||||||
{
|
{
|
||||||
self::backend()->deleteAllCombinedFiles();
|
Requirements::backend()->deleteAllCombinedFiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -428,7 +428,7 @@ class Requirements implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function clear_combined_files()
|
public static function clear_combined_files()
|
||||||
{
|
{
|
||||||
self::backend()->clearCombinedFiles();
|
Requirements::backend()->clearCombinedFiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -436,7 +436,7 @@ class Requirements implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function process_combined_files()
|
public static function process_combined_files()
|
||||||
{
|
{
|
||||||
self::backend()->processCombinedFiles();
|
Requirements::backend()->processCombinedFiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -447,7 +447,7 @@ class Requirements implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function get_write_js_to_body()
|
public static function get_write_js_to_body()
|
||||||
{
|
{
|
||||||
return self::backend()->getWriteJavascriptToBody();
|
return Requirements::backend()->getWriteJavascriptToBody();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -458,7 +458,7 @@ class Requirements implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function set_write_js_to_body($var)
|
public static function set_write_js_to_body($var)
|
||||||
{
|
{
|
||||||
self::backend()->setWriteJavascriptToBody($var);
|
Requirements::backend()->setWriteJavascriptToBody($var);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -469,7 +469,7 @@ class Requirements implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function get_force_js_to_bottom()
|
public static function get_force_js_to_bottom()
|
||||||
{
|
{
|
||||||
return self::backend()->getForceJSToBottom();
|
return Requirements::backend()->getForceJSToBottom();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -480,7 +480,7 @@ class Requirements implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function set_force_js_to_bottom($var)
|
public static function set_force_js_to_bottom($var)
|
||||||
{
|
{
|
||||||
self::backend()->setForceJSToBottom($var);
|
Requirements::backend()->setForceJSToBottom($var);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -490,7 +490,7 @@ class Requirements implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function get_minify_combined_js_files()
|
public static function get_minify_combined_js_files()
|
||||||
{
|
{
|
||||||
return self::backend()->getMinifyCombinedJSFiles();
|
return Requirements::backend()->getMinifyCombinedJSFiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -500,7 +500,7 @@ class Requirements implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function set_minify_combined_js_files($minify)
|
public static function set_minify_combined_js_files($minify)
|
||||||
{
|
{
|
||||||
self::backend()->setMinifyCombinedJSFiles($minify);
|
Requirements::backend()->setMinifyCombinedJSFiles($minify);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -510,7 +510,7 @@ class Requirements implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function get_write_header_comments()
|
public static function get_write_header_comments()
|
||||||
{
|
{
|
||||||
return self::backend()->getWriteHeaderComment();
|
return Requirements::backend()->getWriteHeaderComment();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -520,7 +520,7 @@ class Requirements implements Flushable
|
|||||||
*/
|
*/
|
||||||
public function set_write_header_comments($write)
|
public function set_write_header_comments($write)
|
||||||
{
|
{
|
||||||
self::backend()->setWriteHeaderComment($write);
|
Requirements::backend()->setWriteHeaderComment($write);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -529,6 +529,6 @@ class Requirements implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function debug()
|
public static function debug()
|
||||||
{
|
{
|
||||||
self::backend()->debug();
|
Requirements::backend()->debug();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -194,7 +194,7 @@ class SSViewer implements Flushable
|
|||||||
$message = 'None of the following templates could be found: ';
|
$message = 'None of the following templates could be found: ';
|
||||||
$message .= print_r($templates, true);
|
$message .= print_r($templates, true);
|
||||||
|
|
||||||
$themes = self::get_themes();
|
$themes = SSViewer::get_themes();
|
||||||
if (!$themes) {
|
if (!$themes) {
|
||||||
$message .= ' (no theme in use)';
|
$message .= ' (no theme in use)';
|
||||||
} else {
|
} else {
|
||||||
@ -210,8 +210,8 @@ class SSViewer implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function flush()
|
public static function flush()
|
||||||
{
|
{
|
||||||
self::flush_template_cache(true);
|
SSViewer::flush_template_cache(true);
|
||||||
self::flush_cacheblock_cache(true);
|
SSViewer::flush_cacheblock_cache(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -261,7 +261,7 @@ class SSViewer implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function get_themes()
|
public static function get_themes()
|
||||||
{
|
{
|
||||||
$default = [self::PUBLIC_THEME, self::DEFAULT_THEME];
|
$default = [SSViewer::PUBLIC_THEME, SSViewer::DEFAULT_THEME];
|
||||||
|
|
||||||
if (!SSViewer::config()->uninherited('theme_enabled')) {
|
if (!SSViewer::config()->uninherited('theme_enabled')) {
|
||||||
return $default;
|
return $default;
|
||||||
@ -401,7 +401,7 @@ class SSViewer implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function chooseTemplate($templates)
|
public static function chooseTemplate($templates)
|
||||||
{
|
{
|
||||||
return ThemeResourceLoader::inst()->findTemplate($templates, self::get_themes());
|
return ThemeResourceLoader::inst()->findTemplate($templates, SSViewer::get_themes());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -436,7 +436,7 @@ class SSViewer implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function hasTemplate($templates)
|
public static function hasTemplate($templates)
|
||||||
{
|
{
|
||||||
return (bool)ThemeResourceLoader::inst()->findTemplate($templates, self::get_themes());
|
return (bool)ThemeResourceLoader::inst()->findTemplate($templates, SSViewer::get_themes());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -465,7 +465,7 @@ class SSViewer implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function getTemplateFileByType($identifier, $type = null)
|
public static function getTemplateFileByType($identifier, $type = null)
|
||||||
{
|
{
|
||||||
return ThemeResourceLoader::inst()->findTemplate(['type' => $type, $identifier], self::get_themes());
|
return ThemeResourceLoader::inst()->findTemplate(['type' => $type, $identifier], SSViewer::get_themes());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -478,14 +478,14 @@ class SSViewer implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function flush_template_cache($force = false)
|
public static function flush_template_cache($force = false)
|
||||||
{
|
{
|
||||||
if (!self::$template_cache_flushed || $force) {
|
if (!SSViewer::$template_cache_flushed || $force) {
|
||||||
$dir = dir(TEMP_PATH);
|
$dir = dir(TEMP_PATH);
|
||||||
while (false !== ($file = $dir->read())) {
|
while (false !== ($file = $dir->read())) {
|
||||||
if (strstr($file ?? '', '.cache')) {
|
if (strstr($file ?? '', '.cache')) {
|
||||||
unlink(TEMP_PATH . DIRECTORY_SEPARATOR . $file);
|
unlink(TEMP_PATH . DIRECTORY_SEPARATOR . $file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self::$template_cache_flushed = true;
|
SSViewer::$template_cache_flushed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -499,12 +499,12 @@ class SSViewer implements Flushable
|
|||||||
*/
|
*/
|
||||||
public static function flush_cacheblock_cache($force = false)
|
public static function flush_cacheblock_cache($force = false)
|
||||||
{
|
{
|
||||||
if (!self::$cacheblock_cache_flushed || $force) {
|
if (!SSViewer::$cacheblock_cache_flushed || $force) {
|
||||||
$cache = Injector::inst()->get(CacheInterface::class . '.cacheblock');
|
$cache = Injector::inst()->get(CacheInterface::class . '.cacheblock');
|
||||||
$cache->clear();
|
$cache->clear();
|
||||||
|
|
||||||
|
|
||||||
self::$cacheblock_cache_flushed = true;
|
SSViewer::$cacheblock_cache_flushed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,11 +79,11 @@ class SSViewer_DataPresenter extends SSViewer_Scope
|
|||||||
*/
|
*/
|
||||||
protected function cacheGlobalProperties()
|
protected function cacheGlobalProperties()
|
||||||
{
|
{
|
||||||
if (self::$globalProperties !== null) {
|
if (SSViewer_DataPresenter::$globalProperties !== null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
self::$globalProperties = $this->getPropertiesFromProvider(
|
SSViewer_DataPresenter::$globalProperties = $this->getPropertiesFromProvider(
|
||||||
TemplateGlobalProvider::class,
|
TemplateGlobalProvider::class,
|
||||||
'get_template_global_variables'
|
'get_template_global_variables'
|
||||||
);
|
);
|
||||||
@ -94,11 +94,11 @@ class SSViewer_DataPresenter extends SSViewer_Scope
|
|||||||
*/
|
*/
|
||||||
protected function cacheIteratorProperties()
|
protected function cacheIteratorProperties()
|
||||||
{
|
{
|
||||||
if (self::$iteratorProperties !== null) {
|
if (SSViewer_DataPresenter::$iteratorProperties !== null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
self::$iteratorProperties = $this->getPropertiesFromProvider(
|
SSViewer_DataPresenter::$iteratorProperties = $this->getPropertiesFromProvider(
|
||||||
TemplateIteratorProvider::class,
|
TemplateIteratorProvider::class,
|
||||||
'get_template_iterator_variables',
|
'get_template_iterator_variables',
|
||||||
true // Call non-statically
|
true // Call non-statically
|
||||||
@ -388,8 +388,8 @@ class SSViewer_DataPresenter extends SSViewer_Scope
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Then for iterator-specific overrides
|
// Then for iterator-specific overrides
|
||||||
if (array_key_exists($property, self::$iteratorProperties)) {
|
if (array_key_exists($property, SSViewer_DataPresenter::$iteratorProperties)) {
|
||||||
$source = self::$iteratorProperties[$property];
|
$source = SSViewer_DataPresenter::$iteratorProperties[$property];
|
||||||
/** @var TemplateIteratorProvider $implementor */
|
/** @var TemplateIteratorProvider $implementor */
|
||||||
$implementor = $source['implementor'];
|
$implementor = $source['implementor'];
|
||||||
if ($this->itemIterator) {
|
if ($this->itemIterator) {
|
||||||
@ -408,9 +408,9 @@ class SSViewer_DataPresenter extends SSViewer_Scope
|
|||||||
}
|
}
|
||||||
|
|
||||||
// And finally for global overrides
|
// And finally for global overrides
|
||||||
if (array_key_exists($property, self::$globalProperties)) {
|
if (array_key_exists($property, SSViewer_DataPresenter::$globalProperties)) {
|
||||||
return [
|
return [
|
||||||
'source' => self::$globalProperties[$property] // get the method call
|
'source' => SSViewer_DataPresenter::$globalProperties[$property] // get the method call
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,7 +136,7 @@ class SSViewer_Scope
|
|||||||
/**
|
/**
|
||||||
* Called at the start of every lookup chain by SSTemplateParser to indicate a new lookup from local scope
|
* Called at the start of every lookup chain by SSTemplateParser to indicate a new lookup from local scope
|
||||||
*
|
*
|
||||||
* @return self
|
* @return SSViewer_Scope
|
||||||
*/
|
*/
|
||||||
public function locally()
|
public function locally()
|
||||||
{
|
{
|
||||||
@ -258,7 +258,7 @@ class SSViewer_Scope
|
|||||||
/**
|
/**
|
||||||
* Jump to the last item in the stack, called when a new item is added before a loop/with
|
* Jump to the last item in the stack, called when a new item is added before a loop/with
|
||||||
*
|
*
|
||||||
* @return self
|
* @return SSViewer_Scope
|
||||||
*/
|
*/
|
||||||
public function pushScope()
|
public function pushScope()
|
||||||
{
|
{
|
||||||
@ -280,7 +280,7 @@ class SSViewer_Scope
|
|||||||
/**
|
/**
|
||||||
* Jump back to "previous" item in the stack, called after a loop/with block
|
* Jump back to "previous" item in the stack, called after a loop/with block
|
||||||
*
|
*
|
||||||
* @return self
|
* @return SSViewer_Scope
|
||||||
*/
|
*/
|
||||||
public function popScope()
|
public function popScope()
|
||||||
{
|
{
|
||||||
|
@ -200,7 +200,7 @@ class EmbedShortcodeProvider implements ShortcodeHandler
|
|||||||
'Content' => DBField::create_field('HTMLFragment', $content)
|
'Content' => DBField::create_field('HTMLFragment', $content)
|
||||||
];
|
];
|
||||||
|
|
||||||
return ArrayData::create($data)->renderWith(self::class . '_video')->forTemplate();
|
return ArrayData::create($data)->renderWith(EmbedShortcodeProvider::class . '_video')->forTemplate();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -220,7 +220,7 @@ class EmbedShortcodeProvider implements ShortcodeHandler
|
|||||||
'Title' => !empty($arguments['caption']) ? ($arguments['caption']) : $title
|
'Title' => !empty($arguments['caption']) ? ($arguments['caption']) : $title
|
||||||
];
|
];
|
||||||
|
|
||||||
return ArrayData::create($data)->renderWith(self::class . '_link')->forTemplate();
|
return ArrayData::create($data)->renderWith(EmbedShortcodeProvider::class . '_link')->forTemplate();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -238,7 +238,7 @@ class EmbedShortcodeProvider implements ShortcodeHandler
|
|||||||
'Src' => $src
|
'Src' => $src
|
||||||
];
|
];
|
||||||
|
|
||||||
return ArrayData::create($data)->renderWith(self::class . '_photo')->forTemplate();
|
return ArrayData::create($data)->renderWith(EmbedShortcodeProvider::class . '_photo')->forTemplate();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -327,10 +327,10 @@ class EmbedShortcodeProvider implements ShortcodeHandler
|
|||||||
{
|
{
|
||||||
return implode('-', array_filter([
|
return implode('-', array_filter([
|
||||||
'embed-shortcode',
|
'embed-shortcode',
|
||||||
self::cleanKeySegment($url),
|
EmbedShortcodeProvider::cleanKeySegment($url),
|
||||||
self::cleanKeySegment($class),
|
EmbedShortcodeProvider::cleanKeySegment($class),
|
||||||
self::cleanKeySegment($width),
|
EmbedShortcodeProvider::cleanKeySegment($width),
|
||||||
self::cleanKeySegment($height)
|
EmbedShortcodeProvider::cleanKeySegment($height)
|
||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,7 +161,7 @@ class ThemeManifest implements ThemeList
|
|||||||
*/
|
*/
|
||||||
public function handleDirectory($basename, $pathname, $depth)
|
public function handleDirectory($basename, $pathname, $depth)
|
||||||
{
|
{
|
||||||
if ($basename !== self::TEMPLATES_DIR) {
|
if ($basename !== ThemeManifest::TEMPLATES_DIR) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$dir = trim(substr(dirname($pathname ?? ''), strlen($this->base ?? '')), '/\\');
|
$dir = trim(substr(dirname($pathname ?? ''), strlen($this->base ?? '')), '/\\');
|
||||||
|
@ -46,7 +46,7 @@ class ThemeResourceLoader implements Flushable, TemplateGlobalProvider
|
|||||||
*/
|
*/
|
||||||
public static function inst()
|
public static function inst()
|
||||||
{
|
{
|
||||||
return self::$instance ? self::$instance : self::$instance = new self();
|
return ThemeResourceLoader::$instance ? ThemeResourceLoader::$instance : ThemeResourceLoader::$instance = new ThemeResourceLoader();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -56,7 +56,7 @@ class ThemeResourceLoader implements Flushable, TemplateGlobalProvider
|
|||||||
*/
|
*/
|
||||||
public static function set_instance(ThemeResourceLoader $instance)
|
public static function set_instance(ThemeResourceLoader $instance)
|
||||||
{
|
{
|
||||||
self::$instance = $instance;
|
ThemeResourceLoader::$instance = $instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __construct($base = null)
|
public function __construct($base = null)
|
||||||
@ -390,7 +390,7 @@ class ThemeResourceLoader implements Flushable, TemplateGlobalProvider
|
|||||||
*/
|
*/
|
||||||
public static function flush()
|
public static function flush()
|
||||||
{
|
{
|
||||||
self::inst()->getCache()->clear();
|
ThemeResourceLoader::inst()->getCache()->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -267,7 +267,7 @@ class ViewableData implements IteratorAggregate
|
|||||||
return $this->hasCustomMethod($method);
|
return $this->hasCustomMethod($method);
|
||||||
}
|
}
|
||||||
// All methods defined on ViewableData are accessible to ViewableData
|
// All methods defined on ViewableData are accessible to ViewableData
|
||||||
if (static::class === self::class) {
|
if (static::class === ViewableData::class) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// Private methods defined on subclasses are not accessible to ViewableData
|
// Private methods defined on subclasses are not accessible to ViewableData
|
||||||
@ -284,7 +284,7 @@ class ViewableData implements IteratorAggregate
|
|||||||
if (!property_exists($this, $property)) {
|
if (!property_exists($this, $property)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (static::class === self::class) {
|
if (static::class === ViewableData::class) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
$reflectionProperty = new ReflectionProperty($this, $property);
|
$reflectionProperty = new ReflectionProperty($this, $property);
|
||||||
@ -665,7 +665,7 @@ class ViewableData implements IteratorAggregate
|
|||||||
*/
|
*/
|
||||||
public function getViewerTemplates($suffix = '')
|
public function getViewerTemplates($suffix = '')
|
||||||
{
|
{
|
||||||
return SSViewer::get_templates_by_class(static::class, $suffix, self::class);
|
return SSViewer::get_templates_by_class(static::class, $suffix, ViewableData::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -689,7 +689,7 @@ class ViewableData implements IteratorAggregate
|
|||||||
* @return string
|
* @return string
|
||||||
* @uses ClassInfo
|
* @uses ClassInfo
|
||||||
*/
|
*/
|
||||||
public function CSSClasses($stopAtClass = self::class)
|
public function CSSClasses($stopAtClass = ViewableData::class)
|
||||||
{
|
{
|
||||||
$classes = [];
|
$classes = [];
|
||||||
$classAncestry = array_reverse(ClassInfo::ancestry(static::class) ?? []);
|
$classAncestry = array_reverse(ClassInfo::ancestry(static::class) ?? []);
|
||||||
|
@ -474,7 +474,7 @@ class i18nTextCollector
|
|||||||
if (!empty($themes)) {
|
if (!empty($themes)) {
|
||||||
foreach ($themes as $theme) {
|
foreach ($themes as $theme) {
|
||||||
if (is_dir(Path::join(THEMES_PATH, $theme))) {
|
if (is_dir(Path::join(THEMES_PATH, $theme))) {
|
||||||
$modules[self::THEME_PREFIX . $theme] = new Module(Path::join(THEMES_PATH, $theme), BASE_PATH);
|
$modules[i18nTextCollector::THEME_PREFIX . $theme] = new Module(Path::join(THEMES_PATH, $theme), BASE_PATH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -488,7 +488,7 @@ class i18nTextCollector
|
|||||||
*/
|
*/
|
||||||
private function getModuleName(string $origName, Module $module): string
|
private function getModuleName(string $origName, Module $module): string
|
||||||
{
|
{
|
||||||
return strpos($origName, self::THEME_PREFIX) === 0 ? $origName : $module->getName();
|
return strpos($origName, i18nTextCollector::THEME_PREFIX) === 0 ? $origName : $module->getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -558,7 +558,7 @@ class i18nTextCollector
|
|||||||
$modulePath = $module->getPath();
|
$modulePath = $module->getPath();
|
||||||
|
|
||||||
// Search all .ss files in themes
|
// Search all .ss files in themes
|
||||||
if (stripos($module->getRelativePath() ?? '', self::THEME_PREFIX) === 0) {
|
if (stripos($module->getRelativePath() ?? '', i18nTextCollector::THEME_PREFIX) === 0) {
|
||||||
return $this->getFilesRecursive($modulePath, null, 'ss');
|
return $this->getFilesRecursive($modulePath, null, 'ss');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -608,7 +608,7 @@ class i18nTextCollector
|
|||||||
$inClass = false; // after `class` but before `{`
|
$inClass = false; // after `class` but before `{`
|
||||||
$inUse = false; // pulling in classes from other namespaces
|
$inUse = false; // pulling in classes from other namespaces
|
||||||
$inArrayClosedBy = false; // Set to the expected closing token, or false if not in array
|
$inArrayClosedBy = false; // Set to the expected closing token, or false if not in array
|
||||||
$inSelf = false; // Tracks progress of collecting self::class
|
$inSelf = false; // Tracks progress of collecting i18nTextCollector::class
|
||||||
$currentEntity = [];
|
$currentEntity = [];
|
||||||
$currentNameSpace = []; // The actual namespace for the current class
|
$currentNameSpace = []; // The actual namespace for the current class
|
||||||
$currentClass = []; // Class components
|
$currentClass = []; // Class components
|
||||||
@ -677,7 +677,7 @@ class i18nTextCollector
|
|||||||
// Skip if previous token was '::'. E.g. 'Object::class'
|
// Skip if previous token was '::'. E.g. 'Object::class'
|
||||||
if (is_array($previousToken) && $previousToken[0] === T_DOUBLE_COLON) {
|
if (is_array($previousToken) && $previousToken[0] === T_DOUBLE_COLON) {
|
||||||
if ($inSelf) {
|
if ($inSelf) {
|
||||||
// Handle self::class by allowing logic further down
|
// Handle i18nTextCollector::class by allowing logic further down
|
||||||
// for __CLASS__/__TRAIT__ to handle an array of class parts
|
// for __CLASS__/__TRAIT__ to handle an array of class parts
|
||||||
$id = $id === T_TRAIT ? T_TRAIT_C : T_CLASS_C;
|
$id = $id === T_TRAIT ? T_TRAIT_C : T_CLASS_C;
|
||||||
$inSelf = false;
|
$inSelf = false;
|
||||||
@ -741,7 +741,7 @@ class i18nTextCollector
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start collecting self::class declarations
|
// Start collecting i18nTextCollector::class declarations
|
||||||
if ($id === T_STRING && $text === 'self') {
|
if ($id === T_STRING && $text === 'self') {
|
||||||
$inSelf = true;
|
$inSelf = true;
|
||||||
continue;
|
continue;
|
||||||
@ -770,7 +770,7 @@ class i18nTextCollector
|
|||||||
throw new LogicException("Invalid string escape: " . $text);
|
throw new LogicException("Invalid string escape: " . $text);
|
||||||
}
|
}
|
||||||
} elseif ($id === T_CLASS_C || $id === T_TRAIT_C) {
|
} elseif ($id === T_CLASS_C || $id === T_TRAIT_C) {
|
||||||
// Evaluate __CLASS__ . '.KEY' and self::class concatenation
|
// Evaluate __CLASS__ . '.KEY' and i18nTextCollector::class concatenation
|
||||||
$text = implode('\\', $currentClass);
|
$text = implode('\\', $currentClass);
|
||||||
} else {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
|
@ -264,7 +264,7 @@ class i18n implements TemplateGlobalProvider
|
|||||||
public static function get_closest_translation($locale)
|
public static function get_closest_translation($locale)
|
||||||
{
|
{
|
||||||
// Check if exact match
|
// Check if exact match
|
||||||
$pool = self::getSources()->getKnownLocales();
|
$pool = i18n::getSources()->getKnownLocales();
|
||||||
if (isset($pool[$locale])) {
|
if (isset($pool[$locale])) {
|
||||||
return $locale;
|
return $locale;
|
||||||
}
|
}
|
||||||
@ -308,7 +308,7 @@ class i18n implements TemplateGlobalProvider
|
|||||||
public static function set_locale($locale)
|
public static function set_locale($locale)
|
||||||
{
|
{
|
||||||
if ($locale) {
|
if ($locale) {
|
||||||
self::$current_locale = $locale;
|
i18n::$current_locale = $locale;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,7 +321,7 @@ class i18n implements TemplateGlobalProvider
|
|||||||
*/
|
*/
|
||||||
public static function with_locale($locale, $callback)
|
public static function with_locale($locale, $callback)
|
||||||
{
|
{
|
||||||
$oldLocale = self::$current_locale;
|
$oldLocale = i18n::$current_locale;
|
||||||
static::set_locale($locale);
|
static::set_locale($locale);
|
||||||
try {
|
try {
|
||||||
return $callback();
|
return $callback();
|
||||||
@ -338,10 +338,10 @@ class i18n implements TemplateGlobalProvider
|
|||||||
*/
|
*/
|
||||||
public static function get_locale()
|
public static function get_locale()
|
||||||
{
|
{
|
||||||
if (!self::$current_locale) {
|
if (!i18n::$current_locale) {
|
||||||
self::$current_locale = i18n::config()->uninherited('default_locale');
|
i18n::$current_locale = i18n::config()->uninherited('default_locale');
|
||||||
}
|
}
|
||||||
return self::$current_locale;
|
return i18n::$current_locale;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -11,6 +11,6 @@ class TestFlushable implements Flushable, TestOnly
|
|||||||
|
|
||||||
public static function flush()
|
public static function flush()
|
||||||
{
|
{
|
||||||
self::$flushed = true;
|
TestFlushable::$flushed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,8 +100,8 @@ class RSSFeedTest extends SapphireTest
|
|||||||
{
|
{
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
Config::modify()->set(Director::class, 'alternate_base_url', '/');
|
Config::modify()->set(Director::class, 'alternate_base_url', '/');
|
||||||
if (!self::$original_host) {
|
if (!RSSFeedTest::$original_host) {
|
||||||
self::$original_host = $_SERVER['HTTP_HOST'];
|
RSSFeedTest::$original_host = $_SERVER['HTTP_HOST'];
|
||||||
}
|
}
|
||||||
$_SERVER['HTTP_HOST'] = 'www.example.org';
|
$_SERVER['HTTP_HOST'] = 'www.example.org';
|
||||||
|
|
||||||
@ -116,6 +116,6 @@ class RSSFeedTest extends SapphireTest
|
|||||||
protected function tearDown(): void
|
protected function tearDown(): void
|
||||||
{
|
{
|
||||||
parent::tearDown();
|
parent::tearDown();
|
||||||
$_SERVER['HTTP_HOST'] = self::$original_host;
|
$_SERVER['HTTP_HOST'] = RSSFeedTest::$original_host;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ class ControllerExtension extends Extension implements TestOnly
|
|||||||
*/
|
*/
|
||||||
public function onBeforeHTTPError()
|
public function onBeforeHTTPError()
|
||||||
{
|
{
|
||||||
self::$called_error = true;
|
ControllerExtension::$called_error = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -35,6 +35,6 @@ class ControllerExtension extends Extension implements TestOnly
|
|||||||
*/
|
*/
|
||||||
public function onBeforeHTTPError404()
|
public function onBeforeHTTPError404()
|
||||||
{
|
{
|
||||||
self::$called_404_error = true;
|
ControllerExtension::$called_404_error = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,11 +22,11 @@ class Controller1 extends Controller
|
|||||||
|
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
echo self::OK_MSG;
|
echo Controller1::OK_MSG;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function y1Action()
|
public function y1Action()
|
||||||
{
|
{
|
||||||
echo self::OK_MSG;
|
echo Controller1::OK_MSG;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ class ControllerWithPermissions extends Controller implements PermissionProvider
|
|||||||
|
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
echo self::OK_MSG;
|
echo ControllerWithPermissions::OK_MSG;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function canInit()
|
public function canInit()
|
||||||
|
@ -32,7 +32,7 @@ class DataProvider implements TestOnly
|
|||||||
[],
|
[],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
self::provideEqualLists()
|
DataProvider::provideEqualLists()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,34 +46,34 @@ class DataProvider implements TestOnly
|
|||||||
[
|
[
|
||||||
['FirstName' => 'Ingo'],
|
['FirstName' => 'Ingo'],
|
||||||
],
|
],
|
||||||
self::$oneItemList,
|
DataProvider::$oneItemList,
|
||||||
],
|
],
|
||||||
'twoParametersOneItem' => [
|
'twoParametersOneItem' => [
|
||||||
[
|
[
|
||||||
['FirstName' => 'Ingo', 'Surname' => 'Schommer'],
|
['FirstName' => 'Ingo', 'Surname' => 'Schommer'],
|
||||||
],
|
],
|
||||||
self::$oneItemList,
|
DataProvider::$oneItemList,
|
||||||
],
|
],
|
||||||
'oneParameterTwoItems' => [
|
'oneParameterTwoItems' => [
|
||||||
[
|
[
|
||||||
['FirstName' => 'Ingo'],
|
['FirstName' => 'Ingo'],
|
||||||
['FirstName' => 'Sam'],
|
['FirstName' => 'Sam'],
|
||||||
],
|
],
|
||||||
self::$twoItemList,
|
DataProvider::$twoItemList,
|
||||||
],
|
],
|
||||||
'twoParametersTwoItems' => [
|
'twoParametersTwoItems' => [
|
||||||
[
|
[
|
||||||
['FirstName' => 'Ingo', 'Surname' => 'Schommer'],
|
['FirstName' => 'Ingo', 'Surname' => 'Schommer'],
|
||||||
['FirstName' => 'Sam', 'Surname' => 'Minnee'],
|
['FirstName' => 'Sam', 'Surname' => 'Minnee'],
|
||||||
],
|
],
|
||||||
self::$twoItemList,
|
DataProvider::$twoItemList,
|
||||||
],
|
],
|
||||||
'mixedParametersTwoItems' => [
|
'mixedParametersTwoItems' => [
|
||||||
[
|
[
|
||||||
['FirstName' => 'Ingo', 'Surname' => 'Schommer'],
|
['FirstName' => 'Ingo', 'Surname' => 'Schommer'],
|
||||||
['FirstName' => 'Sam'],
|
['FirstName' => 'Sam'],
|
||||||
],
|
],
|
||||||
self::$twoItemList,
|
DataProvider::$twoItemList,
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -95,28 +95,28 @@ class DataProvider implements TestOnly
|
|||||||
[
|
[
|
||||||
['FirstName' => 'Ingo'],
|
['FirstName' => 'Ingo'],
|
||||||
],
|
],
|
||||||
self::$twoItemList,
|
DataProvider::$twoItemList,
|
||||||
],
|
],
|
||||||
'oneExpectationHasWrontParamter' => [
|
'oneExpectationHasWrontParamter' => [
|
||||||
[
|
[
|
||||||
['FirstName' => 'IngoXX'],
|
['FirstName' => 'IngoXX'],
|
||||||
['FirstName' => 'Sam'],
|
['FirstName' => 'Sam'],
|
||||||
],
|
],
|
||||||
self::$twoItemList,
|
DataProvider::$twoItemList,
|
||||||
],
|
],
|
||||||
'differentParametersInDifferentItemsAreWrong' => [
|
'differentParametersInDifferentItemsAreWrong' => [
|
||||||
[
|
[
|
||||||
['FirstName' => 'IngoXXX', 'Surname' => 'Schommer'],
|
['FirstName' => 'IngoXXX', 'Surname' => 'Schommer'],
|
||||||
['FirstName' => 'Sam', 'Surname' => 'MinneeXXX'],
|
['FirstName' => 'Sam', 'Surname' => 'MinneeXXX'],
|
||||||
],
|
],
|
||||||
self::$twoItemList,
|
DataProvider::$twoItemList,
|
||||||
],
|
],
|
||||||
'differentParametersNotMatching' => [
|
'differentParametersNotMatching' => [
|
||||||
[
|
[
|
||||||
['FirstName' => 'Daniel', 'Surname' => 'Foo'],
|
['FirstName' => 'Daniel', 'Surname' => 'Foo'],
|
||||||
['FirstName' => 'Dan'],
|
['FirstName' => 'Dan'],
|
||||||
],
|
],
|
||||||
self::$twoItemList,
|
DataProvider::$twoItemList,
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -137,21 +137,21 @@ class DataProvider implements TestOnly
|
|||||||
[
|
[
|
||||||
['FirstName' => 'Sam'],
|
['FirstName' => 'Sam'],
|
||||||
],
|
],
|
||||||
self::$oneItemList,
|
DataProvider::$oneItemList,
|
||||||
],
|
],
|
||||||
'twoParametersAreWrong' => [
|
'twoParametersAreWrong' => [
|
||||||
[
|
[
|
||||||
['FirstName' => 'IngoXXX', 'Surname' => 'Schommer'],
|
['FirstName' => 'IngoXXX', 'Surname' => 'Schommer'],
|
||||||
['FirstName' => 'Sam', 'Surname' => 'MinneeXXX'],
|
['FirstName' => 'Sam', 'Surname' => 'MinneeXXX'],
|
||||||
],
|
],
|
||||||
self::$twoItemList,
|
DataProvider::$twoItemList,
|
||||||
],
|
],
|
||||||
'mixedList' => [
|
'mixedList' => [
|
||||||
[
|
[
|
||||||
['FirstName' => 'Daniel', 'Surname' => 'Foo'],
|
['FirstName' => 'Daniel', 'Surname' => 'Foo'],
|
||||||
['FirstName' => 'Dan'],
|
['FirstName' => 'Dan'],
|
||||||
],
|
],
|
||||||
self::$twoItemList,
|
DataProvider::$twoItemList,
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -164,12 +164,12 @@ class DataProvider implements TestOnly
|
|||||||
return [
|
return [
|
||||||
'emptyMatch' => [
|
'emptyMatch' => [
|
||||||
[],
|
[],
|
||||||
self::$memberList,
|
DataProvider::$memberList,
|
||||||
'empty list did not match',
|
'empty list did not match',
|
||||||
],
|
],
|
||||||
'allItemsWithLocaleSet' => [
|
'allItemsWithLocaleSet' => [
|
||||||
['Locale' => 'en_US'],
|
['Locale' => 'en_US'],
|
||||||
self::$memberList,
|
DataProvider::$memberList,
|
||||||
'list with Locale set in all items did not match',
|
'list with Locale set in all items did not match',
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
@ -181,7 +181,7 @@ class DataProvider implements TestOnly
|
|||||||
public static function provideNotMatchingList()
|
public static function provideNotMatchingList()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'notAllItemsHaveLocaleSet' => [['FirstName' => 'Ingo'], self::$memberList],
|
'notAllItemsHaveLocaleSet' => [['FirstName' => 'Ingo'], DataProvider::$memberList],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ class DetailedErrorFormatterTest extends SapphireTest
|
|||||||
$this->assertStringContainsString('ERRNO 401', $result, 'Status code was not found in trace');
|
$this->assertStringContainsString('ERRNO 401', $result, 'Status code was not found in trace');
|
||||||
$this->assertStringContainsString('Denied', $result, 'Message was not found in trace');
|
$this->assertStringContainsString('Denied', $result, 'Message was not found in trace');
|
||||||
$this->assertStringContainsString('Line 4 in index.php', $result, 'Line or filename were not found in trace');
|
$this->assertStringContainsString('Line 4 in index.php', $result, 'Line or filename were not found in trace');
|
||||||
$this->assertStringContainsString(self::class, $result, 'Backtrace doesn\'t show current test class');
|
$this->assertStringContainsString(DetailedErrorFormatterTest::class, $result, 'Backtrace doesn\'t show current test class');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testFormatBatch()
|
public function testFormatBatch()
|
||||||
|
@ -46,7 +46,7 @@ class DataListEagerLoadingTest extends SapphireTest
|
|||||||
|
|
||||||
private const SHOW_QUERIES_RESET = 'SET_TO_THIS_VALUE_WHEN_FINISHED';
|
private const SHOW_QUERIES_RESET = 'SET_TO_THIS_VALUE_WHEN_FINISHED';
|
||||||
|
|
||||||
private $showQueries = self::SHOW_QUERIES_RESET;
|
private $showQueries = DataListEagerLoadingTest::SHOW_QUERIES_RESET;
|
||||||
|
|
||||||
public static function getExtraDataObjects()
|
public static function getExtraDataObjects()
|
||||||
{
|
{
|
||||||
@ -122,7 +122,7 @@ class DataListEagerLoadingTest extends SapphireTest
|
|||||||
*/
|
*/
|
||||||
private function startCountingSelectQueries(): void
|
private function startCountingSelectQueries(): void
|
||||||
{
|
{
|
||||||
if ($this->showQueries !== self::SHOW_QUERIES_RESET) {
|
if ($this->showQueries !== DataListEagerLoadingTest::SHOW_QUERIES_RESET) {
|
||||||
throw new LogicException('showQueries wasnt reset, you did something wrong');
|
throw new LogicException('showQueries wasnt reset, you did something wrong');
|
||||||
}
|
}
|
||||||
$this->showQueries = $_REQUEST['showqueries'] ?? null;
|
$this->showQueries = $_REQUEST['showqueries'] ?? null;
|
||||||
@ -151,7 +151,7 @@ class DataListEagerLoadingTest extends SapphireTest
|
|||||||
*/
|
*/
|
||||||
private function resetShowQueries(): void
|
private function resetShowQueries(): void
|
||||||
{
|
{
|
||||||
if ($this->showQueries === self::SHOW_QUERIES_RESET) {
|
if ($this->showQueries === DataListEagerLoadingTest::SHOW_QUERIES_RESET) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ($this->showQueries) {
|
if ($this->showQueries) {
|
||||||
@ -159,7 +159,7 @@ class DataListEagerLoadingTest extends SapphireTest
|
|||||||
} else {
|
} else {
|
||||||
unset($_REQUEST['showqueries']);
|
unset($_REQUEST['showqueries']);
|
||||||
}
|
}
|
||||||
$this->showQueries = self::SHOW_QUERIES_RESET;
|
$this->showQueries = DataListEagerLoadingTest::SHOW_QUERIES_RESET;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -30,11 +30,11 @@ class MockDynamicAssignmentDataObject extends DataObject implements TestOnly
|
|||||||
];
|
];
|
||||||
|
|
||||||
private static $many_many = [
|
private static $many_many = [
|
||||||
'MockManyMany' => self::class,
|
'MockManyMany' => MockDynamicAssignmentDataObject::class,
|
||||||
];
|
];
|
||||||
|
|
||||||
private static $belongs_many_many = [
|
private static $belongs_many_many = [
|
||||||
'MockBelongsManyMany' => self::class,
|
'MockBelongsManyMany' => MockDynamicAssignmentDataObject::class,
|
||||||
];
|
];
|
||||||
|
|
||||||
private static $many_many_extraFields = [
|
private static $many_many_extraFields = [
|
||||||
|
@ -25,12 +25,12 @@ class TreeNode extends DataObject implements TestOnly
|
|||||||
];
|
];
|
||||||
|
|
||||||
private static $has_one = [
|
private static $has_one = [
|
||||||
'Parent' => self::class,
|
'Parent' => TreeNode::class,
|
||||||
'Cycle' => self::class,
|
'Cycle' => TreeNode::class,
|
||||||
];
|
];
|
||||||
|
|
||||||
private static $has_many = [
|
private static $has_many = [
|
||||||
'Children' => self::class,
|
'Children' => TreeNode::class,
|
||||||
];
|
];
|
||||||
|
|
||||||
public function write($showDebug = false, $forceInsert = false, $forceWrite = false, $writeComponents = false)
|
public function write($showDebug = false, $forceInsert = false, $forceWrite = false, $writeComponents = false)
|
||||||
@ -51,7 +51,7 @@ class TreeNode extends DataObject implements TestOnly
|
|||||||
public function resetCounts()
|
public function resetCounts()
|
||||||
{
|
{
|
||||||
$update = new SQLUpdate(
|
$update = new SQLUpdate(
|
||||||
sprintf('"%s"', self::baseTable()),
|
sprintf('"%s"', TreeNode::baseTable()),
|
||||||
['"WriteCount"' => 0]
|
['"WriteCount"' => 0]
|
||||||
);
|
);
|
||||||
$results = $update->execute();
|
$results = $update->execute();
|
||||||
|
@ -5,6 +5,7 @@ namespace SilverStripe\ORM\Tests\Filters;
|
|||||||
use SilverStripe\Dev\SapphireTest;
|
use SilverStripe\Dev\SapphireTest;
|
||||||
use SilverStripe\ORM\Filters\EndsWithFilter;
|
use SilverStripe\ORM\Filters\EndsWithFilter;
|
||||||
use SilverStripe\View\ArrayData;
|
use SilverStripe\View\ArrayData;
|
||||||
|
use SilverStripe\ORM\Filters\SearchFilter;
|
||||||
|
|
||||||
class EndsWithFilterTest extends SapphireTest
|
class EndsWithFilterTest extends SapphireTest
|
||||||
{
|
{
|
||||||
@ -267,7 +268,7 @@ class EndsWithFilterTest extends SapphireTest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EndsWithFilter::config()->set('default_case_sensitive', $caseSensitive);
|
SearchFilter::config()->set('default_case_sensitive', $caseSensitive);
|
||||||
$filter = new EndsWithFilter();
|
$filter = new EndsWithFilter();
|
||||||
$filter->setValue($filterValue);
|
$filter->setValue($filterValue);
|
||||||
$filter->setModifiers($modifiers);
|
$filter->setModifiers($modifiers);
|
||||||
|
@ -9,6 +9,7 @@ use SilverStripe\ORM\Tests\Filters\ExactMatchFilterTest\Task;
|
|||||||
use SilverStripe\ORM\Tests\Filters\ExactMatchFilterTest\Project;
|
use SilverStripe\ORM\Tests\Filters\ExactMatchFilterTest\Project;
|
||||||
use SilverStripe\ORM\DataList;
|
use SilverStripe\ORM\DataList;
|
||||||
use SilverStripe\View\ArrayData;
|
use SilverStripe\View\ArrayData;
|
||||||
|
use SilverStripe\ORM\Filters\SearchFilter;
|
||||||
|
|
||||||
class ExactMatchFilterTest extends SapphireTest
|
class ExactMatchFilterTest extends SapphireTest
|
||||||
{
|
{
|
||||||
@ -313,7 +314,7 @@ class ExactMatchFilterTest extends SapphireTest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ExactMatchFilter::config()->set('default_case_sensitive', $caseSensitive);
|
SearchFilter::config()->set('default_case_sensitive', $caseSensitive);
|
||||||
$filter = new ExactMatchFilter();
|
$filter = new ExactMatchFilter();
|
||||||
$filter->setValue($filterValue);
|
$filter->setValue($filterValue);
|
||||||
$filter->setModifiers($modifiers);
|
$filter->setModifiers($modifiers);
|
||||||
|
@ -5,6 +5,7 @@ namespace SilverStripe\ORM\Tests\Filters;
|
|||||||
use SilverStripe\Dev\SapphireTest;
|
use SilverStripe\Dev\SapphireTest;
|
||||||
use SilverStripe\ORM\Filters\PartialMatchFilter;
|
use SilverStripe\ORM\Filters\PartialMatchFilter;
|
||||||
use SilverStripe\View\ArrayData;
|
use SilverStripe\View\ArrayData;
|
||||||
|
use SilverStripe\ORM\Filters\SearchFilter;
|
||||||
|
|
||||||
class PartialMatchFilterTest extends SapphireTest
|
class PartialMatchFilterTest extends SapphireTest
|
||||||
{
|
{
|
||||||
@ -267,7 +268,7 @@ class PartialMatchFilterTest extends SapphireTest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PartialMatchFilter::config()->set('default_case_sensitive', $caseSensitive);
|
SearchFilter::config()->set('default_case_sensitive', $caseSensitive);
|
||||||
$filter = new PartialMatchFilter();
|
$filter = new PartialMatchFilter();
|
||||||
$filter->setValue($filterValue);
|
$filter->setValue($filterValue);
|
||||||
$filter->setModifiers($modifiers);
|
$filter->setModifiers($modifiers);
|
||||||
|
@ -5,6 +5,7 @@ namespace SilverStripe\ORM\Tests\Filters;
|
|||||||
use SilverStripe\Dev\SapphireTest;
|
use SilverStripe\Dev\SapphireTest;
|
||||||
use SilverStripe\ORM\Filters\StartsWithFilter;
|
use SilverStripe\ORM\Filters\StartsWithFilter;
|
||||||
use SilverStripe\View\ArrayData;
|
use SilverStripe\View\ArrayData;
|
||||||
|
use SilverStripe\ORM\Filters\SearchFilter;
|
||||||
|
|
||||||
class StartsWithFilterTest extends SapphireTest
|
class StartsWithFilterTest extends SapphireTest
|
||||||
{
|
{
|
||||||
@ -267,7 +268,7 @@ class StartsWithFilterTest extends SapphireTest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StartsWithFilter::config()->set('default_case_sensitive', $caseSensitive);
|
SearchFilter::config()->set('default_case_sensitive', $caseSensitive);
|
||||||
$filter = new StartsWithFilter();
|
$filter = new StartsWithFilter();
|
||||||
$filter->setValue($filterValue);
|
$filter->setValue($filterValue);
|
||||||
$filter->setModifiers($modifiers);
|
$filter->setModifiers($modifiers);
|
||||||
|
@ -394,7 +394,7 @@ EOT;
|
|||||||
$xpath .= '/ul/li[@data-id="' . $node->ID . '"]';
|
$xpath .= '/ul/li[@data-id="' . $node->ID . '"]';
|
||||||
}
|
}
|
||||||
$match = $parser->getByXpath($xpath);
|
$match = $parser->getByXpath($xpath);
|
||||||
self::assertThat((bool)$match, self::isTrue(), $message);
|
MarkedSetTest::assertThat((bool)$match, MarkedSetTest::isTrue(), $message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -410,7 +410,7 @@ EOT;
|
|||||||
$xpath .= '/ul/li[@data-id="' . $node->ID . '"]';
|
$xpath .= '/ul/li[@data-id="' . $node->ID . '"]';
|
||||||
}
|
}
|
||||||
$match = $parser->getByXpath($xpath);
|
$match = $parser->getByXpath($xpath);
|
||||||
self::assertThat((bool)$match, self::isFalse(), $message);
|
MarkedSetTest::assertThat((bool)$match, MarkedSetTest::isFalse(), $message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -62,7 +62,7 @@ class MySQLiConnectorTest extends SapphireTest implements TestOnly
|
|||||||
|
|
||||||
// Note: we do not need to update the utf charset here because mysqli with newer
|
// Note: we do not need to update the utf charset here because mysqli with newer
|
||||||
// version of mysql/mariadb still self-reports as 'utf8' rather than 'utf8mb3'
|
// version of mysql/mariadb still self-reports as 'utf8' rather than 'utf8mb3'
|
||||||
// This is unlike self::testConnectionCollationControl()
|
// This is unlike MySQLiConnectorTest::testConnectionCollationControl()
|
||||||
$this->assertEquals($charset, $cset->charset);
|
$this->assertEquals($charset, $cset->charset);
|
||||||
$this->assertEquals($defaultCollation, $cset->collation);
|
$this->assertEquals($defaultCollation, $cset->collation);
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ class RelatedDataServiceTest extends SapphireTest
|
|||||||
// Add DataExtension and reset database so that tables + columns get added
|
// Add DataExtension and reset database so that tables + columns get added
|
||||||
Hub::add_extension(HubExtension::class);
|
Hub::add_extension(HubExtension::class);
|
||||||
DataObject::reset();
|
DataObject::reset();
|
||||||
self::resetDBSchema(true, true);
|
RelatedDataServiceTest::resetDBSchema(true, true);
|
||||||
//
|
//
|
||||||
$pageTitle = 'My Page that has_one File using HubExtension';
|
$pageTitle = 'My Page that has_one File using HubExtension';
|
||||||
$myFile = new Node();
|
$myFile = new Node();
|
||||||
@ -215,7 +215,7 @@ class RelatedDataServiceTest extends SapphireTest
|
|||||||
// Add DataExtension and reset database so that tables + columns get added
|
// Add DataExtension and reset database so that tables + columns get added
|
||||||
Hub::add_extension(HubExtension::class);
|
Hub::add_extension(HubExtension::class);
|
||||||
DataObject::reset();
|
DataObject::reset();
|
||||||
self::resetDBSchema(true, true);
|
RelatedDataServiceTest::resetDBSchema(true, true);
|
||||||
//
|
//
|
||||||
$pageTitle = 'My Page that many_many File without belong_many_many Page using HubExtension';
|
$pageTitle = 'My Page that many_many File without belong_many_many Page using HubExtension';
|
||||||
$myPage = new Hub();
|
$myPage = new Hub();
|
||||||
|
@ -14,10 +14,10 @@ class CteRecursiveObject extends DataObject implements TestOnly
|
|||||||
];
|
];
|
||||||
|
|
||||||
private static $has_one = [
|
private static $has_one = [
|
||||||
'Parent' => self::class,
|
'Parent' => CteRecursiveObject::class,
|
||||||
];
|
];
|
||||||
|
|
||||||
private static $has_many = [
|
private static $has_many = [
|
||||||
'Children' => self::class . '.Parent',
|
'Children' => CteRecursiveObject::class . '.Parent',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ class TestCacheFlusher implements MemberCacheFlusher
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($memberIDs && is_array($memberIDs)) {
|
if ($memberIDs && is_array($memberIDs)) {
|
||||||
foreach (self::$categories as $category) {
|
foreach (TestCacheFlusher::$categories as $category) {
|
||||||
foreach ($memberIDs as $memberID) {
|
foreach ($memberIDs as $memberID) {
|
||||||
$key = $this->generateCacheKey($category, $memberID);
|
$key = $this->generateCacheKey($category, $memberID);
|
||||||
$this->cache->delete($key);
|
$this->cache->delete($key);
|
||||||
|
@ -23,7 +23,7 @@ class TestPermissionNode extends DataObject implements TestOnly
|
|||||||
];
|
];
|
||||||
|
|
||||||
private static $has_one = [
|
private static $has_one = [
|
||||||
"Parent" => self::class,
|
"Parent" => TestPermissionNode::class,
|
||||||
];
|
];
|
||||||
|
|
||||||
private static $table_name = 'InheritedPermissionsTest_TestPermissionNode';
|
private static $table_name = 'InheritedPermissionsTest_TestPermissionNode';
|
||||||
|
@ -23,7 +23,7 @@ class UnstagedNode extends DataObject implements TestOnly
|
|||||||
];
|
];
|
||||||
|
|
||||||
private static $has_one = [
|
private static $has_one = [
|
||||||
"Parent" => self::class,
|
"Parent" => UnstagedNode::class,
|
||||||
];
|
];
|
||||||
|
|
||||||
private static $table_name = 'InheritedPermissionsTest_UnstagedNode';
|
private static $table_name = 'InheritedPermissionsTest_UnstagedNode';
|
||||||
|
@ -62,7 +62,7 @@ class RequirementsTest extends SapphireTest
|
|||||||
$backend->css('//scheme-relative.example.com/test.css');
|
$backend->css('//scheme-relative.example.com/test.css');
|
||||||
$backend->css('http://www.mydomain.com:3000/test.css');
|
$backend->css('http://www.mydomain.com:3000/test.css');
|
||||||
|
|
||||||
$html = $backend->includeInHTML(self::$html_template);
|
$html = $backend->includeInHTML(RequirementsTest::$html_template);
|
||||||
|
|
||||||
$this->assertStringContainsString('http://www.mydomain.com/test.js', $html, 'Load external javascript URL');
|
$this->assertStringContainsString('http://www.mydomain.com/test.js', $html, 'Load external javascript URL');
|
||||||
$this->assertStringContainsString('https://www.mysecuredomain.com/test.js', $html, 'Load external secure javascript URL');
|
$this->assertStringContainsString('https://www.mysecuredomain.com/test.js', $html, 'Load external secure javascript URL');
|
||||||
@ -89,7 +89,7 @@ class RequirementsTest extends SapphireTest
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
$backend->includeInHTML(self::$html_template);
|
$backend->includeInHTML(RequirementsTest::$html_template);
|
||||||
|
|
||||||
// we get the file path here
|
// we get the file path here
|
||||||
$allCSS = $backend->getCSS();
|
$allCSS = $backend->getCSS();
|
||||||
@ -137,7 +137,7 @@ class RequirementsTest extends SapphireTest
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
$backend->includeInHTML(self::$html_template);
|
$backend->includeInHTML(RequirementsTest::$html_template);
|
||||||
|
|
||||||
// we get the file path here
|
// we get the file path here
|
||||||
$allCSS = $backend->getCSS();
|
$allCSS = $backend->getCSS();
|
||||||
@ -389,7 +389,7 @@ class RequirementsTest extends SapphireTest
|
|||||||
[ 'type' => 'application/json' ]
|
[ 'type' => 'application/json' ]
|
||||||
);
|
);
|
||||||
$backend->javascript('javascript/RequirementsTest_b.js');
|
$backend->javascript('javascript/RequirementsTest_b.js');
|
||||||
$result = $backend->includeInHTML(self::$html_template);
|
$result = $backend->includeInHTML(RequirementsTest::$html_template);
|
||||||
$this->assertMatchesRegularExpression(
|
$this->assertMatchesRegularExpression(
|
||||||
'#<script type="application/json" src=".*/javascript/RequirementsTest_a.js#',
|
'#<script type="application/json" src=".*/javascript/RequirementsTest_a.js#',
|
||||||
$result
|
$result
|
||||||
@ -410,7 +410,7 @@ class RequirementsTest extends SapphireTest
|
|||||||
$combinedFileName = '/_combinedfiles/RequirementsTest_bc-2a55d56.js';
|
$combinedFileName = '/_combinedfiles/RequirementsTest_bc-2a55d56.js';
|
||||||
$combinedFilePath = TestAssetStore::base_path() . $combinedFileName;
|
$combinedFilePath = TestAssetStore::base_path() . $combinedFileName;
|
||||||
|
|
||||||
$html = $backend->includeInHTML(self::$html_template);
|
$html = $backend->includeInHTML(RequirementsTest::$html_template);
|
||||||
|
|
||||||
/* COMBINED JAVASCRIPT FILE IS INCLUDED IN HTML HEADER */
|
/* COMBINED JAVASCRIPT FILE IS INCLUDED IN HTML HEADER */
|
||||||
$this->assertMatchesRegularExpression(
|
$this->assertMatchesRegularExpression(
|
||||||
@ -461,7 +461,7 @@ class RequirementsTest extends SapphireTest
|
|||||||
/** @var Requirements_Backend $backend */
|
/** @var Requirements_Backend $backend */
|
||||||
$backend = Injector::inst()->create(Requirements_Backend::class);
|
$backend = Injector::inst()->create(Requirements_Backend::class);
|
||||||
$this->setupCombinedNonrequiredRequirements($backend);
|
$this->setupCombinedNonrequiredRequirements($backend);
|
||||||
$html = $backend->includeInHTML(self::$html_template);
|
$html = $backend->includeInHTML(RequirementsTest::$html_template);
|
||||||
|
|
||||||
/* COMBINED JAVASCRIPT FILE IS INCLUDED IN HTML HEADER */
|
/* COMBINED JAVASCRIPT FILE IS INCLUDED IN HTML HEADER */
|
||||||
$this->assertMatchesRegularExpression(
|
$this->assertMatchesRegularExpression(
|
||||||
@ -511,7 +511,7 @@ class RequirementsTest extends SapphireTest
|
|||||||
$combinedFileName = '/_combinedfiles/RequirementsTest_bc-2a55d56.js';
|
$combinedFileName = '/_combinedfiles/RequirementsTest_bc-2a55d56.js';
|
||||||
$combinedFilePath = TestAssetStore::base_path() . $combinedFileName;
|
$combinedFilePath = TestAssetStore::base_path() . $combinedFileName;
|
||||||
|
|
||||||
$html = $backend->includeInHTML(self::$html_template);
|
$html = $backend->includeInHTML(RequirementsTest::$html_template);
|
||||||
|
|
||||||
/* ASYNC IS INCLUDED IN SCRIPT TAG */
|
/* ASYNC IS INCLUDED IN SCRIPT TAG */
|
||||||
$this->assertMatchesRegularExpression(
|
$this->assertMatchesRegularExpression(
|
||||||
@ -585,7 +585,7 @@ class RequirementsTest extends SapphireTest
|
|||||||
|
|
||||||
$this->setupCombinedRequirementsJavascriptAsyncDefer($backend, false, true);
|
$this->setupCombinedRequirementsJavascriptAsyncDefer($backend, false, true);
|
||||||
|
|
||||||
$html = $backend->includeInHTML(self::$html_template);
|
$html = $backend->includeInHTML(RequirementsTest::$html_template);
|
||||||
|
|
||||||
/* DEFER IS INCLUDED IN SCRIPT TAG */
|
/* DEFER IS INCLUDED IN SCRIPT TAG */
|
||||||
$this->assertMatchesRegularExpression(
|
$this->assertMatchesRegularExpression(
|
||||||
@ -659,7 +659,7 @@ class RequirementsTest extends SapphireTest
|
|||||||
|
|
||||||
$this->setupCombinedRequirementsJavascriptAsyncDefer($backend, true, true);
|
$this->setupCombinedRequirementsJavascriptAsyncDefer($backend, true, true);
|
||||||
|
|
||||||
$html = $backend->includeInHTML(self::$html_template);
|
$html = $backend->includeInHTML(RequirementsTest::$html_template);
|
||||||
|
|
||||||
/* ASYNC/DEFER IS INCLUDED IN SCRIPT TAG */
|
/* ASYNC/DEFER IS INCLUDED IN SCRIPT TAG */
|
||||||
$this->assertMatchesRegularExpression(
|
$this->assertMatchesRegularExpression(
|
||||||
@ -745,7 +745,7 @@ class RequirementsTest extends SapphireTest
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
$html = $backend->includeInHTML(self::$html_template);
|
$html = $backend->includeInHTML(RequirementsTest::$html_template);
|
||||||
|
|
||||||
$this->assertMatchesRegularExpression(
|
$this->assertMatchesRegularExpression(
|
||||||
'/href=".*\/print\-69ce614\.css/',
|
'/href=".*\/print\-69ce614\.css/',
|
||||||
@ -781,7 +781,7 @@ class RequirementsTest extends SapphireTest
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
$html = $backend->includeInHTML(self::$html_template);
|
$html = $backend->includeInHTML(RequirementsTest::$html_template);
|
||||||
$this->assertMatchesRegularExpression(
|
$this->assertMatchesRegularExpression(
|
||||||
'/href=".*\/style\-8011538\.css/',
|
'/href=".*\/style\-8011538\.css/',
|
||||||
$html,
|
$html,
|
||||||
@ -801,7 +801,7 @@ class RequirementsTest extends SapphireTest
|
|||||||
$backend->block('RequirementsTest_bc.js');
|
$backend->block('RequirementsTest_bc.js');
|
||||||
|
|
||||||
clearstatcache(); // needed to get accurate file_exists() results
|
clearstatcache(); // needed to get accurate file_exists() results
|
||||||
$html = $backend->includeInHTML(self::$html_template);
|
$html = $backend->includeInHTML(RequirementsTest::$html_template);
|
||||||
$this->assertFileDoesNotExist($combinedFilePath);
|
$this->assertFileDoesNotExist($combinedFilePath);
|
||||||
$this->assertDoesNotMatchRegularExpression(
|
$this->assertDoesNotMatchRegularExpression(
|
||||||
'/src=".*\/RequirementsTest_bc\.js/',
|
'/src=".*\/RequirementsTest_bc\.js/',
|
||||||
@ -816,7 +816,7 @@ class RequirementsTest extends SapphireTest
|
|||||||
$combinedFileName2 = '/_combinedfiles/RequirementsTest_bc-3748f67.js'; // SHA1 without file b included
|
$combinedFileName2 = '/_combinedfiles/RequirementsTest_bc-3748f67.js'; // SHA1 without file b included
|
||||||
$combinedFilePath2 = TestAssetStore::base_path() . $combinedFileName2;
|
$combinedFilePath2 = TestAssetStore::base_path() . $combinedFileName2;
|
||||||
clearstatcache(); // needed to get accurate file_exists() results
|
clearstatcache(); // needed to get accurate file_exists() results
|
||||||
$backend->includeInHTML(self::$html_template);
|
$backend->includeInHTML(RequirementsTest::$html_template);
|
||||||
$this->assertFileExists($combinedFilePath2);
|
$this->assertFileExists($combinedFilePath2);
|
||||||
$this->assertStringNotContainsString(
|
$this->assertStringNotContainsString(
|
||||||
"alert('b')",
|
"alert('b')",
|
||||||
@ -856,7 +856,7 @@ class RequirementsTest extends SapphireTest
|
|||||||
|
|
||||||
$backend->javascript('javascript/RequirementsTest_a.js?test=1&test=2&test=3');
|
$backend->javascript('javascript/RequirementsTest_a.js?test=1&test=2&test=3');
|
||||||
$backend->css('css/RequirementsTest_a.css?test=1&test=2&test=3');
|
$backend->css('css/RequirementsTest_a.css?test=1&test=2&test=3');
|
||||||
$html = $backend->includeInHTML(self::$html_template);
|
$html = $backend->includeInHTML(RequirementsTest::$html_template);
|
||||||
|
|
||||||
/* Javascript has correct path */
|
/* Javascript has correct path */
|
||||||
$this->assertMatchesRegularExpression(
|
$this->assertMatchesRegularExpression(
|
||||||
@ -1406,7 +1406,7 @@ EOS
|
|||||||
// Tests attribute appending AND lowercase string conversion
|
// Tests attribute appending AND lowercase string conversion
|
||||||
$backend->customScriptWithAttributes("//TEST", ['type' => 'module', 'crossorigin' => 'Anonymous']);
|
$backend->customScriptWithAttributes("//TEST", ['type' => 'module', 'crossorigin' => 'Anonymous']);
|
||||||
$backend->css('css/RequirementsTest_a.css', null, ['integrity' => 'def', 'crossorigin' => 'anonymous']);
|
$backend->css('css/RequirementsTest_a.css', null, ['integrity' => 'def', 'crossorigin' => 'anonymous']);
|
||||||
$html = $backend->includeInHTML(self::$html_template);
|
$html = $backend->includeInHTML(RequirementsTest::$html_template);
|
||||||
|
|
||||||
/* Javascript has correct attributes */
|
/* Javascript has correct attributes */
|
||||||
$this->assertMatchesRegularExpression(
|
$this->assertMatchesRegularExpression(
|
||||||
@ -1447,7 +1447,7 @@ EOS
|
|||||||
$backend->customCSS("Override", 42);
|
$backend->customCSS("Override", 42);
|
||||||
$backend->insertHeadTags("<span>Override</span>", 42);
|
$backend->insertHeadTags("<span>Override</span>", 42);
|
||||||
|
|
||||||
$html = $backend->includeInHTML(self::$html_template);
|
$html = $backend->includeInHTML(RequirementsTest::$html_template);
|
||||||
|
|
||||||
/* customScript is overwritten by customScriptWithAttributes */
|
/* customScript is overwritten by customScriptWithAttributes */
|
||||||
$this->assertMatchesRegularExpression(
|
$this->assertMatchesRegularExpression(
|
||||||
|
@ -32,6 +32,6 @@ class LevelTestData extends ViewableData implements TestOnly
|
|||||||
|
|
||||||
public function forWith($number)
|
public function forWith($number)
|
||||||
{
|
{
|
||||||
return new self($number);
|
return new LevelTestData($number);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,13 +11,13 @@ class TestObject implements TestOnly, i18nEntityProvider
|
|||||||
|
|
||||||
public static function my_translatable_property()
|
public static function my_translatable_property()
|
||||||
{
|
{
|
||||||
return _t(__CLASS__ . ".my_translatable_property", self::$my_translatable_property);
|
return _t(__CLASS__ . ".my_translatable_property", TestObject::$my_translatable_property);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideI18nEntities()
|
public function provideI18nEntities()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
__CLASS__ . ".my_translatable_property" => self::$my_translatable_property,
|
__CLASS__ . ".my_translatable_property" => TestObject::$my_translatable_property,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user