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
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..8701510a0 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);
@@ -396,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 = $this->class;
- while ($parentClass != __CLASS__) {
- $templates[] = strtok($parentClass, '_') . '_' . $action;
- $parentClass = get_parent_class($parentClass);
+ // Build templates based on class hierarchy
+ $actionTemplates = [];
+ $classTemplates = [];
+ $parentClass = static::class;
+ while ($parentClass !== parent::class) {
+ // _action templates have higher priority
+ if ($action && $action != 'index') {
+ $actionTemplates[] = strtok($parentClass, '_') . '_' . $action;
}
- }
- // Add controller templates for inheritance chain
- $parentClass = $this->class;
- while ($parentClass != __CLASS__) {
- $templates[] = strtok($parentClass, '_');
+ // 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);
@@ -469,7 +469,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 +496,7 @@ class Controller extends RequestHandler implements TemplateGlobalProvider
return true;
}
- $parentClass = $this->class;
+ $parentClass = static::class;
$templates = array();
while ($parentClass != __CLASS__) {
@@ -614,8 +614,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..ca50d9d8f 100644
--- a/src/Dev/FunctionalTest.php
+++ b/src/Dev/FunctionalTest.php
@@ -83,8 +83,8 @@ class FunctionalTest extends SapphireTest
protected function setUp()
{
// Skip calling FunctionalTest directly.
- if (get_class($this) == __CLASS__) {
- $this->markTestSkipped(sprintf('Skipping %s ', get_class($this)));
+ if (static::class == __CLASS__) {
+ $this->markTestSkipped(sprintf('Skipping %s ', static::class));
}
parent::setUp();
diff --git a/src/Dev/SapphireTest.php b/src/Dev/SapphireTest.php
index 3a3ce1f8f..6485836cd 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,8 +243,8 @@ class SapphireTest extends PHPUnit_Framework_TestCase
}
// We cannot run the tests on this abstract class.
- if (get_class($this) == __CLASS__) {
- $this->markTestSkipped(sprintf('Skipping %s ', get_class($this)));
+ if (static::class == __CLASS__) {
+ $this->markTestSkipped(sprintf('Skipping %s ', static::class));
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;
@@ -559,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/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..87553c87e 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 = 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"
+ . " '{$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..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)
);
}
@@ -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..653c10edc 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;
@@ -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)) {
@@ -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..48bfac77f 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, static::class);
} 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}'