From fba8e2c245ba21febb983de8148242fdf27394c4 Mon Sep 17 00:00:00 2001 From: Damian Mooyman Date: Wed, 17 May 2017 17:40:13 +1200 Subject: [PATCH 1/3] API Remove Object class API DataObjectSchema::manyManyComponent() return array is now associative array --- docs/en/04_Changelogs/4.0.0.md | 89 +++++ src/Control/CliController.php | 2 +- src/Control/ContentNegotiator.php | 7 +- src/Control/Controller.php | 27 +- src/Control/Email/Email.php | 3 +- src/Control/RSS/RSSFeed.php | 2 +- src/Control/RSS/RSSFeed_Entry.php | 2 +- src/Control/RequestHandler.php | 23 +- src/Core/ClassInfo.php | 157 +++++++++ .../Config/Middleware/ExtensionMiddleware.php | 3 +- src/Core/CustomMethods.php | 21 +- src/Core/Extensible.php | 44 ++- src/Core/Extension.php | 10 +- src/Core/Injector/Injectable.php | 15 +- src/Core/Injector/Injector.php | 34 +- src/Core/Object.php | 324 ------------------ src/Dev/BuildTask.php | 16 +- src/Dev/BulkLoader.php | 3 +- src/Dev/BulkLoader_Result.php | 9 +- src/Dev/CLI.php | 4 +- src/Dev/CSSContentParser.php | 8 +- src/Dev/CSVParser.php | 7 +- src/Dev/CsvBulkLoader.php | 2 +- src/Dev/DebugView.php | 7 +- src/Dev/FixtureBlueprint.php | 13 +- src/Dev/FunctionalTest.php | 2 +- src/Dev/SapphireTest.php | 8 +- src/Dev/YamlFixture.php | 7 +- src/Forms/CompositeField.php | 14 +- src/Forms/FieldList.php | 11 +- src/Forms/FileField.php | 8 +- src/Forms/FileUploadReceiver.php | 4 +- src/Forms/Form.php | 5 +- src/Forms/FormField.php | 13 +- src/Forms/FormRequestHandler.php | 2 +- src/Forms/FormScaffolder.php | 11 +- src/Forms/FormTransformation.php | 25 +- src/Forms/GridField/GridFieldConfig.php | 15 +- src/Forms/GridField/GridFieldDetailForm.php | 22 +- src/Forms/GridField/GridFieldFilterHeader.php | 2 +- src/Forms/GridField/GridFieldLevelup.php | 12 +- src/Forms/GridField/GridFieldPageCount.php | 2 +- src/Forms/GridField/GridFieldPaginator.php | 2 +- .../GridField/GridFieldSortableHeader.php | 2 +- .../HTMLEditor/HTMLEditorField_Toolbar.php | 10 +- src/Forms/NullableField.php | 2 +- src/Forms/Validator.php | 11 +- src/ORM/ArrayList.php | 2 +- src/ORM/Connect/DBConnector.php | 8 +- src/ORM/Connect/DBSchemaManager.php | 4 +- src/ORM/Connect/Database.php | 2 +- src/ORM/DataExtension.php | 4 +- src/ORM/DataList.php | 5 +- src/ORM/DataObject.php | 133 ++++--- src/ORM/DataObjectSchema.php | 64 ++-- src/ORM/DataQuery.php | 38 +- src/ORM/FieldType/DBBoolean.php | 3 +- src/ORM/FieldType/DBComposite.php | 6 +- src/ORM/FieldType/DBDecimal.php | 2 +- src/ORM/FieldType/DBField.php | 6 +- src/ORM/FieldType/DBPolymorphicForeignKey.php | 2 +- src/ORM/Filters/SearchFilter.php | 20 +- src/ORM/Hierarchy/Hierarchy.php | 4 +- src/ORM/ManyManyList.php | 8 +- src/ORM/Search/FulltextSearchable.php | 2 - src/ORM/Search/SearchContext.php | 9 +- src/ORM/UnsavedRelationList.php | 2 +- src/Security/Authenticator.php | 17 +- src/Security/PasswordValidator.php | 11 +- src/Security/Security.php | 2 +- src/Security/SecurityToken.php | 8 +- src/View/Parsers/HTMLCleaner.php | 8 +- src/View/Parsers/SQLFormatter.php | 5 +- src/View/Parsers/ShortcodeParser.php | 14 +- src/View/Parsers/Transliterator.php | 14 +- src/View/Parsers/URLSegmentFilter.php | 7 +- src/View/SSViewer.php | 2 +- src/View/SSViewer_DataPresenter.php | 3 +- src/View/ViewableData.php | 52 ++- src/View/ViewableData_Debugger.php | 11 +- tests/php/Core/ClassInfoTest.php | 16 +- tests/php/Core/Config/ConfigTest.php | 16 - .../php/Core/Config/ConfigTest/BaseObject.php | 11 + .../php/Core/Config/ConfigTest/DefinesFoo.php | 5 +- tests/php/Core/Config/ConfigTest/TestNest.php | 5 +- .../Injector/InjectorTest/SSObjectCreator.php | 11 +- tests/php/Core/Manifest/ClassManifestTest.php | 2 +- .../module/classes/ClassI.php | 2 +- tests/php/Core/ObjectTest.php | 98 ++---- tests/php/Core/ObjectTest/BaseObject.php | 20 ++ tests/php/Core/ObjectTest/CacheTest.php | 5 +- tests/php/Core/ObjectTest/CreateTest.php | 4 +- tests/php/Core/ObjectTest/CreateTest2.php | 4 +- tests/php/Core/ObjectTest/CreateTest3.php | 4 +- tests/php/Core/ObjectTest/ExtendTest.php | 4 +- tests/php/Core/ObjectTest/ExtendTest1.php | 3 +- tests/php/Core/ObjectTest/ExtendTest2.php | 10 +- tests/php/Core/ObjectTest/ExtendTest3.php | 10 +- tests/php/Core/ObjectTest/Extending.php | 5 +- .../Core/ObjectTest/ExtensionRemoveTest.php | 4 +- tests/php/Core/ObjectTest/ExtensionTest.php | 4 +- tests/php/Core/ObjectTest/ExtensionTest2.php | 4 +- tests/php/Core/ObjectTest/ExtensionTest3.php | 4 +- tests/php/Core/ObjectTest/MyObject.php | 8 +- tests/php/Core/ObjectTest/T1A.php | 4 +- tests/php/Core/ObjectTest/T1B.php | 4 +- tests/php/Core/ObjectTest/T1C.php | 4 +- tests/php/Core/ObjectTest/T2.php | 4 +- tests/php/Core/ObjectTest/TestExtension.php | 3 +- .../TestController.php | 8 +- tests/php/ORM/DBHTMLTextTest.php | 23 +- tests/php/ORM/DBStringTest.php | 16 +- tests/php/ORM/DataObjectSchemaTest.php | 4 +- tests/php/ORM/DataObjectTest.php | 33 +- tests/php/ORM/ManyManyListExtensionTest.php | 8 +- .../ORM/ManyManyListTest/IndirectPrimary.php | 3 + .../IndirectSecondaryExtension.php | 3 + tests/php/ORM/ManyManyThroughListTest.php | 24 +- tests/php/Security/MemberTest.php | 20 +- .../MemberTest/TestPasswordValidator.php | 1 - .../i18nothermodule/code/i18nOtherModule.php | 4 +- .../i18ntestmodule/code/i18nTestModule.php | 3 +- .../code/subfolder/i18nTestSubModule.php | 6 +- 123 files changed, 974 insertions(+), 960 deletions(-) delete mode 100755 src/Core/Object.php create mode 100644 tests/php/Core/Config/ConfigTest/BaseObject.php create mode 100644 tests/php/Core/ObjectTest/BaseObject.php diff --git a/docs/en/04_Changelogs/4.0.0.md b/docs/en/04_Changelogs/4.0.0.md index 451397217..4ba1342f5 100644 --- a/docs/en/04_Changelogs/4.0.0.md +++ b/docs/en/04_Changelogs/4.0.0.md @@ -30,6 +30,7 @@ guide developers in preparing existing 3.x code for compatibility with 4.0 arrangement of templates, as well as other references to classes via string literals or configuration. Automatic upgrading tools have been developed to cope with the bulk of these changes (see [upgrading notes](#upgrading)). +* Object class has been removed. * Asset storage has been abstracted, and a new concept of `DBFile` references via database column references now exists in addition to references via the existing `File` dataobject. File security and protected files are now a core feature. @@ -161,6 +162,90 @@ Note also that `$_FILE_TO_URL_MAPPING` has been removed and replaced with `SS_BA See [Environment Management docs](/getting-started/environment_management/) for full details. +#### Replace usages of Object class + +Object has been superseded by a trio of traits which replace components of this legacy class: + + - Injectable: Provides `MyClass::create()` and `MyClass::singleton()` + - Configurable: Provides `MyClass::config()` + - Extensible: Provides all methods related to extensions (E.g. add_extension()). Note: + All classes which use this trait MUST invoke `constructExtensions()` in its constructor. + +In particular specific Object class usages should be replaced as below: + + +Upgrade subclasses + + + :::php + // old + class MyClass extends Object {} + // new + class MyClass { + use Extensible; + use Injectable; + use Configurable; + + public function __construct() { + // Only needed if using Extensible trait + $this->constructExtensions(); + } + } + + +References to $this->class + + + :::php + // old + $obj->class + $this->class; + // new + get_class($obj); + static::class; + + +Upgrade parse_class_spec() + + + :::php + // old + $spec = Object::parse_class_spec($spec); + // new + $spec = ClassInfo::parse_class_spec($spec); + + +Upgrade create_from_string() + + + :::php + // old + $obj = Object::create_from_string('Varchar(100)'); + // new + $obj = Injector::inst()->create('Varchar(100)'); + + +Extensions + + + :::php + // old + Object::add_extension('File', 'Versioned'); + $has = Object::has_extension('File', 'Versioned'); + $extensions = Object::get_extensions('File'); + // new + File::add_extension(Versioned::class); + $has = File::has_extension(Versioned::class) + $extensions = File::get_extensions(); + + // new (alternate form) + // Note: The class the extension method is called on MUST be a parent class + // of the first argument. + DataObject::add_extension(File::class, Versioned::class); // alternate + $has = DataObject::has_extension(File::class, Versioned::class); // alternate + $extensions = DataObject::get_extensions(File::class); + + #### Compatibility with the new front-end building tools If you are using Requirements from 3.x then your scripts should continue to work as they did before. @@ -1203,6 +1288,10 @@ After (`mysite/_config/config.yml`): * Introduced new ModuleLoader manifest, which allows modules to be found via composer name. E.g. `$cms = ModuleLoader::inst()->getManifest()->getModule('silverstripe/cms')` * `ClassManifest::getOwnerModule()` now returns a `Module` object instance. +* `Object` class has been removed. + * `parse_class_spec` moved to `ClassInfo` + * `create_from_spec` functionality removed, but now supportede by `Injector` natively. + * `Injectable`, `Extensible` and `Configurable` traits added to support other methods. * Certain methods have been moved from `Controller` to `RequestHandler`: * `Link` * `redirect` diff --git a/src/Control/CliController.php b/src/Control/CliController.php index e63503d34..de67e28fe 100644 --- a/src/Control/CliController.php +++ b/src/Control/CliController.php @@ -32,7 +32,7 @@ abstract class CliController extends Controller public function index() { - foreach (ClassInfo::subclassesFor($this->class) as $subclass) { + foreach (ClassInfo::subclassesFor(static::class) as $subclass) { echo $subclass . "\n"; /** @var CliController $task */ $task = Injector::inst()->create($subclass); diff --git a/src/Control/ContentNegotiator.php b/src/Control/ContentNegotiator.php index 601e2b5e1..c3f532cbb 100644 --- a/src/Control/ContentNegotiator.php +++ b/src/Control/ContentNegotiator.php @@ -3,7 +3,8 @@ namespace SilverStripe\Control; use SilverStripe\Core\Config\Config; -use SilverStripe\Core\Object; +use SilverStripe\Core\Config\Configurable; +use SilverStripe\Core\Injector\Injectable; /** * The content negotiator performs "text/html" or "application/xhtml+xml" switching. It does this through @@ -31,8 +32,10 @@ use SilverStripe\Core\Object; * Some developers might know what they're doing and don't want ContentNegotiator messing with their * HTML4 doctypes, but still find it useful to have self-closing tags removed. */ -class ContentNegotiator extends Object +class ContentNegotiator { + use Injectable; + use Configurable; /** * @config diff --git a/src/Control/Controller.php b/src/Control/Controller.php index a521bc5c9..76ea7597e 100644 --- a/src/Control/Controller.php +++ b/src/Control/Controller.php @@ -3,7 +3,6 @@ namespace SilverStripe\Control; use SilverStripe\Core\ClassInfo; -use SilverStripe\Core\Object; use SilverStripe\Core\Injector\Injector; use SilverStripe\Dev\Debug; use SilverStripe\ORM\DataModel; @@ -122,8 +121,9 @@ class Controller extends RequestHandler implements TemplateGlobalProvider $this->baseInitCalled = false; $this->init(); if (!$this->baseInitCalled) { + $class = static::class; user_error( - "init() method on class '$this->class' doesn't call Controller::init()." + "init() method on class '{$class}' doesn't call Controller::init()." . "Make sure that you have parent::init() included.", E_USER_WARNING ); @@ -231,18 +231,22 @@ class Controller extends RequestHandler implements TemplateGlobalProvider { if ($response instanceof HTTPResponse) { if (isset($_REQUEST['debug_request'])) { + $class = static::class; Debug::message( - "Request handler returned HTTPResponse object to $this->class controller;" + "Request handler returned HTTPResponse object to {$class} controller;" . "returning it without modification." ); } $this->setResponse($response); } else { - if ($response instanceof Object && $response->hasMethod('getViewer')) { + // Could be Controller, or ViewableData_Customised controller wrapper + if (ClassInfo::hasMethod($response, 'getViewer')) { if (isset($_REQUEST['debug_request'])) { + $class = static::class; + $responseClass = get_class($response); Debug::message( - "Request handler $response->class object to $this->class controller;" - . "rendering with template returned by $response->class::getViewer()" + "Request handler {$responseClass} object to {$class} controller;" + . "rendering with template returned by {$responseClass}::getViewer()" ); } $response = $response->getViewer($this->getAction())->process($response); @@ -399,14 +403,14 @@ class Controller extends RequestHandler implements TemplateGlobalProvider // Add action-specific templates for inheritance chain $templates = array(); if ($action && $action != 'index') { - $parentClass = $this->class; + $parentClass = static::class; while ($parentClass != __CLASS__) { $templates[] = strtok($parentClass, '_') . '_' . $action; $parentClass = get_parent_class($parentClass); } } // Add controller templates for inheritance chain - $parentClass = $this->class; + $parentClass = static::class; while ($parentClass != __CLASS__) { $templates[] = strtok($parentClass, '_'); $parentClass = get_parent_class($parentClass); @@ -469,7 +473,7 @@ class Controller extends RequestHandler implements TemplateGlobalProvider return $definingClass; } - $class = get_class($this); + $class = static::class; while ($class != 'SilverStripe\\Control\\RequestHandler') { $templateName = strtok($class, '_') . '_' . $action; if (SSViewer::hasTemplate($templateName)) { @@ -496,7 +500,7 @@ class Controller extends RequestHandler implements TemplateGlobalProvider return true; } - $parentClass = $this->class; + $parentClass = static::class; $templates = array(); while ($parentClass != __CLASS__) { @@ -614,8 +618,9 @@ class Controller extends RequestHandler implements TemplateGlobalProvider if ($this === self::$controller_stack[0]) { array_shift(self::$controller_stack); } else { + $class = static::class; user_error( - "popCurrent called on $this->class controller, but it wasn't at the top of the stack", + "popCurrent called on {$class} controller, but it wasn't at the top of the stack", E_USER_WARNING ); } diff --git a/src/Control/Email/Email.php b/src/Control/Email/Email.php index 3e0908e87..a01bf6f0d 100644 --- a/src/Control/Email/Email.php +++ b/src/Control/Email/Email.php @@ -573,7 +573,8 @@ class Email extends ViewableData { $this->render(); - return "

Email template {$this->class}:

\n" . '
' . $this->getSwiftMessage()->toString() . '
'; + $class = static::class; + return "

Email template {$class}:

\n" . '
' . $this->getSwiftMessage()->toString() . '
'; } /** diff --git a/src/Control/RSS/RSSFeed.php b/src/Control/RSS/RSSFeed.php index 6b31d9763..3fe5f586e 100644 --- a/src/Control/RSS/RSSFeed.php +++ b/src/Control/RSS/RSSFeed.php @@ -272,7 +272,7 @@ class RSSFeed extends ViewableData */ public function getTemplates() { - $templates = SSViewer::get_templates_by_class(get_class($this), '', __CLASS__); + $templates = SSViewer::get_templates_by_class(static::class, '', __CLASS__); // Prefer any custom template if ($this->getTemplate()) { array_unshift($templates, $this->getTemplate()); diff --git a/src/Control/RSS/RSSFeed_Entry.php b/src/Control/RSS/RSSFeed_Entry.php index 3afa70bf8..f2d733b09 100644 --- a/src/Control/RSS/RSSFeed_Entry.php +++ b/src/Control/RSS/RSSFeed_Entry.php @@ -130,7 +130,7 @@ class RSSFeed_Entry extends ViewableData } throw new BadMethodCallException( - $this->failover->class . + get_class($this->failover) . " object has neither an AbsoluteLink nor a Link method." . " Can't put a link in the RSS feed", E_USER_WARNING diff --git a/src/Control/RequestHandler.php b/src/Control/RequestHandler.php index b2b2bf313..43fdfef95 100644 --- a/src/Control/RequestHandler.php +++ b/src/Control/RequestHandler.php @@ -5,7 +5,6 @@ namespace SilverStripe\Control; use InvalidArgumentException; use SilverStripe\Core\ClassInfo; use SilverStripe\Core\Config\Config; -use SilverStripe\Core\Object; use SilverStripe\Dev\Debug; use SilverStripe\ORM\DataModel; use SilverStripe\Security\Security; @@ -164,7 +163,7 @@ class RequestHandler extends ViewableData { // $handlerClass is used to step up the class hierarchy to implement url_handlers inheritance if ($this->brokenOnConstruct) { - $handlerClass = get_class($this); + $handlerClass = static::class; throw new BadMethodCallException( "parent::__construct() needs to be called on {$handlerClass}::__construct()" ); @@ -205,7 +204,7 @@ class RequestHandler extends ViewableData user_error("Non-string method name: " . var_export($action, true), E_USER_ERROR); } - $classMessage = Director::isLive() ? 'on this handler' : 'on class '.get_class($this); + $classMessage = Director::isLive() ? 'on this handler' : 'on class '.static::class; try { if (!$this->hasAction($action)) { @@ -263,7 +262,7 @@ class RequestHandler extends ViewableData */ protected function findAction($request) { - $handlerClass = ($this->class) ? $this->class : get_class($this); + $handlerClass = static::class; // We stop after RequestHandler; in other words, at ViewableData while ($handlerClass && $handlerClass != ViewableData::class) { @@ -272,14 +271,18 @@ class RequestHandler extends ViewableData if ($urlHandlers) { foreach ($urlHandlers as $rule => $action) { if (isset($_REQUEST['debug_request'])) { - Debug::message("Testing '$rule' with '" . $request->remaining() . "' on $this->class"); + $class = static::class; + $remaining = $request->remaining(); + Debug::message("Testing '{$rule}' with '{$remaining}' on {$class}"); } if ($request->match($rule, true)) { if (isset($_REQUEST['debug_request'])) { + $class = static::class; + $latestParams = var_export($request->latestParams(), true); Debug::message( - "Rule '$rule' matched to action '$action' on $this->class. ". - "Latest request params: " . var_export($request->latestParams(), true) + "Rule '{$rule}' matched to action '{$action}' on {$class}. ". + "Latest request params: {$latestParams}" ); } @@ -304,7 +307,7 @@ class RequestHandler extends ViewableData */ protected function handleAction($request, $action) { - $classMessage = Director::isLive() ? 'on this handler' : 'on class '.get_class($this); + $classMessage = Director::isLive() ? 'on this handler' : 'on class '.static::class; if (!$this->hasMethod($action)) { return new HTTPResponse("Action '$action' isn't available $classMessage.", 404); @@ -469,7 +472,7 @@ class RequestHandler extends ViewableData $isAllowed = true; } elseif (substr($test, 0, 2) == '->') { // Determined by custom method with "->" prefix - list($method, $arguments) = Object::parse_class_spec(substr($test, 2)); + list($method, $arguments) = ClassInfo::parse_class_spec(substr($test, 2)); $isAllowed = call_user_func_array(array($this, $method), $arguments); } else { // Value is a permission code to check the current member against @@ -564,7 +567,7 @@ class RequestHandler extends ViewableData // no link defined by default trigger_error( - 'Request handler '.get_class($this). ' does not have a url_segment defined. '. + 'Request handler '.static::class. ' does not have a url_segment defined. '. 'Relying on this link may be an application error', E_USER_WARNING ); diff --git a/src/Core/ClassInfo.php b/src/Core/ClassInfo.php index 0a8a2ab8b..bc4c22a8d 100644 --- a/src/Core/ClassInfo.php +++ b/src/Core/ClassInfo.php @@ -2,6 +2,7 @@ namespace SilverStripe\Core; +use Exception; use SilverStripe\Control\Director; use SilverStripe\Core\Manifest\ClassLoader; use SilverStripe\Dev\Deprecation; @@ -43,14 +44,26 @@ class ClassInfo /** * Cache for {@link hasTable()} + * + * @internal + * @var array */ private static $_cache_all_tables = array(); /** + * @internal * @var array Cache for {@link ancestry()}. */ private static $_cache_ancestry = array(); + /** + * Cache for parse_class_spec + * + * @internal + * @var array + */ + private static $_cache_parse = []; + /** * @todo Move this to SS_Database or DB * @@ -358,4 +371,148 @@ class ClassInfo } return method_exists($object, 'hasMethod') && $object->hasMethod($method); } + + /** + * Parses a class-spec, such as "Versioned('Stage','Live')", as passed to create_from_string(). + * Returns a 2-element array, with classname and arguments + * + * @param string $classSpec + * @return array + * @throws Exception + */ + public static function parse_class_spec($classSpec) + { + if (isset(static::$_cache_parse[$classSpec])) { + return static::$_cache_parse[$classSpec]; + } + + $tokens = token_get_all("defineMethods(); } @@ -151,12 +151,12 @@ trait CustomMethods /** * Get meta-data details on a named method * - * @param array $method + * @param string $method * @return array List of custom method details, if defined for this method */ protected function getExtraMethodConfig($method) { - $class = get_class($this); + $class = static::class; if (isset(self::$extra_methods[$class][strtolower($method)])) { return self::$extra_methods[$class][strtolower($method)]; } @@ -171,7 +171,7 @@ trait CustomMethods */ public function allMethodNames($custom = false) { - $class = get_class($this); + $class = static::class; if (!isset(self::$built_in_methods[$class])) { self::$built_in_methods[$class] = array_map('strtolower', get_class_methods($this)); } @@ -198,10 +198,11 @@ trait CustomMethods $extension->clearOwner(); } } else { - if (!isset(self::$built_in_methods[$extension->class])) { - self::$built_in_methods[$extension->class] = array_map('strtolower', get_class_methods($extension)); + $class = get_class($extension); + if (!isset(self::$built_in_methods[$class])) { + self::$built_in_methods[$class] = array_map('strtolower', get_class_methods($extension)); } - $methods = self::$built_in_methods[$extension->class]; + $methods = self::$built_in_methods[$class]; } return $methods; @@ -216,7 +217,7 @@ trait CustomMethods */ protected function addMethodsFrom($property, $index = null) { - $class = get_class($this); + $class = static::class; $extension = ($index !== null) ? $this->{$property}[$index] : $this->$property; if (!$extension) { @@ -253,7 +254,7 @@ trait CustomMethods protected function removeMethodsFrom($property, $index = null) { $extension = ($index !== null) ? $this->{$property}[$index] : $this->$property; - $class = get_class($this); + $class = static::class; if (!$extension) { throw new InvalidArgumentException( @@ -286,7 +287,7 @@ trait CustomMethods */ protected function addWrapperMethod($method, $wrap) { - $class = get_class($this); + $class = static::class; self::$extra_methods[$class][strtolower($method)] = array ( 'wrap' => $wrap, 'method' => $method diff --git a/src/Core/Extensible.php b/src/Core/Extensible.php index 7b4e4d893..dc8254267 100644 --- a/src/Core/Extensible.php +++ b/src/Core/Extensible.php @@ -3,8 +3,10 @@ namespace SilverStripe\Core; use InvalidArgumentException; +use SilverStripe\Control\RequestHandler; use SilverStripe\Core\Config\Config; use SilverStripe\Core\Injector\Injector; +use SilverStripe\View\ViewableData; /** * Allows an object to have extensions applied to it. @@ -46,9 +48,8 @@ trait Extensible * @var array */ private static $unextendable_classes = array( - 'SilverStripe\\Core\\Object', - 'SilverStripe\\View\\ViewableData', - 'SilverStripe\\Control\\RequestHandler' + ViewableData::class, + RequestHandler::class, ); /** @@ -110,7 +111,7 @@ trait Extensible protected function constructExtensions() { - $class = get_class($this); + $class = static::class; // Register this trait as a method source $this->registerExtraMethodCallback('defineExtensionMethods', function () { @@ -126,9 +127,9 @@ trait Extensible if ($extensions) { foreach ($extensions as $extension) { - $instance = Object::create_from_string($extension); + $instance = Injector::inst()->create($extension); $instance->setOwner(null, $class); - $this->extension_instances[$instance->class] = $instance; + $this->extension_instances[get_class($instance)] = $instance; } } } @@ -177,7 +178,7 @@ trait Extensible */ public static function add_extension($classOrExtension, $extension = null) { - if (func_num_args() > 1) { + if ($extension) { $class = $classOrExtension; } else { $class = get_called_class(); @@ -285,14 +286,18 @@ trait Extensible } /** - * @param string $class + * @param string $class If omitted, will get extensions for the current class * @param bool $includeArgumentString Include the argument string in the return array, * FALSE would return array("Versioned"), TRUE returns array("Versioned('Stage','Live')"). * @return array Numeric array of either {@link DataExtension} class names, * or eval'ed class name strings with constructor arguments. */ - public static function get_extensions($class, $includeArgumentString = false) + public static function get_extensions($class = null, $includeArgumentString = false) { + if (!$class) { + $class = get_called_class(); + } + $extensions = Config::forClass($class)->get('extensions', Config::EXCLUDE_EXTRA_SOURCES); if (empty($extensions)) { return array(); @@ -315,9 +320,15 @@ trait Extensible } + /** + * Get extra config sources for this class + * + * @param string $class Name of class. If left null will return for the current class + * @return array|null + */ public static function get_extra_config_sources($class = null) { - if ($class === null) { + if (!$class) { $class = get_called_class(); } @@ -340,7 +351,7 @@ trait Extensible $sources = array(); foreach ($extensions as $extension) { - list($extensionClass, $extensionArgs) = Object::parse_class_spec($extension); + list($extensionClass, $extensionArgs) = ClassInfo::parse_class_spec($extension); $sources[] = $extensionClass; if (!class_exists($extensionClass)) { @@ -367,16 +378,16 @@ trait Extensible * Return TRUE if a class has a specified extension. * This supports backwards-compatible format (static Object::has_extension($requiredExtension)) * and new format ($object->has_extension($class, $requiredExtension)) - * @param string $classOrExtension if 1 argument supplied, the class name of the extension to - * check for; if 2 supplied, the class name to test - * @param string $requiredExtension used only if 2 arguments supplied + * @param string $classOrExtension Class to check extension for, or the extension name to check + * if the second argument is null. + * @param string $requiredExtension If the first argument is the parent class, this is the extension to check. + * If left null, the first parameter will be treated as the extension. * @param boolean $strict if the extension has to match the required extension and not be a subclass * @return bool Flag if the extension exists */ public static function has_extension($classOrExtension, $requiredExtension = null, $strict = false) { - //BC support - if (func_num_args() > 1) { + if ($requiredExtension) { $class = $classOrExtension; } else { $class = get_called_class(); @@ -500,6 +511,7 @@ trait Extensible if ($this->hasExtension($extension)) { return $this->extension_instances[$extension]; } + return null; } /** diff --git a/src/Core/Extension.php b/src/Core/Extension.php index 0914ab635..aca0ea377 100644 --- a/src/Core/Extension.php +++ b/src/Core/Extension.php @@ -16,7 +16,6 @@ use SilverStripe\ORM\DataObject; */ abstract class Extension { - /** * This is used by extensions designed to be applied to controllers. * It works the same way as {@link Controller::$allowed_actions}. @@ -45,13 +44,6 @@ abstract class Extension */ private $ownerStack = []; - public $class; - - public function __construct() - { - $this->class = get_class($this); - } - /** * Called when this extension is added to a particular class * @@ -67,7 +59,7 @@ abstract class Extension /** * Set the owner of this extension. * - * @param Object $owner The owner object, + * @param object $owner The owner object, * @param string $ownerBaseClass The base class that the extension is applied to; this may be * the class of owner, or it may be a parent. For example, if Versioned was applied to SiteTree, * and then a Page object was instantiated, $owner would be a Page object, but $ownerBaseClass diff --git a/src/Core/Injector/Injectable.php b/src/Core/Injector/Injectable.php index 5c6fcf05b..5a5117ca0 100644 --- a/src/Core/Injector/Injectable.php +++ b/src/Core/Injector/Injectable.php @@ -20,22 +20,13 @@ trait Injectable * $list = DataList::create('SiteTree'); * $list = SiteTree::get(); * - * @param string $classOrArgument The first argument, or class name (if called directly - * on Object). - * @param mixed $argument,... arguments to pass to the constructor + * @param array $args * @return static */ - public static function create($classOrArgument = null, $argument = null) + public static function create(...$args) { - $args = func_get_args(); - - // Class to create should be the calling class if not Object, - // otherwise the first parameter + // Class to create should be the calling class $class = get_called_class(); - if ($class == 'SilverStripe\\Core\\Object') { - $class = array_shift($args); - } - return Injector::inst()->createWithArgs($class, $args); } diff --git a/src/Core/Injector/Injector.php b/src/Core/Injector/Injector.php index 235fa258a..650069e7b 100644 --- a/src/Core/Injector/Injector.php +++ b/src/Core/Injector/Injector.php @@ -3,6 +3,7 @@ namespace SilverStripe\Core\Injector; use Psr\Container\NotFoundExceptionInterface; +use SilverStripe\Core\ClassInfo; use SilverStripe\Core\Config\Config; use ReflectionProperty; use ArrayObject; @@ -828,7 +829,7 @@ class Injector implements ContainerInterface */ public function getServiceName($name) { - // common case, get it over with first + // common case, get it overwith first if (isset($this->specs[$name])) { return $name; } @@ -902,7 +903,7 @@ class Injector implements ContainerInterface * if this object is to be created from scratch (with $asSingleton = false) * @return mixed Instance of the specified object */ - public function get($name, $asSingleton = true, $constructorArgs = null) + public function get($name, $asSingleton = true, $constructorArgs = []) { $object = $this->getNamedService($name, $asSingleton, $constructorArgs); @@ -921,8 +922,11 @@ class Injector implements ContainerInterface * @param array $constructorArgs * @return mixed|null Instance of the specified object (if it exists) */ - protected function getNamedService($name, $asSingleton = true, $constructorArgs = null) + protected function getNamedService($name, $asSingleton = true, $constructorArgs = []) { + // Normalise service / args + list($name, $constructorArgs) = $this->normaliseArguments($name, $constructorArgs); + // reassign the name as it might actually be a compound name if ($serviceName = $this->getServiceName($name)) { // check to see what the type of bean is. If it's a prototype, @@ -974,6 +978,28 @@ class Injector implements ContainerInterface return $this->instantiate($spec); } + /** + * Detect service references with constructor arguments included. + * These will be split out of the service name reference and appended + * to the $args + * + * @param string $name + * @param array $args + * @return array Two items with name and new args + */ + protected function normaliseArguments($name, $args = []) + { + if (strstr($name, '(')) { + list($name, $extraArgs) = ClassInfo::parse_class_spec($name); + if ($args) { + $args = array_merge($args, $extraArgs); + } else { + $args = $extraArgs; + } + } + return [ $name, $args ]; + } + /** * Magic method to return an item directly * @@ -999,7 +1025,7 @@ class Injector implements ContainerInterface { $constructorArgs = func_get_args(); array_shift($constructorArgs); - return $this->get($name, false, count($constructorArgs) ? $constructorArgs : null); + return $this->createWithArgs($name, $constructorArgs); } /** diff --git a/src/Core/Object.php b/src/Core/Object.php deleted file mode 100755 index dc64e57b9..000000000 --- a/src/Core/Object.php +++ /dev/null @@ -1,324 +0,0 @@ -getStaticProperties(); - } - - if (isset($static_properties[$class][$name])) { - $value = $static_properties[$class][$name]; - - $parent = get_parent_class($class); - if (!$parent) { - return $value; - } - - if (!isset($static_properties[$parent])) { - $reflection = new ReflectionClass($parent); - $static_properties[$parent] = $reflection->getStaticProperties(); - } - - if (!isset($static_properties[$parent][$name]) || $static_properties[$parent][$name] !== $value) { - return $value; - } - } - } - - return $default; - } - - public function __construct() - { - $this->class = get_class($this); - $this->constructExtensions(); - } - - // -------------------------------------------------------------------------------------------------------------- - - /** - * Return true if this object "exists" i.e. has a sensible value - * - * This method should be overriden in subclasses to provide more context about the classes state. For example, a - * {@link DataObject} class could return false when it is deleted from the database - * - * @return bool - */ - public function exists() - { - return true; - } - - /** - * @return string this classes parent class - */ - public function parentClass() - { - return get_parent_class($this); - } - - /** - * Check if this class is an instance of a specific class, or has that class as one of its parents - * - * @param string $class - * @return bool - */ - public function is_a($class) - { - return $this instanceof $class; - } - - /** - * @return string the class name - */ - public function __toString() - { - return $this->class; - } -} diff --git a/src/Dev/BuildTask.php b/src/Dev/BuildTask.php index b00e3ff6a..b8c403e8d 100644 --- a/src/Dev/BuildTask.php +++ b/src/Dev/BuildTask.php @@ -3,7 +3,9 @@ namespace SilverStripe\Dev; use SilverStripe\Control\HTTPRequest; -use SilverStripe\Core\Object; +use SilverStripe\Core\Config\Configurable; +use SilverStripe\Core\Extensible; +use SilverStripe\Core\Injector\Injectable; /** * Interface for a generic build task. Does not support dependencies. This will simply @@ -12,8 +14,16 @@ use SilverStripe\Core\Object; * To disable the task (in the case of potentially destructive updates or deletes), declare * the $Disabled property on the subclass. */ -abstract class BuildTask extends Object +abstract class BuildTask { + use Injectable; + use Configurable; + use Extensible; + + public function __construct() + { + $this->constructExtensions(); + } /** * Set a custom url segment (to follow dev/tasks/) @@ -63,7 +73,7 @@ abstract class BuildTask extends Object */ public function getTitle() { - return ($this->title) ? $this->title : $this->class; + return $this->title ?: static::class; } /** diff --git a/src/Dev/BulkLoader.php b/src/Dev/BulkLoader.php index f1a89cbdb..3658b0a96 100644 --- a/src/Dev/BulkLoader.php +++ b/src/Dev/BulkLoader.php @@ -200,7 +200,8 @@ abstract class BulkLoader extends ViewableData */ public function Title() { - return ($title = $this->stat('title')) ? $title : $this->class; + $title = $this->stat('title'); + return $title ?: static::class; } /** diff --git a/src/Dev/BulkLoader_Result.php b/src/Dev/BulkLoader_Result.php index 32868dcd9..957154105 100644 --- a/src/Dev/BulkLoader_Result.php +++ b/src/Dev/BulkLoader_Result.php @@ -2,7 +2,7 @@ namespace SilverStripe\Dev; -use SilverStripe\Core\Object; +use SilverStripe\Core\Injector\Injectable; use SilverStripe\ORM\ArrayList; use SilverStripe\ORM\DataObject; use SilverStripe\View\ArrayData; @@ -15,8 +15,9 @@ use SilverStripe\View\ArrayData; * * @author Ingo Schommer, Silverstripe Ltd. (@silverstripe.com) */ -class BulkLoader_Result extends Object +class BulkLoader_Result { + use Injectable; /** * Stores a map of ID and ClassNames @@ -139,7 +140,7 @@ class BulkLoader_Result extends Object { $this->created[] = $this->lastChange = array( 'ID' => $obj->ID, - 'ClassName' => $obj->class, + 'ClassName' => get_class($obj), 'Message' => $message ); $this->lastChange['ChangeType'] = 'created'; @@ -153,7 +154,7 @@ class BulkLoader_Result extends Object { $this->updated[] = $this->lastChange = array( 'ID' => $obj->ID, - 'ClassName' => $obj->class, + 'ClassName' => get_class($obj), 'Message' => $message ); $this->lastChange['ChangeType'] = 'updated'; diff --git a/src/Dev/CLI.php b/src/Dev/CLI.php index f6988669d..1e9077178 100644 --- a/src/Dev/CLI.php +++ b/src/Dev/CLI.php @@ -2,13 +2,11 @@ namespace SilverStripe\Dev; -use SilverStripe\Core\Object; - /** * Class to facilitate command-line output. * Support less-trivial output stuff such as colours (on xterm-color) */ -class CLI extends Object +class CLI { /** * Returns true if the current STDOUT supports the use of colour control codes. diff --git a/src/Dev/CSSContentParser.php b/src/Dev/CSSContentParser.php index 5d7295569..56f201617 100644 --- a/src/Dev/CSSContentParser.php +++ b/src/Dev/CSSContentParser.php @@ -2,7 +2,7 @@ namespace SilverStripe\Dev; -use SilverStripe\Core\Object; +use SilverStripe\Core\Injector\Injectable; use SimpleXMLElement; use tidy; use Exception; @@ -22,8 +22,10 @@ use Exception; * Caution: Doesn't fully support HTML elements like
* due to them being declared illegal by the "tidy" preprocessing step. */ -class CSSContentParser extends Object +class CSSContentParser { + use Injectable; + protected $simpleXML = null; public function __construct($content) @@ -59,8 +61,6 @@ class CSSContentParser extends Object throw new Exception('CSSContentParser::__construct(): Could not parse content.' . ' Please check the PHP extension tidy is installed.'); } - - parent::__construct(); } /** diff --git a/src/Dev/CSVParser.php b/src/Dev/CSVParser.php index 4ffa02574..f03ccffde 100644 --- a/src/Dev/CSVParser.php +++ b/src/Dev/CSVParser.php @@ -2,7 +2,7 @@ namespace SilverStripe\Dev; -use SilverStripe\Core\Object; +use SilverStripe\Core\Injector\Injectable; use Iterator; use SilverStripe\Control\Director; @@ -31,8 +31,9 @@ use SilverStripe\Control\Director; * } * */ -class CSVParser extends Object implements Iterator +class CSVParser implements Iterator { + use Injectable; /** * @var string $filename @@ -117,8 +118,6 @@ class CSVParser extends Object implements Iterator $this->filename = $filename; $this->delimiter = $delimiter; $this->enclosure = $enclosure; - - parent::__construct(); } /** diff --git a/src/Dev/CsvBulkLoader.php b/src/Dev/CsvBulkLoader.php index 878fb2fac..fdfa5ef87 100644 --- a/src/Dev/CsvBulkLoader.php +++ b/src/Dev/CsvBulkLoader.php @@ -180,7 +180,7 @@ class CsvBulkLoader extends BulkLoader */ protected function processChunk($filepath, $preview = false) { - $results = new BulkLoader_Result(); + $results = BulkLoader_Result::create(); $csv = new CSVParser( $filepath, diff --git a/src/Dev/DebugView.php b/src/Dev/DebugView.php index 33f341b81..64bf4243a 100644 --- a/src/Dev/DebugView.php +++ b/src/Dev/DebugView.php @@ -5,15 +5,18 @@ namespace SilverStripe\Dev; use SilverStripe\Control\Controller; use SilverStripe\Control\Director; use SilverStripe\Control\HTTPRequest; +use SilverStripe\Core\Config\Configurable; use SilverStripe\Core\Convert; -use SilverStripe\Core\Object; +use SilverStripe\Core\Injector\Injectable; /** * A basic HTML wrapper for stylish rendering of a developement info view. * Used to output error messages, and test results. */ -class DebugView extends Object +class DebugView { + use Configurable; + use Injectable; /** * Column size to wrap long strings to diff --git a/src/Dev/FixtureBlueprint.php b/src/Dev/FixtureBlueprint.php index 0977b6866..a511f86fd 100644 --- a/src/Dev/FixtureBlueprint.php +++ b/src/Dev/FixtureBlueprint.php @@ -2,6 +2,7 @@ namespace SilverStripe\Dev; +use SilverStripe\Assets\File; use SilverStripe\ORM\DataModel; use SilverStripe\ORM\DB; use SilverStripe\ORM\DataObject; @@ -85,8 +86,8 @@ class FixtureBlueprint // which they are imported doesnt guarantee valid relations until after the import is complete. // Also disable filesystem manipulations Config::nest(); - Config::inst()->update('SilverStripe\\ORM\\DataObject', 'validation_enabled', false); - Config::inst()->update('SilverStripe\\Assets\\File', 'update_filesystem', false); + Config::modify()->set(DataObject::class, 'validation_enabled', false); + Config::modify()->set(File::class, 'update_filesystem', false); $this->invokeCallbacks('beforeCreate', array($identifier, &$data, &$fixtures)); @@ -132,10 +133,10 @@ class FixtureBlueprint if ($data) { foreach ($data as $fieldName => $fieldVal) { if ($schema->manyManyComponent($class, $fieldName) - || $schema->hasManyComponent($class, $fieldName) - || $schema->hasOneComponent($class, $fieldName) - ) { - continue; + || $schema->hasManyComponent($class, $fieldName) + || $schema->hasOneComponent($class, $fieldName) + ) { + continue; } $this->setValue($obj, $fieldName, $fieldVal, $fixtures); diff --git a/src/Dev/FunctionalTest.php b/src/Dev/FunctionalTest.php index 99ecfba9f..73601253f 100644 --- a/src/Dev/FunctionalTest.php +++ b/src/Dev/FunctionalTest.php @@ -83,7 +83,7 @@ class FunctionalTest extends SapphireTest protected function setUp() { // Skip calling FunctionalTest directly. - if (get_class($this) == __CLASS__) { + if (static::class == __CLASS__) { $this->markTestSkipped(sprintf('Skipping %s ', get_class($this))); } diff --git a/src/Dev/SapphireTest.php b/src/Dev/SapphireTest.php index 3a3ce1f8f..7cb302aef 100644 --- a/src/Dev/SapphireTest.php +++ b/src/Dev/SapphireTest.php @@ -111,13 +111,14 @@ class SapphireTest extends PHPUnit_Framework_TestCase */ protected $requireDefaultRecordsFrom = array(); - /** * A list of extensions that can't be applied during the execution of this run. If they are * applied, they will be temporarily removed and a database migration called. * * The keys of the are the classes that the extensions can't be applied the extensions to, and * the values are an array of illegal extensions on that class. + * + * Set a class to `*` to remove all extensions (unadvised) */ protected static $illegal_extensions = []; @@ -242,7 +243,7 @@ class SapphireTest extends PHPUnit_Framework_TestCase } // We cannot run the tests on this abstract class. - if (get_class($this) == __CLASS__) { + if (static::class == __CLASS__) { $this->markTestSkipped(sprintf('Skipping %s ', get_class($this))); return; } @@ -357,6 +358,9 @@ class SapphireTest extends PHPUnit_Framework_TestCase if (!class_exists($class)) { continue; } + if ($extensions === '*') { + $extensions = $class::get_extensions(); + } foreach ($extensions as $extension) { if (!class_exists($extension) || !$class::has_extension($extension)) { continue; diff --git a/src/Dev/YamlFixture.php b/src/Dev/YamlFixture.php index 77c54a5b0..1ae95dafc 100644 --- a/src/Dev/YamlFixture.php +++ b/src/Dev/YamlFixture.php @@ -4,7 +4,7 @@ namespace SilverStripe\Dev; use SilverStripe\Control\Director; use SilverStripe\Core\ClassInfo; -use SilverStripe\Core\Object; +use SilverStripe\Core\Injector\Injectable; use Symfony\Component\Yaml\Parser; use InvalidArgumentException; @@ -68,8 +68,9 @@ use InvalidArgumentException; * ErrorCode: 404 * */ -class YamlFixture extends Object +class YamlFixture { + use Injectable; /** * Absolute path to the .yml fixture file @@ -104,8 +105,6 @@ class YamlFixture extends Object $this->fixtureFile = $fixture; } - - parent::__construct(); } /** diff --git a/src/Forms/CompositeField.php b/src/Forms/CompositeField.php index 706ea0e2c..70d6dc16d 100644 --- a/src/Forms/CompositeField.php +++ b/src/Forms/CompositeField.php @@ -246,9 +246,14 @@ class CompositeField extends FormField if ($name) { $formName = (isset($this->form)) ? $this->form->FormName() : '(unknown form)'; if (isset($list[$name])) { - user_error("collateDataFields() I noticed that a field called '$name' appears twice in" - . " your form: '{$formName}'. One is a '{$field->class}' and the other is a" - . " '{$list[$name]->class}'", E_USER_ERROR); + $fieldClass = get_class($field); + $otherFieldClass = $list[$name]->class; + user_error( + "collateDataFields() I noticed that a field called '$name' appears twice in" + . " your form: '{$formName}'. One is a '{$fieldClass}' and the other is a" + . " '{$otherFieldClass}'", + E_USER_ERROR + ); } $list[$name] = $field; } @@ -509,7 +514,8 @@ class CompositeField extends FormField public function debug() { - $result = "$this->class ($this->name)
    "; + $class = static::class; + $result = "$class ($this->name)
      "; foreach ($this->children as $child) { $result .= "
    • " . Debug::text($child) . " 
    • "; } diff --git a/src/Forms/FieldList.php b/src/Forms/FieldList.php index bbc0325b7..5563022a4 100644 --- a/src/Forms/FieldList.php +++ b/src/Forms/FieldList.php @@ -347,8 +347,12 @@ class FieldList extends ArrayList $withName = $parentPointer instanceof FormField ? " named '{$parentPointer->getName()}'" : null; - user_error("FieldList::addFieldToTab() Tried to add a tab to object" - . " '{$parentPointer->class}'{$withName} - '$part' didn't exist.", E_USER_ERROR); + $parentPointerClass = get_class($parentPointer); + user_error( + "FieldList::addFieldToTab() Tried to add a tab to object" + . " '{$parentPointerClass}'{$withName} - '{$part}' didn't exist.", + E_USER_ERROR + ); } } } @@ -379,8 +383,9 @@ class FieldList extends ArrayList if ($child instanceof CompositeField) { return $child->fieldByName($remainder); } else { + $childClass = get_class($child); user_error( - "Trying to get field '$remainder' from non-composite field $child->class.$name", + "Trying to get field '{$remainder}' from non-composite field {$childClass}.{$name}", E_USER_WARNING ); return null; diff --git a/src/Forms/FileField.php b/src/Forms/FileField.php index 084f74256..718f9d385 100644 --- a/src/Forms/FileField.php +++ b/src/Forms/FileField.php @@ -2,10 +2,10 @@ namespace SilverStripe\Forms; +use SilverStripe\Core\Injector\Injector; use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObjectInterface; use SilverStripe\Assets\File; -use SilverStripe\Core\Object; /** * Represents a file type which can be added to a form. @@ -104,15 +104,15 @@ class FileField extends FormField implements FileHandleField $objectClass = DataObject::getSchema()->hasOneComponent(get_class($record), $this->name); if ($objectClass === File::class || empty($objectClass)) { // Create object of the appropriate file class - $file = Object::create($fileClass); + $file = Injector::inst()->create($fileClass); } else { // try to create a file matching the relation - $file = Object::create($objectClass); + $file = Injector::inst()->create($objectClass); } } elseif ($record instanceof File) { $file = $record; } else { - $file = Object::create($fileClass); + $file = Injector::inst()->create($fileClass); } $this->upload->loadIntoFile($_FILES[$this->name], $file, $this->getFolderName()); diff --git a/src/Forms/FileUploadReceiver.php b/src/Forms/FileUploadReceiver.php index 39689c915..3c277d956 100644 --- a/src/Forms/FileUploadReceiver.php +++ b/src/Forms/FileUploadReceiver.php @@ -6,7 +6,7 @@ use Exception; use InvalidArgumentException; use SilverStripe\Assets\File; use SilverStripe\Assets\Storage\AssetContainer; -use SilverStripe\Core\Object; +use SilverStripe\Core\Injector\Injector; use SilverStripe\ORM\ArrayList; use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObjectInterface; @@ -308,7 +308,7 @@ trait FileUploadReceiver ); } // Create new object explicitly. Otherwise rely on Upload::load to choose the class. - $fileObject = Object::create($relationClass); + $fileObject = Injector::inst()->create($relationClass); if (! ($fileObject instanceof DataObject) || !($fileObject instanceof AssetContainer)) { throw new InvalidArgumentException("Invalid asset container $relationClass"); } diff --git a/src/Forms/Form.php b/src/Forms/Form.php index 5e0ec417c..edf4895c3 100644 --- a/src/Forms/Form.php +++ b/src/Forms/Form.php @@ -942,7 +942,7 @@ class Form extends ViewableData implements HasRequestHandler */ public function getTemplates() { - $templates = SSViewer::get_templates_by_class(get_class($this), '', __CLASS__); + $templates = SSViewer::get_templates_by_class(static::class, '', __CLASS__); // Prefer any custom template if ($this->getTemplate()) { array_unshift($templates, $this->getTemplate()); @@ -1702,7 +1702,8 @@ class Form extends ViewableData implements HasRequestHandler public function debug() { - $result = "

      $this->class

        "; + $class = static::class; + $result = "

        $class

          "; foreach ($this->fields as $field) { $result .= "
        • $field" . $field->debug() . "
        • "; } diff --git a/src/Forms/FormField.php b/src/Forms/FormField.php index 71229ca79..93e2e488f 100644 --- a/src/Forms/FormField.php +++ b/src/Forms/FormField.php @@ -1140,7 +1140,7 @@ class FormField extends RequestHandler */ protected function _templates($customTemplate = null, $customTemplateSuffix = null) { - $templates = SSViewer::get_templates_by_class(get_class($this), $customTemplateSuffix, __CLASS__); + $templates = SSViewer::get_templates_by_class(static::class, $customTemplateSuffix, __CLASS__); // Prefer any custom template if ($customTemplate) { // Prioritise direct template @@ -1278,7 +1278,7 @@ class FormField extends RequestHandler */ public function performDisabledTransformation() { - $disabledClassName = $this->class . '_Disabled'; + $disabledClassName = static::class . '_Disabled'; if (ClassInfo::exists($disabledClassName)) { $clone = $this->castedCopy($disabledClassName); @@ -1310,7 +1310,7 @@ class FormField extends RequestHandler { $patten = '/' . strtolower($class) . '/i'; - $subject = strtolower($this->class . ' ' . $this->extraClass()); + $subject = strtolower(static::class . ' ' . $this->extraClass()); return preg_match($patten, $subject); } @@ -1377,7 +1377,7 @@ class FormField extends RequestHandler { return sprintf( '%s (%s: %s : %s) = %s', - $this->class, + static::class, $this->name, $this->title, $this->message, @@ -1435,12 +1435,13 @@ class FormField extends RequestHandler */ public function rootFieldList() { - if (is_object($this->containerFieldList)) { + if ($this->containerFieldList) { return $this->containerFieldList->rootFieldList(); } + $class = static::class; user_error( - "rootFieldList() called on $this->class object without a containerFieldList", + "rootFieldList() called on {$class} object without a containerFieldList", E_USER_ERROR ); diff --git a/src/Forms/FormRequestHandler.php b/src/Forms/FormRequestHandler.php index bc2ca1437..6d07f7edf 100644 --- a/src/Forms/FormRequestHandler.php +++ b/src/Forms/FormRequestHandler.php @@ -258,7 +258,7 @@ class FormRequestHandler extends RequestHandler if ($legacyActions) { throw new BadMethodCallException( "allowed_actions are not valid on Form class " . get_class($this->form) . - ". Implement these in subclasses of " . get_class($this) . " instead" + ". Implement these in subclasses of " . static::class . " instead" ); } diff --git a/src/Forms/FormScaffolder.php b/src/Forms/FormScaffolder.php index b68a68473..d2d804da4 100644 --- a/src/Forms/FormScaffolder.php +++ b/src/Forms/FormScaffolder.php @@ -2,7 +2,8 @@ namespace SilverStripe\Forms; -use SilverStripe\Core\Object; +use SilverStripe\Core\Injector\Injectable; +use SilverStripe\Core\Injector\Injector; use SilverStripe\Forms\GridField\GridField; use SilverStripe\Forms\GridField\GridFieldConfig_RelationEditor; use SilverStripe\ORM\DataObject; @@ -11,8 +12,9 @@ use SilverStripe\ORM\DataObject; * @uses DBField::scaffoldFormField() * @uses DataObject::fieldLabels() */ -class FormScaffolder extends Object +class FormScaffolder { + use Injectable; /** * @var DataObject $obj The object defining the fields to be scaffolded @@ -58,7 +60,6 @@ class FormScaffolder extends Object public function __construct($obj) { $this->obj = $obj; - parent::__construct(); } /** @@ -151,7 +152,7 @@ class FormScaffolder extends Object ? $this->fieldClasses[$relationship] : 'SilverStripe\\Forms\\GridField\\GridField'; /** @var GridField $grid */ - $grid = Object::create( + $grid = Injector::inst()->create( $fieldClass, $relationship, $this->obj->fieldLabel($relationship), @@ -181,7 +182,7 @@ class FormScaffolder extends Object : 'SilverStripe\\Forms\\GridField\\GridField'; /** @var GridField $grid */ - $grid = Object::create( + $grid = Injector::inst()->create( $fieldClass, $relationship, $this->obj->fieldLabel($relationship), diff --git a/src/Forms/FormTransformation.php b/src/Forms/FormTransformation.php index 8e9655163..ee9cd7032 100644 --- a/src/Forms/FormTransformation.php +++ b/src/Forms/FormTransformation.php @@ -2,9 +2,11 @@ namespace SilverStripe\Forms; +use BadMethodCallException; use SilverStripe\Core\ClassInfo; -use SilverStripe\Core\Object; -use SilverStripe\Dev\Debug; +use SilverStripe\Core\Config\Configurable; +use SilverStripe\Core\Extensible; +use SilverStripe\Core\Injector\Injectable; /** * This class represents "transformations" of a form - such as making it printable or making it readonly. @@ -18,8 +20,17 @@ use SilverStripe\Dev\Debug; * * To actually perform the transformation, call $form->transform(new MyTransformation()); */ -class FormTransformation extends Object +class FormTransformation { + use Configurable; + use Injectable; + use Extensible; + + public function __construct() + { + $this->constructExtensions(); + } + public function transform(FormField $field) { // Look for a performXXTransformation() method on the field itself. @@ -34,13 +45,13 @@ class FormTransformation extends Object function ($name) { return ClassInfo::shortName($name); }, - array_values(ClassInfo::ancestry($this->class)) + array_values(ClassInfo::ancestry($this)) )); $fieldClasses = array_reverse(array_map( function ($name) { return ClassInfo::shortName($name); }, - array_values(ClassInfo::ancestry($field->class)) + array_values(ClassInfo::ancestry($field)) )); $len = max(sizeof($transNames), sizeof($fieldClasses)); @@ -64,6 +75,8 @@ class FormTransformation extends Object } } - throw new \BadMethodCallException("FormTransformation:: Can't perform '$this->class' on '$field->class'"); + $class = static::class; + $fieldClass = get_class($field); + throw new BadMethodCallException("FormTransformation:: Can't perform '{$class}' on '{$fieldClass}'"); } } diff --git a/src/Forms/GridField/GridFieldConfig.php b/src/Forms/GridField/GridFieldConfig.php index 21990e621..6491070d2 100644 --- a/src/Forms/GridField/GridFieldConfig.php +++ b/src/Forms/GridField/GridFieldConfig.php @@ -2,8 +2,10 @@ namespace SilverStripe\Forms\GridField; +use SilverStripe\Core\Config\Configurable; +use SilverStripe\Core\Extensible; +use SilverStripe\Core\Injector\Injectable; use SilverStripe\ORM\ArrayList; -use SilverStripe\Core\Object; /** * Encapsulates a collection of components following the @@ -22,22 +24,21 @@ use SilverStripe\Core\Object; * - {@link GridFieldConfig_RecordEditor} * - {@link GridFieldConfig_RelationEditor} */ -class GridFieldConfig extends Object +class GridFieldConfig { + use Injectable; + use Extensible; + use Configurable; /** * @var ArrayList */ protected $components = null; - - /** - * - */ public function __construct() { - parent::__construct(); $this->components = new ArrayList(); + $this->constructExtensions(); } /** diff --git a/src/Forms/GridField/GridFieldDetailForm.php b/src/Forms/GridField/GridFieldDetailForm.php index 13a40ed2b..bcc0c0d7d 100644 --- a/src/Forms/GridField/GridFieldDetailForm.php +++ b/src/Forms/GridField/GridFieldDetailForm.php @@ -3,16 +3,17 @@ namespace SilverStripe\Forms\GridField; use SilverStripe\Control\HTTPRequest; +use SilverStripe\Control\HTTPResponse; use SilverStripe\Control\RequestHandler; use SilverStripe\Core\Extensible; use SilverStripe\ORM\DataModel; use SilverStripe\ORM\DataObject; -use SilverStripe\Core\Object; use SilverStripe\Core\ClassInfo; use SilverStripe\Core\Injector\Injector; use SilverStripe\Forms\Validator; use SilverStripe\Forms\FieldList; use Closure; +use SilverStripe\ORM\Filterable; /** * Provides view and edit forms at GridField-specific URLs. @@ -91,7 +92,7 @@ class GridFieldDetailForm implements GridField_URLHandler * * @param GridField $gridField * @param HTTPRequest $request - * @return GridFieldDetailForm_ItemRequest + * @return HTTPResponse */ public function handleItem($gridField, $request) { @@ -102,21 +103,18 @@ class GridFieldDetailForm implements GridField_URLHandler /** @var DataObject $record */ if (is_numeric($request->param('ID'))) { - $record = $gridField->getList()->byID($request->param("ID")); + /** @var Filterable $dataList */ + $dataList = $gridField->getList(); + $record = $dataList->byID($request->param("ID")); } else { - $record = Object::create($gridField->getModelClass()); + $record = Injector::inst()->create($gridField->getModelClass()); } $handler = $this->getItemRequestHandler($gridField, $record, $requestHandler); // if no validator has been set on the GridField and the record has a // CMS validator, use that. - if (!$this->getValidator() - && ( - method_exists($record, 'getCMSValidator') - || $record instanceof Object && $record->hasMethod('getCMSValidator') - ) - ) { + if (!$this->getValidator() && ClassInfo::hasMethod($record, 'getCMSValidator')) { $this->setValidator($record->getCMSValidator()); } @@ -236,8 +234,8 @@ class GridFieldDetailForm implements GridField_URLHandler { if ($this->itemRequestClass) { return $this->itemRequestClass; - } elseif (ClassInfo::exists(get_class($this) . "_ItemRequest")) { - return get_class($this) . "_ItemRequest"; + } elseif (ClassInfo::exists(static::class . "_ItemRequest")) { + return static::class . "_ItemRequest"; } else { return __CLASS__ . '_ItemRequest'; } diff --git a/src/Forms/GridField/GridFieldFilterHeader.php b/src/Forms/GridField/GridFieldFilterHeader.php index 494edf322..c69df9aca 100755 --- a/src/Forms/GridField/GridFieldFilterHeader.php +++ b/src/Forms/GridField/GridFieldFilterHeader.php @@ -65,7 +65,7 @@ class GridFieldFilterHeader implements GridField_HTMLProvider, GridField_DataMan } else { if ($this->throwExceptionOnBadDataType) { throw new LogicException( - get_class($this) . " expects an SS_Filterable list to be passed to the GridField." + static::class . " expects an SS_Filterable list to be passed to the GridField." ); } return false; diff --git a/src/Forms/GridField/GridFieldLevelup.php b/src/Forms/GridField/GridFieldLevelup.php index 7d6a84de1..807e3a193 100644 --- a/src/Forms/GridField/GridFieldLevelup.php +++ b/src/Forms/GridField/GridFieldLevelup.php @@ -2,10 +2,11 @@ namespace SilverStripe\Forms\GridField; -use SilverStripe\Core\Object; +use SilverStripe\Core\Injector\Injectable; use SilverStripe\Forms\FormField; use SilverStripe\ORM\DataObject; use SilverStripe\ORM\FieldType\DBField; +use SilverStripe\ORM\Hierarchy\Hierarchy; use SilverStripe\View\ArrayData; use SilverStripe\View\SSViewer; @@ -14,8 +15,9 @@ use SilverStripe\View\SSViewer; * hierarchical data. Requires the managed record to have a "getParent()" * method or has_one relationship called "Parent". */ -class GridFieldLevelup extends Object implements GridField_HTMLProvider +class GridFieldLevelup implements GridField_HTMLProvider { + use Injectable; /** * @var integer - the record id of the level up to @@ -40,12 +42,15 @@ class GridFieldLevelup extends Object implements GridField_HTMLProvider */ public function __construct($currentID) { - parent::__construct(); if ($currentID && is_numeric($currentID)) { $this->currentID = $currentID; } } + /** + * @param GridField $gridField + * @return array|null + */ public function getHTMLFragments($gridField) { $modelClass = $gridField->getModelClass(); @@ -55,6 +60,7 @@ class GridFieldLevelup extends Object implements GridField_HTMLProvider return null; } + /** @var DataObject|Hierarchy $modelObj */ $modelObj = DataObject::get_by_id($modelClass, $this->currentID); $parent = null; diff --git a/src/Forms/GridField/GridFieldPageCount.php b/src/Forms/GridField/GridFieldPageCount.php index c46dd580e..e080edbc6 100755 --- a/src/Forms/GridField/GridFieldPageCount.php +++ b/src/Forms/GridField/GridFieldPageCount.php @@ -51,7 +51,7 @@ class GridFieldPageCount implements GridField_HTMLProvider if (!$paginator && GridFieldPageCount::config()->uninherited('require_paginator')) { throw new LogicException( - get_class($this) . " relies on a GridFieldPaginator to be added " . + static::class . " 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 d1438e943..0a860218a 100755 --- a/src/Forms/GridField/GridFieldPaginator.php +++ b/src/Forms/GridField/GridFieldPaginator.php @@ -88,7 +88,7 @@ class GridFieldPaginator implements GridField_HTMLProvider, GridField_DataManipu } else { if ($this->throwExceptionOnBadDataType) { throw new LogicException( - get_class($this) . " expects an SS_Limitable list to be passed to the GridField." + static::class . " expects an SS_Limitable list to be passed to the GridField." ); } return false; diff --git a/src/Forms/GridField/GridFieldSortableHeader.php b/src/Forms/GridField/GridFieldSortableHeader.php index 29baec4f3..0dd66a64c 100644 --- a/src/Forms/GridField/GridFieldSortableHeader.php +++ b/src/Forms/GridField/GridFieldSortableHeader.php @@ -75,7 +75,7 @@ class GridFieldSortableHeader implements GridField_HTMLProvider, GridField_DataM } else { if ($this->throwExceptionOnBadDataType) { throw new LogicException( - get_class($this) . " expects an SS_Sortable list to be passed to the GridField." + static::class . " expects an SS_Sortable list to be passed to the GridField." ); } return false; diff --git a/src/Forms/HTMLEditor/HTMLEditorField_Toolbar.php b/src/Forms/HTMLEditor/HTMLEditorField_Toolbar.php index 0da5cfa6d..d9f5a5dcf 100644 --- a/src/Forms/HTMLEditor/HTMLEditorField_Toolbar.php +++ b/src/Forms/HTMLEditor/HTMLEditorField_Toolbar.php @@ -47,7 +47,7 @@ class HTMLEditorField_Toolbar extends RequestHandler */ public function getTemplateViewFile() { - return SSViewer::get_templates_by_class(get_class($this), '_viewfile', __CLASS__); + return SSViewer::get_templates_by_class(static::class, '_viewfile', __CLASS__); } /** @@ -185,7 +185,7 @@ class HTMLEditorField_Toolbar extends RequestHandler return $form; } - + /** * Builds and returns the external link form * @@ -200,7 +200,7 @@ class HTMLEditorField_Toolbar extends RequestHandler } return null; } - + /** * Builds and returns the external link form * @@ -210,13 +210,13 @@ class HTMLEditorField_Toolbar extends RequestHandler { /** @var EditorEmailLinkFormFactory $factory */ $factory = Injector::inst()->get(EditorEmailLinkFormFactory::class); - + if ($factory) { return $factory->getForm($this->controller, "{$this->name}/EditorEmailLink"); } return null; } - + /** * Get the folder ID to filter files by for the "from cms" tab * diff --git a/src/Forms/NullableField.php b/src/Forms/NullableField.php index 8a3ff2577..9bd3f9c4d 100644 --- a/src/Forms/NullableField.php +++ b/src/Forms/NullableField.php @@ -170,7 +170,7 @@ class NullableField extends FormField { $result = sprintf( '%s (%s: $s : %s) = ', - $this->class, + static::class, $this->name, $this->title, $this->message diff --git a/src/Forms/Validator.php b/src/Forms/Validator.php index 223eb229f..6ac357894 100644 --- a/src/Forms/Validator.php +++ b/src/Forms/Validator.php @@ -2,7 +2,9 @@ namespace SilverStripe\Forms; -use SilverStripe\Core\Object; +use SilverStripe\Core\Config\Configurable; +use SilverStripe\Core\Extensible; +use SilverStripe\Core\Injector\Injectable; use SilverStripe\ORM\ValidationResult; /** @@ -10,13 +12,16 @@ use SilverStripe\ORM\ValidationResult; * fields. It relies on javascript for client-side validation, and marking fields after server-side * validation. It acts as a visitor to individual form fields. */ -abstract class Validator extends Object +abstract class Validator { + use Injectable; + use Configurable; + use Extensible; public function __construct() { - parent::__construct(); $this->resetResult(); + $this->constructExtensions(); } /** diff --git a/src/ORM/ArrayList.php b/src/ORM/ArrayList.php index 9919beef1..5d1ad744b 100644 --- a/src/ORM/ArrayList.php +++ b/src/ORM/ArrayList.php @@ -118,7 +118,7 @@ class ArrayList extends ViewableData implements SS_List, Filterable, Sortable, L public function debug() { - $val = "

          " . $this->class . "

            "; + $val = "

            " . static::class . "

              "; foreach ($this->toNestedArray() as $item) { $val .= "
            • " . Debug::text($item) . "
            • "; } diff --git a/src/ORM/Connect/DBConnector.php b/src/ORM/Connect/DBConnector.php index bea5aa53a..c5af38205 100644 --- a/src/ORM/Connect/DBConnector.php +++ b/src/ORM/Connect/DBConnector.php @@ -73,8 +73,8 @@ abstract class DBConnector public function isQueryMutable($sql) { $operations = array_merge( - Config::inst()->get(get_class($this), 'write_operations'), - Config::inst()->get(get_class($this), 'ddl_operations') + Config::inst()->get(static::class, 'write_operations'), + Config::inst()->get(static::class, 'ddl_operations') ); return $this->isQueryType($sql, $operations); } @@ -87,7 +87,7 @@ abstract class DBConnector */ public function isQueryDDL($sql) { - $operations = Config::inst()->get(get_class($this), 'ddl_operations'); + $operations = Config::inst()->get(static::class, 'ddl_operations'); return $this->isQueryType($sql, $operations); } @@ -100,7 +100,7 @@ abstract class DBConnector */ public function isQueryWrite($sql) { - $operations = Config::inst()->get(get_class($this), 'write_operations'); + $operations = Config::inst()->get(static::class, 'write_operations'); return $this->isQueryType($sql, $operations); } diff --git a/src/ORM/Connect/DBSchemaManager.php b/src/ORM/Connect/DBSchemaManager.php index 04bda4082..d60496aea 100644 --- a/src/ORM/Connect/DBSchemaManager.php +++ b/src/ORM/Connect/DBSchemaManager.php @@ -4,7 +4,7 @@ namespace SilverStripe\ORM\Connect; use SilverStripe\Control\Director; use SilverStripe\Core\Config\Config; -use SilverStripe\Core\Object; +use SilverStripe\Core\Injector\Injector; use SilverStripe\ORM\FieldType\DBPrimaryKey; use SilverStripe\ORM\FieldType\DBField; use Exception; @@ -389,7 +389,7 @@ abstract class DBSchemaManager } /** @var DBField $fieldObj */ - $fieldObj = Object::create_from_string($fieldSpec, $fieldName); + $fieldObj = Injector::inst()->create($fieldSpec, $fieldName); $fieldObj->setArrayValue($arrayValue); $fieldObj->setTable($table); diff --git a/src/ORM/Connect/Database.php b/src/ORM/Connect/Database.php index 6d5627ced..4396d884a 100644 --- a/src/ORM/Connect/Database.php +++ b/src/ORM/Connect/Database.php @@ -777,7 +777,7 @@ abstract class Database public function selectDatabase($name, $create = false, $errorLevel = E_USER_ERROR) { // In case our live environment is locked down, we can bypass a SHOW DATABASE check - $canConnect = Config::inst()->get(get_class($this), 'optimistic_connect') + $canConnect = Config::inst()->get(static::class, 'optimistic_connect') || $this->schemaManager->databaseExists($name); if ($canConnect) { return $this->connector->selectDatabase($name); diff --git a/src/ORM/DataExtension.php b/src/ORM/DataExtension.php index 6478be9b9..40a7ecfc1 100644 --- a/src/ORM/DataExtension.php +++ b/src/ORM/DataExtension.php @@ -165,7 +165,7 @@ abstract class DataExtension extends Extension */ public function updateSummaryFields(&$fields) { - $summary_fields = Config::inst()->get($this->class, 'summary_fields'); + $summary_fields = Config::inst()->get(static::class, 'summary_fields'); if ($summary_fields) { // if summary_fields were passed in numeric array, // convert to an associative array @@ -188,7 +188,7 @@ abstract class DataExtension extends Extension */ public function updateFieldLabels(&$labels) { - $field_labels = Config::inst()->get($this->class, 'field_labels'); + $field_labels = Config::inst()->get(static::class, 'field_labels'); if ($field_labels) { $labels = array_merge($labels, $field_labels); } diff --git a/src/ORM/DataList.php b/src/ORM/DataList.php index fd5632696..ce16ed483 100644 --- a/src/ORM/DataList.php +++ b/src/ORM/DataList.php @@ -750,8 +750,7 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li public function debug() { - $val = "

              " . $this->class . "

                "; - + $val = "

                " . static::class . "

                  "; foreach ($this->toNestedArray() as $item) { $val .= "
                • " . Debug::text($item) . "
                • "; } @@ -1072,7 +1071,7 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li /** * Remove every element in this DataList matching the given $filter. * - * @param string $filter - a sql type where filter + * @param string|array $filter - a sql type where filter * @return $this */ public function removeByFilter($filter) diff --git a/src/ORM/DataObject.php b/src/ORM/DataObject.php index 70bbd1ce9..f2fe8ce3d 100644 --- a/src/ORM/DataObject.php +++ b/src/ORM/DataObject.php @@ -4,7 +4,6 @@ namespace SilverStripe\ORM; use SilverStripe\Core\ClassInfo; use SilverStripe\Core\Config\Config; -use SilverStripe\Core\Object; use SilverStripe\Core\Injector\Injector; use SilverStripe\Core\Resettable; use SilverStripe\Dev\Deprecation; @@ -30,6 +29,7 @@ use LogicException; use InvalidArgumentException; use BadMethodCallException; use Exception; +use stdClass; /** * A single database record & abstract class for the data-access-model. @@ -306,7 +306,11 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity ); } - if (!is_array($record) && !is_a($record, "stdClass")) { + if ($record instanceof stdClass) { + $record = (array)$record; + } + + if (!is_array($record)) { if (is_object($record)) { $passed = "an object of type '".get_class($record)."'"; } else { @@ -321,10 +325,6 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity $record = null; } - if (is_a($record, "stdClass")) { - $record = (array)$record; - } - // Set $this->record to $record, but ignore NULLs $this->record = array(); foreach ($record as $k => $v) { @@ -517,7 +517,6 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity return $this; } - $this->class = $className; $this->setField("ClassName", $className); $this->setField('RecordClassName', $className); return $this; @@ -568,20 +567,6 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity { parent::defineMethods(); - // Define the extra db fields - this is only necessary for extensions added in the - // class definition. Object::add_extension() will call this at definition time for - // those objects, which is a better mechanism. Perhaps extensions defined inside the - // class def can somehow be applied at definiton time also? - if ($this->extension_instances) { - foreach ($this->extension_instances as $i => $instance) { - if (!$instance->class) { - $class = get_class($instance); - user_error("DataObject::defineMethods(): Please ensure {$class}::__construct() calls" - . " parent::__construct()", E_USER_ERROR); - } - } - } - if (static::class === self::class) { return; } @@ -815,11 +800,12 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity */ public function update($data) { - foreach ($data as $k => $v) { + foreach ($data as $key => $value) { // Implement dot syntax for updates - if (strpos($k, '.') !== false) { - $relations = explode('.', $k); + if (strpos($key, '.') !== false) { + $relations = explode('.', $key); $fieldName = array_pop($relations); + /** @var static $relObj */ $relObj = $this; $relation = null; foreach ($relations as $i => $relation) { @@ -829,7 +815,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity $parentObj = $relObj; $relObj = $relObj->$relation(); // If the intermediate relationship objects have been created, then write them - if ($iID || (!$relObj->ID && $parentObj != $this)) { + if ($iID || (!$relObj->ID && $parentObj !== $this)) { $relObj->write(); $relatedFieldName = $relation."ID"; $parentObj->$relatedFieldName = $relObj->ID; @@ -848,16 +834,17 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity } if ($relObj) { - $relObj->$fieldName = $v; + $relObj->$fieldName = $value; $relObj->write(); $relatedFieldName = $relation."ID"; $this->$relatedFieldName = $relObj->ID; $relObj->flushCache(); } else { - user_error("Couldn't follow dot syntax '$k' on '$this->class' object", E_USER_WARNING); + $class = static::class; + user_error("Couldn't follow dot syntax '{$key}' on '{$class}' object", E_USER_WARNING); } } else { - $this->$k = $v; + $this->$key = $value; } } return $this; @@ -949,6 +936,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity if ($includeRelations) { if ($manyMany = $this->manyMany()) { foreach ($manyMany as $relationship => $class) { + /** @var DataObject $leftComponents */ $leftComponents = $leftObj->getManyManyComponents($relationship); $rightComponents = $rightObj->getManyManyComponents($relationship); if ($rightComponents && $rightComponents->exists()) { @@ -1110,7 +1098,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity if ($defaults && !is_array($defaults)) { user_error( - "Bad '$this->class' defaults given: " . var_export($defaults, true), + "Bad '" . static::class . "' defaults given: " . var_export($defaults, true), E_USER_WARNING ); $defaults = null; @@ -1181,7 +1169,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity $this->brokenOnWrite = true; $this->onBeforeWrite(); if ($this->brokenOnWrite) { - user_error("$this->class has a broken onBeforeWrite() function." + user_error(static::class . " has a broken onBeforeWrite() function." . " Make sure that you call parent::onBeforeWrite().", E_USER_ERROR); } } @@ -1251,7 +1239,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity = empty($this->record['Created']) ? $now : $this->record['Created']; - $manipulation[$table]['fields']['ClassName'] = $this->class; + $manipulation[$table]['fields']['ClassName'] = static::class; } } @@ -1434,7 +1422,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity $this->brokenOnDelete = true; $this->onBeforeDelete(); if ($this->brokenOnDelete) { - user_error("$this->class has a broken onBeforeDelete() function." + user_error(static::class . " has a broken onBeforeDelete() function." . " Make sure that you call parent::onBeforeDelete().", E_USER_ERROR); } @@ -1447,7 +1435,10 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity // - move the details of the delete code in the DataQuery system // - update the code to just delete the base table, and rely on cascading deletes in the DB to do the rest // obviously, that means getting requireTable() to configure cascading deletes ;-) - $srcQuery = DataList::create($this->class, $this->model)->where("ID = $this->ID")->dataQuery()->query(); + $srcQuery = DataList::create(static::class, $this->model) + ->filter('ID', $this->ID) + ->dataQuery() + ->query(); foreach ($srcQuery->queriedTables() as $table) { $delete = new SQLDelete("\"$table\"", array('"ID"' => $this->ID)); $delete->execute(); @@ -1538,7 +1529,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity if ($polymorphic) { $filter = array( "{$joinField}ID" => $joinID, - "{$joinField}Class" => $this->class + "{$joinField}Class" => static::class, ); } else { $filter = array( @@ -1557,7 +1548,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity $component = $this->model->$class->newObject(); if ($polymorphic) { $component->{$joinField.'ID'} = $this->ID; - $component->{$joinField.'Class'} = $this->class; + $component->{$joinField.'Class'} = static::class; } else { $component->$joinField = $this->ID; } @@ -1588,7 +1579,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity throw new InvalidArgumentException(sprintf( "DataObject::getComponents(): Unknown 1-to-many component '%s' on class '%s'", $componentName, - $this->class + static::class )); } @@ -1596,7 +1587,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity if (!$this->ID) { if (!isset($this->unsavedRelations[$componentName])) { $this->unsavedRelations[$componentName] = - new UnsavedRelationList($this->class, $componentName, $componentClass); + new UnsavedRelationList(static::class, $componentName, $componentClass); } return $this->unsavedRelations[$componentName]; } @@ -1605,7 +1596,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity $joinField = $schema->getRemoteJoinField(static::class, $componentName, 'has_many', $polymorphic); /** @var HasManyList $result */ if ($polymorphic) { - $result = PolymorphicHasManyList::create($componentClass, $joinField, $this->class); + $result = PolymorphicHasManyList::create($componentClass, $joinField, get_class($this)); } else { $result = HasManyList::create($componentClass, $joinField); } @@ -1630,11 +1621,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity // Parse many_many $manyManyComponent = $this->getSchema()->manyManyComponent(static::class, $relationName); if ($manyManyComponent) { - list( - $relationClass, $parentClass, $componentClass, - $parentField, $childField, $tableOrClass - ) = $manyManyComponent; - return $componentClass; + return $manyManyComponent['childClass']; } // Go through all relationship configuration fields. @@ -1772,18 +1759,17 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity case 'many_many': case 'belongs_many_many': { // Get components and extra fields from parent - list($relationClass, $componentClass, $parentClass, $componentField, $parentField, $table) - = $remote->getSchema()->manyManyComponent($remoteClass, $remoteRelation); + $manyMany = $remote->getSchema()->manyManyComponent($remoteClass, $remoteRelation); $extraFields = $schema->manyManyExtraFieldsForComponent($remoteClass, $remoteRelation) ?: array(); // Reverse parent and component fields and create an inverse ManyManyList /** @var RelationList $result */ $result = Injector::inst()->create( - $relationClass, - $componentClass, - $table, - $componentField, - $parentField, + $manyMany['relationClass'], + $manyMany['parentClass'], // Substitute parent class for dataClass + $manyMany['join'], + $manyMany['parentField'], // Reversed parent / child field + $manyMany['childField'], // Reversed parent / child field $extraFields ); if ($this->model) { @@ -1816,18 +1802,15 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity throw new InvalidArgumentException(sprintf( "DataObject::getComponents(): Unknown many-to-many component '%s' on class '%s'", $componentName, - $this->class + static::class )); } - list($relationClass, $parentClass, $componentClass, $parentField, $componentField, $tableOrClass) - = $manyManyComponent; - // If we haven't been written yet, we can't save these relations, so use a list that handles this case if (!$this->ID) { if (!isset($this->unsavedRelations[$componentName])) { $this->unsavedRelations[$componentName] = - new UnsavedRelationList($parentClass, $componentName, $componentClass); + new UnsavedRelationList($manyManyComponent['parentClass'], $componentName, $manyManyComponent['childClass']); } return $this->unsavedRelations[$componentName]; } @@ -1835,11 +1818,11 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity $extraFields = $schema->manyManyExtraFieldsForComponent(static::class, $componentName) ?: array(); /** @var RelationList $result */ $result = Injector::inst()->create( - $relationClass, - $componentClass, - $tableOrClass, - $componentField, - $parentField, + $manyManyComponent['relationClass'], + $manyManyComponent['childClass'], + $manyManyComponent['join'], + $manyManyComponent['childField'], + $manyManyComponent['parentField'], $extraFields ); @@ -1968,7 +1951,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity public function getDefaultSearchContext() { return new SearchContext( - $this->class, + static::class, $this->scaffoldSearchFields(), $this->defaultSearchFilters() ); @@ -2069,7 +2052,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity (array)$_params ); - $fs = new FormScaffolder($this); + $fs = FormScaffolder::create($this); $fs->tabbed = $params['tabbed']; $fs->includeRelations = $params['includeRelations']; $fs->restrictFields = $params['restrictFields']; @@ -2634,7 +2617,8 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity */ public function debug() { - $val = "

                  Database record: $this->class

                  \n
                    \n"; + $class = static::class; + $val = "

                    Database record: {$class}

                    \n
                      \n"; if ($this->record) { foreach ($this->record as $fieldName => $fieldVal) { $val .= "\t
                    • $fieldName: " . Debug::text($fieldVal) . "
                    • \n"; @@ -2680,7 +2664,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity list($class, $spec) = explode('.', $helper); /** @var DBField $obj */ $table = $schema->tableName($class); - $obj = Object::create_from_string($spec, $fieldName); + $obj = Injector::inst()->create($spec, $fieldName); $obj->setTable($table); $obj->setValue($value, $this, false); return $obj; @@ -2712,6 +2696,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity if (method_exists($component, $relation)) { $component = $component->$relation(); } else { + /** @var DataList $component */ $component = $component->relation($relation); } } else { @@ -2749,6 +2734,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity $component = $component->$relation(); } elseif ($component instanceof SS_List) { // Select adjacent relation from DataList + /** @var DataList $component */ $component = $component->relation($relation); } elseif ($component instanceof DataObject && ($dbObject = $component->dbObject($relation)) @@ -2914,12 +2900,12 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity */ public function flushCache($persistent = true) { - if ($this->class == self::class) { + if (static::class == self::class) { self::$_cache_get_one = array(); return $this; } - $classes = ClassInfo::ancestry($this->class); + $classes = ClassInfo::ancestry(static::class); foreach ($classes as $class) { if (isset(self::$_cache_get_one[$class])) { unset(self::$_cache_get_one[$class]); @@ -3139,10 +3125,9 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity foreach ($manyMany as $component => $spec) { // Get many_many spec $manyManyComponent = $schema->manyManyComponent(static::class, $component); - list( - $relationClass, $parentClass, $componentClass, - $parentField, $childField, $tableOrClass - ) = $manyManyComponent; + $parentField = $manyManyComponent['parentField']; + $childField = $manyManyComponent['childField']; + $tableOrClass = $manyManyComponent['join']; // Skip if backed by actual class if (class_exists($tableOrClass)) { @@ -3184,9 +3169,9 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity $defaultRecords = $this->config()->uninherited('default_records'); if (!empty($defaultRecords)) { - $hasData = DataObject::get_one($this->class); + $hasData = DataObject::get_one(static::class); if (!$hasData) { - $className = $this->class; + $className = static::class; foreach ($defaultRecords as $record) { $obj = $this->model->$className->newObject($record); $obj->write(); @@ -3308,14 +3293,14 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity */ public function fieldLabels($includerelations = true) { - $cacheKey = $this->class . '_' . $includerelations; + $cacheKey = static::class . '_' . $includerelations; if (!isset(self::$_cache_field_labels[$cacheKey])) { $customLabels = $this->stat('field_labels'); $autoLabels = array(); // get all translated static properties as defined in i18nCollectStatics() - $ancestry = ClassInfo::ancestry($this->class); + $ancestry = ClassInfo::ancestry(static::class); $ancestry = array_reverse($ancestry); if ($ancestry) { foreach ($ancestry as $ancestorClass) { diff --git a/src/ORM/DataObjectSchema.php b/src/ORM/DataObjectSchema.php index 547fce44e..00a1cdd28 100644 --- a/src/ORM/DataObjectSchema.php +++ b/src/ORM/DataObjectSchema.php @@ -5,10 +5,10 @@ namespace SilverStripe\ORM; use Exception; use SilverStripe\Core\Injector\Injectable; use SilverStripe\Core\Config\Configurable; +use SilverStripe\Core\Injector\Injector; use SilverStripe\ORM\FieldType\DBComposite; use SilverStripe\Core\ClassInfo; use SilverStripe\Core\Config\Config; -use SilverStripe\Core\Object; use InvalidArgumentException; use LogicException; @@ -438,7 +438,7 @@ class DataObjectSchema // Merge composite fields into DB foreach ($compositeFields as $fieldName => $fieldSpec) { - $fieldObj = Object::create_from_string($fieldSpec, $fieldName); + $fieldObj = Injector::inst()->create($fieldSpec, $fieldName); $fieldObj->setTable($class); $nestedFields = $fieldObj->compositeDatabaseFields(); foreach ($nestedFields as $nestedName => $nestedSpec) { @@ -498,7 +498,7 @@ class DataObjectSchema } // Find regular field - while ($candidateClass) { + while ($candidateClass && $candidateClass !== DataObject::class) { $fields = $this->databaseFields($candidateClass, false); if (isset($fields[$fieldName])) { return $candidateClass; @@ -533,9 +533,9 @@ class DataObjectSchema $classes = ClassInfo::ancestry($class); foreach ($classes as $parentClass) { // Check if the component is defined in many_many on this class - $manyMany = Config::inst()->get($parentClass, 'many_many', Config::UNINHERITED); - if (isset($manyMany[$component])) { - return $this->parseManyManyComponent($parentClass, $component, $manyMany[$component]); + $otherManyMany = Config::inst()->get($parentClass, 'many_many', Config::UNINHERITED); + if (isset($otherManyMany[$component])) { + return $this->parseManyManyComponent($parentClass, $component, $otherManyMany[$component]); } // Check if the component is defined in belongs_many_many on this class @@ -545,13 +545,22 @@ class DataObjectSchema } // Extract class and relation name from dot-notation - list($childClass, $relationName) - = $this->parseBelongsManyManyComponent($parentClass, $component, $belongsManyMany[$component]); + $belongs = $this->parseBelongsManyManyComponent( + $parentClass, + $component, + $belongsManyMany[$component] + ); // Build inverse relationship from other many_many, and swap parent/child - list($relationClass, $childClass, $parentClass, $childField, $parentField, $joinTable) - = $this->manyManyComponent($childClass, $relationName); - return [$relationClass, $parentClass, $childClass, $parentField, $childField, $joinTable]; + $otherManyMany = $this->manyManyComponent($belongs['childClass'], $belongs['relationName']); + return [ + 'relationClass' => $otherManyMany['relationClass'], + 'parentClass' => $otherManyMany['childClass'], + 'childClass' => $otherManyMany['parentClass'], + 'parentField' => $otherManyMany['childField'], + 'childField' => $otherManyMany['parentField'], + 'join' => $otherManyMany['join'], + ]; } return null; } @@ -596,7 +605,10 @@ class DataObjectSchema } // Return relatios - return array($childClass, $relationName); + return [ + 'childClass' => $childClass, + 'relationName' => $relationName + ]; } /** @@ -619,12 +631,12 @@ class DataObjectSchema $belongsManyMany = Config::inst()->get($class, 'belongs_many_many', Config::UNINHERITED); if (isset($belongsManyMany[$component])) { // Reverse relationship and find extrafields from child class - list($childClass, $relationName) = $this->parseBelongsManyManyComponent( + $belongs = $this->parseBelongsManyManyComponent( $class, $component, $belongsManyMany[$component] ); - return $this->manyManyExtraFieldsForComponent($childClass, $relationName); + return $this->manyManyExtraFieldsForComponent($belongs['childClass'], $belongs['relationName']); } $class = get_parent_class($class); } @@ -717,12 +729,12 @@ class DataObjectSchema $parentClass = $this->checkManyManyFieldClass($parentClass, $component, $joinClass, $specification, 'from'); $joinChildClass = $this->checkManyManyFieldClass($parentClass, $component, $joinClass, $specification, 'to'); return [ - ManyManyThroughList::class, - $parentClass, - $joinChildClass, - $specification['from'] . 'ID', - $specification['to'] . 'ID', - $joinClass, + 'relationClass' => ManyManyThroughList::class, + 'parentClass' => $parentClass, + 'childClass' => $joinChildClass, + 'parentField' => $specification['from'] . 'ID', + 'childField' => $specification['to'] . 'ID', + 'join' => $joinClass, ]; } @@ -740,12 +752,12 @@ class DataObjectSchema } $joinTable = "{$classTable}_{$component}"; return [ - ManyManyList::class, - $parentClass, - $specification, - $parentField, - $childField, - $joinTable, + 'relationClass' => ManyManyList::class, + 'parentClass' => $parentClass, + 'childClass' => $specification, + 'parentField' => $parentField, + 'childField' => $childField, + 'join' => $joinTable, ]; } diff --git a/src/ORM/DataQuery.php b/src/ORM/DataQuery.php index 207513d21..3c711eec1 100644 --- a/src/ORM/DataQuery.php +++ b/src/ORM/DataQuery.php @@ -4,7 +4,6 @@ namespace SilverStripe\ORM; use SilverStripe\Core\ClassInfo; use SilverStripe\Core\Convert; -use SilverStripe\Core\Object; use SilverStripe\Core\Injector\Injector; use SilverStripe\ORM\Connect\Query; use SilverStripe\ORM\Queries\SQLConditionGroup; @@ -452,8 +451,8 @@ class DataQuery */ public function max($field) { - $table = ClassInfo::table_for_object_field($this->dataClass, $field); - if (!$table || $table === 'DataObject') { + $table = DataObject::getSchema()->tableForField($this->dataClass, $field); + if (!$table) { return $this->aggregate("MAX(\"$field\")"); } return $this->aggregate("MAX(\"$table\".\"$field\")"); @@ -468,8 +467,8 @@ class DataQuery */ public function min($field) { - $table = ClassInfo::table_for_object_field($this->dataClass, $field); - if (!$table || $table === 'DataObject') { + $table = DataObject::getSchema()->tableForField($this->dataClass, $field); + if (!$table) { return $this->aggregate("MIN(\"$field\")"); } return $this->aggregate("MIN(\"$table\".\"$field\")"); @@ -484,8 +483,8 @@ class DataQuery */ public function avg($field) { - $table = ClassInfo::table_for_object_field($this->dataClass, $field); - if (!$table || $table === 'DataObject') { + $table = DataObject::getSchema()->tableForField($this->dataClass, $field); + if (!$table) { return $this->aggregate("AVG(\"$field\")"); } return $this->aggregate("AVG(\"$table\".\"$field\")"); @@ -500,8 +499,8 @@ class DataQuery */ public function sum($field) { - $table = ClassInfo::table_for_object_field($this->dataClass, $field); - if (!$table || $table === 'DataObject') { + $table = DataObject::getSchema()->tableForField($this->dataClass, $field); + if (!$table) { return $this->aggregate("SUM(\"$field\")"); } return $this->aggregate("SUM(\"$table\".\"$field\")"); @@ -569,7 +568,7 @@ class DataQuery foreach ($compositeFields as $k => $v) { if ((is_null($columns) || in_array($k, $columns)) && $v) { $tableName = $schema->tableName($tableClass); - $dbO = Object::create_from_string($v, $k); + $dbO = Injector::inst()->create($v, $k); $dbO->setTable($tableName); $dbO->addToQuery($query); } @@ -799,18 +798,15 @@ class DataQuery if ($linearOnly) { throw new InvalidArgumentException("$rel is not a linear relation on model $modelClass"); } - // Join via many_many - list($relationClass, $parentClass, $componentClass, $parentField, $componentField, $relationTable) - = $component; $this->joinManyManyRelationship( - $relationClass, - $parentClass, - $componentClass, - $parentField, - $componentField, - $relationTable + $component['relationClass'], + $component['parentClass'], + $component['childClass'], + $component['parentField'], + $component['childField'], + $component['join'] ); - $modelClass = $componentClass; + $modelClass = $component['childClass']; } else { throw new InvalidArgumentException("$rel is not a relation on model $modelClass"); } @@ -1073,7 +1069,7 @@ class DataQuery * It's expected that the $key will be namespaced, e.g, 'Versioned.stage' instead of just 'stage'. * * @param string $key - * @param string $value + * @param string|array $value * @return $this */ public function setQueryParam($key, $value) diff --git a/src/ORM/FieldType/DBBoolean.php b/src/ORM/FieldType/DBBoolean.php index 4d74fa24e..a6459583d 100644 --- a/src/ORM/FieldType/DBBoolean.php +++ b/src/ORM/FieldType/DBBoolean.php @@ -49,7 +49,8 @@ class DBBoolean extends DBField if ($fieldName) { $dataObject->$fieldName = ($this->value) ? 1 : 0; } else { - user_error("DBField::saveInto() Called on a nameless '$this->class' object", E_USER_ERROR); + $class = static::class; + user_error("DBField::saveInto() Called on a nameless '$class' object", E_USER_ERROR); } } diff --git a/src/ORM/FieldType/DBComposite.php b/src/ORM/FieldType/DBComposite.php index 57dad29c7..8ad958611 100644 --- a/src/ORM/FieldType/DBComposite.php +++ b/src/ORM/FieldType/DBComposite.php @@ -2,7 +2,7 @@ namespace SilverStripe\ORM\FieldType; -use SilverStripe\Core\Object; +use SilverStripe\Core\Injector\Injector; use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DB; use SilverStripe\ORM\Queries\SQLSelect; @@ -145,6 +145,7 @@ abstract class DBComposite extends DBField * @param mixed $value * @param mixed $record Parent object to this field, which could be a DataObject, record array, or other * @param bool $markChanged + * @return $this */ public function setValue($value, $record = null, $markChanged = true) { @@ -172,6 +173,7 @@ abstract class DBComposite extends DBField $this->setField($field, $record[$key]); } } + return $this; } /** @@ -277,7 +279,7 @@ abstract class DBComposite extends DBField $key = $this->getName() . $field; $spec = $fields[$field]; /** @var DBField $fieldObject */ - $fieldObject = Object::create_from_string($spec, $key); + $fieldObject = Injector::inst()->create($spec, $key); $fieldObject->setValue($this->getField($field), null, false); return $fieldObject; } diff --git a/src/ORM/FieldType/DBDecimal.php b/src/ORM/FieldType/DBDecimal.php index ea657cd52..437d2908e 100644 --- a/src/ORM/FieldType/DBDecimal.php +++ b/src/ORM/FieldType/DBDecimal.php @@ -72,7 +72,7 @@ class DBDecimal extends DBField if ($fieldName) { $dataObject->$fieldName = (float)preg_replace('/[^0-9.\-\+]/', '', $this->value); } else { - user_error("DBField::saveInto() Called on a nameless '" . get_class($this) . "' object", E_USER_ERROR); + user_error("DBField::saveInto() Called on a nameless '" . static::class . "' object", E_USER_ERROR); } } diff --git a/src/ORM/FieldType/DBField.php b/src/ORM/FieldType/DBField.php index d2eacc3de..c43253b61 100644 --- a/src/ORM/FieldType/DBField.php +++ b/src/ORM/FieldType/DBField.php @@ -3,7 +3,6 @@ namespace SilverStripe\ORM\FieldType; use SilverStripe\Core\Injector\Injector; -use SilverStripe\Core\Object; use SilverStripe\Core\Convert; use SilverStripe\Forms\FormField; use SilverStripe\Forms\TextField; @@ -132,9 +131,8 @@ abstract class DBField extends ViewableData public static function create_field($className, $value, $name = null, $object = null) { /** @var DBField $dbField */ - $dbField = Object::create($className, $name, $object); + $dbField = Injector::inst()->create($className, $name, $object); $dbField->setValue($value, null, false); - return $dbField; } @@ -449,7 +447,7 @@ abstract class DBField extends ViewableData $fieldName = $this->name; if (empty($fieldName)) { throw new \BadMethodCallException( - "DBField::saveInto() Called on a nameless '" . get_class($this) . "' object" + "DBField::saveInto() Called on a nameless '" . static::class . "' object" ); } $dataObject->$fieldName = $this->value; diff --git a/src/ORM/FieldType/DBPolymorphicForeignKey.php b/src/ORM/FieldType/DBPolymorphicForeignKey.php index 711633a22..aea9344b4 100644 --- a/src/ORM/FieldType/DBPolymorphicForeignKey.php +++ b/src/ORM/FieldType/DBPolymorphicForeignKey.php @@ -71,7 +71,7 @@ class DBPolymorphicForeignKey extends DBComposite if ($value instanceof DataObject) { $value = array( 'ID' => $value->ID, - 'Class' => $value->class + 'Class' => get_class($value), ); } diff --git a/src/ORM/Filters/SearchFilter.php b/src/ORM/Filters/SearchFilter.php index 7e1f34baf..e7a077026 100644 --- a/src/ORM/Filters/SearchFilter.php +++ b/src/ORM/Filters/SearchFilter.php @@ -2,7 +2,7 @@ namespace SilverStripe\ORM\Filters; -use SilverStripe\Core\Object; +use SilverStripe\Core\Injector\Injectable; use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataQuery; use InvalidArgumentException; @@ -23,8 +23,9 @@ use SilverStripe\ORM\FieldType\DBField; * class: EndsWithFilter * */ -abstract class SearchFilter extends Object +abstract class SearchFilter { + use Injectable; /** * @var string Classname of the inspected {@link DataObject} @@ -79,7 +80,6 @@ abstract class SearchFilter extends Object */ public function __construct($fullName = null, $value = false, array $modifiers = array()) { - parent::__construct(); $this->fullName = $fullName; // sets $this->name and $this->relation @@ -178,7 +178,7 @@ abstract class SearchFilter extends Object $unsupported = array_diff($modifiers, $allowed); if ($unsupported) { throw new InvalidArgumentException( - get_class($this) . ' does not accept ' . implode(', ', $unsupported) . ' as modifiers' + static::class . ' does not accept ' . implode(', ', $unsupported) . ' as modifiers' ); } @@ -258,11 +258,11 @@ abstract class SearchFilter extends Object // Ensure that we're dealing with a DataObject. if (!is_subclass_of($this->model, DataObject::class)) { throw new InvalidArgumentException( - "Model supplied to " . get_class($this) . " should be an instance of DataObject." + "Model supplied to " . static::class . " should be an instance of DataObject." ); } $schema = DataObject::getSchema(); - + if ($this->aggregate) { $column = $this->aggregate['column']; $function = $this->aggregate['function']; @@ -309,7 +309,7 @@ abstract class SearchFilter extends Object { // SRM: This code finds the table where the field named $this->name lives // Todo: move to somewhere more appropriate, such as DataMapper, the magical class-to-be? - + if ($this->aggregate) { return intval($this->value); } @@ -330,7 +330,7 @@ abstract class SearchFilter extends Object { $schema = DataObject::getSchema(); $baseTable = $schema->baseDataTable($query->dataClass()); - + return $query ->having($having) ->groupby("\"{$baseTable}\".\"ID\""); @@ -371,7 +371,7 @@ abstract class SearchFilter extends Object */ protected function applyMany(DataQuery $query) { - throw new InvalidArgumentException(get_class($this) . " can't be used to filter by a list of items."); + throw new InvalidArgumentException(static::class . " can't be used to filter by a list of items."); } /** @@ -409,7 +409,7 @@ abstract class SearchFilter extends Object */ protected function excludeMany(DataQuery $query) { - throw new InvalidArgumentException(get_class($this) . " can't be used to filter by a list of items."); + throw new InvalidArgumentException(static::class . " can't be used to filter by a list of items."); } /** diff --git a/src/ORM/Hierarchy/Hierarchy.php b/src/ORM/Hierarchy/Hierarchy.php index ec74437ba..8db80a394 100644 --- a/src/ORM/Hierarchy/Hierarchy.php +++ b/src/ORM/Hierarchy/Hierarchy.php @@ -122,10 +122,10 @@ class Hierarchy extends DataExtension // Hierarchy is looping. $validationResult->addError( _t( - 'SilverStripe\\ORM\\Hierarchy\\Hierarchy.InfiniteLoopNotAllowed', + __CLASS__ . '.InfiniteLoopNotAllowed', 'Infinite loop found within the "{type}" hierarchy. Please change the parent to resolve this', 'First argument is the class that makes up the hierarchy.', - array('type' => $owner->class) + array('type' => get_class($owner)) ), 'bad', 'INFINITE_LOOP' diff --git a/src/ORM/ManyManyList.php b/src/ORM/ManyManyList.php index 3aa3b5bb1..e0e2d6ab1 100644 --- a/src/ORM/ManyManyList.php +++ b/src/ORM/ManyManyList.php @@ -3,7 +3,7 @@ namespace SilverStripe\ORM; use BadMethodCallException; -use SilverStripe\Core\Object; +use SilverStripe\Core\Injector\Injector; use SilverStripe\ORM\Queries\SQLSelect; use SilverStripe\ORM\Queries\SQLDelete; use SilverStripe\ORM\FieldType\DBComposite; @@ -100,7 +100,7 @@ class ManyManyList extends RelationList $finalized = array(); foreach ($this->extraFields as $field => $spec) { - $obj = Object::create_from_string($spec); + $obj = Injector::inst()->create($spec); if ($obj instanceof DBComposite) { $this->_compositeExtraFields[$field] = array(); @@ -146,7 +146,7 @@ class ManyManyList extends RelationList } } - $obj = Object::create_from_string($this->extraFields[$fieldName], $fieldName); + $obj = Injector::inst()->create($this->extraFields[$fieldName], $fieldName); $obj->setValue($value, null, false); $add[$fieldName] = $obj; } @@ -281,7 +281,7 @@ class ManyManyList extends RelationList foreach ($this->extraFields as $fieldName => $fieldSpec) { // Skip fields without an assignment if (array_key_exists($fieldName, $extraFields)) { - $fieldObject = Object::create_from_string($fieldSpec, $fieldName); + $fieldObject = Injector::inst()->create($fieldSpec, $fieldName); $fieldObject->setValue($extraFields[$fieldName]); $fieldObject->writeToManipulation($manipulation[$this->joinTable]); } diff --git a/src/ORM/Search/FulltextSearchable.php b/src/ORM/Search/FulltextSearchable.php index 6aba2cbae..09f378bf9 100644 --- a/src/ORM/Search/FulltextSearchable.php +++ b/src/ORM/Search/FulltextSearchable.php @@ -98,8 +98,6 @@ class FulltextSearchable extends DataExtension } else { $this->searchFields = $searchFields; } - - parent::__construct(); } public static function get_extra_config($class, $extensionClass, $args) diff --git a/src/ORM/Search/SearchContext.php b/src/ORM/Search/SearchContext.php index 251e07f29..050c72079 100644 --- a/src/ORM/Search/SearchContext.php +++ b/src/ORM/Search/SearchContext.php @@ -4,7 +4,7 @@ namespace SilverStripe\ORM\Search; use SilverStripe\Control\HTTPRequest; use SilverStripe\Core\ClassInfo; -use SilverStripe\Core\Object; +use SilverStripe\Core\Injector\Injectable; use SilverStripe\Forms\FieldList; use SilverStripe\Forms\FormField; use SilverStripe\ORM\DataObject; @@ -34,8 +34,9 @@ use Exception; * * @see http://doc.silverstripe.com/doku.php?id=searchcontext */ -class SearchContext extends Object +class SearchContext { + use Injectable; /** * DataObject subclass to which search parameters relate to. @@ -85,8 +86,6 @@ class SearchContext extends Object $this->modelClass = $modelClass; $this->fields = ($fields) ? $fields : new FieldList(); $this->filters = ($filters) ? $filters : array(); - - parent::__construct(); } /** @@ -136,6 +135,7 @@ class SearchContext extends Object public function getQuery($searchParams, $sort = false, $limit = false, $existingQuery = null) { /** DataList $query */ + $query = null; if ($existingQuery) { if (!($existingQuery instanceof DataList)) { throw new InvalidArgumentException("existingQuery must be DataList"); @@ -158,6 +158,7 @@ class SearchContext extends Object $query = $query->limit($limit); } + /** @var DataList $query */ $query = $query->sort($sort); // hack to work with $searchParems when it's an Object diff --git a/src/ORM/UnsavedRelationList.php b/src/ORM/UnsavedRelationList.php index 471078ac8..9677aeeee 100644 --- a/src/ORM/UnsavedRelationList.php +++ b/src/ORM/UnsavedRelationList.php @@ -51,7 +51,7 @@ class UnsavedRelationList extends ArrayList implements Relation /** * Create a new UnsavedRelationList * - * @param array $baseClass + * @param string $baseClass * @param string $relationName * @param string $dataClass The DataObject class used in the relation */ diff --git a/src/Security/Authenticator.php b/src/Security/Authenticator.php index 1e0191742..66bbc7843 100644 --- a/src/Security/Authenticator.php +++ b/src/Security/Authenticator.php @@ -2,9 +2,10 @@ namespace SilverStripe\Security; -use SilverStripe\Core\Object; +use SilverStripe\Core\Config\Configurable; +use SilverStripe\Core\Extensible; +use SilverStripe\Core\Injector\Injectable; use SilverStripe\Control\Controller; -use SilverStripe\Dev\Deprecation; use SilverStripe\Forms\Form; /** @@ -15,8 +16,16 @@ use SilverStripe\Forms\Form; * * @author Markus Lanthaler */ -abstract class Authenticator extends Object +abstract class Authenticator { + use Injectable; + use Configurable; + use Extensible; + + public function __construct() + { + $this->constructExtensions(); + } /** * This variable holds all authenticators that should be used @@ -78,7 +87,7 @@ abstract class Authenticator extends Object { return false; } - + /** * Check if a given authenticator is registered * diff --git a/src/Security/PasswordValidator.php b/src/Security/PasswordValidator.php index 313a907b5..5f9a3bfae 100644 --- a/src/Security/PasswordValidator.php +++ b/src/Security/PasswordValidator.php @@ -2,7 +2,8 @@ namespace SilverStripe\Security; -use SilverStripe\Core\Object; +use SilverStripe\Core\Config\Configurable; +use SilverStripe\Core\Injector\Injectable; use SilverStripe\ORM\ValidationResult; /** @@ -17,9 +18,15 @@ use SilverStripe\ORM\ValidationResult; * Member::set_password_validator($pwdValidator); * */ -class PasswordValidator extends Object +class PasswordValidator { + use Injectable; + use Configurable; + /** + * @config + * @var array + */ private static $character_strength_tests = array( 'lowercase' => '/[a-z]/', 'uppercase' => '/[A-Z]/', diff --git a/src/Security/Security.php b/src/Security/Security.php index 8cc9ac41e..13b4fe9af 100644 --- a/src/Security/Security.php +++ b/src/Security/Security.php @@ -879,7 +879,7 @@ class Security extends Controller implements TemplateGlobalProvider */ public function getTemplatesFor($action) { - $templates = SSViewer::get_templates_by_class(get_class($this), "_{$action}", __CLASS__); + $templates = SSViewer::get_templates_by_class(static::class, "_{$action}", __CLASS__); return array_merge( $templates, [ diff --git a/src/Security/SecurityToken.php b/src/Security/SecurityToken.php index 5275c1dbd..6ca092e8e 100644 --- a/src/Security/SecurityToken.php +++ b/src/Security/SecurityToken.php @@ -3,7 +3,8 @@ namespace SilverStripe\Security; use SilverStripe\Control\HTTPRequest; -use SilverStripe\Core\Object; +use SilverStripe\Core\Config\Configurable; +use SilverStripe\Core\Injector\Injectable; use SilverStripe\Control\Session; use SilverStripe\Control\Controller; use SilverStripe\Forms\FieldList; @@ -34,8 +35,10 @@ use SilverStripe\View\TemplateGlobalProvider; * * @todo Make token name form specific for additional forgery protection. */ -class SecurityToken extends Object implements TemplateGlobalProvider +class SecurityToken implements TemplateGlobalProvider { + use Configurable; + use Injectable; /** * @var string @@ -63,7 +66,6 @@ class SecurityToken extends Object implements TemplateGlobalProvider public function __construct($name = null) { $this->name = ($name) ? $name : self::get_default_name(); - parent::__construct(); } /** diff --git a/src/View/Parsers/HTMLCleaner.php b/src/View/Parsers/HTMLCleaner.php index 000d67045..6582268a1 100644 --- a/src/View/Parsers/HTMLCleaner.php +++ b/src/View/Parsers/HTMLCleaner.php @@ -2,13 +2,16 @@ namespace SilverStripe\View\Parsers; -use SilverStripe\Core\Object; +use SilverStripe\Core\Config\Configurable; +use SilverStripe\Core\Injector\Injectable; /** * Base class for HTML cleaning implementations. */ -abstract class HTMLCleaner extends Object +abstract class HTMLCleaner { + use Configurable; + use Injectable; /** * @var array @@ -27,7 +30,6 @@ abstract class HTMLCleaner extends Object */ public function __construct($config = null) { - parent::__construct(); if ($config) { $config = array_merge($this->defaultConfig, $config); } else { diff --git a/src/View/Parsers/SQLFormatter.php b/src/View/Parsers/SQLFormatter.php index 22aecb696..7fded0aa2 100644 --- a/src/View/Parsers/SQLFormatter.php +++ b/src/View/Parsers/SQLFormatter.php @@ -2,7 +2,7 @@ namespace SilverStripe\View\Parsers; -use SilverStripe\Core\Object; +use SilverStripe\Core\Injector\Injectable; /** * Format a SQL Query for better readable output in HTML or Plaintext. @@ -12,8 +12,9 @@ use SilverStripe\Core\Object; * * @author Ingo Schommer, Silverstripe Ltd. (@silverstripe.com) */ -class SQLFormatter extends Object +class SQLFormatter { + use Injectable; protected static $newline_before_tokens = array( 'SELECT', diff --git a/src/View/Parsers/ShortcodeParser.php b/src/View/Parsers/ShortcodeParser.php index 8a282d221..edcf81f28 100644 --- a/src/View/Parsers/ShortcodeParser.php +++ b/src/View/Parsers/ShortcodeParser.php @@ -3,7 +3,9 @@ namespace SilverStripe\View\Parsers; use DOMNodeList; -use SilverStripe\Core\Object; +use SilverStripe\Core\Config\Configurable; +use SilverStripe\Core\Extensible; +use SilverStripe\Core\Injector\Injectable; use SilverStripe\Core\Injector\Injector; use InvalidArgumentException; use DOMElement; @@ -16,8 +18,16 @@ use DOMElement; * * @see http://doc.silverstripe.org/framework/en/reference/shortcodes */ -class ShortcodeParser extends Object +class ShortcodeParser { + use Injectable; + use Configurable; + use Extensible; + + public function __construct() + { + $this->constructExtensions(); + } public function img_shortcode($attrs) { diff --git a/src/View/Parsers/Transliterator.php b/src/View/Parsers/Transliterator.php index 53e0b5033..dfe0c82d9 100644 --- a/src/View/Parsers/Transliterator.php +++ b/src/View/Parsers/Transliterator.php @@ -2,7 +2,8 @@ namespace SilverStripe\View\Parsers; -use SilverStripe\Core\Object; +use SilverStripe\Core\Config\Configurable; +use SilverStripe\Core\Injector\Injectable; /** * Support class for converting unicode strings into a suitable 7-bit ASCII equivalent. @@ -14,8 +15,11 @@ use SilverStripe\Core\Object; * $ascii = $tr->toASCII($unicode); * */ -class Transliterator extends Object +class Transliterator { + use Injectable; + use Configurable; + /** * @config * @var boolean Allow the use of iconv() to perform transliteration. Set to false to disable. @@ -53,11 +57,11 @@ class Transliterator extends Object 'Õ'=>'O', 'Ö'=>'Oe', 'Ø'=>'O', 'Ù'=>'U', 'Ú'=>'U', 'Û'=>'U', 'Ü'=>'Ue', 'Ý'=>'Y', 'Þ'=>'B', 'ß'=>'ss', 'à'=>'a', 'á'=>'a', 'â'=>'a', 'ã'=>'a', 'ä'=>'ae', 'å'=>'a', 'æ'=>'ae', 'ç'=>'c', 'è'=>'e', 'é'=>'e', 'ê'=>'e', 'ë'=>'e', 'ì'=>'i', 'í'=>'i', 'î'=>'i', 'ï'=>'i', 'ð'=>'o', 'ñ'=>'n', 'ò'=>'o', 'ó'=>'o', - 'ô'=>'o', 'õ'=>'o', 'ö'=>'oe', 'ø'=>'o', 'ù'=>'u', 'ú'=>'u', 'û'=>'u', 'ü'=>'ue', 'ý'=>'y', 'ý'=>'y', + 'ô'=>'o', 'õ'=>'o', 'ö'=>'oe', 'ø'=>'o', 'ù'=>'u', 'ú'=>'u', 'û'=>'u', 'ü'=>'ue', 'ý'=>'y', 'þ'=>'b', 'ÿ'=>'y', 'Ŕ'=>'R', 'ŕ'=>'r', 'Ā'=>'A', 'ā'=>'a', 'Ē'=>'E', 'ē'=>'e', 'Ī'=>'I', 'ī'=>'i', 'Ō'=>'O', 'ō'=>'o', 'Ū'=>'U', 'ū'=>'u', - 'œ'=>'oe', 'ß'=>'ss', 'ij'=>'ij', 'ą'=>'a','ę'=>'e', 'ė'=>'e', 'į'=>'i','ų'=>'u','ū'=>'u', 'Ą'=>'A', - 'Ę'=>'E', 'Ė'=>'E', 'Į'=>'I','Ų'=>'U','Ū'=>'U', + 'œ'=>'oe', 'ij'=>'ij', 'ą'=>'a','ę'=>'e', 'ė'=>'e', 'į'=>'i', 'ų'=>'u', 'Ą'=>'A', + 'Ę'=>'E', 'Ė'=>'E', 'Į'=>'I','Ų'=>'U', "ľ"=>"l", "Ľ"=>"L", "ť"=>"t", "Ť"=>"T", "ů"=>"u", "Ů"=>"U", 'ł'=>'l', 'Ł'=>'L', 'ń'=>'n', 'Ń'=>'N', 'ś'=>'s', 'Ś'=>'S', 'ź'=>'z', 'Ź'=>'Z', 'ż'=>'z', 'Ż'=>'Z', 'а'=>"a",'б'=>"b",'в'=>"v",'г'=>"g",'д'=>"d",'е'=>"e",'ё'=>"yo",'ж'=>"zh",'з'=>"z",'и'=>"i", diff --git a/src/View/Parsers/URLSegmentFilter.php b/src/View/Parsers/URLSegmentFilter.php index 604ee9ede..c97fc2793 100644 --- a/src/View/Parsers/URLSegmentFilter.php +++ b/src/View/Parsers/URLSegmentFilter.php @@ -2,7 +2,8 @@ namespace SilverStripe\View\Parsers; -use SilverStripe\Core\Object; +use SilverStripe\Core\Config\Configurable; +use SilverStripe\Core\Injector\Injectable; /** * Filter certain characters from "URL segments" (also called "slugs"), for nicer (more SEO-friendly) URLs. @@ -14,8 +15,10 @@ use SilverStripe\Core\Object; * * See {@link FileNameFilter} for similar implementation for filesystem-based URLs. */ -class URLSegmentFilter extends Object +class URLSegmentFilter { + use Configurable; + use Injectable; /** * @config diff --git a/src/View/SSViewer.php b/src/View/SSViewer.php index 6ed7119ea..3cde50277 100644 --- a/src/View/SSViewer.php +++ b/src/View/SSViewer.php @@ -313,7 +313,7 @@ class SSViewer implements Flushable /** * Returns true if at least one of the listed templates exists. * - * @param array $templates + * @param array|string $templates * * @return boolean */ diff --git a/src/View/SSViewer_DataPresenter.php b/src/View/SSViewer_DataPresenter.php index c0999bc96..c915ac317 100644 --- a/src/View/SSViewer_DataPresenter.php +++ b/src/View/SSViewer_DataPresenter.php @@ -5,7 +5,6 @@ namespace SilverStripe\View; use InvalidArgumentException; use SilverStripe\Core\ClassInfo; use SilverStripe\Core\Injector\Injector; -use SilverStripe\Core\Object; /** * This extends SSViewer_Scope to mix in data on top of what the item provides. This can be "global" @@ -304,7 +303,7 @@ class SSViewer_DataPresenter extends SSViewer_Scope if ($val) { $obj = $val['obj']; if ($name === 'hasValue') { - $res = $obj instanceof Object + $res = $obj instanceof ViewableData ? $obj->exists() : (bool)$obj; } else { diff --git a/src/View/ViewableData.php b/src/View/ViewableData.php index 5f0704148..9d3209d57 100644 --- a/src/View/ViewableData.php +++ b/src/View/ViewableData.php @@ -2,7 +2,10 @@ namespace SilverStripe\View; -use SilverStripe\Core\Object; +use Exception; +use SilverStripe\Core\Config\Configurable; +use SilverStripe\Core\Extensible; +use SilverStripe\Core\Injector\Injectable; use SilverStripe\ORM\ArrayLib; use SilverStripe\ORM\FieldType\DBField; use SilverStripe\ORM\FieldType\DBHTMLText; @@ -23,8 +26,13 @@ use ArrayIterator; * is provided and automatically escaped by ViewableData. Any class that needs to be available to a view (controllers, * {@link DataObject}s, page controls) should inherit from this class. */ -class ViewableData extends Object implements IteratorAggregate +class ViewableData implements IteratorAggregate { + use Extensible { + defineMethods as extensibleDefineMethods; + } + use Injectable; + use Configurable; /** * An array of objects to cast certain fields to. This is set up as an array in the format: @@ -75,6 +83,11 @@ class ViewableData extends Object implements IteratorAggregate */ private $objCache = array(); + public function __construct() + { + $this->constructExtensions(); + } + // ----------------------------------------------------------------------------------------------------------------- // FIELD GETTERS & SETTERS ----------------------------------------------------------------------------------------- @@ -218,11 +231,12 @@ class ViewableData extends Object implements IteratorAggregate $this->addMethodsFrom('failover'); if (isset($_REQUEST['debugfailover'])) { - Debug::message("$this->class created with a failover class of {$this->failover->class}"); + $class = static::class; + $failoverClass = get_class($this->failover); + Debug::message("$class created with a failover class of {$failoverClass}"); } } - - parent::defineMethods(); + $this->extensibleDefineMethods(); } /** @@ -249,6 +263,27 @@ class ViewableData extends Object implements IteratorAggregate ); } + /** + * Return true if this object "exists" i.e. has a sensible value + * + * This method should be overriden in subclasses to provide more context about the classes state. For example, a + * {@link DataObject} class could return false when it is deleted from the database + * + * @return bool + */ + public function exists() + { + return true; + } + + /** + * @return string the class name + */ + public function __toString() + { + return static::class; + } + /** * @return ViewableData */ @@ -273,6 +308,7 @@ class ViewableData extends Object implements IteratorAggregate * * @param string $field * @return string Casting helper As a constructor pattern, and may include arguments. + * @throws Exception */ public function castingHelper($field) { @@ -295,7 +331,7 @@ class ViewableData extends Object implements IteratorAggregate // Fall back to default_cast $default = $this->config()->get('default_cast'); if (empty($default)) { - throw new \Exception("No default_cast"); + throw new Exception("No default_cast"); } return $default; } @@ -448,7 +484,7 @@ class ViewableData extends Object implements IteratorAggregate if (!is_object($value)) { // Force cast $castingHelper = $this->castingHelper($fieldName); - $valueObject = Object::create_from_string($castingHelper, $fieldName); + $valueObject = Injector::inst()->create($castingHelper, $fieldName); $valueObject->setValue($value, $this); $value = $valueObject; } @@ -564,7 +600,7 @@ class ViewableData extends Object implements IteratorAggregate public function CSSClasses($stopAtClass = self::class) { $classes = array(); - $classAncestry = array_reverse(ClassInfo::ancestry($this->class)); + $classAncestry = array_reverse(ClassInfo::ancestry(static::class)); $stopClasses = ClassInfo::ancestry($stopAtClass); foreach ($classAncestry as $class) { diff --git a/src/View/ViewableData_Debugger.php b/src/View/ViewableData_Debugger.php index ad9b1fe72..e72e463fe 100644 --- a/src/View/ViewableData_Debugger.php +++ b/src/View/ViewableData_Debugger.php @@ -42,15 +42,16 @@ class ViewableData_Debugger extends ViewableData public function forTemplate($field = null) { // debugging info for a specific field + $class = get_class($this->object); if ($field) { - return "Debugging Information for {$this->class}->{$field}
                      " . - ($this->object->hasMethod($field) ? "Has method '$field'
                      " : null) . - ($this->object->hasField($field) ? "Has field '$field'
                      " : null); + return "Debugging Information for {$class}->{$field}
                      " . + ($this->object->hasMethod($field) ? "Has method '$field'
                      " : null) . + ($this->object->hasField($field) ? "Has field '$field'
                      " : null); } // debugging information for the entire class $reflector = new ReflectionObject($this->object); - $debug = "Debugging Information: all methods available in '{$this->object->class}'
                        "; + $debug = "Debugging Information: all methods available in '{$class}'
                          "; foreach ($this->object->allMethodNames() as $method) { // check that the method is public @@ -74,7 +75,7 @@ class ViewableData_Debugger extends ViewableData $debug .= '
                        '; if ($this->object->hasMethod('toMap')) { - $debug .= "Debugging Information: all fields available in '{$this->object->class}'
                          "; + $debug .= "Debugging Information: all fields available in '{$class}'
                            "; foreach ($this->object->toMap() as $field => $value) { $debug .= "
                          • \$$field
                          • "; diff --git a/tests/php/Core/ClassInfoTest.php b/tests/php/Core/ClassInfoTest.php index 5a9d12d55..fb4d41ec4 100644 --- a/tests/php/Core/ClassInfoTest.php +++ b/tests/php/Core/ClassInfoTest.php @@ -2,7 +2,7 @@ namespace SilverStripe\Core\Tests; -use SilverStripe\Core\Object; +use ReflectionException; use SilverStripe\Core\Tests\ClassInfoTest\BaseClass; use SilverStripe\Core\Tests\ClassInfoTest\BaseDataClass; use SilverStripe\Core\Tests\ClassInfoTest\ChildClass; @@ -39,8 +39,8 @@ class ClassInfoTest extends SapphireTest public function testExists() { - $this->assertTrue(ClassInfo::exists('SilverStripe\\Core\\Object')); - $this->assertTrue(ClassInfo::exists('SilverStripe\\Core\\object')); + $this->assertTrue(ClassInfo::exists(ClassInfo::class)); + $this->assertTrue(ClassInfo::exists('SilverStripe\\Core\\classinfo')); $this->assertTrue(ClassInfo::exists('SilverStripe\\Core\\Tests\\ClassInfoTest')); $this->assertTrue(ClassInfo::exists('SilverStripe\\Core\\Tests\\CLASSINFOTEST')); $this->assertTrue(ClassInfo::exists('stdClass')); @@ -89,7 +89,8 @@ class ClassInfoTest extends SapphireTest public function testNonClassName() { - $this->setExpectedException('ReflectionException', 'Class IAmAClassThatDoesNotExist does not exist'); + $this->expectException(ReflectionException::class); + $this->expectExceptionMessage('Class IAmAClassThatDoesNotExist does not exist'); $this->assertEquals('IAmAClassThatDoesNotExist', ClassInfo::class_name('IAmAClassThatDoesNotExist')); } @@ -117,15 +118,12 @@ class ClassInfoTest extends SapphireTest public function testAncestry() { $ancestry = ClassInfo::ancestry(ChildClass::class); - $expect = ArrayLib::valuekey( - array( - Object::class, + $expect = ArrayLib::valuekey([ ViewableData::class, DataObject::class, BaseClass::class, ChildClass::class, - ) - ); + ]); $this->assertEquals($expect, $ancestry); ClassInfo::reset_db_cache(); diff --git a/tests/php/Core/Config/ConfigTest.php b/tests/php/Core/Config/ConfigTest.php index 803cc75a7..aa57435fe 100644 --- a/tests/php/Core/Config/ConfigTest.php +++ b/tests/php/Core/Config/ConfigTest.php @@ -3,7 +3,6 @@ namespace SilverStripe\Core\Tests\Config; use SilverStripe\Config\MergeStrategy\Priority; -use SilverStripe\Core\Object; use SilverStripe\Core\Config\Config; use SilverStripe\Dev\SapphireTest; @@ -260,21 +259,6 @@ class ConfigTest extends SapphireTest ); } - public function testStaticLookup() - { - $this->assertEquals(Object::static_lookup(ConfigTest\DefinesFoo::class, 'foo'), 1); - $this->assertEquals(Object::static_lookup(ConfigTest\DefinesFoo::class, 'bar'), null); - - $this->assertEquals(Object::static_lookup(ConfigTest\DefinesBar::class, 'foo'), null); - $this->assertEquals(Object::static_lookup(ConfigTest\DefinesBar::class, 'bar'), 2); - - $this->assertEquals(Object::static_lookup(ConfigTest\DefinesFooAndBar::class, 'foo'), 3); - $this->assertEquals(Object::static_lookup(ConfigTest\DefinesFooAndBar::class, 'bar'), 3); - - $this->assertEquals(Object::static_lookup(ConfigTest\DefinesFooDoesntExtendObject::class, 'foo'), 4); - $this->assertEquals(Object::static_lookup(ConfigTest\DefinesFooDoesntExtendObject::class, 'bar'), null); - } - public function testForClass() { $config = ConfigTest\DefinesFoo::config(); diff --git a/tests/php/Core/Config/ConfigTest/BaseObject.php b/tests/php/Core/Config/ConfigTest/BaseObject.php new file mode 100644 index 000000000..79e36974f --- /dev/null +++ b/tests/php/Core/Config/ConfigTest/BaseObject.php @@ -0,0 +1,11 @@ +injector->convertServiceProperty($params); return parent::create($class, $params); } diff --git a/tests/php/Core/Manifest/ClassManifestTest.php b/tests/php/Core/Manifest/ClassManifestTest.php index 378a0780e..7ed2f3b26 100644 --- a/tests/php/Core/Manifest/ClassManifestTest.php +++ b/tests/php/Core/Manifest/ClassManifestTest.php @@ -154,7 +154,7 @@ class ClassManifestTest extends SapphireTest */ public function testManifestWarnsAboutDuplicateClasses() { - $this->setExpectedException(Exception::class); + $this->expectException(Exception::class); new ClassManifest(dirname(__FILE__) . '/fixtures/classmanifest_duplicates', false); } } diff --git a/tests/php/Core/Manifest/fixtures/namespaced_classmanifest/module/classes/ClassI.php b/tests/php/Core/Manifest/fixtures/namespaced_classmanifest/module/classes/ClassI.php index 714c53577..5ffe2948c 100644 --- a/tests/php/Core/Manifest/fixtures/namespaced_classmanifest/module/classes/ClassI.php +++ b/tests/php/Core/Manifest/fixtures/namespaced_classmanifest/module/classes/ClassI.php @@ -12,7 +12,7 @@ use SilverStripe\Control\HTTPRequest as Request, SilverStripe\Control\HTTPRespon /** @skipUpgrade */ use silverstripe\test\ClassA; /** @skipUpgrade */ -use \SilverStripe\Core\Object; +use \SilverStripe\Core\ClassInfo; /** @skipUpgrade */ class ClassI extends ModelAdmin implements P { diff --git a/tests/php/Core/ObjectTest.php b/tests/php/Core/ObjectTest.php index b6151c33f..023896225 100644 --- a/tests/php/Core/ObjectTest.php +++ b/tests/php/Core/ObjectTest.php @@ -2,7 +2,7 @@ namespace SilverStripe\Core\Tests; -use SilverStripe\Core\Object; +use SilverStripe\Core\ClassInfo; use SilverStripe\Core\Injector\Injector; use SilverStripe\Core\Tests\ObjectTest\ExtendTest1; use SilverStripe\Core\Tests\ObjectTest\ExtendTest2; @@ -52,7 +52,7 @@ class ObjectTest extends SapphireTest foreach ($trueMethods as $method) { $methodU = strtoupper($method); $methodL = strtoupper($method); - $this->assertTrue($obj->hasMethod($method), "Test that obj#$i has method $method ($obj->class)"); + $this->assertTrue($obj->hasMethod($method), "Test that obj#$i has method $method"); $this->assertTrue($obj->hasMethod($methodU), "Test that obj#$i has method $methodU"); $this->assertTrue($obj->hasMethod($methodL), "Test that obj#$i has method $methodL"); @@ -73,32 +73,21 @@ class ObjectTest extends SapphireTest public function testSingletonCreation() { - $myObject = singleton(MyObject::class); - $this->assertEquals( - $myObject->class, + $myObject = MyObject::singleton(); + $this->assertInstanceOf( MyObject::class, + $myObject, 'singletons are creating a correct class instance' ); - $this->assertEquals( - get_class($myObject), - MyObject::class, - 'singletons are creating a correct class instance' - ); - - $mySubObject = singleton(MySubObject::class); - $this->assertEquals( - $mySubObject->class, - MySubObject::class, - 'singletons are creating a correct subclass instance' - ); - $this->assertEquals( - get_class($mySubObject), + $mySubObject = MySubObject::singleton(); + $this->assertInstanceOf( MySubObject::class, + $mySubObject, 'singletons are creating a correct subclass instance' ); - $myFirstObject = singleton(MyObject::class); - $mySecondObject = singleton(MyObject::class); + $myFirstObject = MyObject::singleton(); + $mySecondObject = MyObject::singleton(); $this->assertTrue( $myFirstObject === $mySecondObject, 'singletons are using the same object on subsequent calls' @@ -182,14 +171,14 @@ class ObjectTest extends SapphireTest 'SilverStripe\\Core\\Tests\\oBjEcTTEST\\EXTENDTest1', "SilverStripe\\Core\\Tests\\ObjectTest\\ExtendTest2", ), - Object::get_extensions(ExtensionTest::class) + ExtensionTest::get_extensions() ); $this->assertEquals( array( 'SilverStripe\\Core\\Tests\\oBjEcTTEST\\EXTENDTest1', "SilverStripe\\Core\\Tests\\ObjectTest\\ExtendTest2('FOO', 'BAR')", ), - Object::get_extensions(ExtensionTest::class, true) + ExtensionTest::get_extensions(null, true) ); $inst = new ExtensionTest(); $extensions = $inst->getExtensionInstances(); @@ -336,7 +325,7 @@ class ObjectTest extends SapphireTest ObjectTest\ExtensionRemoveTest::remove_extension(ExtendTest2::class); $this->assertFalse( - Object::has_extension(ExtensionRemoveTest::class, ExtendTest2::class), + ExtensionRemoveTest::has_extension(ExtendTest2::class), "Extension added through \$add_extension() are detected as removed in has_extension()" ); @@ -347,14 +336,9 @@ class ObjectTest extends SapphireTest ); } - public function testParentClass() - { - $this->assertEquals(ObjectTest\MyObject::create()->parentClass(), 'SilverStripe\\Core\\Object'); - } - public function testIsA() { - $this->assertTrue(ObjectTest\MyObject::create() instanceof Object); + $this->assertTrue(ObjectTest\MyObject::create() instanceof ObjectTest\BaseObject); $this->assertTrue(ObjectTest\MyObject::create() instanceof ObjectTest\MyObject); } @@ -369,30 +353,6 @@ class ObjectTest extends SapphireTest $this->assertTrue($obj->getExtensionInstance(TestExtension::class) instanceof ObjectTest\TestExtension); } - public function testCacheToFile() - { - $this->markTestIncomplete(); - /* - // This doesn't run properly on our build slave. - $obj = new ObjectTest_CacheTest(); - - $obj->clearCache('cacheMethod'); - $obj->clearCache('cacheMethod', null, array(true)); - $obj->clearCache('incNumber'); - - $this->assertEquals('noarg', $obj->cacheToFile('cacheMethod', -1)); - $this->assertEquals('hasarg', $obj->cacheToFile('cacheMethod', -1, null, array(true))); - $this->assertEquals('hasarg', $obj->cacheToFile('cacheMethod', 3600, null, array(true))); - - // -1 lifetime will ensure that the cache isn't read - number incremented - $this->assertEquals(1, $obj->cacheToFile('incNumber', -1)); - // -1 lifetime will ensure that the cache isn't read - number incremented - $this->assertEquals(2, $obj->cacheToFile('incNumber', -1)); - // Number shouldn't be incremented now because we're using the cached version - $this->assertEquals(2, $obj->cacheToFile('incNumber')); - */ - } - public function testExtend() { $object = new ObjectTest\ExtendTest(); @@ -434,52 +394,52 @@ class ObjectTest extends SapphireTest // Simple case $this->assertEquals( array(Versioned::class,array('Stage', 'Live')), - Object::parse_class_spec("SilverStripe\\Versioned\\Versioned('Stage','Live')") + ClassInfo::parse_class_spec("SilverStripe\\Versioned\\Versioned('Stage','Live')") ); // String with commas $this->assertEquals( array(Versioned::class,array('Stage,Live', 'Stage')), - Object::parse_class_spec("SilverStripe\\Versioned\\Versioned('Stage,Live','Stage')") + ClassInfo::parse_class_spec("SilverStripe\\Versioned\\Versioned('Stage,Live','Stage')") ); // String with quotes $this->assertEquals( array(Versioned::class,array('Stage\'Stage,Live\'Live', 'Live')), - Object::parse_class_spec("SilverStripe\\Versioned\\Versioned('Stage\\'Stage,Live\\'Live','Live')") + ClassInfo::parse_class_spec("SilverStripe\\Versioned\\Versioned('Stage\\'Stage,Live\\'Live','Live')") ); // True, false and null values $this->assertEquals( array('ClassName', array('string', true, array('string', false))), - Object::parse_class_spec('ClassName("string", true, array("string", false))') + ClassInfo::parse_class_spec('ClassName("string", true, array("string", false))') ); $this->assertEquals( array('ClassName', array(true, false, null)), - Object::parse_class_spec('ClassName(true, false, null)') + ClassInfo::parse_class_spec('ClassName(true, false, null)') ); // Array $this->assertEquals( array('Enum',array(array('Accepted', 'Pending', 'Declined', 'Unsubmitted'), 'Unsubmitted')), - Object::parse_class_spec("Enum(array('Accepted', 'Pending', 'Declined', 'Unsubmitted'), 'Unsubmitted')") + ClassInfo::parse_class_spec("Enum(array('Accepted', 'Pending', 'Declined', 'Unsubmitted'), 'Unsubmitted')") ); // Nested array $this->assertEquals( array('Enum',array(array('Accepted', 'Pending', 'Declined', array('UnsubmittedA','UnsubmittedB')), 'Unsubmitted')), - Object::parse_class_spec( + ClassInfo::parse_class_spec( "Enum(array('Accepted', 'Pending', 'Declined', array('UnsubmittedA','UnsubmittedB')), 'Unsubmitted')" ) ); // 5.4 Shorthand Array $this->assertEquals( array('Enum',array(array('Accepted', 'Pending', 'Declined', 'Unsubmitted'), 'Unsubmitted')), - Object::parse_class_spec("Enum(['Accepted', 'Pending', 'Declined', 'Unsubmitted'], 'Unsubmitted')") + ClassInfo::parse_class_spec("Enum(['Accepted', 'Pending', 'Declined', 'Unsubmitted'], 'Unsubmitted')") ); // 5.4 Nested shorthand array $this->assertEquals( array('Enum',array(array('Accepted', 'Pending', 'Declined', array('UnsubmittedA','UnsubmittedB')), 'Unsubmitted')), - Object::parse_class_spec( + ClassInfo::parse_class_spec( "Enum(['Accepted', 'Pending', 'Declined', ['UnsubmittedA','UnsubmittedB']], 'Unsubmitted')" ) ); @@ -487,33 +447,33 @@ class ObjectTest extends SapphireTest // Associative array $this->assertEquals( array('Varchar', array(255, array('nullifyEmpty' => false))), - Object::parse_class_spec("Varchar(255, array('nullifyEmpty' => false))") + ClassInfo::parse_class_spec("Varchar(255, array('nullifyEmpty' => false))") ); // Nested associative array $this->assertEquals( array('Test', array('string', array('nested' => array('foo' => 'bar')))), - Object::parse_class_spec("Test('string', array('nested' => array('foo' => 'bar')))") + ClassInfo::parse_class_spec("Test('string', array('nested' => array('foo' => 'bar')))") ); // 5.4 shorthand associative array $this->assertEquals( array('Varchar', array(255, array('nullifyEmpty' => false))), - Object::parse_class_spec("Varchar(255, ['nullifyEmpty' => false])") + ClassInfo::parse_class_spec("Varchar(255, ['nullifyEmpty' => false])") ); // 5.4 shorthand nested associative array $this->assertEquals( array('Test', array('string', array('nested' => array('foo' => 'bar')))), - Object::parse_class_spec("Test('string', ['nested' => ['foo' => 'bar']])") + ClassInfo::parse_class_spec("Test('string', ['nested' => ['foo' => 'bar']])") ); // Namespaced class $this->assertEquals( array('Test\MyClass', array()), - Object::parse_class_spec('Test\MyClass') + ClassInfo::parse_class_spec('Test\MyClass') ); // Fully qualified namespaced class $this->assertEquals( array('\Test\MyClass', array()), - Object::parse_class_spec('\Test\MyClass') + ClassInfo::parse_class_spec('\Test\MyClass') ); } } diff --git a/tests/php/Core/ObjectTest/BaseObject.php b/tests/php/Core/ObjectTest/BaseObject.php new file mode 100644 index 000000000..a51be4cc1 --- /dev/null +++ b/tests/php/Core/ObjectTest/BaseObject.php @@ -0,0 +1,20 @@ +constructExtensions(); + } +} diff --git a/tests/php/Core/ObjectTest/CacheTest.php b/tests/php/Core/ObjectTest/CacheTest.php index af2995934..77b636b71 100644 --- a/tests/php/Core/ObjectTest/CacheTest.php +++ b/tests/php/Core/ObjectTest/CacheTest.php @@ -2,11 +2,8 @@ namespace SilverStripe\Core\Tests\ObjectTest; -use SilverStripe\Core\Object; - -class CacheTest extends Object +class CacheTest extends BaseObject { - public $count = 0; public function cacheMethod($arg1 = null) diff --git a/tests/php/Core/ObjectTest/CreateTest.php b/tests/php/Core/ObjectTest/CreateTest.php index f901750d3..3dfaec71f 100644 --- a/tests/php/Core/ObjectTest/CreateTest.php +++ b/tests/php/Core/ObjectTest/CreateTest.php @@ -2,9 +2,7 @@ namespace SilverStripe\Core\Tests\ObjectTest; -use SilverStripe\Core\Object; - -class CreateTest extends Object +class CreateTest extends BaseObject { public $constructArguments; diff --git a/tests/php/Core/ObjectTest/CreateTest2.php b/tests/php/Core/ObjectTest/CreateTest2.php index 2da22e467..75258e21c 100644 --- a/tests/php/Core/ObjectTest/CreateTest2.php +++ b/tests/php/Core/ObjectTest/CreateTest2.php @@ -2,8 +2,6 @@ namespace SilverStripe\Core\Tests\ObjectTest; -use SilverStripe\Core\Object; - -class CreateTest2 extends Object +class CreateTest2 extends BaseObject { } diff --git a/tests/php/Core/ObjectTest/CreateTest3.php b/tests/php/Core/ObjectTest/CreateTest3.php index 1be701cc6..29e3e2e24 100644 --- a/tests/php/Core/ObjectTest/CreateTest3.php +++ b/tests/php/Core/ObjectTest/CreateTest3.php @@ -2,8 +2,6 @@ namespace SilverStripe\Core\Tests\ObjectTest; -use SilverStripe\Core\Object; - -class CreateTest3 extends Object +class CreateTest3 extends BaseObject { } diff --git a/tests/php/Core/ObjectTest/ExtendTest.php b/tests/php/Core/ObjectTest/ExtendTest.php index aad1caa17..c43e9fc78 100644 --- a/tests/php/Core/ObjectTest/ExtendTest.php +++ b/tests/php/Core/ObjectTest/ExtendTest.php @@ -2,9 +2,7 @@ namespace SilverStripe\Core\Tests\ObjectTest; -use SilverStripe\Core\Object; - -class ExtendTest extends Object +class ExtendTest extends BaseObject { private static $extensions = array( ExtendTest1::class, diff --git a/tests/php/Core/ObjectTest/ExtendTest1.php b/tests/php/Core/ObjectTest/ExtendTest1.php index 41936496c..b33ce8476 100644 --- a/tests/php/Core/ObjectTest/ExtendTest1.php +++ b/tests/php/Core/ObjectTest/ExtendTest1.php @@ -3,8 +3,9 @@ namespace SilverStripe\Core\Tests\ObjectTest; use SilverStripe\Core\Extension; +use SilverStripe\Dev\TestOnly; -class ExtendTest1 extends Extension +class ExtendTest1 extends Extension implements TestOnly { public function extendableMethod(&$argument = null) { diff --git a/tests/php/Core/ObjectTest/ExtendTest2.php b/tests/php/Core/ObjectTest/ExtendTest2.php index 5501006d8..2e0aad98a 100644 --- a/tests/php/Core/ObjectTest/ExtendTest2.php +++ b/tests/php/Core/ObjectTest/ExtendTest2.php @@ -3,9 +3,17 @@ namespace SilverStripe\Core\Tests\ObjectTest; use SilverStripe\Core\Extension; +use SilverStripe\Dev\TestOnly; -class ExtendTest2 extends Extension +class ExtendTest2 extends Extension implements TestOnly { + protected $constructorArgs = []; + + public function __construct() + { + $this->constructorArgs = func_get_args(); + } + public function extendableMethod($argument = null) { $args = implode(',', array_filter(func_get_args())); diff --git a/tests/php/Core/ObjectTest/ExtendTest3.php b/tests/php/Core/ObjectTest/ExtendTest3.php index f3692b00f..318e01d6e 100644 --- a/tests/php/Core/ObjectTest/ExtendTest3.php +++ b/tests/php/Core/ObjectTest/ExtendTest3.php @@ -3,9 +3,17 @@ namespace SilverStripe\Core\Tests\ObjectTest; use SilverStripe\Core\Extension; +use SilverStripe\Dev\TestOnly; -class ExtendTest3 extends Extension +class ExtendTest3 extends Extension implements TestOnly { + protected $constructorArgs = []; + + public function __construct() + { + $this->constructorArgs = func_get_args(); + } + public function extendableMethod($argument = null) { return "ExtendTest3($argument)"; diff --git a/tests/php/Core/ObjectTest/Extending.php b/tests/php/Core/ObjectTest/Extending.php index a5a96d0e5..84a5dbb7c 100644 --- a/tests/php/Core/ObjectTest/Extending.php +++ b/tests/php/Core/ObjectTest/Extending.php @@ -2,10 +2,7 @@ namespace SilverStripe\Core\Tests\ObjectTest; -use SilverStripe\Core\Object; -use SilverStripe\Dev\TestOnly; - -class Extending extends Object implements TestOnly +class Extending extends BaseObject { private static $extensions = array( diff --git a/tests/php/Core/ObjectTest/ExtensionRemoveTest.php b/tests/php/Core/ObjectTest/ExtensionRemoveTest.php index 038ee10f7..87e99d2fa 100644 --- a/tests/php/Core/ObjectTest/ExtensionRemoveTest.php +++ b/tests/php/Core/ObjectTest/ExtensionRemoveTest.php @@ -2,9 +2,7 @@ namespace SilverStripe\Core\Tests\ObjectTest; -use SilverStripe\Core\Object; - -class ExtensionRemoveTest extends Object +class ExtensionRemoveTest extends BaseObject { private static $extensions = array( ExtendTest1::class, diff --git a/tests/php/Core/ObjectTest/ExtensionTest.php b/tests/php/Core/ObjectTest/ExtensionTest.php index 0a63cda88..c99fafe88 100644 --- a/tests/php/Core/ObjectTest/ExtensionTest.php +++ b/tests/php/Core/ObjectTest/ExtensionTest.php @@ -2,9 +2,7 @@ namespace SilverStripe\Core\Tests\ObjectTest; -use SilverStripe\Core\Object; - -class ExtensionTest extends Object +class ExtensionTest extends BaseObject { private static $extensions = array( 'SilverStripe\\Core\\Tests\\oBjEcTTEST\\EXTENDTest1', diff --git a/tests/php/Core/ObjectTest/ExtensionTest2.php b/tests/php/Core/ObjectTest/ExtensionTest2.php index 725316be6..8a569155f 100644 --- a/tests/php/Core/ObjectTest/ExtensionTest2.php +++ b/tests/php/Core/ObjectTest/ExtensionTest2.php @@ -2,9 +2,7 @@ namespace SilverStripe\Core\Tests\ObjectTest; -use SilverStripe\Core\Object; - -class ExtensionTest2 extends Object +class ExtensionTest2 extends BaseObject { private static $extensions = [ TestExtension::class, diff --git a/tests/php/Core/ObjectTest/ExtensionTest3.php b/tests/php/Core/ObjectTest/ExtensionTest3.php index f88fb5edf..1641e6525 100644 --- a/tests/php/Core/ObjectTest/ExtensionTest3.php +++ b/tests/php/Core/ObjectTest/ExtensionTest3.php @@ -2,8 +2,6 @@ namespace SilverStripe\Core\Tests\ObjectTest; -use SilverStripe\Core\Object; - -class ExtensionTest3 extends Object +class ExtensionTest3 extends BaseObject { } diff --git a/tests/php/Core/ObjectTest/MyObject.php b/tests/php/Core/ObjectTest/MyObject.php index 27bba1242..5c2615521 100644 --- a/tests/php/Core/ObjectTest/MyObject.php +++ b/tests/php/Core/ObjectTest/MyObject.php @@ -2,14 +2,12 @@ namespace SilverStripe\Core\Tests\ObjectTest; -use SilverStripe\Core\Object; - -class MyObject extends Object +class MyObject extends BaseObject { public $title = 'my object'; /** - * @config -*/ + * @config + */ private static $mystaticProperty = "MyObject"; static $mystaticArray = array('one'); } diff --git a/tests/php/Core/ObjectTest/T1A.php b/tests/php/Core/ObjectTest/T1A.php index cb5b50a51..62d0cd946 100644 --- a/tests/php/Core/ObjectTest/T1A.php +++ b/tests/php/Core/ObjectTest/T1A.php @@ -2,9 +2,7 @@ namespace SilverStripe\Core\Tests\ObjectTest; -use SilverStripe\Core\Object; - -class T1A extends Object +class T1A extends BaseObject { public function testMethod() { diff --git a/tests/php/Core/ObjectTest/T1B.php b/tests/php/Core/ObjectTest/T1B.php index 6e1eaa72b..803955f2d 100644 --- a/tests/php/Core/ObjectTest/T1B.php +++ b/tests/php/Core/ObjectTest/T1B.php @@ -2,9 +2,7 @@ namespace SilverStripe\Core\Tests\ObjectTest; -use SilverStripe\Core\Object; - -class T1B extends Object +class T1B extends BaseObject { public function someMethod() { diff --git a/tests/php/Core/ObjectTest/T1C.php b/tests/php/Core/ObjectTest/T1C.php index d36704ea5..836e299ff 100644 --- a/tests/php/Core/ObjectTest/T1C.php +++ b/tests/php/Core/ObjectTest/T1C.php @@ -2,9 +2,7 @@ namespace SilverStripe\Core\Tests\ObjectTest; -use SilverStripe\Core\Object; - -class T1C extends Object +class T1C extends BaseObject { public function t1cMethod() { diff --git a/tests/php/Core/ObjectTest/T2.php b/tests/php/Core/ObjectTest/T2.php index 7fc888fac..885e32610 100644 --- a/tests/php/Core/ObjectTest/T2.php +++ b/tests/php/Core/ObjectTest/T2.php @@ -2,9 +2,7 @@ namespace SilverStripe\Core\Tests\ObjectTest; -use SilverStripe\Core\Object; - -class T2 extends Object +class T2 extends BaseObject { protected $failover; protected $failoverArr = array(); diff --git a/tests/php/Core/ObjectTest/TestExtension.php b/tests/php/Core/ObjectTest/TestExtension.php index d41a37140..cfc3b130a 100644 --- a/tests/php/Core/ObjectTest/TestExtension.php +++ b/tests/php/Core/ObjectTest/TestExtension.php @@ -3,7 +3,8 @@ namespace SilverStripe\Core\Tests\ObjectTest; use SilverStripe\Core\Extension; +use SilverStripe\Dev\TestOnly; -class TestExtension extends Extension +class TestExtension extends Extension implements TestOnly { } diff --git a/tests/php/Forms/GridField/GridFieldDetailFormTest/TestController.php b/tests/php/Forms/GridField/GridFieldDetailFormTest/TestController.php index 2dc2fe129..abfb62a0c 100644 --- a/tests/php/Forms/GridField/GridFieldDetailFormTest/TestController.php +++ b/tests/php/Forms/GridField/GridFieldDetailFormTest/TestController.php @@ -37,14 +37,10 @@ class TestController extends Controller implements TestOnly $field->getConfig()->addComponent(new GridFieldAddNewButton('toolbar-header-right')); $field->getConfig()->addComponent(new GridFieldViewButton()); $field->getConfig()->addComponent(new GridFieldEditButton()); - /** - * @skipUpgrade -*/ + /** @skipUpgrade */ $field->getConfig()->addComponent($gridFieldForm = new GridFieldDetailForm($this, 'Form')); $field->getConfig()->addComponent(new GridFieldEditButton()); - /** - * @skipUpgrade -*/ + /** @skipUpgrade */ return new Form($this, 'Form', new FieldList($field), new FieldList()); } } diff --git a/tests/php/ORM/DBHTMLTextTest.php b/tests/php/ORM/DBHTMLTextTest.php index 1958b0b08..b7ab4e9a7 100644 --- a/tests/php/ORM/DBHTMLTextTest.php +++ b/tests/php/ORM/DBHTMLTextTest.php @@ -2,10 +2,11 @@ namespace SilverStripe\ORM\Tests; +use SilverStripe\Control\Director; +use SilverStripe\Core\Injector\Injector; use SilverStripe\ORM\FieldType\DBHTMLText; use SilverStripe\ORM\FieldType\DBField; use SilverStripe\Core\Convert; -use SilverStripe\Core\Object; use SilverStripe\Core\Config\Config; use SilverStripe\Dev\SapphireTest; use SilverStripe\ORM\Tests\DBHTMLTextTest\TestShortcode; @@ -217,26 +218,24 @@ class DBHTMLTextTest extends SapphireTest public function testCreate() { - /** - * @var DBHTMLText $field -*/ - $field = Object::create_from_string("HTMLFragment(['whitelist' => 'link'])", 'MyField'); + /** @var DBHTMLText $field */ + $field = Injector::inst()->create("HTMLFragment(['whitelist' => 'link'])", 'MyField'); $this->assertEquals(['link'], $field->getWhitelist()); - $field = Object::create_from_string("HTMLFragment(['whitelist' => 'link,a'])", 'MyField'); + $field = Injector::inst()->create("HTMLFragment(['whitelist' => 'link,a'])", 'MyField'); $this->assertEquals(['link', 'a'], $field->getWhitelist()); - $field = Object::create_from_string("HTMLFragment(['whitelist' => ['link', 'a']])", 'MyField'); + $field = Injector::inst()->create("HTMLFragment(['whitelist' => ['link', 'a']])", 'MyField'); $this->assertEquals(['link', 'a'], $field->getWhitelist()); - $field = Object::create_from_string("HTMLFragment", 'MyField'); + $field = Injector::inst()->create("HTMLFragment", 'MyField'); $this->assertEmpty($field->getWhitelist()); // Test shortcodes - $field = Object::create_from_string("HTMLFragment(['shortcodes' => true])", 'MyField'); + $field = Injector::inst()->create("HTMLFragment(['shortcodes' => true])", 'MyField'); $this->assertEquals(true, $field->getProcessShortcodes()); - $field = Object::create_from_string("HTMLFragment(['shortcodes' => false])", 'MyField'); + $field = Injector::inst()->create("HTMLFragment(['shortcodes' => false])", 'MyField'); $this->assertEquals(false, $field->getProcessShortcodes()); // Mix options - $field = Object::create_from_string("HTMLFragment(['shortcodes' => true, 'whitelist' => ['a'])", 'MyField'); + $field = Injector::inst()->create("HTMLFragment(['shortcodes' => true, 'whitelist' => ['a'])", 'MyField'); $this->assertEquals(true, $field->getProcessShortcodes()); $this->assertEquals(['a'], $field->getWhitelist()); } @@ -553,7 +552,7 @@ class DBHTMLTextTest extends SapphireTest $field->Plain() ); Config::nest(); - Config::inst()->update('SilverStripe\\Control\\Director', 'alternate_base_url', 'http://example.com/'); + Director::config()->set('alternate_base_url', 'http://example.com/'); $this->assertEquals( '

                            Replaced short code with this. home

                            ', $field->AbsoluteLinks() diff --git a/tests/php/ORM/DBStringTest.php b/tests/php/ORM/DBStringTest.php index 3eaaa184a..9fdf39b4c 100644 --- a/tests/php/ORM/DBStringTest.php +++ b/tests/php/ORM/DBStringTest.php @@ -2,7 +2,7 @@ namespace SilverStripe\ORM\Tests; -use SilverStripe\Core\Object; +use SilverStripe\Core\Injector\Injector; use SilverStripe\ORM\FieldType\DBField; use SilverStripe\ORM\FieldType\DBString; use SilverStripe\Dev\SapphireTest; @@ -24,10 +24,8 @@ class DBStringTest extends SapphireTest public function testDefault() { - /** - * @var DBString $dbField -*/ - $dbField = Object::create_from_string( + /** @var DBString $dbField */ + $dbField = Injector::inst()->create( DBStringTest\MyStringField::class."(['default' => 'Here is my default text'])", 'Myfield' ); @@ -42,9 +40,11 @@ class DBStringTest extends SapphireTest */ public function testLowerCase() { + /** @var MyStringField $field */ + $field = DBField::create_field(MyStringField::class, 'This is a TEST!'); $this->assertEquals( 'this is a test!', - DBField::create_field(MyStringField::class, 'This is a TEST!')->LowerCase() + $field->LowerCase() ); } @@ -53,9 +53,11 @@ class DBStringTest extends SapphireTest */ public function testUpperCase() { + /** @var MyStringField $field */ + $field = DBField::create_field(MyStringField::class, 'This is a TEST!'); $this->assertEquals( 'THIS IS A TEST!', - DBField::create_field(MyStringField::class, 'This is a TEST!')->UpperCase() + $field->UpperCase() ); } diff --git a/tests/php/ORM/DataObjectSchemaTest.php b/tests/php/ORM/DataObjectSchemaTest.php index 5c09c8350..94688822a 100644 --- a/tests/php/ORM/DataObjectSchemaTest.php +++ b/tests/php/ORM/DataObjectSchemaTest.php @@ -2,7 +2,7 @@ namespace SilverStripe\ORM\Tests; -use SilverStripe\Core\Object; +use SilverStripe\Core\ClassInfo; use SilverStripe\ORM\DataObject; use SilverStripe\Dev\SapphireTest; use SilverStripe\ORM\DataObjectSchema; @@ -139,7 +139,7 @@ class DataObjectSchemaTest extends SapphireTest ); $this->assertNull( - $schema->tableForField(Object::class, 'Title') + $schema->tableForField(ClassInfo::class, 'Title') ); // Test fixed fields diff --git a/tests/php/ORM/DataObjectTest.php b/tests/php/ORM/DataObjectTest.php index 01ea5c0b9..3bce211a1 100644 --- a/tests/php/ORM/DataObjectTest.php +++ b/tests/php/ORM/DataObjectTest.php @@ -619,17 +619,17 @@ class DataObjectTest extends SapphireTest // Set the favourite team for fan1 $fan1->setField('FavouriteID', $team1->ID); - $fan1->setField('FavouriteClass', $team1->class); + $fan1->setField('FavouriteClass', get_class($team1)); $this->assertEquals($team1->ID, $fan1->Favourite()->ID, 'The team is assigned to fan 1'); - $this->assertInstanceOf($team1->class, $fan1->Favourite(), 'The team is assigned to fan 1'); + $this->assertInstanceOf(get_class($team1), $fan1->Favourite(), 'The team is assigned to fan 1'); $this->assertEquals( $team1->ID, $fan1->getComponent('Favourite')->ID, 'The team exists through the component getter' ); $this->assertInstanceOf( - $team1->class, + get_class($team1), $fan1->getComponent('Favourite'), 'The team exists through the component getter' ); @@ -847,10 +847,10 @@ class DataObjectTest extends SapphireTest // Test for polymorphic has_one relations $fan = $this->objFromFixture(DataObjectTest\Fan::class, 'fan1'); $fan->FavouriteID = $team->ID; - $fan->FavouriteClass = $team->class; + $fan->FavouriteClass = DataObjectTest\Team::class; $this->assertNotNull($fan->Favourite()); $this->assertEquals($team->ID, $fan->Favourite()->ID); - $this->assertInstanceOf($team->class, $fan->Favourite()); + $this->assertInstanceOf(DataObjectTest\Team::class, $fan->Favourite()); } public function testFieldNamesThatMatchMethodNamesWork() @@ -1434,26 +1434,25 @@ class DataObjectTest extends SapphireTest $equipmentSuppliers = $team->EquipmentSuppliers(); // Check that DataObject::many_many() works as expected - list($relationClass, $class, $targetClass, $parentField, $childField, $joinTable) - = DataObject::getSchema()->manyManyComponent(DataObjectTest\Team::class, 'Sponsors'); - $this->assertEquals(ManyManyList::class, $relationClass); + $manyManyComponent = DataObject::getSchema()->manyManyComponent(DataObjectTest\Team::class, 'Sponsors'); + $this->assertEquals(ManyManyList::class, $manyManyComponent['relationClass']); $this->assertEquals( DataObjectTest\Team::class, - $class, + $manyManyComponent['parentClass'], 'DataObject::many_many() didn\'t find the correct base class' ); $this->assertEquals( DataObjectTest\EquipmentCompany::class, - $targetClass, + $manyManyComponent['childClass'], 'DataObject::many_many() didn\'t find the correct target class for the relation' ); $this->assertEquals( 'DataObjectTest_EquipmentCompany_SponsoredTeams', - $joinTable, + $manyManyComponent['join'], 'DataObject::many_many() didn\'t find the correct relation table' ); - $this->assertEquals('DataObjectTest_TeamID', $parentField); - $this->assertEquals('DataObjectTest_EquipmentCompanyID', $childField); + $this->assertEquals('DataObjectTest_TeamID', $manyManyComponent['parentField']); + $this->assertEquals('DataObjectTest_EquipmentCompanyID', $manyManyComponent['childField']); // Check that ManyManyList still works $this->assertEquals(2, $sponsors->count(), 'Rows are missing from relation'); @@ -1918,11 +1917,15 @@ class DataObjectTest extends SapphireTest // Test belongs_to assignment $company->OwnerID = $ceo->ID; - $company->OwnerClass = $ceo->class; + $company->OwnerClass = DataObjectTest\CEO::class; $company->write(); $this->assertEquals($company->ID, $ceo->CompanyOwned()->ID, 'belongs_to returns the right results.'); - $this->assertEquals($company->class, $ceo->CompanyOwned()->class, 'belongs_to returns the right results.'); + $this->assertInstanceOf( + DataObjectTest\Company::class, + $ceo->CompanyOwned(), + 'belongs_to returns the right results.' + ); // Test automatic creation of class where no assigment exists $ceo = new DataObjectTest\CEO(); diff --git a/tests/php/ORM/ManyManyListExtensionTest.php b/tests/php/ORM/ManyManyListExtensionTest.php index 4985ba117..47eeebf5c 100644 --- a/tests/php/ORM/ManyManyListExtensionTest.php +++ b/tests/php/ORM/ManyManyListExtensionTest.php @@ -2,11 +2,7 @@ namespace SilverStripe\ORM\Tests; -use SilverStripe\ORM\DataObject; -use SilverStripe\ORM\DataExtension; -use SilverStripe\Core\Object; use SilverStripe\Dev\SapphireTest; -use SilverStripe\Dev\TestOnly; class ManyManyListExtensionTest extends SapphireTest { @@ -26,9 +22,10 @@ class ManyManyListExtensionTest extends SapphireTest // This extends ManyManyListTest_Secondary with the secondary extension that adds the relationship back // to the primary. The instance from the fixture is ManyManyListTest_SecondarySub, deliberately a sub-class of // the extended class. - Object::add_extension(ManyManyListTest\Secondary::class, ManyManyListTest\IndirectSecondaryExtension::class); + ManyManyListTest\Secondary::add_extension(ManyManyListTest\IndirectSecondaryExtension::class); // Test from the primary (not extended) to the secondary (which is extended) + /** @var ManyManyListTest\IndirectPrimary $primary */ $primary = $this->objFromFixture(ManyManyListTest\IndirectPrimary::class, 'manymany_extra_primary'); $secondaries = $primary->Secondary(); $extraFields = $secondaries->getExtraFields(); @@ -37,6 +34,7 @@ class ManyManyListExtensionTest extends SapphireTest $this->assertTrue(isset($extraFields['DocumentSort']), 'has DocumentSort'); // Test from the secondary (which is extended) to the primary (not extended) + /** @var ManyManyListTest\SecondarySub|ManyManyListTest\IndirectSecondaryExtension $secondary */ $secondary = $this->objFromFixture(ManyManyListTest\SecondarySub::class, 'manymany_extra_secondary'); $primaries = $secondary->Primary(); diff --git a/tests/php/ORM/ManyManyListTest/IndirectPrimary.php b/tests/php/ORM/ManyManyListTest/IndirectPrimary.php index f2ed82874..5f60c40eb 100644 --- a/tests/php/ORM/ManyManyListTest/IndirectPrimary.php +++ b/tests/php/ORM/ManyManyListTest/IndirectPrimary.php @@ -4,11 +4,14 @@ namespace SilverStripe\ORM\Tests\ManyManyListTest; use SilverStripe\Dev\TestOnly; use SilverStripe\ORM\DataObject; +use SilverStripe\ORM\ManyManyList; /** * A data object that implements the primary side of a many_many (where the extra fields are * defined.) The many-many refers to ManyManyListTest_Secondary rather than ManyManyListTest_SecondarySub * by design, because we're trying to test that a subclass instance picks up the extra fields of it's parent. + * + * @method ManyManyList Secondary() */ class IndirectPrimary extends DataObject implements TestOnly { diff --git a/tests/php/ORM/ManyManyListTest/IndirectSecondaryExtension.php b/tests/php/ORM/ManyManyListTest/IndirectSecondaryExtension.php index 1ab4be585..29f6479e2 100644 --- a/tests/php/ORM/ManyManyListTest/IndirectSecondaryExtension.php +++ b/tests/php/ORM/ManyManyListTest/IndirectSecondaryExtension.php @@ -4,10 +4,13 @@ namespace SilverStripe\ORM\Tests\ManyManyListTest; use SilverStripe\Dev\TestOnly; use SilverStripe\ORM\DataExtension; +use SilverStripe\ORM\ManyManyList; /** * An extension that is applied to ManyManyListTest_Secondary that * implements the other side of the many-many relationship. + * + * @method ManyManyList Primary() */ class IndirectSecondaryExtension extends DataExtension implements TestOnly { diff --git a/tests/php/ORM/ManyManyThroughListTest.php b/tests/php/ORM/ManyManyThroughListTest.php index f81315239..5d9167e9f 100644 --- a/tests/php/ORM/ManyManyThroughListTest.php +++ b/tests/php/ORM/ManyManyThroughListTest.php @@ -160,12 +160,12 @@ class ManyManyThroughListTest extends SapphireTest // Parent components $this->assertEquals( [ - ManyManyThroughList::class, - ManyManyThroughListTest\TestObject::class, - ManyManyThroughListTest\Item::class, - 'ParentID', - 'ChildID', - ManyManyThroughListTest\JoinObject::class + 'relationClass' => ManyManyThroughList::class, + 'parentClass' => ManyManyThroughListTest\TestObject::class, + 'childClass' => ManyManyThroughListTest\Item::class, + 'parentField' => 'ParentID', + 'childField' => 'ChildID', + 'join' => ManyManyThroughListTest\JoinObject::class ], $schema->manyManyComponent(ManyManyThroughListTest\TestObject::class, 'Items') ); @@ -173,12 +173,12 @@ class ManyManyThroughListTest extends SapphireTest // Belongs_many_many is the same, but with parent/child substituted $this->assertEquals( [ - ManyManyThroughList::class, - ManyManyThroughListTest\Item::class, - ManyManyThroughListTest\TestObject::class, - 'ChildID', - 'ParentID', - ManyManyThroughListTest\JoinObject::class + 'relationClass' => ManyManyThroughList::class, + 'parentClass' => ManyManyThroughListTest\Item::class, + 'childClass' => ManyManyThroughListTest\TestObject::class, + 'parentField' => 'ChildID', + 'childField' => 'ParentID', + 'join' => ManyManyThroughListTest\JoinObject::class ], $schema->manyManyComponent(ManyManyThroughListTest\Item::class, 'Objects') ); diff --git a/tests/php/Security/MemberTest.php b/tests/php/Security/MemberTest.php index 971a89d74..e03f77b6a 100644 --- a/tests/php/Security/MemberTest.php +++ b/tests/php/Security/MemberTest.php @@ -3,7 +3,6 @@ namespace SilverStripe\Security\Tests; use SilverStripe\Core\Convert; -use SilverStripe\Core\Object; use SilverStripe\Dev\FunctionalTest; use SilverStripe\Control\Cookie; use SilverStripe\i18n\i18n; @@ -27,14 +26,9 @@ class MemberTest extends FunctionalTest protected $orig = array(); - protected static $illegal_extensions = array( - Member::class => array( - // TODO Coupling with modules, this should be resolved by automatically - // removing all applied extensions before a unit test - 'ForumRole', - 'OpenIDAuthenticatedRole' - ) - ); + protected static $illegal_extensions = [ + Member::class => '*', + ]; public function __construct() { @@ -537,7 +531,6 @@ class MemberTest extends FunctionalTest */ public function testCanManipulateOwnRecord() { - $extensions = $this->removeExtensions(Object::get_extensions(Member::class)); $member = $this->objFromFixture(Member::class, 'test'); $member2 = $this->objFromFixture(Member::class, 'staffmember'); @@ -560,13 +553,11 @@ class MemberTest extends FunctionalTest $this->assertFalse($member->canDelete()); $this->assertFalse($member->canEdit()); - $this->addExtensions($extensions); $this->session()->inst_set('loggedInAs', null); } public function testAuthorisedMembersCanManipulateOthersRecords() { - $extensions = $this->removeExtensions(Object::get_extensions(Member::class)); $member = $this->objFromFixture(Member::class, 'test'); $member2 = $this->objFromFixture(Member::class, 'staffmember'); @@ -575,14 +566,10 @@ class MemberTest extends FunctionalTest $this->assertTrue($member2->canView()); $this->assertTrue($member2->canDelete()); $this->assertTrue($member2->canEdit()); - - $this->addExtensions($extensions); - $this->session()->inst_set('loggedInAs', null); } public function testExtendedCan() { - $extensions = $this->removeExtensions(Object::get_extensions(Member::class)); $member = $this->objFromFixture(Member::class, 'test'); /* Normal behaviour is that you can't view a member unless canView() on an extension returns true */ @@ -617,7 +604,6 @@ class MemberTest extends FunctionalTest $this->assertTrue($member4->canEdit()); Member::remove_extension(MemberTest\EditingAllowedDeletingDeniedExtension::class); - $this->addExtensions($extensions); } /** diff --git a/tests/php/Security/MemberTest/TestPasswordValidator.php b/tests/php/Security/MemberTest/TestPasswordValidator.php index 386f35012..6e7270a8c 100644 --- a/tests/php/Security/MemberTest/TestPasswordValidator.php +++ b/tests/php/Security/MemberTest/TestPasswordValidator.php @@ -8,7 +8,6 @@ class TestPasswordValidator extends PasswordValidator { public function __construct() { - parent::__construct(); $this->minLength(7); $this->checkHistoricalPasswords(6); $this->characterStrength(3, array('lowercase', 'uppercase', 'digits', 'punctuation')); diff --git a/tests/php/i18n/i18nTest/_fakewebroot/i18nothermodule/code/i18nOtherModule.php b/tests/php/i18n/i18nTest/_fakewebroot/i18nothermodule/code/i18nOtherModule.php index 2641cdf88..90c83e0f6 100644 --- a/tests/php/i18n/i18nTest/_fakewebroot/i18nothermodule/code/i18nOtherModule.php +++ b/tests/php/i18n/i18nTest/_fakewebroot/i18nothermodule/code/i18nOtherModule.php @@ -1,8 +1,6 @@ Date: Tue, 23 May 2017 11:36:15 +1200 Subject: [PATCH 2/3] Response to feedback --- src/Control/Controller.php | 28 ++++++++++++---------------- src/Dev/FunctionalTest.php | 2 +- src/Dev/SapphireTest.php | 6 +++--- src/Forms/CompositeField.php | 2 +- src/Forms/FormRequestHandler.php | 2 +- src/ORM/Connect/DBSchemaManager.php | 2 +- src/ORM/DataObject.php | 2 +- 7 files changed, 20 insertions(+), 24 deletions(-) diff --git a/src/Control/Controller.php b/src/Control/Controller.php index 76ea7597e..8701510a0 100644 --- a/src/Control/Controller.php +++ b/src/Control/Controller.php @@ -400,26 +400,22 @@ class Controller extends RequestHandler implements TemplateGlobalProvider } elseif ($this->template) { $templates = $this->template; } else { - // Add action-specific templates for inheritance chain - $templates = array(); - if ($action && $action != 'index') { - $parentClass = static::class; - while ($parentClass != __CLASS__) { - $templates[] = strtok($parentClass, '_') . '_' . $action; - $parentClass = get_parent_class($parentClass); - } - } - // Add controller templates for inheritance chain + // Build templates based on class hierarchy + $actionTemplates = []; + $classTemplates = []; $parentClass = static::class; - while ($parentClass != __CLASS__) { - $templates[] = strtok($parentClass, '_'); + while ($parentClass !== parent::class) { + // _action templates have higher priority + if ($action && $action != 'index') { + $actionTemplates[] = strtok($parentClass, '_') . '_' . $action; + } + // class templates have lower priority + $classTemplates[] = strtok($parentClass, '_'); $parentClass = get_parent_class($parentClass); } - $templates[] = __CLASS__; - - // remove duplicates - $templates = array_unique($templates); + // Add controller templates for inheritance chain + $templates = array_unique(array_merge($actionTemplates, $classTemplates)); } return new SSViewer($templates); diff --git a/src/Dev/FunctionalTest.php b/src/Dev/FunctionalTest.php index 73601253f..ca50d9d8f 100644 --- a/src/Dev/FunctionalTest.php +++ b/src/Dev/FunctionalTest.php @@ -84,7 +84,7 @@ class FunctionalTest extends SapphireTest { // Skip calling FunctionalTest directly. if (static::class == __CLASS__) { - $this->markTestSkipped(sprintf('Skipping %s ', get_class($this))); + $this->markTestSkipped(sprintf('Skipping %s ', static::class)); } parent::setUp(); diff --git a/src/Dev/SapphireTest.php b/src/Dev/SapphireTest.php index 7cb302aef..6485836cd 100644 --- a/src/Dev/SapphireTest.php +++ b/src/Dev/SapphireTest.php @@ -244,7 +244,7 @@ class SapphireTest extends PHPUnit_Framework_TestCase // We cannot run the tests on this abstract class. if (static::class == __CLASS__) { - $this->markTestSkipped(sprintf('Skipping %s ', get_class($this))); + $this->markTestSkipped(sprintf('Skipping %s ', static::class)); return; } @@ -563,9 +563,9 @@ class SapphireTest extends PHPUnit_Framework_TestCase */ protected function getCurrentAbsolutePath() { - $filename = self::$test_class_manifest->getItemPath(get_class($this)); + $filename = self::$test_class_manifest->getItemPath(static::class); if (!$filename) { - throw new LogicException("getItemPath returned null for " . get_class($this)); + throw new LogicException("getItemPath returned null for " . static::class); } return dirname($filename); } diff --git a/src/Forms/CompositeField.php b/src/Forms/CompositeField.php index 70d6dc16d..87553c87e 100644 --- a/src/Forms/CompositeField.php +++ b/src/Forms/CompositeField.php @@ -247,7 +247,7 @@ class CompositeField extends FormField $formName = (isset($this->form)) ? $this->form->FormName() : '(unknown form)'; if (isset($list[$name])) { $fieldClass = get_class($field); - $otherFieldClass = $list[$name]->class; + $otherFieldClass = get_class($list[$name]); user_error( "collateDataFields() I noticed that a field called '$name' appears twice in" . " your form: '{$formName}'. One is a '{$fieldClass}' and the other is a" diff --git a/src/Forms/FormRequestHandler.php b/src/Forms/FormRequestHandler.php index 6d07f7edf..a2115e8e0 100644 --- a/src/Forms/FormRequestHandler.php +++ b/src/Forms/FormRequestHandler.php @@ -213,7 +213,7 @@ class FormRequestHandler extends RequestHandler ) { return $this->httpError( 403, - sprintf('Action "%s" not allowed on form request handler (Class: "%s")', $funcName, get_class($this)) + sprintf('Action "%s" not allowed on form request handler (Class: "%s")', $funcName, static::class) ); } diff --git a/src/ORM/Connect/DBSchemaManager.php b/src/ORM/Connect/DBSchemaManager.php index d60496aea..653c10edc 100644 --- a/src/ORM/Connect/DBSchemaManager.php +++ b/src/ORM/Connect/DBSchemaManager.php @@ -356,7 +356,7 @@ abstract class DBSchemaManager // Check if options changed $tableOptionsChanged = false; // Check for DB constant on the schema class - $dbIDName = sprintf('%s::ID', get_class($this)); + $dbIDName = sprintf('%s::ID', static::class); $dbID = defined($dbIDName) ? constant($dbIDName) : null; if ($dbID && isset($options[$dbID])) { if (preg_match('/ENGINE=([^\s]*)/', $options[$dbID], $alteredEngineMatches)) { diff --git a/src/ORM/DataObject.php b/src/ORM/DataObject.php index f2fe8ce3d..48bfac77f 100644 --- a/src/ORM/DataObject.php +++ b/src/ORM/DataObject.php @@ -1596,7 +1596,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity $joinField = $schema->getRemoteJoinField(static::class, $componentName, 'has_many', $polymorphic); /** @var HasManyList $result */ if ($polymorphic) { - $result = PolymorphicHasManyList::create($componentClass, $joinField, get_class($this)); + $result = PolymorphicHasManyList::create($componentClass, $joinField, static::class); } else { $result = HasManyList::create($componentClass, $joinField); } From e945ea64b57161251fdf9308956f7be7d304a1da Mon Sep 17 00:00:00 2001 From: Damian Mooyman Date: Tue, 23 May 2017 13:45:21 +1200 Subject: [PATCH 3/3] Temporarily switch to composer 1.5 --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 705f43493..c5df530f2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -56,6 +56,9 @@ before_script: - phpenv config-rm xdebug.ini - echo 'memory_limit = 2048M' >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini +# Temporarily update to 1.5.x-dev of composer + - composer self-update --snapshot + # Install composer dependencies - composer validate - composer install --prefer-dist