From 3362e15a2978918c7d3f2b72b30844e2f5ee53eb Mon Sep 17 00:00:00 2001 From: Damian Mooyman Date: Wed, 22 Feb 2017 16:14:53 +1300 Subject: [PATCH] API Upgrade code to use updated config --- _config/email.yml | 2 +- _config/routes.yml | 5 - admin/code/AdminRootController.php | 11 +- admin/code/CMSMenu.php | 4 +- admin/code/CampaignAdminList.php | 2 +- admin/code/LeftAndMain.php | 33 ++--- admin/tests/CMSProfileControllerTest.php | 3 +- src/Assets/AssetControlExtension.php | 3 +- src/Assets/FileFinder.php | 8 ++ src/Assets/Flysystem/AssetAdapter.php | 6 +- src/Assets/Flysystem/FlysystemAssetStore.php | 13 +- .../Flysystem/ProtectedAssetAdapter.php | 7 +- src/Assets/Image.php | 3 +- src/Assets/ImageManipulation.php | 10 +- src/Assets/ImagickBackend.php | 2 +- src/Assets/Upload_Validator.php | 2 +- src/Control/CookieJar.php | 2 +- src/Control/Email/Email.php | 6 +- src/Control/HTTP.php | 9 +- src/Control/RSS/RSSFeed.php | 2 +- src/Control/RequestHandler.php | 23 +-- src/Dev/SapphireTest.php | 70 +++++++--- src/Forms/CountryDropdownField.php | 6 +- src/Forms/CurrencyField.php | 4 +- src/Forms/DateField.php | 2 +- src/Forms/DateField_View_JQuery.php | 3 +- src/Forms/DatetimeField.php | 2 +- src/Forms/FormField.php | 2 +- src/Forms/FormScaffolder.php | 2 +- src/Forms/GridField/GridField.php | 3 +- .../GridFieldAddExistingAutocompleter.php | 2 +- src/Forms/GridField/GridFieldPageCount.php | 4 +- src/Forms/GridField/GridFieldPaginator.php | 3 +- src/Forms/HTMLEditor/HTMLEditorField.php | 4 +- src/Forms/HTMLEditor/HTMLEditorField_File.php | 14 +- .../HTMLEditor/HTMLEditorField_Image.php | 4 +- .../HTMLEditor/HTMLEditorField_Toolbar.php | 5 +- src/Forms/HTMLEditor/TinyMCEConfig.php | 3 +- src/Forms/MemberDatetimeOptionsetField.php | 2 +- src/Forms/NumericField.php | 5 +- src/Forms/ReadonlyField.php | 3 +- src/Forms/TimeField.php | 2 +- src/Forms/UploadField_SelectHandler.php | 3 +- src/ORM/DataObject.php | 132 +++++++----------- src/ORM/DataObjectSchema.php | 11 +- src/ORM/Versioning/Versioned.php | 14 +- src/Security/BasicAuth.php | 2 +- src/Security/Member.php | 8 +- src/Security/MemberLoginForm.php | 2 +- src/Security/Security.php | 2 +- src/View/SSTemplateParser.php | 2 +- src/View/SSViewer.php | 80 +---------- src/View/SSViewer_DataPresenter.php | 5 +- src/View/ThemeResourceLoader.php | 26 ++-- src/View/ViewableData.php | 15 +- src/conf/ConfigureFromEnv.php | 5 - src/i18n/Data/Sources.php | 4 +- src/i18n/Messages/YamlWriter.php | 2 +- src/i18n/TextCollection/i18nTextCollector.php | 4 +- src/i18n/i18n.php | 8 +- 60 files changed, 280 insertions(+), 346 deletions(-) diff --git a/_config/email.yml b/_config/email.yml index fdcf87276..8842d39d2 100644 --- a/_config/email.yml +++ b/_config/email.yml @@ -1,5 +1,5 @@ --- -Name: coreconfig +Name: emailconfig --- SilverStripe\Core\Injector\Injector: Swift_Transport: Swift_MailTransport diff --git a/_config/routes.yml b/_config/routes.yml index 3f97a0f9d..0ed413097 100644 --- a/_config/routes.yml +++ b/_config/routes.yml @@ -1,16 +1,13 @@ --- Name: rootroutes -Before: '*' --- SilverStripe\Control\Director: rules: '': SilverStripe\Control\Controller --- Name: coreroutes -Before: '*' After: - '#rootroutes' - - '#modelascontrollerroutes' --- SilverStripe\Control\Director: rules: @@ -23,11 +20,9 @@ SilverStripe\Control\Director: 'SapphireREPL//$Action/$ID/$OtherID': SilverStripe\Dev\SapphireREPL --- Name: adminroutes -Before: '*' After: - '#rootroutes' - '#coreroutes' - - '#modelascontrollerroutes' --- SilverStripe\Control\Director: rules: diff --git a/admin/code/AdminRootController.php b/admin/code/AdminRootController.php index 5c7e9207d..c3857eec0 100644 --- a/admin/code/AdminRootController.php +++ b/admin/code/AdminRootController.php @@ -50,7 +50,7 @@ class AdminRootController extends Controller implements TemplateGlobalProvider * The LeftAndMain child that will be used as the initial panel to display if none is selected (i.e. if you * visit /admin) */ - private static $default_panel = 'SilverStripe\\Admin\\SecurityAdmin'; + private static $default_panel = SecurityAdmin::class; /** * @var array @@ -84,8 +84,9 @@ class AdminRootController extends Controller implements TemplateGlobalProvider */ protected static function add_rule_for_controller($controllerClass) { - $urlSegment = Config::inst()->get($controllerClass, 'url_segment', Config::FIRST_SET); - $urlRule = Config::inst()->get($controllerClass, 'url_rule', Config::FIRST_SET); + $config = Config::forClass($controllerClass); + $urlSegment = $config->get('url_segment'); + $urlRule = $config->get('url_rule'); if ($urlSegment) { // Make director rule @@ -105,7 +106,8 @@ class AdminRootController extends Controller implements TemplateGlobalProvider { // If this is the final portion of the request (i.e. the URL is just /admin), direct to the default panel if ($request->allParsed()) { - $segment = Config::inst()->get($this->config()->default_panel, 'url_segment'); + $segment = Config::forClass($this->config()->default_panel) + ->get('url_segment'); $this->redirect(Controller::join_links(self::admin_url(), $segment, '/')); return $this->getResponse(); @@ -114,6 +116,7 @@ class AdminRootController extends Controller implements TemplateGlobalProvider $rules = self::rules(); foreach ($rules as $pattern => $controller) { if (($arguments = $request->match($pattern, true)) !== false) { + /** @var LeftAndMain $controllerObj */ $controllerObj = Injector::inst()->create($controller); $controllerObj->setSession($this->session); diff --git a/admin/code/CMSMenu.php b/admin/code/CMSMenu.php index 25312b158..5daced4ff 100644 --- a/admin/code/CMSMenu.php +++ b/admin/code/CMSMenu.php @@ -88,8 +88,8 @@ class CMSMenu extends Object implements IteratorAggregate, i18nEntityProvider protected static function menuitem_for_controller($controllerClass) { $urlBase = AdminRootController::admin_url(); - $urlSegment = Config::inst()->get($controllerClass, 'url_segment', Config::FIRST_SET); - $menuPriority = Config::inst()->get($controllerClass, 'menu_priority', Config::FIRST_SET); + $urlSegment = Config::inst()->get($controllerClass, 'url_segment'); + $menuPriority = Config::inst()->get($controllerClass, 'menu_priority'); // Don't add menu items defined the old way if (!$urlSegment) { diff --git a/admin/code/CampaignAdminList.php b/admin/code/CampaignAdminList.php index 3ee85b1e8..215d99d2a 100644 --- a/admin/code/CampaignAdminList.php +++ b/admin/code/CampaignAdminList.php @@ -21,7 +21,7 @@ class CampaignAdminList extends FormField // Get endpoints from admin $admin = CampaignAdmin::singleton(); - $data['data']['recordType'] = $admin->config()->get('tree_class'); + $data['data']['recordType'] = $admin->config()->uninherited('tree_class'); $oneSetAction = $admin->Link("set") . "/:id"; $setsAction = $admin->Link("sets"); $schemaEndpoint = $admin->Link("schema") . "/DetailEditForm"; diff --git a/admin/code/LeftAndMain.php b/admin/code/LeftAndMain.php index ec4ea4a42..2e08c6373 100644 --- a/admin/code/LeftAndMain.php +++ b/admin/code/LeftAndMain.php @@ -86,7 +86,7 @@ class LeftAndMain extends Controller implements PermissionProvider * @config * @var string */ - private static $url_segment; + private static $url_segment = null; /** * @config @@ -265,7 +265,7 @@ class LeftAndMain extends Controller implements PermissionProvider /** * Gets the combined configuration of all LeafAndMain subclasses required by the client app. * - * @return array + * @return string * * WARNING: Experimental API */ @@ -289,7 +289,7 @@ class LeftAndMain extends Controller implements PermissionProvider // Set env $combinedClientConfig['environment'] = Director::get_environment_type(); - $combinedClientConfig['debugging'] = $this->config()->client_debugging; + $combinedClientConfig['debugging'] = LeftAndMain::config()->uninherited('client_debugging'); return Convert::raw2json($combinedClientConfig); } @@ -471,7 +471,7 @@ class LeftAndMain extends Controller implements PermissionProvider public static function getRequiredPermissions() { $class = get_called_class(); - $code = Config::inst()->get($class, 'required_permission_codes', Config::FIRST_SET); + $code = Config::inst()->get($class, 'required_permission_codes'); if ($code === false) { return false; } @@ -509,7 +509,7 @@ class LeftAndMain extends Controller implements PermissionProvider CMSMenu::add_link( 'Help', _t('LeftAndMain.HELP', 'Help', 'Menu title'), - $this->config()->help_link, + LeftAndMain::config()->uninherited('help_link'), -2, array( 'target' => '_blank' @@ -591,7 +591,7 @@ class LeftAndMain extends Controller implements PermissionProvider Requirements::add_i18n_javascript(ltrim(FRAMEWORK_DIR . '/client/lang', '/'), false, true); Requirements::add_i18n_javascript(FRAMEWORK_ADMIN_DIR . '/client/lang', false, true); - if ($this->config()->session_keepalive_ping) { + if (LeftAndMain::config()->uninherited('session_keepalive_ping')) { Requirements::javascript(FRAMEWORK_ADMIN_DIR . '/client/dist/js/LeftAndMain.Ping.js'); } @@ -644,7 +644,7 @@ class LeftAndMain extends Controller implements PermissionProvider $this->extend('init', $dummy); // Assign default cms theme and replace user-specified themes - SSViewer::set_themes($this->config()->admin_themes); + SSViewer::set_themes(LeftAndMain::config()->uninherited('admin_themes')); //set the reading mode for the admin to stage Versioned::set_stage(Versioned::DRAFT); @@ -676,7 +676,7 @@ class LeftAndMain extends Controller implements PermissionProvider // Prevent clickjacking, see https://developer.mozilla.org/en-US/docs/HTTP/X-Frame-Options $originalResponse = $this->getResponse(); - $originalResponse->addHeader('X-Frame-Options', $this->config()->frame_options); + $originalResponse->addHeader('X-Frame-Options', LeftAndMain::config()->uninherited('frame_options')); $originalResponse->addHeader('Vary', 'X-Requested-With'); return $response; @@ -714,7 +714,7 @@ class LeftAndMain extends Controller implements PermissionProvider $this->setResponse($newResponse); return ''; // Actual response will be re-requested by client } else { - parent::redirect($url, $code); + return parent::redirect($url, $code); } } @@ -752,11 +752,8 @@ class LeftAndMain extends Controller implements PermissionProvider public function Link($action = null) { // Handle missing url_segments - if ($this->config()->url_segment) { - $segment = $this->config()->get('url_segment', Config::FIRST_SET); - } else { - $segment = $this->class; - }; + $segment = $this->config()->get('url_segment') + ?: $this->class; $link = Controller::join_links( AdminRootController::admin_url(), @@ -795,7 +792,7 @@ class LeftAndMain extends Controller implements PermissionProvider } // Get default class title - $title = Config::inst()->get($class, 'menu_title', Config::FIRST_SET); + $title = static::config()->get('menu_title'); if (!$title) { $title = preg_replace('/Admin$/', '', $class); } @@ -816,7 +813,7 @@ class LeftAndMain extends Controller implements PermissionProvider */ public static function menu_icon_for_class($class) { - $icon = Config::inst()->get($class, 'menu_icon', Config::FIRST_SET); + $icon = Config::inst()->get($class, 'menu_icon'); if (!empty($icon)) { $class = strtolower(Convert::raw2htmlname(str_replace('\\', '-', $class))); return ".icon.icon-16.icon-{$class} { background-image: url('{$icon}'); } "; @@ -834,7 +831,7 @@ class LeftAndMain extends Controller implements PermissionProvider */ public static function menu_icon_class_for_class($class) { - return Config::inst()->get($class, 'menu_icon_class', Config::FIRST_SET); + return Config::inst()->get($class, 'menu_icon_class'); } /** @@ -951,8 +948,6 @@ class LeftAndMain extends Controller implements PermissionProvider // Provide styling for custom $menu-icon. Done here instead of in // CMSMenu::populate_menu(), because the icon is part of // the CMS right pane for the specified class as well... - $iconClass = false; - if ($menuItem->controller) { $menuIcon = LeftAndMain::menu_icon_for_class($menuItem->controller); diff --git a/admin/tests/CMSProfileControllerTest.php b/admin/tests/CMSProfileControllerTest.php index d6ef24c0a..8a05d525e 100644 --- a/admin/tests/CMSProfileControllerTest.php +++ b/admin/tests/CMSProfileControllerTest.php @@ -2,6 +2,7 @@ namespace SilverStripe\Admin\Tests; +use SilverStripe\Core\Config\Config; use SilverStripe\Dev\FunctionalTest; use SilverStripe\Security\Member; @@ -57,7 +58,7 @@ class CMSProfileControllerTest extends FunctionalTest public function testExtendedPermissionsStopEditingOwnProfile() { - $existingExtensions = Member::config()->get('extensions'); + $existingExtensions = Member::config()->get('extensions', Config::EXCLUDE_EXTRA_SOURCES); Member::config()->update('extensions', [ CMSProfileControllerTest\TestExtension::class ]); diff --git a/src/Assets/AssetControlExtension.php b/src/Assets/AssetControlExtension.php index 4a6d9f731..48443a957 100644 --- a/src/Assets/AssetControlExtension.php +++ b/src/Assets/AssetControlExtension.php @@ -127,7 +127,8 @@ class AssetControlExtension extends DataExtension protected function processManipulation(AssetManipulationList $manipulations) { // When deleting from stage then check if we should archive assets - $archive = $this->owner->config()->keep_archived_assets; + $archive = $this->owner->config()->get('keep_archived_assets'); + // Publish assets $this->publishAll($manipulations->getPublicAssets()); diff --git a/src/Assets/FileFinder.php b/src/Assets/FileFinder.php index d89e94ec4..64f1630be 100644 --- a/src/Assets/FileFinder.php +++ b/src/Assets/FileFinder.php @@ -11,6 +11,7 @@ use InvalidArgumentException; * * Each file finder instance can have several options set on it: * - name_regex (string): A regular expression that file basenames must match. + * - dir_regexp (string): A regular expression that dir basenames must match * - accept_callback (callback): A callback that is called to accept a file. * If it returns false the item will be skipped. The callback is passed the * basename, pathname and depth. @@ -51,6 +52,7 @@ class FileFinder */ protected static $default_options = array( 'name_regex' => null, + 'dir_regex' => null, 'accept_callback' => null, 'accept_dir_callback' => null, 'accept_file_callback' => null, @@ -193,6 +195,12 @@ class FileFinder */ protected function acceptDir($basename, $pathname, $depth) { + if ($regex = $this->getOption('dir_regex')) { + if (!preg_match($regex, $basename)) { + return false; + } + } + if ($this->getOption('ignore_vcs') && in_array($basename, self::$vcs_dirs)) { return false; } diff --git a/src/Assets/Flysystem/AssetAdapter.php b/src/Assets/Flysystem/AssetAdapter.php index 8c4173121..d594c8d28 100644 --- a/src/Assets/Flysystem/AssetAdapter.php +++ b/src/Assets/Flysystem/AssetAdapter.php @@ -7,6 +7,7 @@ use League\Flysystem\Config as FlysystemConfig; use SilverStripe\Assets\File; use SilverStripe\Assets\Filesystem; use SilverStripe\Core\Config\Config; +use SilverStripe\Core\Config\Configurable; use SilverStripe\ORM\ArrayList; use SilverStripe\View\ArrayData; use SilverStripe\View\SSViewer; @@ -16,6 +17,7 @@ use SilverStripe\View\SSViewer; */ class AssetAdapter extends Local { + use Configurable; /** * Server specific configuration necessary to block http traffic to a local folder @@ -50,7 +52,7 @@ class AssetAdapter extends Local $root = realpath($root); // Override permissions with config - $permissions = Config::inst()->get(get_class($this), 'file_permissions'); + $permissions = $this->config()->get('file_permissions'); parent::__construct($root, $writeFlags, $linkHandling, $permissions); // Configure server @@ -104,7 +106,7 @@ class AssetAdapter extends Local list($type) = explode('/', strtolower($type)); // Determine configurations to write - $rules = Config::inst()->get(get_class($this), 'server_configuration', Config::FIRST_SET); + $rules = $this->config()->get('server_configuration'); if (empty($rules[$type])) { return; } diff --git a/src/Assets/Flysystem/FlysystemAssetStore.php b/src/Assets/Flysystem/FlysystemAssetStore.php index 8cb64fa7a..62be01d09 100644 --- a/src/Assets/Flysystem/FlysystemAssetStore.php +++ b/src/Assets/Flysystem/FlysystemAssetStore.php @@ -16,7 +16,7 @@ use SilverStripe\Assets\Storage\AssetStoreRouter; use SilverStripe\Control\Director; use SilverStripe\Control\Session; use SilverStripe\Control\HTTPResponse; -use SilverStripe\Core\Config\Config; +use SilverStripe\Core\Config\Configurable; use SilverStripe\Core\Flushable; use SilverStripe\Core\Injector\Injector; @@ -25,6 +25,7 @@ use SilverStripe\Core\Injector\Injector; */ class FlysystemAssetStore implements AssetStore, AssetStoreRouter, Flushable { + use Configurable; /** * Session key to use for user grants @@ -347,7 +348,7 @@ class FlysystemAssetStore implements AssetStore, AssetStoreRouter, Flushable { if ($dirname && ltrim(dirname($dirname), '.') - && ! Config::inst()->get(get_class($this), 'keep_empty_dirs') + && ! $this->config()->get('keep_empty_dirs') && ! $filesystem->listContents($dirname) ) { $filesystem->deleteDir($dirname); @@ -612,7 +613,7 @@ class FlysystemAssetStore implements AssetStore, AssetStoreRouter, Flushable */ protected function useLegacyFilenames() { - return Config::inst()->get(get_class($this), 'legacy_filenames'); + return $this->config()->get('legacy_filenames'); } public function getMetadata($filename, $hash, $variant = null) @@ -860,7 +861,7 @@ class FlysystemAssetStore implements AssetStore, AssetStoreRouter, Flushable // Add headers $response->addHeader('Content-Type', $mime); - $headers = Config::inst()->get(get_class($this), 'file_response_headers'); + $headers = $this->config()->get('file_response_headers'); foreach ($headers as $header => $value) { $response->addHeader($header, $value); } @@ -874,7 +875,7 @@ class FlysystemAssetStore implements AssetStore, AssetStoreRouter, Flushable */ protected function createDeniedResponse() { - $code = (int)Config::inst()->get(get_class($this), 'denied_response_code'); + $code = (int)$this->config()->get('denied_response_code'); return $this->createErrorResponse($code); } @@ -885,7 +886,7 @@ class FlysystemAssetStore implements AssetStore, AssetStoreRouter, Flushable */ protected function createMissingResponse() { - $code = (int)Config::inst()->get(get_class($this), 'missing_response_code'); + $code = (int)$this->config()->get('missing_response_code'); return $this->createErrorResponse($code); } diff --git a/src/Assets/Flysystem/ProtectedAssetAdapter.php b/src/Assets/Flysystem/ProtectedAssetAdapter.php index 7a47ff759..f6b9ddb33 100644 --- a/src/Assets/Flysystem/ProtectedAssetAdapter.php +++ b/src/Assets/Flysystem/ProtectedAssetAdapter.php @@ -36,7 +36,12 @@ class ProtectedAssetAdapter extends AssetAdapter implements ProtectedAdapter } // Use environment defined path or default location is under assets - return getenv('SS_PROTECTED_ASSETS_PATH') ?: ASSETS_PATH . '/' . Config::inst()->get(get_class($this), 'secure_folder'); + if ($path = getenv('SS_PROTECTED_ASSETS_PATH')) { + return $path; + } + + // Default location + return ASSETS_PATH . '/' . Config::inst()->get(__CLASS__, 'secure_folder'); } /** diff --git a/src/Assets/Image.php b/src/Assets/Image.php index d194d231e..e11be4ea5 100644 --- a/src/Assets/Image.php +++ b/src/Assets/Image.php @@ -21,7 +21,6 @@ use SilverStripe\Forms\FieldList; */ class Image extends File implements ShortcodeHandler { - /** * @config * @var string @@ -54,7 +53,7 @@ class Image extends File implements ShortcodeHandler $image = ""; $link = $this->Link(); - + $statusTitle = $this->getStatusTitle(); $statusFlag = "{$statusTitle}"; diff --git a/src/Assets/ImageManipulation.php b/src/Assets/ImageManipulation.php index 7e0b8fa9b..104a86be7 100644 --- a/src/Assets/ImageManipulation.php +++ b/src/Assets/ImageManipulation.php @@ -479,8 +479,8 @@ trait ImageManipulation */ public function CMSThumbnail() { - $width = (int)Config::inst()->get(get_class($this), 'cms_thumbnail_width'); - $height = (int)Config::inst()->get(get_class($this), 'cms_thumbnail_height'); + $width = (int)Config::inst()->get(__CLASS__, 'cms_thumbnail_width'); + $height = (int)Config::inst()->get(__CLASS__, 'cms_thumbnail_height'); return $this->ThumbnailIcon($width, $height); } @@ -491,8 +491,8 @@ trait ImageManipulation */ public function StripThumbnail() { - $width = (int)Config::inst()->get(get_class($this), 'strip_thumbnail_width'); - $height = (int)Config::inst()->get(get_class($this), 'strip_thumbnail_height'); + $width = (int)Config::inst()->get(__CLASS__, 'strip_thumbnail_width'); + $height = (int)Config::inst()->get(__CLASS__, 'strip_thumbnail_height'); return $this->ThumbnailIcon($width, $height); } @@ -503,7 +503,7 @@ trait ImageManipulation */ public function PreviewThumbnail() { - $width = (int)Config::inst()->get(get_class($this), 'asset_preview_width'); + $width = (int)Config::inst()->get(__CLASS__, 'asset_preview_width'); return $this->ScaleMaxWidth($width) ?: $this->IconTag(); } diff --git a/src/Assets/ImagickBackend.php b/src/Assets/ImagickBackend.php index a9dc8268d..3e738e2eb 100644 --- a/src/Assets/ImagickBackend.php +++ b/src/Assets/ImagickBackend.php @@ -61,7 +61,7 @@ class ImagickBackend extends Imagick implements Image_Backend protected function setDefaultQuality() { - $this->setQuality(Config::inst()->get('SilverStripe\\Assets\\ImagickBackend', 'default_quality')); + $this->setQuality(Config::inst()->get(__CLASS__, 'default_quality')); } public function writeToStore(AssetStore $assetStore, $filename, $hash = null, $variant = null, $config = array()) diff --git a/src/Assets/Upload_Validator.php b/src/Assets/Upload_Validator.php index 2bd7497c8..11fd4c3c2 100644 --- a/src/Assets/Upload_Validator.php +++ b/src/Assets/Upload_Validator.php @@ -90,7 +90,7 @@ class Upload_Validator // Check if there is any defined instance max file sizes if (empty($this->allowedMaxFileSize)) { // Set default max file sizes if there isn't - $fileSize = Config::inst()->get('SilverStripe\\Assets\\Upload_Validator', 'default_max_file_size'); + $fileSize = Config::inst()->get(__CLASS__, 'default_max_file_size'); if ($fileSize) { $this->setAllowedMaxFileSize($fileSize); } else { diff --git a/src/Control/CookieJar.php b/src/Control/CookieJar.php index 33ac83675..dcd8889bc 100644 --- a/src/Control/CookieJar.php +++ b/src/Control/CookieJar.php @@ -173,7 +173,7 @@ class CookieJar implements Cookie_Backend return setcookie($name, $value, $expiry, $path, $domain, $secure, $httpOnly); } - if (Cookie::config()->get('report_errors')) { + if (Cookie::config()->uninherited('report_errors')) { throw new LogicException( "Cookie '$name' can't be set. The site started outputting content at line $line in $file" ); diff --git a/src/Control/Email/Email.php b/src/Control/Email/Email.php index 69e8545c3..3e0908e87 100644 --- a/src/Control/Email/Email.php +++ b/src/Control/Email/Email.php @@ -111,15 +111,15 @@ class Email extends ViewableData public static function obfuscate($email, $method = 'visible') { switch ($method) { - case 'direction' : + case 'direction': Requirements::customCSS('span.codedirection { unicode-bidi: bidi-override; direction: rtl; }', 'codedirectionCSS'); return '' . strrev($email) . ''; - case 'visible' : + case 'visible': $obfuscated = array('@' => ' [at] ', '.' => ' [dot] ', '-' => ' [dash] '); return strtr($email, $obfuscated); - case 'hex' : + case 'hex': $encoded = ''; for ($x = 0; $x < strlen($email); $x++) { $encoded .= '&#x' . bin2hex($email{$x}) . ';'; diff --git a/src/Control/HTTP.php b/src/Control/HTTP.php index 3d108cb90..494530c04 100644 --- a/src/Control/HTTP.php +++ b/src/Control/HTTP.php @@ -5,7 +5,6 @@ namespace SilverStripe\Control; use SilverStripe\Assets\File; use SilverStripe\Core\Config\Configurable; use SilverStripe\Core\Convert; -use SilverStripe\Core\Config\Config; use InvalidArgumentException; use finfo; @@ -308,7 +307,7 @@ class HTTP // to get the file mime-type $ext = File::get_file_extension($filename); // Get the mime-types - $mimeTypes = HTTP::config()->get('MimeTypes'); + $mimeTypes = HTTP::config()->uninherited('MimeTypes'); // The mime type doesn't exist if (!isset($mimeTypes[$ext])) { @@ -397,11 +396,11 @@ class HTTP // Populate $responseHeaders with all the headers that we want to build $responseHeaders = array(); - $cacheControlHeaders = Config::inst()->get(__CLASS__, 'cache_control'); + $cacheControlHeaders = HTTP::config()->uninherited('cache_control'); // currently using a config setting to cancel this, seems to be so that the CMS caches ajax requests - if (function_exists('apache_request_headers') && Config::inst()->get(__CLASS__, 'cache_ajax_requests')) { + if (function_exists('apache_request_headers') && static::config()->uninherited('cache_ajax_requests')) { $requestHeaders = array_change_key_case(apache_request_headers(), CASE_LOWER); if (isset($requestHeaders['x-requested-with']) && $requestHeaders['x-requested-with']=='XMLHttpRequest' @@ -421,7 +420,7 @@ class HTTP // To do: User-Agent should only be added in situations where you *are* actually // varying according to user-agent. - $vary = Config::inst()->get(__CLASS__, 'vary'); + $vary = HTTP::config()->uninherited('vary'); if ($vary && strlen($vary)) { $responseHeaders['Vary'] = $vary; } diff --git a/src/Control/RSS/RSSFeed.php b/src/Control/RSS/RSSFeed.php index a9acbb0b0..6b31d9763 100644 --- a/src/Control/RSS/RSSFeed.php +++ b/src/Control/RSS/RSSFeed.php @@ -221,7 +221,7 @@ class RSSFeed extends ViewableData */ public function outputToBrowser() { - $prevState = SSViewer::config()->get('source_file_comments'); + $prevState = SSViewer::config()->uninherited('source_file_comments'); SSViewer::config()->update('source_file_comments', false); $response = Controller::curr()->getResponse(); diff --git a/src/Control/RequestHandler.php b/src/Control/RequestHandler.php index 98c79349a..14e1a6a9e 100644 --- a/src/Control/RequestHandler.php +++ b/src/Control/RequestHandler.php @@ -2,10 +2,10 @@ namespace SilverStripe\Control; +use InvalidArgumentException; use SilverStripe\Core\Config\Config; use SilverStripe\Core\Object; use SilverStripe\Dev\Debug; -use SilverStripe\Dev\Deprecation; use SilverStripe\ORM\DataModel; use SilverStripe\Security\Security; use SilverStripe\Security\PermissionFailureException; @@ -264,7 +264,7 @@ class RequestHandler extends ViewableData $handlerClass = ($this->class) ? $this->class : get_class($this); // We stop after RequestHandler; in other words, at ViewableData - while ($handlerClass && $handlerClass != 'SilverStripe\\View\\ViewableData') { + while ($handlerClass && $handlerClass != ViewableData::class) { $urlHandlers = Config::inst()->get($handlerClass, 'url_handlers', Config::UNINHERITED); if ($urlHandlers) { @@ -338,22 +338,14 @@ class RequestHandler extends ViewableData public function allowedActions($limitToClass = null) { if ($limitToClass) { - $actions = Config::inst()->get( - $limitToClass, - 'allowed_actions', - Config::UNINHERITED | Config::EXCLUDE_EXTRA_SOURCES - ); + $actions = Config::forClass($limitToClass)->get('allowed_actions', true); } else { - $actions = Config::inst()->get(get_class($this), 'allowed_actions'); + $actions = $this->config()->get('allowed_actions'); } if (is_array($actions)) { if (array_key_exists('*', $actions)) { - Deprecation::notice( - '3.0', - 'Wildcards (*) are no longer valid in $allowed_actions due their ambiguous ' - . ' and potentially insecure behaviour. Please define all methods explicitly instead.' - ); + throw new InvalidArgumentException("Invalid allowed_action '*'"); } // convert all keys and values to lowercase to @@ -413,10 +405,7 @@ class RequestHandler extends ViewableData } } - $actionsWithoutExtra = $this->config()->get( - 'allowed_actions', - Config::UNINHERITED | Config::EXCLUDE_EXTRA_SOURCES - ); + $actionsWithoutExtra = $this->config()->get('allowed_actions', true); if (!is_array($actions) || !$actionsWithoutExtra) { if ($action != 'doInit' && $action != 'run' && method_exists($this, $action)) { return true; diff --git a/src/Dev/SapphireTest.php b/src/Dev/SapphireTest.php index 08f9ad0be..3a11bb1cb 100644 --- a/src/Dev/SapphireTest.php +++ b/src/Dev/SapphireTest.php @@ -3,26 +3,28 @@ namespace SilverStripe\Dev; use SilverStripe\CMS\Controllers\RootURLController; -use SilverStripe\CMS\Model\SiteTree; use SilverStripe\Control\Cookie; use SilverStripe\Control\Email\Email; use SilverStripe\Control\Email\Mailer; use SilverStripe\Control\Session; use SilverStripe\Control\Controller; use SilverStripe\Control\Director; +use SilverStripe\Control\Tests\FakeController; use SilverStripe\Core\Config\Config; use SilverStripe\Core\ClassInfo; +use SilverStripe\Core\Config\ConfigLoader; +use SilverStripe\Core\Config\CoreConfigCreator; +use SilverStripe\Core\Config\DefaultConfig; +use SilverStripe\Core\Config\Middleware\ExtensionMiddleware; use SilverStripe\Core\Flushable; use SilverStripe\Core\Injector\Injector; use SilverStripe\Core\Manifest\ClassManifest; use SilverStripe\Core\Manifest\ClassLoader; -use SilverStripe\Core\Manifest\ConfigStaticManifest; use SilverStripe\Core\Resettable; use SilverStripe\i18n\i18n; use SilverStripe\ORM\SS_List; use SilverStripe\ORM\Versioning\Versioned; use SilverStripe\ORM\DataObject; -use SilverStripe\ORM\Hierarchy\Hierarchy; use SilverStripe\ORM\DataModel; use SilverStripe\ORM\FieldType\DBDatetime; use SilverStripe\ORM\FieldType\DBField; @@ -224,13 +226,15 @@ class SapphireTest extends PHPUnit_Framework_TestCase */ protected $originalReadingMode = null; + protected $originalEnv = null; + public function setUp() { - //nest config and injector for each test so they are effectively sandboxed per test Config::nest(); Injector::nest(); + $this->originalEnv = Director::get_environment_type(); $this->originalReadingMode = Versioned::get_reading_mode(); // We cannot run the tests on this abstract class. @@ -244,7 +248,7 @@ class SapphireTest extends PHPUnit_Framework_TestCase self::$is_running_test = true; // i18n needs to be set to the defaults or tests fail - i18n::set_locale(i18n::config()->get('default_locale')); + i18n::set_locale(i18n::config()->uninherited('default_locale')); // Set default timezone consistently to avoid NZ-specific dependencies date_default_timezone_set('UTC'); @@ -333,6 +337,8 @@ class SapphireTest extends PHPUnit_Framework_TestCase */ public function setUpOnce() { + static::start(); + //nest config and injector for each suite so they are effectively sandboxed Config::nest(); Injector::nest(); @@ -590,6 +596,7 @@ class SapphireTest extends PHPUnit_Framework_TestCase $response->removeHeader('Location'); } + Director::set_environment_type($this->originalEnv); Versioned::set_reading_mode($this->originalReadingMode); //unnest injector / config now that tests are over @@ -985,11 +992,23 @@ class SapphireTest extends PHPUnit_Framework_TestCase return var_export($extracted, true); } + /** + * Start test environment + */ + public static function start() + { + if (!static::is_running_test()) { + new FakeController(); + static::use_test_manifest(); + static::set_is_running_test(true); + } + } + /** * Pushes a class and template manifest instance that include tests onto the * top of the loader stacks. */ - public static function use_test_manifest() + protected static function use_test_manifest() { $flush = !empty($_GET['flush']); $classManifest = new ClassManifest( @@ -1008,11 +1027,9 @@ class SapphireTest extends PHPUnit_Framework_TestCase $flush )); - Config::inst()->pushConfigStaticManifest(new ConfigStaticManifest( - BASE_PATH, - true, - $flush - )); + // Once new class loader is registered, push a new uncached config + $config = CoreConfigCreator::inst()->createCore(); + ConfigLoader::instance()->pushManifest($config); // Invalidate classname spec since the test manifest will now pull out new subclasses for each internal class // (e.g. Member will now have various subclasses of DataObjects that implement TestOnly) @@ -1322,6 +1339,30 @@ class SapphireTest extends PHPUnit_Framework_TestCase } protected function setUpRoutes() + { + // Get overridden routes + $rules = $this->getExtraRoutes(); + + // Add all other routes + foreach (Director::config()->uninherited('rules') as $route => $rule) { + if (!isset($rules[$route])) { + $rules[$route] = $rule; + } + } + + // Add default catch-all rule + $rules['$Controller//$Action/$ID/$OtherID'] = '*'; + + // Add controller-name auto-routing + Director::config()->set('rules', $rules); + } + + /** + * Get extra routes to merge into Director.rules + * + * @return array + */ + protected function getExtraRoutes() { $rules = []; foreach ($this->getExtraControllers() as $class) { @@ -1330,11 +1371,6 @@ class SapphireTest extends PHPUnit_Framework_TestCase $route = rtrim($link, '/') . '//$Action/$ID/$OtherID'; $rules[$route] = $class; } - - // Add default catch-all rule - $rules['$Controller//$Action/$ID/$OtherID'] = '*'; - - // Add controller-name auto-routing - Director::config()->update('rules', $rules); + return $rules; } } diff --git a/src/Forms/CountryDropdownField.php b/src/Forms/CountryDropdownField.php index 882e78744..54ae894e6 100644 --- a/src/Forms/CountryDropdownField.php +++ b/src/Forms/CountryDropdownField.php @@ -52,7 +52,7 @@ class CountryDropdownField extends DropdownField } // Get sorted countries - $source = i18n::getData()->i18nCountries(); + $source = i18n::getData()->getCountries(); return parent::setSource($source); } @@ -62,7 +62,7 @@ class CountryDropdownField extends DropdownField // Default value to best availabel locale $value = $this->Value(); - if ($this->config()->default_to_locale + if (CountryDropdownField::config()->default_to_locale && (!$value || !isset($source[$value])) && $this->locale() ) { @@ -74,7 +74,7 @@ class CountryDropdownField extends DropdownField // Default to default country otherwise if (!$value || !isset($source[$value])) { - $this->setValue($this->config()->default_country); + $this->setValue(CountryDropdownField::config()->default_country); } return parent::Field($properties); diff --git a/src/Forms/CurrencyField.php b/src/Forms/CurrencyField.php index 82b394c7f..66f6e826a 100644 --- a/src/Forms/CurrencyField.php +++ b/src/Forms/CurrencyField.php @@ -27,7 +27,7 @@ class CurrencyField extends TextField if (!$value) { $value = 0.00; } - $this->value = DBCurrency::config()->get('currency_symbol') + $this->value = DBCurrency::config()->uninherited('currency_symbol') . number_format((double)preg_replace('/[^0-9.\-]/', '', $value), 2); return $this; } @@ -59,7 +59,7 @@ class CurrencyField extends TextField public function validate($validator) { - $currencySymbol = preg_quote(DBCurrency::config()->get('currency_symbol')); + $currencySymbol = preg_quote(DBCurrency::config()->uninherited('currency_symbol')); $regex = '/^\s*(\-?'.$currencySymbol.'?|'.$currencySymbol.'\-?)?(\d{1,3}(\,\d{3})*|(\d+))(\.\d{2})?\s*$/'; if (!empty($this->value) && !preg_match($regex, $this->value)) { $validator->validationError( diff --git a/src/Forms/DateField.php b/src/Forms/DateField.php index 9a759fade..ea3e3a7dc 100644 --- a/src/Forms/DateField.php +++ b/src/Forms/DateField.php @@ -244,7 +244,7 @@ class DateField extends TextField protected function getISO8601Formatter() { $formatter = IntlDateFormatter::create( - i18n::config()->get('default_locale'), + i18n::config()->uninherited('default_locale'), IntlDateFormatter::MEDIUM, IntlDateFormatter::NONE ); diff --git a/src/Forms/DateField_View_JQuery.php b/src/Forms/DateField_View_JQuery.php index 4e5a164b1..b00539b80 100644 --- a/src/Forms/DateField_View_JQuery.php +++ b/src/Forms/DateField_View_JQuery.php @@ -3,6 +3,7 @@ namespace SilverStripe\Forms; use InvalidArgumentException; +use SilverStripe\Core\Config\Config; use SilverStripe\Core\Config\Configurable; use SilverStripe\Core\Injector\Injectable; use SilverStripe\i18n\i18n; @@ -109,7 +110,7 @@ class DateField_View_JQuery $locale = $this->getField()->getClientLocale(); // Check standard mappings - $map = $this->config()->locale_map; + $map = Config::inst()->get(__CLASS__, 'locale_map'); if (array_key_exists($locale, $map)) { return $map[$locale]; } diff --git a/src/Forms/DatetimeField.php b/src/Forms/DatetimeField.php index a92213de6..4190e2d3e 100644 --- a/src/Forms/DatetimeField.php +++ b/src/Forms/DatetimeField.php @@ -137,7 +137,7 @@ class DatetimeField extends FormField protected function getISO8601Formatter() { $formatter = IntlDateFormatter::create( - i18n::config()->get('default_locale'), + i18n::config()->uninherited('default_locale'), IntlDateFormatter::MEDIUM, IntlDateFormatter::MEDIUM, date_default_timezone_get() // Default to server timezone diff --git a/src/Forms/FormField.php b/src/Forms/FormField.php index ebcdf4d85..ac60eb425 100644 --- a/src/Forms/FormField.php +++ b/src/Forms/FormField.php @@ -375,7 +375,7 @@ class FormField extends RequestHandler */ protected function setupDefaultClasses() { - $defaultClasses = self::config()->get('default_classes'); + $defaultClasses = $this->config()->get('default_classes'); if ($defaultClasses) { foreach ($defaultClasses as $class) { $this->addExtraClass($class); diff --git a/src/Forms/FormScaffolder.php b/src/Forms/FormScaffolder.php index a4a91cdda..3e946017a 100644 --- a/src/Forms/FormScaffolder.php +++ b/src/Forms/FormScaffolder.php @@ -80,7 +80,7 @@ class FormScaffolder extends Object } // Add logical fields directly specified in db config - foreach ($this->obj->config()->db as $fieldName => $fieldType) { + foreach ($this->obj->config()->get('db') as $fieldName => $fieldType) { // Skip restricted fields if ($this->restrictFields && !in_array($fieldName, $this->restrictFields)) { continue; diff --git a/src/Forms/GridField/GridField.php b/src/Forms/GridField/GridField.php index 24b56dfcd..4fa52cd36 100644 --- a/src/Forms/GridField/GridField.php +++ b/src/Forms/GridField/GridField.php @@ -18,7 +18,6 @@ use SilverStripe\Forms\FormField; use SilverStripe\Forms\Form; use LogicException; use InvalidArgumentException; -use SilverStripe\View\Requirements; /** * Displays a {@link SS_List} in a grid format. @@ -128,7 +127,7 @@ class GridField extends FormField $this->setConfig($config); - $state = $this->config->getComponentByType('SilverStripe\\Forms\\GridField\\GridState_Component'); + $state = $this->config->getComponentByType(GridState_Component::class); if (!$state) { $this->config->addComponent(new GridState_Component()); diff --git a/src/Forms/GridField/GridFieldAddExistingAutocompleter.php b/src/Forms/GridField/GridFieldAddExistingAutocompleter.php index 4c5051038..3199c1cdd 100644 --- a/src/Forms/GridField/GridFieldAddExistingAutocompleter.php +++ b/src/Forms/GridField/GridFieldAddExistingAutocompleter.php @@ -326,7 +326,7 @@ class GridFieldAddExistingAutocompleter implements GridField_HTMLProvider, GridF */ public function scaffoldSearchFields($dataClass) { - $obj = singleton($dataClass); + $obj = DataObject::singleton($dataClass); $fields = null; if ($fieldSpecs = $obj->searchableFields()) { $customSearchableFields = $obj->stat('searchable_fields'); diff --git a/src/Forms/GridField/GridFieldPageCount.php b/src/Forms/GridField/GridFieldPageCount.php index f8d51af90..c46dd580e 100755 --- a/src/Forms/GridField/GridFieldPageCount.php +++ b/src/Forms/GridField/GridFieldPageCount.php @@ -47,9 +47,9 @@ class GridFieldPageCount implements GridField_HTMLProvider protected function getPaginator($gridField) { /** @var GridFieldPaginator $paginator */ - $paginator = $gridField->getConfig()->getComponentByType('SilverStripe\\Forms\\GridField\\GridFieldPaginator'); + $paginator = $gridField->getConfig()->getComponentByType(GridFieldPaginator::class); - if (!$paginator && $this->config()->get('require_paginator')) { + if (!$paginator && GridFieldPageCount::config()->uninherited('require_paginator')) { throw new LogicException( get_class($this) . " relies on a GridFieldPaginator to be added " . "to the same GridField, but none are present." diff --git a/src/Forms/GridField/GridFieldPaginator.php b/src/Forms/GridField/GridFieldPaginator.php index fb84a30da..d1438e943 100755 --- a/src/Forms/GridField/GridFieldPaginator.php +++ b/src/Forms/GridField/GridFieldPaginator.php @@ -42,7 +42,8 @@ class GridFieldPaginator implements GridField_HTMLProvider, GridField_DataManipu */ public function __construct($itemsPerPage = null) { - $this->itemsPerPage = $itemsPerPage ?: GridFieldPaginator::config()->get('default_items_per_page'); + $this->itemsPerPage = $itemsPerPage + ?: GridFieldPaginator::config()->uninherited('default_items_per_page'); } /** diff --git a/src/Forms/HTMLEditor/HTMLEditorField.php b/src/Forms/HTMLEditor/HTMLEditorField.php index 2ed31aa00..a46a01086 100644 --- a/src/Forms/HTMLEditor/HTMLEditorField.php +++ b/src/Forms/HTMLEditor/HTMLEditorField.php @@ -105,7 +105,7 @@ class HTMLEditorField extends TextareaField $this->setEditorConfig($config); } - $this->setRows($this->config()->default_rows); + $this->setRows(HTMLEditorField::config()->default_rows); } public function getAttributes() @@ -130,7 +130,7 @@ class HTMLEditorField extends TextareaField // Sanitise if requested $htmlValue = Injector::inst()->create('HTMLValue', $this->Value()); - if ($this->config()->sanitise_server_side) { + if (HTMLEditorField::config()->sanitise_server_side) { $santiser = HTMLEditorSanitiser::create(HTMLEditorConfig::get_active()); $santiser->sanitise($htmlValue); } diff --git a/src/Forms/HTMLEditor/HTMLEditorField_File.php b/src/Forms/HTMLEditor/HTMLEditorField_File.php index afb8d1ba2..a8b697d52 100644 --- a/src/Forms/HTMLEditor/HTMLEditorField_File.php +++ b/src/Forms/HTMLEditor/HTMLEditorField_File.php @@ -118,7 +118,7 @@ abstract class HTMLEditorField_File extends ViewableData 'left' => _t('HTMLEditorField.CSSCLASSLEFT', 'On the left, with text wrapping around.'), 'right' => _t('HTMLEditorField.CSSCLASSRIGHT', 'On the right, with text wrapping around.') ), - HtmlEditorField::config()->get('media_alignment') + HtmlEditorField::config()->uninherited('media_alignment') ), FieldGroup::create( _t('HTMLEditorField.IMAGEDIMENSIONS', 'Dimensions'), @@ -313,8 +313,8 @@ abstract class HTMLEditorField_File extends ViewableData { // Get preview from file if ($this->file) { - $width = $this->config()->media_preview_width; - $height = $this->config()->media_preview_height; + $width = HTMLEditorField_File::config()->media_preview_width; + $height = HTMLEditorField_File::config()->media_preview_height; return $this->file->ThumbnailURL($width, $height); } return null; @@ -356,7 +356,7 @@ abstract class HTMLEditorField_File extends ViewableData return $height; } } - return $this->config()->insert_height; + return HTMLEditorField_File::config()->insert_height; } /** @@ -372,7 +372,7 @@ abstract class HTMLEditorField_File extends ViewableData return $width; } } - return $this->config()->insert_width; + return HTMLEditorField_File::config()->insert_width; } /** @@ -383,7 +383,7 @@ abstract class HTMLEditorField_File extends ViewableData public function getInsertWidth() { $width = $this->getWidth(); - $maxWidth = $this->config()->insert_width; + $maxWidth = HTMLEditorField_File::config()->insert_width; return ($width <= $maxWidth) ? $width : $maxWidth; } @@ -396,7 +396,7 @@ abstract class HTMLEditorField_File extends ViewableData { $width = $this->getWidth(); $height = $this->getHeight(); - $maxWidth = $this->config()->insert_width; + $maxWidth = HTMLEditorField_File::config()->insert_width; return ($width <= $maxWidth) ? $height : round($height * ($maxWidth / $width)); } } diff --git a/src/Forms/HTMLEditor/HTMLEditorField_Image.php b/src/Forms/HTMLEditor/HTMLEditorField_Image.php index 41ae82707..e18d19f93 100644 --- a/src/Forms/HTMLEditor/HTMLEditorField_Image.php +++ b/src/Forms/HTMLEditor/HTMLEditorField_Image.php @@ -181,7 +181,7 @@ class HTMLEditorField_Image extends HTMLEditorField_File public function getInsertWidth() { $width = $this->getWidth(); - $maxWidth = $this->config()->insert_width; + $maxWidth = HTMLEditorField_Image::config()->insert_width; return $width <= $maxWidth ? $width : $maxWidth; @@ -196,7 +196,7 @@ class HTMLEditorField_Image extends HTMLEditorField_File { $width = $this->getWidth(); $height = $this->getHeight(); - $maxWidth = $this->config()->insert_width; + $maxWidth = HTMLEditorField_Image::config()->insert_width; return ($width <= $maxWidth) ? $height : round($height * ($maxWidth / $width)); } diff --git a/src/Forms/HTMLEditor/HTMLEditorField_Toolbar.php b/src/Forms/HTMLEditor/HTMLEditorField_Toolbar.php index becc05b73..6ab7f5a15 100644 --- a/src/Forms/HTMLEditor/HTMLEditorField_Toolbar.php +++ b/src/Forms/HTMLEditor/HTMLEditorField_Toolbar.php @@ -3,6 +3,7 @@ namespace SilverStripe\Forms\HTMLEditor; use SilverStripe\Assets\File; +use SilverStripe\Assets\Folder; use SilverStripe\Assets\Upload; use SilverStripe\CMS\Model\SiteTree; use SilverStripe\Control\Controller; @@ -252,7 +253,7 @@ class HTMLEditorField_Toolbar extends RequestHandler )); } $scheme = strtolower(parse_url($fileUrl, PHP_URL_SCHEME)); - $allowed_schemes = self::config()->fileurl_scheme_whitelist; + $allowed_schemes = self::config()->get('fileurl_scheme_whitelist'); if (!$scheme || ($allowed_schemes && !in_array($scheme, $allowed_schemes))) { throw $this->getErrorFor(_t( "HTMLEditorField_Toolbar.ERROR_SCHEME", @@ -260,7 +261,7 @@ class HTMLEditorField_Toolbar extends RequestHandler )); } $domain = strtolower(parse_url($fileUrl, PHP_URL_HOST)); - $allowed_domains = self::config()->fileurl_domain_whitelist; + $allowed_domains = self::config()->get('fileurl_domain_whitelist'); if (!$domain || ($allowed_domains && !in_array($domain, $allowed_domains))) { throw $this->getErrorFor(_t( "HTMLEditorField_Toolbar.ERROR_HOSTNAME", diff --git a/src/Forms/HTMLEditor/TinyMCEConfig.php b/src/Forms/HTMLEditor/TinyMCEConfig.php index 475ce62a6..4285aa310 100644 --- a/src/Forms/HTMLEditor/TinyMCEConfig.php +++ b/src/Forms/HTMLEditor/TinyMCEConfig.php @@ -555,7 +555,8 @@ class TinyMCEConfig extends HTMLEditorConfig // https://www.tinymce.com/docs/api/class/tinymce.editormanager/#baseURL $tinyMCEBaseURL = Controller::join_links( Director::absoluteBaseURL(), - $this->config()->get('base_dir') ?: ADMIN_THIRDPARTY_DIR . '/tinymce' + TinyMCEConfig::config()->get('base_dir') + ?: ADMIN_THIRDPARTY_DIR . '/tinymce' ); $settings['baseURL'] = $tinyMCEBaseURL; diff --git a/src/Forms/MemberDatetimeOptionsetField.php b/src/Forms/MemberDatetimeOptionsetField.php index e49b91e1b..b815ca009 100644 --- a/src/Forms/MemberDatetimeOptionsetField.php +++ b/src/Forms/MemberDatetimeOptionsetField.php @@ -95,7 +95,7 @@ class MemberDatetimeOptionsetField extends OptionsetField */ protected function previewFormat($format) { - $date = DBDatetime::create_field('Datetime', $this->config()->preview_date); + $date = DBDatetime::create_field('Datetime', MemberDatetimeOptionsetField::config()->preview_date); return $date->Format($format); } diff --git a/src/Forms/NumericField.php b/src/Forms/NumericField.php index 63a2007fb..022c896e4 100644 --- a/src/Forms/NumericField.php +++ b/src/Forms/NumericField.php @@ -55,7 +55,10 @@ class NumericField extends TextField { if ($this->getHTML5()) { // Locale-independent html5 number formatter - $formatter = NumberFormatter::create(i18n::config()->get('default_locale'), NumberFormatter::DECIMAL); + $formatter = NumberFormatter::create( + i18n::config()->uninherited('default_locale'), + NumberFormatter::DECIMAL + ); $formatter->setAttribute(NumberFormatter::GROUPING_USED, false); $formatter->setSymbol(NumberFormatter::DECIMAL_SEPARATOR_SYMBOL, '.'); } else { diff --git a/src/Forms/ReadonlyField.php b/src/Forms/ReadonlyField.php index b42b9c159..649fa689f 100644 --- a/src/Forms/ReadonlyField.php +++ b/src/Forms/ReadonlyField.php @@ -106,6 +106,7 @@ class ReadonlyField extends FormField } // Use default casting - return $this->config()->casting['Value']; + $casting = $this->config()->get('casting'); + return $casting['Value']; } } diff --git a/src/Forms/TimeField.php b/src/Forms/TimeField.php index 1ea49bfb1..ee5427510 100644 --- a/src/Forms/TimeField.php +++ b/src/Forms/TimeField.php @@ -158,7 +158,7 @@ class TimeField extends TextField protected function getISO8601Formatter() { $formatter = IntlDateFormatter::create( - i18n::config()->get('default_locale'), + i18n::config()->uninherited('default_locale'), IntlDateFormatter::NONE, IntlDateFormatter::MEDIUM, date_default_timezone_get() // Default to server timezone diff --git a/src/Forms/UploadField_SelectHandler.php b/src/Forms/UploadField_SelectHandler.php index 72e6720e5..665212465 100644 --- a/src/Forms/UploadField_SelectHandler.php +++ b/src/Forms/UploadField_SelectHandler.php @@ -135,9 +135,8 @@ class UploadField_SelectHandler extends RequestHandler )); // Set configurable pagination for file list field - $pageSize = Config::inst()->get(get_class($this), 'page_size'); + $pageSize = $this->config()->get('page_size'); $config->addComponent(new GridFieldPaginator($pageSize)); - // If relation is to be autoset, we need to make sure we only list compatible objects. $baseClass = $this->parent->getRelationAutosetClass(); diff --git a/src/ORM/DataObject.php b/src/ORM/DataObject.php index b0577a71c..2bd3e8377 100644 --- a/src/ORM/DataObject.php +++ b/src/ORM/DataObject.php @@ -2,6 +2,7 @@ namespace SilverStripe\ORM; +use SilverStripe\Assets\AssetControlExtension; use SilverStripe\Core\ClassInfo; use SilverStripe\Core\Config\Config; use SilverStripe\Core\Object; @@ -252,9 +253,9 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity * @config * @var array */ - private static $extensions = array( - 'AssetControl' => 'SilverStripe\\Assets\\AssetControlExtension' - ); + private static $extensions = [ + 'AssetControl' => AssetControlExtension::class, + ]; /** * Override table name for this class. If ignored will default to FQN of class. @@ -651,7 +652,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity */ public function isEmpty() { - $fixed = $this->config()->fixed_fields; + $fixed = DataObject::config()->uninherited('fixed_fields'); foreach ($this->toMap() as $field => $value) { // only look at custom fields if (isset($fixed[$field])) { @@ -1175,7 +1176,8 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity ); } - if ($this->config()->get('validation_enabled')) { + // Note: Validation can only be disabled at the global level, not per-model + if (DataObject::config()->uninherited('validation_enabled')) { $result = $this->validate(); if (!$result->isValid()) { return new ValidationException($result); @@ -1659,10 +1661,11 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity } // Go through all relationship configuration fields. + $config = $this->config(); $candidates = array_merge( - ($relations = Config::inst()->get($this->class, 'has_one')) ? $relations : array(), - ($relations = Config::inst()->get($this->class, 'has_many')) ? $relations : array(), - ($relations = Config::inst()->get($this->class, 'belongs_to')) ? $relations : array() + ($relations = $config->get('has_one')) ? $relations : array(), + ($relations = $config->get('has_many')) ? $relations : array(), + ($relations = $config->get('belongs_to')) ? $relations : array() ); if (isset($candidates[$relationName])) { @@ -1689,8 +1692,9 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity public function getRelationType($component) { $types = array('has_one', 'has_many', 'many_many', 'belongs_many_many', 'belongs_to'); + $config = $this->config(); foreach ($types as $type) { - $relations = Config::inst()->get($this->class, $type); + $relations = $config->get($type); if ($relations && isset($relations[$component])) { return $type; } @@ -1891,7 +1895,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity */ public function hasOne() { - return (array)Config::inst()->get($this->class, 'has_one', Config::INHERITED); + return (array)$this->config()->get('has_one'); } /** @@ -1904,7 +1908,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity */ public function belongsTo($classOnly = true) { - $belongsTo = (array)Config::inst()->get($this->class, 'belongs_to', Config::INHERITED); + $belongsTo = (array)$this->config()->get('belongs_to'); if ($belongsTo && $classOnly) { return preg_replace('/(.+)?\..+/', '$1', $belongsTo); } else { @@ -1922,7 +1926,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity */ public function hasMany($classOnly = true) { - $hasMany = (array)Config::inst()->get($this->class, 'has_many', Config::INHERITED); + $hasMany = (array)$this->config()->get('has_many'); if ($hasMany && $classOnly) { return preg_replace('/(.+)?\..+/', '$1', $hasMany); } else { @@ -1940,7 +1944,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity */ public function manyManyExtraFields() { - return Config::inst()->get($this->class, 'many_many_extraFields', Config::INHERITED); + return $this->config()->get('many_many_extraFields'); } /** @@ -1953,8 +1957,9 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity */ public function manyMany() { - $manyManys = (array)Config::inst()->get($this->class, 'many_many', Config::INHERITED); - $belongsManyManys = (array)Config::inst()->get($this->class, 'belongs_many_many', Config::INHERITED); + $config = $this->config(); + $manyManys = (array)$config->get('many_many'); + $belongsManyManys = (array)$config->get('belongs_many_many'); $items = array_merge($manyManys, $belongsManyManys); return $items; } @@ -1970,7 +1975,6 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity public function database_extensions($class) { $extensions = Config::inst()->get($class, 'database_extensions', Config::UNINHERITED); - if ($extensions) { return $extensions; } else { @@ -2533,65 +2537,25 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity */ public function can($perm, $member = null, $context = array()) { - if (!isset($member)) { - $member = Member::currentUser(); + if (!$member || !($member instanceof Member) || is_numeric($member)) { + $member = Member::currentUserID(); } - if (Permission::checkMember($member, "ADMIN")) { + + if ($member && Permission::checkMember($member, "ADMIN")) { return true; } - if ($this->getSchema()->manyManyComponent(static::class, 'Can' . $perm)) { - if ($this->ParentID && $this->SecurityType == 'Inherit') { - if (!($p = $this->Parent)) { - return false; - } - return $this->Parent->can($perm, $member); - } else { - $permissionCache = $this->uninherited('permissionCache'); - $memberID = $member ? $member->ID : 'none'; - - if (!isset($permissionCache[$memberID][$perm])) { - if ($member->ID) { - $groups = $member->Groups(); - } - - $groupList = implode(', ', $groups->column("ID")); - - // TODO Fix relation table hardcoding - $query = new SQLSelect( - "\"Page_Can$perm\".PageID", - array("\"Page_Can$perm\""), - "GroupID IN ($groupList)" - ); - - $permissionCache[$memberID][$perm] = $query->execute()->column(); - - if ($perm == "View") { - // TODO Fix relation table hardcoding - $query = new SQLSelect("\"SiteTree\".\"ID\"", array( - "\"SiteTree\"", - "LEFT JOIN \"Page_CanView\" ON \"Page_CanView\".\"PageID\" = \"SiteTree\".\"ID\"" - ), "\"Page_CanView\".\"PageID\" IS NULL"); - - $unsecuredPages = $query->execute()->column(); - if ($permissionCache[$memberID][$perm]) { - $permissionCache[$memberID][$perm] - = array_merge($permissionCache[$memberID][$perm], $unsecuredPages); - } else { - $permissionCache[$memberID][$perm] = $unsecuredPages; - } - } - - Config::inst()->update($this->class, 'permissionCache', $permissionCache); - } - - if ($permissionCache[$memberID][$perm]) { - return in_array($this->ID, $permissionCache[$memberID][$perm]); - } - } - } else { - return parent::can($perm, $member); + if (is_string($perm) && method_exists($this, 'can' . ucfirst($perm))) { + $method = 'can' . ucfirst($perm); + return $this->$method($member); } + + $results = $this->extendedCan('can', $member); + if (isset($results)) { + return $results; + } + + return ($member && Permission::checkMember($member, $perm)); } /** @@ -3240,7 +3204,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity */ public function requireDefaultRecords() { - $defaultRecords = $this->config()->get('default_records', Config::UNINHERITED); + $defaultRecords = $this->config()->uninherited('default_records'); if (!empty($defaultRecords)) { $hasData = DataObject::get_one($this->class); @@ -3381,9 +3345,9 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity if ($ancestorClass === ViewableData::class) { break; } - $types = array( - 'db' => (array)Config::inst()->get($ancestorClass, 'db', Config::UNINHERITED) - ); + $types = [ + 'db' => (array)Config::inst()->get($ancestorClass, 'db', Config::UNINHERITED) + ]; if ($includerelations) { $types['has_one'] = (array)Config::inst()->get($ancestorClass, 'has_one', Config::UNINHERITED); $types['has_many'] = (array)Config::inst()->get($ancestorClass, 'has_many', Config::UNINHERITED); @@ -3537,7 +3501,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity * @var array * @config */ - private static $db = null; + private static $db = []; /** * Use a casting object for a field. This is a map from @@ -3593,7 +3557,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity * @var array * @config */ - private static $defaults = null; + private static $defaults = []; /** * Multidimensional array which inserts default data into the database @@ -3621,7 +3585,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity * @var array * @config */ - private static $has_one = null; + private static $has_one = []; /** * A meta-relationship that allows you to define the reverse side of a {@link DataObject::$has_one}. @@ -3635,7 +3599,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity * @var array * @config */ - private static $belongs_to; + private static $belongs_to = []; /** * This defines a one-to-many relationship. It is a map of component name to the remote data class. @@ -3648,7 +3612,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity * @var array * @config */ - private static $has_many = null; + private static $has_many = []; /** * many-many relationship definitions. @@ -3656,7 +3620,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity * @var array * @config */ - private static $many_many = null; + private static $many_many = []; /** * Extra fields to include on the connecting many-many table. @@ -3674,7 +3638,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity * @var array * @config */ - private static $many_many_extraFields = null; + private static $many_many_extraFields = []; /** * The inverse side of a many-many relationship. @@ -3682,7 +3646,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity * @var array * @config */ - private static $belongs_many_many = null; + private static $belongs_many_many = []; /** * The default sort expression. This will be inserted in the ORDER BY @@ -3733,14 +3697,14 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity * default display in the search form. * @config */ - private static $field_labels = null; + private static $field_labels = []; /** * Provides a default list of fields to be used by a 'summary' * view of this object. * @config */ - private static $summary_fields = null; + private static $summary_fields = []; public function provideI18nEntities() { diff --git a/src/ORM/DataObjectSchema.php b/src/ORM/DataObjectSchema.php index 5152966bf..a5477d098 100644 --- a/src/ORM/DataObjectSchema.php +++ b/src/ORM/DataObjectSchema.php @@ -17,7 +17,6 @@ use LogicException; */ class DataObjectSchema { - use Injectable; use Configurable; @@ -289,7 +288,7 @@ class DataObjectSchema // Generate default table name if (!$table) { - $separator = $this->config()->get('table_namespace_separator'); + $separator = DataObjectSchema::config()->uninherited('table_namespace_separator'); $table = str_replace('\\', $separator, trim($class, '\\')); } @@ -410,7 +409,7 @@ class DataObjectSchema $dbFields = array(); // Ensure fixed fields appear at the start - $fixedFields = DataObject::config()->get('fixed_fields'); + $fixedFields = DataObject::config()->uninherited('fixed_fields'); if (get_parent_class($class) === DataObject::class) { // Merge fixed with ClassName spec and custom db fields $dbFields = $fixedFields; @@ -495,7 +494,7 @@ class DataObjectSchema } // Short circuit for fixed fields - $fixed = DataObject::config()->get('fixed_fields'); + $fixed = DataObject::config()->uninherited('fixed_fields'); if (isset($fixed[$fieldName])) { return $this->baseDataClass($candidateClass); } @@ -660,7 +659,7 @@ class DataObjectSchema */ public function hasOneComponent($class, $component) { - $hasOnes = Config::inst()->get($class, 'has_one'); + $hasOnes = Config::forClass($class)->get('has_one'); if (!isset($hasOnes[$component])) { return null; } @@ -682,7 +681,7 @@ class DataObjectSchema */ public function belongsToComponent($class, $component, $classOnly = true) { - $belongsTo = (array)Config::inst()->get($class, 'belongs_to'); + $belongsTo = (array)Config::forClass($class)->get('belongs_to'); if (!isset($belongsTo[$component])) { return null; } diff --git a/src/ORM/Versioning/Versioned.php b/src/ORM/Versioning/Versioned.php index 712882529..ef1e0af23 100644 --- a/src/ORM/Versioning/Versioned.php +++ b/src/ORM/Versioning/Versioned.php @@ -595,7 +595,7 @@ class Versioned extends DataExtension implements TemplateGlobalProvider, Resetta // Build a list of suffixes whose tables need versioning $allSuffixes = array(); - $versionableExtensions = $owner->config()->versionableExtensions; + $versionableExtensions = $owner->config()->get('versionableExtensions'); if (count($versionableExtensions)) { foreach ($versionableExtensions as $versionableExtension => $suffixes) { if ($owner->hasExtension($versionableExtension)) { @@ -622,7 +622,7 @@ class Versioned extends DataExtension implements TemplateGlobalProvider, Resetta $fields = $schema->databaseFields($class, false); unset($fields['ID']); if ($fields) { - $options = Config::inst()->get($class, 'create_table_options', Config::FIRST_SET); + $options = Config::inst()->get($class, 'create_table_options'); $indexes = $owner->databaseIndexes(); $extensionClass = $allSuffixes[$suffix]; if ($suffix && ($extension = $owner->getExtensionInstance($extensionClass))) { @@ -1104,7 +1104,7 @@ class Versioned extends DataExtension implements TemplateGlobalProvider, Resetta return $list; } - $relationships = $owner->config()->{$source}; + $relationships = $owner->config()->get($source); foreach ($relationships as $relationship) { // Warn if invalid config if (!$owner->hasMethod($relationship)) { @@ -1375,7 +1375,7 @@ class Versioned extends DataExtension implements TemplateGlobalProvider, Resetta } // Fall back to default permission check - $permissions = Config::inst()->get($owner->class, 'non_live_permissions', Config::FIRST_SET); + $permissions = Config::inst()->get($owner->class, 'non_live_permissions'); $check = Permission::checkMember($member, $permissions); return (bool)$check; } @@ -1441,7 +1441,7 @@ class Versioned extends DataExtension implements TemplateGlobalProvider, Resetta public function extendWithSuffix($table) { $owner = $this->owner; - $versionableExtensions = $owner->config()->versionableExtensions; + $versionableExtensions = $owner->config()->get('versionableExtensions'); if (count($versionableExtensions)) { foreach ($versionableExtensions as $versionableExtension => $suffixes) { @@ -1546,8 +1546,8 @@ class Versioned extends DataExtension implements TemplateGlobalProvider, Resetta // after publishing, objects which used to be owned need to be // dis-connected from this object (set ForeignKeyID = 0) - $owns = $owner->config()->owns; - $hasMany = $owner->config()->has_many; + $owns = $owner->config()->get('owns'); + $hasMany = $owner->config()->get('has_many'); if (empty($owns) || empty($hasMany)) { return; } diff --git a/src/Security/BasicAuth.php b/src/Security/BasicAuth.php index fb00fdc0e..073f9c30d 100644 --- a/src/Security/BasicAuth.php +++ b/src/Security/BasicAuth.php @@ -160,7 +160,7 @@ class BasicAuth */ public static function protect_site_if_necessary() { - $config = Config::inst()->forClass('SilverStripe\\Security\\BasicAuth'); + $config = Config::forClass('SilverStripe\\Security\\BasicAuth'); if ($config->entire_site_protected) { self::requireLogin($config->entire_site_protected_message, $config->entire_site_protected_code, false); } diff --git a/src/Security/Member.php b/src/Security/Member.php index e590114f4..ed217be17 100644 --- a/src/Security/Member.php +++ b/src/Security/Member.php @@ -474,8 +474,8 @@ class Member extends DataObject implements TemplateGlobalProvider } if ($remember) { $rememberLoginHash = RememberLoginHash::generate($this); - $tokenExpiryDays = RememberLoginHash::config()->get('token_expiry_days'); - $deviceExpiryDays = RememberLoginHash::config()->get('device_expiry_days'); + $tokenExpiryDays = RememberLoginHash::config()->uninherited('token_expiry_days'); + $deviceExpiryDays = RememberLoginHash::config()->uninherited('device_expiry_days'); Cookie::set( 'alc_enc', $this->ID . ':' . $rememberLoginHash->getToken(), @@ -610,7 +610,7 @@ class Member extends DataObject implements TemplateGlobalProvider if ($rememberLoginHash) { $rememberLoginHash->renew(); - $tokenExpiryDays = RememberLoginHash::config()->get('token_expiry_days'); + $tokenExpiryDays = RememberLoginHash::config()->uninherited('token_expiry_days'); Cookie::set( 'alc_enc', $member->ID . ':' . $rememberLoginHash->getToken(), @@ -930,7 +930,7 @@ class Member extends DataObject implements TemplateGlobalProvider */ public static function create_new_password() { - $words = Security::config()->get('word_list'); + $words = Security::config()->uninherited('word_list'); if ($words && file_exists($words)) { $words = file($words); diff --git a/src/Security/MemberLoginForm.php b/src/Security/MemberLoginForm.php index 8b4156c5e..8a90af9e0 100644 --- a/src/Security/MemberLoginForm.php +++ b/src/Security/MemberLoginForm.php @@ -123,7 +123,7 @@ class MemberLoginForm extends LoginForm 'title', sprintf( _t('Member.REMEMBERME', "Remember me next time? (for %d days on this device)"), - RememberLoginHash::config()->get('token_expiry_days') + RememberLoginHash::config()->uninherited('token_expiry_days') ) ) ); diff --git a/src/Security/Security.php b/src/Security/Security.php index 46710400b..a15381853 100644 --- a/src/Security/Security.php +++ b/src/Security/Security.php @@ -367,7 +367,7 @@ class Security extends Controller implements TemplateGlobalProvider $controller->extend('permissionDenied', $member); return $controller->redirect(Controller::join_links( - static::config()->get('login_url'), + Security::config()->uninherited('login_url'), "?BackURL=" . urlencode($_SERVER['REQUEST_URI']) )); } diff --git a/src/View/SSTemplateParser.php b/src/View/SSTemplateParser.php index f5c2a30ce..ff96843a4 100644 --- a/src/View/SSTemplateParser.php +++ b/src/View/SSTemplateParser.php @@ -4000,7 +4000,7 @@ class SSTemplateParser extends Parser implements TemplateParser // the passed cache key, the block index, and the sha hash of the template. $res['php'] .= '$keyExpression = function() use ($scope, $cache) {' . PHP_EOL; $res['php'] .= '$val = \'\';' . PHP_EOL; - if ($globalKey = SSViewer::config()->get('global_key')) { + if ($globalKey = SSViewer::config()->uninherited('global_key')) { // Embed the code necessary to evaluate the globalKey directly into the template, // so that SSTemplateParser only needs to be called during template regeneration. // Warning: If the global key is changed, it's necessary to flush the template cache. diff --git a/src/View/SSViewer.php b/src/View/SSViewer.php index 6b3cc09e2..8ad0ee926 100644 --- a/src/View/SSViewer.php +++ b/src/View/SSViewer.php @@ -62,29 +62,6 @@ class SSViewer implements Flushable */ private static $cacheblock_cache_flushed = false; - /** - * Set whether HTML comments indicating the source .SS file used to render this page should be - * included in the output. This is enabled by default - * - * @deprecated 4.0 Use the "SSViewer.source_file_comments" config setting instead - * @param boolean $val - */ - public static function set_source_file_comments($val) - { - Deprecation::notice('4.0', 'Use the "SSViewer.source_file_comments" config setting instead'); - SSViewer::config()->update('source_file_comments', $val); - } - - /** - * @deprecated 4.0 Use the "SSViewer.source_file_comments" config setting instead - * @return boolean - */ - public static function get_source_file_comments() - { - Deprecation::notice('4.0', 'Use the "SSViewer.source_file_comments" config setting instead'); - return SSViewer::config()->get('source_file_comments'); - } - /** * @var array $templates List of templates to select from */ @@ -181,31 +158,29 @@ class SSViewer implements Flushable */ public static function set_themes($themes = []) { - SSViewer::config() - ->remove('themes') - ->update('themes', $themes); + SSViewer::config()->set('themes', $themes); } public static function add_themes($themes = []) { - SSViewer::config()->update('themes', $themes); + SSViewer::config()->merge('themes', $themes); } public static function get_themes() { $default = [self::DEFAULT_THEME]; - if (!SSViewer::config()->get('theme_enabled')) { + if (!SSViewer::config()->uninherited('theme_enabled')) { return $default; } // Explicit list is assigned - if ($list = SSViewer::config()->get('themes')) { + if ($list = SSViewer::config()->uninherited('themes')) { return $list; } // Support legacy behaviour - if ($theme = SSViewer::config()->get('theme')) { + if ($theme = SSViewer::config()->uninherited('theme')) { return [$theme, self::DEFAULT_THEME]; } @@ -347,47 +322,6 @@ class SSViewer implements Flushable return (bool)ThemeResourceLoader::instance()->findTemplate($templates, self::get_themes()); } - /** - * Set a global rendering option. - * - * The following options are available: - * - rewriteHashlinks: If true (the default), will be rewritten to contain the - * current URL. This lets it play nicely with our tag. - * - If rewriteHashlinks = 'php' then, a piece of PHP script will be inserted before the hash - * links: "". This is useful if you're generating a - * page that will be saved to a .php file and may be accessed from different URLs. - * - * @deprecated 4.0 Use the "SSViewer.rewrite_hash_links" config setting instead - * @param string $optionName - * @param mixed $optionVal - */ - public static function setOption($optionName, $optionVal) - { - if ($optionName == 'rewriteHashlinks') { - Deprecation::notice('4.0', 'Use the "SSViewer.rewrite_hash_links" config setting instead'); - SSViewer::config()->update('rewrite_hash_links', $optionVal); - } else { - Deprecation::notice('4.0', 'Use the "SSViewer.' . $optionName . '" config setting instead'); - SSViewer::config()->update($optionName, $optionVal); - } - } - - /** - * @deprecated 4.0 Use the "SSViewer.rewrite_hash_links" config setting instead - * @param string - * @return mixed - */ - public static function getOption($optionName) - { - if ($optionName == 'rewriteHashlinks') { - Deprecation::notice('4.0', 'Use the "SSViewer.rewrite_hash_links" config setting instead'); - return SSViewer::config()->get('rewrite_hash_links'); - } else { - Deprecation::notice('4.0', 'Use the "SSViewer.' . $optionName . '" config setting instead'); - return SSViewer::config()->get($optionName); - } - } - /** * @config * @var boolean @@ -612,7 +546,7 @@ class SSViewer implements Flushable // If we have our crazy base tag, then fix # links referencing the current page. - $rewrite = SSViewer::config()->get('rewrite_hash_links'); + $rewrite = SSViewer::config()->uninherited('rewrite_hash_links'); if ($this->rewriteHashlinks && $rewrite) { if (strpos($output, 'getParser()->compileString( $content, $template, - Director::isDev() && SSViewer::config()->get('source_file_comments') + Director::isDev() && SSViewer::config()->uninherited('source_file_comments') ); } diff --git a/src/View/SSViewer_DataPresenter.php b/src/View/SSViewer_DataPresenter.php index 97986f8c1..c0999bc96 100644 --- a/src/View/SSViewer_DataPresenter.php +++ b/src/View/SSViewer_DataPresenter.php @@ -4,7 +4,6 @@ namespace SilverStripe\View; use InvalidArgumentException; use SilverStripe\Core\ClassInfo; -use SilverStripe\Core\Config\Config; use SilverStripe\Core\Injector\Injector; use SilverStripe\Core\Object; @@ -82,7 +81,7 @@ class SSViewer_DataPresenter extends SSViewer_Scope if (!is_array($details)) { $details = array( 'method' => $details, - 'casting' => ViewableData::config()->get('default_cast', Config::FIRST_SET) + 'casting' => ViewableData::config()->uninherited('default_cast') ); } @@ -185,7 +184,7 @@ class SSViewer_DataPresenter extends SSViewer_Scope // If not provided, use default if (!$casting) { - $casting = ViewableData::config()->get('default_cast', Config::FIRST_SET); + $casting = ViewableData::config()->uninherited('default_cast'); } $obj = Injector::inst()->get($casting, false, array($property)); diff --git a/src/View/ThemeResourceLoader.php b/src/View/ThemeResourceLoader.php index 525c14580..a2ea928ef 100644 --- a/src/View/ThemeResourceLoader.php +++ b/src/View/ThemeResourceLoader.php @@ -2,6 +2,7 @@ namespace SilverStripe\View; +use SilverStripe\Core\Manifest\ModuleLoader; use SilverStripe\Dev\Debug; /** @@ -119,23 +120,20 @@ class ThemeResourceLoader $subpath = ''; } - // To do: implement more flexible module path lookup $package = $parts[0]; - switch ($package) { - case 'silverstripe/framework': - $modulePath = FRAMEWORK_DIR; - break; - case 'silverstripe/cms': - $modulePath = CMS_DIR; - break; + // Find matching module for this package + $module = ModuleLoader::instance()->getManifest()->getModule($package); + if ($module) { + $modulePath = $module->getRelativePath(); + } else { + // fall back to dirname + list(, $modulePath) = explode('/', $parts[0], 2); - default: - list($vendor, $modulePath) = explode('/', $parts[0], 2); - // If the module is in the themes// prefer that - if (is_dir(THEMES_PATH . '/' .$modulePath)) { - $modulePath = THEMES_DIR . '/' . $$modulePath; - } + // If the module is in the themes// prefer that + if (is_dir(THEMES_PATH . '/' .$modulePath)) { + $modulePath = THEMES_DIR . '/' . $$modulePath; + } } return ltrim($modulePath . $subpath, '/'); diff --git a/src/View/ViewableData.php b/src/View/ViewableData.php index e7e9f5107..c7d6d32d7 100644 --- a/src/View/ViewableData.php +++ b/src/View/ViewableData.php @@ -6,7 +6,6 @@ use SilverStripe\Core\Object; use SilverStripe\ORM\ArrayLib; use SilverStripe\ORM\FieldType\DBField; use SilverStripe\ORM\FieldType\DBHTMLText; -use SilverStripe\Core\Config\Config; use SilverStripe\Core\ClassInfo; use SilverStripe\Core\Convert; use SilverStripe\Core\Injector\Injector; @@ -277,7 +276,7 @@ class ViewableData extends Object implements IteratorAggregate */ public function castingHelper($field) { - $specs = $this->config()->casting; + $specs = $this->config()->get('casting'); if (isset($specs[$field])) { return $specs[$field]; } @@ -294,7 +293,11 @@ class ViewableData extends Object implements IteratorAggregate } // Fall back to default_cast - return $this->config()->get('default_cast'); + $default = $this->config()->get('default_cast'); + if (empty($default)) { + throw new \Exception("No default_cast"); + } + return $default; } /** @@ -318,11 +321,13 @@ class ViewableData extends Object implements IteratorAggregate */ public function escapeTypeForField($field) { - $class = $this->castingClass($field) ?: $this->config()->default_cast; + $class = $this->castingClass($field) ?: $this->config()->get('default_cast'); // TODO: It would be quicker not to instantiate the object, but to merely // get its class from the Injector - return Injector::inst()->get($class, true)->config()->escape_type; + /** @var DBField $type */ + $type = Injector::inst()->get($class, true); + return $type->config()->get('escape_type'); } // TEMPLATE ACCESS LAYER ------------------------------------------------------------------------------------------- diff --git a/src/conf/ConfigureFromEnv.php b/src/conf/ConfigureFromEnv.php index 71e140a77..3ffe44256 100644 --- a/src/conf/ConfigureFromEnv.php +++ b/src/conf/ConfigureFromEnv.php @@ -48,17 +48,12 @@ use Monolog\Logger; use Monolog\Handler\StreamHandler; -use SilverStripe\Control\Director; use SilverStripe\Control\Email\Email; use SilverStripe\Core\Injector\Injector; use SilverStripe\Dev\Install\DatabaseAdapterRegistry; use SilverStripe\Security\BasicAuth; use SilverStripe\Security\Security; -if ($envType = getenv('SS_ENVIRONMENT_TYPE')) { - Director::config()->environment_type = $envType; -} - global $database; // No database provided diff --git a/src/i18n/Data/Sources.php b/src/i18n/Data/Sources.php index eb45d17ac..6f6aac613 100644 --- a/src/i18n/Data/Sources.php +++ b/src/i18n/Data/Sources.php @@ -44,8 +44,8 @@ class Sources implements Resettable array_splice($moduleNames, $idx, 1); } - // Get the order from the config syste (lowest to highest) - $order = static::config()->get('module_priority'); + // Get the order from the config system (lowest to highest) + $order = Sources::config()->uninherited('module_priority'); // Find all modules that don't have their order specified by the config system $unspecified = array_diff($moduleNames, $order); diff --git a/src/i18n/Messages/YamlWriter.php b/src/i18n/Messages/YamlWriter.php index 8028ef571..ad9abb1d7 100644 --- a/src/i18n/Messages/YamlWriter.php +++ b/src/i18n/Messages/YamlWriter.php @@ -135,7 +135,7 @@ class YamlWriter implements Writer { // Strip non-plural keys away if (is_array($value)) { - $forms = i18n::config()->get('plurals'); + $forms = i18n::config()->uninherited('plurals'); $forms = array_combine($forms, $forms); return array_intersect_key($value, $forms); } diff --git a/src/i18n/TextCollection/i18nTextCollector.php b/src/i18n/TextCollection/i18nTextCollector.php index 7dc761448..8dcaa6f4f 100644 --- a/src/i18n/TextCollection/i18nTextCollector.php +++ b/src/i18n/TextCollection/i18nTextCollector.php @@ -99,10 +99,10 @@ class i18nTextCollector { $this->defaultLocale = $locale ? $locale - : i18n::getData()->langFromLocale(i18n::config()->get('default_locale')); + : i18n::getData()->langFromLocale(i18n::config()->uninherited('default_locale')); $this->basePath = Director::baseFolder(); $this->baseSavePath = Director::baseFolder(); - $this->setWarnOnEmptyDefault(i18n::config()->get('missing_default_warning')); + $this->setWarnOnEmptyDefault(i18n::config()->uninherited('missing_default_warning')); } /** diff --git a/src/i18n/i18n.php b/src/i18n/i18n.php index d10c0335e..ee7c5fcea 100644 --- a/src/i18n/i18n.php +++ b/src/i18n/i18n.php @@ -163,7 +163,7 @@ class i18n implements TemplateGlobalProvider } // Encourage the provision of default values so that text collector can discover new strings - if (!$default && static::config()->get('missing_default_warning')) { + if (!$default && i18n::config()->uninherited('missing_default_warning')) { user_error("Missing default for localisation key $entity", E_USER_WARNING); } @@ -232,7 +232,7 @@ class i18n implements TemplateGlobalProvider public static function parse_plurals($string) { if (strstr($string, '|') && strstr($string, '{count}')) { - $keys = i18n::config()->get('default_plurals'); + $keys = i18n::config()->uninherited('default_plurals'); $values = explode('|', $string); if (count($keys) == count($values)) { return array_combine($keys, $values); @@ -251,7 +251,7 @@ class i18n implements TemplateGlobalProvider public static function encode_plurals($plurals) { // Validate against global plural list - $forms = static::config()->get('plurals'); + $forms = i18n::config()->uninherited('plurals'); $forms = array_combine($forms, $forms); $intersect = array_intersect_key($plurals, $forms); if ($intersect) { @@ -343,7 +343,7 @@ class i18n implements TemplateGlobalProvider */ public static function get_locale() { - return self::$current_locale ?: static::config()->get('default_locale'); + return self::$current_locale ?: i18n::config()->uninherited('default_locale'); } /**