diff --git a/admin/code/LeftAndMain.php b/admin/code/LeftAndMain.php index d139e9500..b45eea61e 100644 --- a/admin/code/LeftAndMain.php +++ b/admin/code/LeftAndMain.php @@ -86,7 +86,7 @@ class LeftAndMain extends Controller { // cms menus only for logged-in members if(!$member) return false; - // alternative decorated checks + // alternative extended checks if($this->hasMethod('alternateAccessCheck')) { $alternateAllowed = $this->alternateAccessCheck(); if($alternateAllowed === FALSE) return false; @@ -102,8 +102,8 @@ class LeftAndMain extends Controller { } /** - * @uses LeftAndMainDecorator->init() - * @uses LeftAndMainDecorator->accessedCMS() + * @uses LeftAndMainExtension->init() + * @uses LeftAndMainExtension->accessedCMS() * @uses CMSMenu */ function init() { @@ -124,7 +124,7 @@ class LeftAndMain extends Controller { self::$help_link ); - // Allow customisation of the access check by a decorator + // Allow customisation of the access check by a extension // Also all the canView() check to execute Director::redirect() if(!$this->canView() && !$this->response->isFinished()) { // When access /admin/, we should try a redirect to another part of the admin rather than be locked out diff --git a/admin/code/LeftAndMainDecorator.php b/admin/code/LeftAndMainDecorator.php index 7e6970e0f..5e4263cb7 100644 --- a/admin/code/LeftAndMainDecorator.php +++ b/admin/code/LeftAndMainDecorator.php @@ -1,21 +1,17 @@ \ No newline at end of file +} \ No newline at end of file diff --git a/admin/code/LeftAndMainExtension.php b/admin/code/LeftAndMainExtension.php new file mode 100644 index 000000000..89dff7aa5 --- /dev/null +++ b/admin/code/LeftAndMainExtension.php @@ -0,0 +1,19 @@ +)->hasExtension() as it will * give you inconsistent results based on when the singleton was first @@ -1010,7 +1009,7 @@ abstract class Object { * See {@link get_extensions()} to get all applied extension classes * for this class (not the instance). * - * @return array Map of {@link DataObjectDecorator} instances, keyed by classname. + * @return array Map of {@link DataExtension} instances, keyed by classname. */ public function getExtensionInstances() { return $this->extension_instances; diff --git a/dev/SapphireTest.php b/dev/SapphireTest.php index 800d1d4ab..6f55b7739 100755 --- a/dev/SapphireTest.php +++ b/dev/SapphireTest.php @@ -688,9 +688,9 @@ class SapphireTest extends PHPUnit_Framework_TestCase { $dbConn = DB::getConn(); $dbName = $dbConn->currentDatabase(); if($dbName && DB::getConn()->databaseExists($dbName)) { - // Some DataObjectsDecorators keep a static cache of information that needs to + // Some DataExtensions keep a static cache of information that needs to // be reset whenever the database is killed - foreach(ClassInfo::subclassesFor('DataObjectDecorator') as $class) { + foreach(ClassInfo::subclassesFor('DataExtension') as $class) { $toCall = array($class, 'on_db_reset'); if(is_callable($toCall)) call_user_func($toCall); } @@ -709,9 +709,9 @@ class SapphireTest extends PHPUnit_Framework_TestCase { $dbadmin = new DatabaseAdmin(); $dbadmin->clearAllData(); - // Some DataObjectsDecorators keep a static cache of information that needs to + // Some DataExtensions keep a static cache of information that needs to // be reset whenever the database is cleaned out - foreach(array_merge(ClassInfo::subclassesFor('DataObjectDecorator'), ClassInfo::subclassesFor('DataObject')) as $class) { + foreach(array_merge(ClassInfo::subclassesFor('DataExtension'), ClassInfo::subclassesFor('DataObject')) as $class) { $toCall = array($class, 'on_db_reset'); if(is_callable($toCall)) call_user_func($toCall); } diff --git a/docs/en/reference/dataobjectdecorator.md b/docs/en/reference/dataextension.md similarity index 75% rename from docs/en/reference/dataobjectdecorator.md rename to docs/en/reference/dataextension.md index 2fab18cee..a23bd6e8c 100644 --- a/docs/en/reference/dataobjectdecorator.md +++ b/docs/en/reference/dataextension.md @@ -1,22 +1,22 @@ -# DataObjectDecorator +# DataExtension ## Introduction -Extensions (also referred to as decorators) allow for adding additional functionality to a `[api:DataObject]`. +Extensions allow for adding additional functionality to a `[api:DataObject]`. In some cases, it can be easier to completely replace the used class throughout the core with your custom implementation. Have a look at `[api:Object->useCustomClass()]`. ## Usage -Your Decorator will nee to be a subclass of `[api:DataObjectDecorator]` or the `[api:Extension]` class. +Your extension will nee to be a subclass of `[api:DataExtension]` or the `[api:Extension]` class. :::php owner`` for information about the data object, such as the fields it has * You can use **DB::requireTable($tableName, $fieldList, $indexList)** to set up your new tables. This function takes @@ -125,18 +125,18 @@ be modified as needed by your method. Instead of a manipulation array, we have ### Additional methods -The other thing you may want to do with a decorator is provide a method that can be called on the `[api:DataObject]` that is -being decorated. For instance, you may add a publish() method to every `[api:DataObject]` that is decorated with `[api:Versioned]`. +The other thing you may want to do with a extension is provide a method that can be called on the `[api:DataObject]` that is +being extended. For instance, you may add a publish() method to every `[api:DataObject]` that is extended with `[api:Versioned]`. -This is as simple as defining a method called publish() on your decorator. Bear in mind, however, that instead of +This is as simple as defining a method called publish() on your extension. Bear in mind, however, that instead of $this, you should be referring to $this->owner. -* $this = The `[api:DataObjectDecorator]` object. +* $this = The `[api:DataExtension]` object. * $this->owner = The related `[api:DataObject]` object. -If you want to add your own internal properties, you can add this to the `[api:DataObjectDecorator]`, and these will be referred -to as `$this->propertyName`. Every `[api:DataObject]` has an associated `[api:DataObjectDecorator]` instance for each class that it is -decorated by. +If you want to add your own internal properties, you can add this to the `[api:DataExtension]`, and these will be referred +to as `$this->propertyName`. Every `[api:DataObject]` has an associated `[api:DataExtension]` instance for each class that it is +extended by. :::php class Customer extends DataObject { @@ -159,7 +159,7 @@ decorated by. } - class CustomerWorkflow extends DataObjectDecorator { + class CustomerWorkflow extends DataExtension { function IsMarkedForDeletion() { return ($this->owner->Account()->IsMarkedForDeletion == 1) ? true : false; @@ -169,4 +169,4 @@ decorated by. ## API Documentation -`[api:DataObjectDecorator]` \ No newline at end of file +`[api:DataExtension]` \ No newline at end of file diff --git a/docs/en/reference/dataobject.md b/docs/en/reference/dataobject.md index 628fc0043..66f2481db 100644 --- a/docs/en/reference/dataobject.md +++ b/docs/en/reference/dataobject.md @@ -40,7 +40,7 @@ These calls retrieve a `[api:FieldSet]` for the area where you intend to work wi ### For the Frontend Used for simple frontend forms without relation editing or `[api:TabSet] behaviour. Uses `scaffoldFormFields()` by -default. To customize, either overload this method in your subclass, or decorate it by `DataObjectDecorator->updateFormFields()`. +default. To customize, either overload this method in your subclass, or extend it by `DataExtension->updateFormFields()`. * Requirements: SilverStripe 2.3.* diff --git a/docs/en/reference/index.md b/docs/en/reference/index.md index 57f75f5e8..0d04d599e 100644 --- a/docs/en/reference/index.md +++ b/docs/en/reference/index.md @@ -8,7 +8,7 @@ Reference articles complement our auto-generated [API docs](http://api.silverstr * [ComplexTableField](complextablefield): Manage records and their relations inside the CMS * [Database Structure](database-structure): Conventions and best practices for database tables and fields * [DataObject](dataobject): Base class for database records -* [DataObjectDecorator](dataobjectdecorator): A "mixin" system allowing to extend core classes +* [DataExtension](dataextension): A "mixin" system allowing to extend core classes * [DataObjectSet](dataobjectset): The base collection of database records in the ORM * [Director](director): Routes URLs and handles HTTP requests * [Execution Pipeline](execution-pipeline): Detailed look on the way an HTTP request takes through the system diff --git a/docs/en/reference/member.md b/docs/en/reference/member.md index de22b9942..f4e696884 100644 --- a/docs/en/reference/member.md +++ b/docs/en/reference/member.md @@ -38,7 +38,7 @@ Returns the full *Member* Object for the current user, returns *null* if user is ## Subclassing
-This is the least desirable way of extending the `[api:Member]` class. It's better to use `[api:DataObjectDecorator]` +This is the least desirable way of extending the `[api:Member]` class. It's better to use `[api:DataExtension]` (see below).
@@ -86,22 +86,22 @@ For persons without login-capabilities (e.g. for an address-database), you shoul with the Member-database. This enables us to have a different subclass of `[api:Member]` for an email-address with login-data, and another subclass for the same email-address in the address-database. -## Member Role Decorator +## Member Role Extension Using inheritance to add extra behaviour or data fields to a member is limiting, because you can only inherit from 1 -class. A better way is to use role decorators to add this behaviour. +class. A better way is to use role extensions to add this behaviour. :::php - DataObject::add_extension('Member', 'ForumRole'); + Object::add_extension('Member', 'ForumRole'); // OR Member::add_role('ForumRole'); -A role decorator is simply a subclass of `[api:DataObjectDecorator]` that is designed to be used to add behaviour to `[api:Member]`. +A role extension is simply a subclass of `[api:DataExtension]` that is designed to be used to add behaviour to `[api:Member]`. The roles affect the entire class - all members will get the additional behaviour. However, if you want to restrict things, you should add appropriate `[api:Permission::checkMember()]` calls to the role's methods. :::php - class ForumRole extends DataObjectDecorator { + class ForumRole extends DataExtension { /** * Modify the field set to be displayed in the CMS detail pop-up diff --git a/docs/en/reference/siteconfig.md b/docs/en/reference/siteconfig.md index 4b3ef50db..b2e83f51e 100644 --- a/docs/en/reference/siteconfig.md +++ b/docs/en/reference/siteconfig.md @@ -37,7 +37,7 @@ Create a mysite/code/CustomSiteConfig.php file. :::php true, + 'has_one' => true, + 'belongs_to' => true, + 'indexes' => true, + 'defaults' => true, + 'has_many' => true, + 'many_many' => true, + 'belongs_many_many' => true, + 'many_many_extraFields' => true, + 'searchable_fields' => true, + 'api_access' => false, + ); + + private static $extra_statics_loaded = array(); + + /** + * Load the extra static definitions for the given extension + * class name, called by {@link Object::add_extension()} + * + * @param string $class Class name of the owner class (or owner base class) + * @param string $extension Class name of the extension class + */ + public static function load_extra_statics($class, $extension) { + if(!empty(self::$extra_statics_loaded[$class][$extension])) return; + self::$extra_statics_loaded[$class][$extension] = true; + + if(preg_match('/^([^(]*)/', $extension, $matches)) { + $extensionClass = $matches[1]; + } else { + user_error("Bad extenion '$extension' - can't find classname", E_USER_WARNING); + return; + } + + // @deprecated 2.4 - use extraStatics() now, not extraDBFields() + if(method_exists($extensionClass, 'extraDBFields')) { + user_error('DataExtension::extraDBFields() is deprecated. Please use extraStatics() instead.', E_USER_NOTICE); + $extraStaticsMethod = 'extraDBFields'; + } else { + $extraStaticsMethod = 'extraStatics'; + } + + // If the extension has been manually applied to a subclass, we should ignore that. + if(Object::has_extension(get_parent_class($class), $extensionClass)) return; + + $statics = call_user_func(array($extensionClass, $extraStaticsMethod), $class, $extension); + + if($statics) { + foreach($statics as $name => $newVal) { + if(isset(self::$extendable_statics[$name])) { + + // Array to be merged + if(self::$extendable_statics[$name]) { + $origVal = Object::uninherited_static($class, $name); + // Can't use add_static_var() here as it would merge the array rather than replacing + Object::set_static($class, $name, array_merge((array)$origVal, $newVal)); + + // Value to be overwritten + } else { + Object::set_static($class, $name, $newVal); + } + } + } + + DataObject::$cache_has_own_table[$class] = null; + DataObject::$cache_has_own_table_field[$class] = null; + } + } + + /** + * Edit the given query object to support queries for this extension + * + * @param SQLQuery $query Query to augment. + */ + function augmentSQL(SQLQuery &$query) { + } + + /** + * Update the database schema as required by this extension. + */ + function augmentDatabase() { + } + + /** + * Augment a write-record request. + * + * @param SQLQuery $manipulation Query to augment. + */ + function augmentWrite(&$manipulation) { + } + + function onBeforeWrite() { + } + + function onAfterWrite() { + } + + function onBeforeDelete() { + } + + function onAfterDelete() { + } + + function requireDefaultRecords() { + } + + function populateDefaults() { + } + + function can($member) { + } + + function canEdit($member) { + } + + function canDelete($member) { + } + + function canCreate($member) { + } + + /** + * Define extra database fields + * + * Return a map where the keys are db, has_one, etc, and the values are + * additional fields/relations to be defined. + * + * @return array Returns a map where the keys are db, has_one, etc, and + * the values are additional fields/relations to be defined. + */ + function extraStatics() { + return array(); + } + + /** + * This function is used to provide modifications to the form in the CMS + * by the extension. By default, no changes are made. {@link DataObject->getCMSFields()}. + * + * Please consider using {@link updateFormFields()} to globally add + * formfields to the record. The method {@link updateCMSFields()} + * should just be used to add or modify tabs, or fields which + * are specific to the CMS-context. + * + * Caution: Use {@link FieldSet->addFieldToTab()} to add fields. + * + * @param FieldSet $fields FieldSet with a contained TabSet + */ + function updateCMSFields(FieldSet &$fields) { + } + + /** + * This function is used to provide modifications to the form used + * for front end forms. {@link DataObject->getFrontEndFields()} + * + * Caution: Use {@link FieldSet->push()} to add fields. + * + * @param FieldSet $fields FieldSet without TabSet nesting + */ + function updateFrontEndFields(FieldSet &$fields) { + } + + /** + * This is used to provide modifications to the form actions + * used in the CMS. {@link DataObject->getCMSActions()}. + * + * @param FieldSet $actions FieldSet + */ + function updateCMSActions(FieldSet &$actions) { + } + + /** + * this function is used to provide modifications to the summary fields in CMS + * by the extension + * By default, the summaryField() of its owner will merge more fields defined in the extension's + * $extra_fields['summary_fields'] + */ + function updateSummaryFields(&$fields){ + $extra_fields = $this->extraStatics(); + if(isset($extra_fields['summary_fields'])){ + $summary_fields = $extra_fields['summary_fields']; + + // if summary_fields were passed in numeric array, + // convert to an associative array + if($summary_fields && array_key_exists(0, $summary_fields)) { + $summary_fields = array_combine(array_values($summary_fields), array_values($summary_fields)); + } + if($summary_fields) $fields = array_merge($fields, $summary_fields); + } + } + + /** + * this function is used to provide modifications to the fields labels in CMS + * by the extension + * By default, the fieldLabels() of its owner will merge more fields defined in the extension's + * $extra_fields['field_labels'] + */ + function updateFieldLabels(&$lables){ + $extra_fields = $this->extraStatics(); + if(isset($extra_fields['field_labels'])){ + $field_labels = $extra_fields['field_labels']; + if($field_labels) $lables = array_merge($lables, $field_labels); + } + } + + /** + * Clear any internal caches. + */ + function flushCache() { + } + +} +?> diff --git a/model/DataObject.php b/model/DataObject.php index 1d3e53d57..b6991cd00 100755 --- a/model/DataObject.php +++ b/model/DataObject.php @@ -2,9 +2,9 @@ /** * A single database record & abstract class for the data-access-model. * - *

Extensions and Decorators

+ *

Extensions

* - * See {@link Extension} and {@link DataObjectDecorator}. + * See {@link Extension} and {@link DataExtension}. * *

Permission Control

* @@ -890,7 +890,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity * * This called after {@link $this->validate()}, so you can be sure that your data is valid. * - * @uses DataObjectDecorator->onBeforeWrite() + * @uses DataExtension->onBeforeWrite() */ protected function onBeforeWrite() { $this->brokenOnWrite = false; @@ -905,7 +905,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity * $this->changed will have a record * database. Don't forget to call parent::onAfterWrite(), though! * - * @uses DataObjectDecorator->onAfterWrite() + * @uses DataExtension->onAfterWrite() */ protected function onAfterWrite() { $dummy = null; @@ -917,7 +917,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity * You can overload this to clean up or otherwise process data before delete this * record. Don't forget to call parent::onBeforeDelete(), though! * - * @uses DataObjectDecorator->onBeforeDelete() + * @uses DataExtension->onBeforeDelete() */ protected function onBeforeDelete() { $this->brokenOnDelete = false; @@ -935,7 +935,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity * Will traverse the defaults of the current class and all its parent classes. * Called by the constructor when creating new records. * - * @uses DataObjectDecorator->populateDefaults() + * @uses DataExtension->populateDefaults() */ public function populateDefaults() { $classes = array_reverse(ClassInfo::ancestry($this)); @@ -976,7 +976,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity * - Extensions such as Versioned will ammend the database-write to ensure that a version is saved. * - Calls to {@link DataObjectLog} can be used to see everything that's been changed. * - * @uses DataObjectDecorator->augmentWrite() + * @uses DataExtension->augmentWrite() * * @param boolean $showDebug Show debugging information * @param boolean $forceInsert Run INSERT command rather than UPDATE, even if record already exists @@ -1183,7 +1183,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity * Delete this data object. * $this->onBeforeDelete() gets called. * Note that in Versioned objects, both Stage and Live will be deleted. - * @uses DataObjectDecorator->augmentSQL() + * @uses DataExtension->augmentSQL() */ public function delete() { $this->brokenOnDelete = true; @@ -1983,7 +1983,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity * which returns a {@link FieldSet} suitable for a {@link Form} object. * If not overloaded, we're using {@link scaffoldFormFields()} to automatically * generate this set. To customize, overload this method in a subclass - * or decorate onto it by using {@link DataObjectDecorator->updateCMSFields()}. + * or extended onto it by using {@link DataExtension->updateCMSFields()}. * * * klass MyCustomClass extends DataObject { @@ -2019,7 +2019,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity /** * need to be overload by solid dataobject, so that the customised actions of that dataobject, - * including that dataobject's decorator customised actions could be added to the EditForm. + * including that dataobject's extensions customised actions could be added to the EditForm. * * @return an Empty FieldSet(); need to be overload by solid subclass */ @@ -2034,7 +2034,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity * Used for simple frontend forms without relation editing * or {@link TabSet} behaviour. Uses {@link scaffoldFormFields()} * by default. To customize, either overload this method in your - * subclass, or decorate it by {@link DataObjectDecorator->updateFrontEndFields()}. + * subclass, or extend it by {@link DataExtension->updateFrontEndFields()}. * * @todo Decide on naming for "website|frontend|site|page" and stick with it in the API * @@ -2277,7 +2277,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity if($field == "LastEdited" && get_parent_class($this) == "DataObject") return "SS_Datetime"; if($field == "Created" && get_parent_class($this) == "DataObject") return "SS_Datetime"; - // Add fields from Versioned decorator + // Add fields from Versioned extension if($field == 'Version' && $this->hasExtension('Versioned')) { return 'Int'; } @@ -2408,11 +2408,11 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity } /** - * Process tri-state responses from permission-alterting decorators. The decorators are + * Process tri-state responses from permission-alterting extensions. The extensions are * expected to return one of three values: * - * - false: Disallow this permission, regardless of what other decorators say - * - true: Allow this permission, as long as no other decorators return false + * - false: Disallow this permission, regardless of what other extensions say + * - true: Allow this permission, as long as no other extensions return false * - NULL: Don't affect the outcome * * This method itself returns a tri-state value, and is designed to be used like this: @@ -2756,7 +2756,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity /** * Like {@link buildSQL}, but applies the extension modifications. * - * @uses DataObjectDecorator->augmentSQL() + * @uses DataExtension->augmentSQL() * * @param string $filter A filter to be inserted into the WHERE clause. * @param string|array $sort A sort expression to be inserted into the ORDER BY clause. If omitted, self::$default_sort will be used. @@ -2936,7 +2936,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity /** * Does the hard work for get_one() * - * @uses DataObjectDecorator->augmentSQL() + * @uses DataExtension->augmentSQL() * * @param string $filter A filter to be inserted into the WHERE clause * @param string $orderby A sort expression to be inserted into the ORDER BY clause. @@ -3042,7 +3042,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity /** * Check the database schema and update it as necessary. * - * @uses DataObjectDecorator->augmentDatabase() + * @uses DataExtension->augmentDatabase() */ public function requireTable() { // Only build the table if we've actually got fields @@ -3091,7 +3091,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity * this to add default records when the database is built, but make sure you * call parent::requireDefaultRecords(). * - * @uses DataObjectDecorator->requireDefaultRecords() + * @uses DataExtension->requireDefaultRecords() */ public function requireDefaultRecords() { $defaultRecords = $this->stat('default_records'); @@ -3172,8 +3172,8 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity if(!$fields) $fields = array_keys($this->summaryFields()); // we need to make sure the format is unified before - // augmenting fields, so decorators can apply consistent checks - // but also after augmenting fields, because the decorator + // augmenting fields, so extensions can apply consistent checks + // but also after augmenting fields, because the extension // might use the shorthand notation as well // rewrite array, if it is using shorthand syntax @@ -3210,7 +3210,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity $fields = $rewrite; - // apply DataObjectDecorators if present + // apply DataExtensions if present $this->extend('updateSearchableFields', $fields); return $fields; @@ -3349,7 +3349,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity /** * Sets a 'context object' that can be used to provide hints about how to process a particular get / get_one request. - * In particular, DataObjectDecorators can use this to amend queries more effectively. + * In particular, DataExtensions can use this to amend queries more effectively. * Care must be taken to unset the context object after you're done with it, otherwise you will have a stale context, * which could cause horrible bugs. */ diff --git a/model/DataObjectDecorator.php b/model/DataObjectDecorator.php index fde4deba3..01ed429e2 100755 --- a/model/DataObjectDecorator.php +++ b/model/DataObjectDecorator.php @@ -1,235 +1,17 @@ true, - 'has_one' => true, - 'belongs_to' => true, - 'indexes' => true, - 'defaults' => true, - 'has_many' => true, - 'many_many' => true, - 'belongs_many_many' => true, - 'many_many_extraFields' => true, - 'searchable_fields' => true, - 'api_access' => false, - ); - - private static $extra_statics_loaded = array(); - - /** - * Load the extra static definitions for the given extension - * class name, called by {@link Object::add_extension()} - * - * @param string $class Class name of the owner class (or owner base class) - * @param string $extension Class name of the extension class - */ - public static function load_extra_statics($class, $extension) { - if(!empty(self::$extra_statics_loaded[$class][$extension])) return; - self::$extra_statics_loaded[$class][$extension] = true; - - if(preg_match('/^([^(]*)/', $extension, $matches)) { - $extensionClass = $matches[1]; - } else { - user_error("Bad extenion '$extension' - can't find classname", E_USER_WARNING); - return; - } - - // @deprecated 2.4 - use extraStatics() now, not extraDBFields() - if(method_exists($extensionClass, 'extraDBFields')) { - user_error('DataObjectDecorator::extraDBFields() is deprecated. Please use extraStatics() instead.', E_USER_NOTICE); - $extraStaticsMethod = 'extraDBFields'; - } else { - $extraStaticsMethod = 'extraStatics'; - } - - // If the extension has been manually applied to a subclass, we should ignore that. - if(Object::has_extension(get_parent_class($class), $extensionClass)) return; - - $statics = call_user_func(array($extensionClass, $extraStaticsMethod), $class, $extension); - - if($statics) { - foreach($statics as $name => $newVal) { - if(isset(self::$decoratable_statics[$name])) { - - // Array to be merged - if(self::$decoratable_statics[$name]) { - $origVal = Object::uninherited_static($class, $name); - // Can't use add_static_var() here as it would merge the array rather than replacing - Object::set_static($class, $name, array_merge((array)$origVal, $newVal)); - - // Value to be overwritten - } else { - Object::set_static($class, $name, $newVal); - } - } - } - - DataObject::$cache_has_own_table[$class] = null; - DataObject::$cache_has_own_table_field[$class] = null; - } - } - - /** - * Edit the given query object to support queries for this extension - * - * @param SQLQuery $query Query to augment. - */ - function augmentSQL(SQLQuery &$query) { + public function __construct() { + user_error( + 'DataObjectDecorator is deprecated, please use DataExtension instead.', + E_USER_NOTICE + ); + parent::__construct(); } - /** - * Update the database schema as required by this extension. - */ - function augmentDatabase() { - } - - /** - * Augment a write-record request. - * - * @param SQLQuery $manipulation Query to augment. - */ - function augmentWrite(&$manipulation) { - } - - function onBeforeWrite() { - } - - function onAfterWrite() { - } - - function onBeforeDelete() { - } - - function onAfterDelete() { - } - - function requireDefaultRecords() { - } - - function populateDefaults() { - } - - function can($member) { - } - - function canEdit($member) { - } - - function canDelete($member) { - } - - function canCreate($member) { - } - - /** - * Define extra database fields - * - * Return a map where the keys are db, has_one, etc, and the values are - * additional fields/relations to be defined. - * - * @return array Returns a map where the keys are db, has_one, etc, and - * the values are additional fields/relations to be defined. - */ - function extraStatics() { - return array(); - } - - /** - * This function is used to provide modifications to the form in the CMS - * by the decorator. By default, no changes are made. {@link DataObject->getCMSFields()}. - * - * Please consider using {@link updateFormFields()} to globally add - * formfields to the record. The method {@link updateCMSFields()} - * should just be used to add or modify tabs, or fields which - * are specific to the CMS-context. - * - * Caution: Use {@link FieldSet->addFieldToTab()} to add fields. - * - * @param FieldSet $fields FieldSet with a contained TabSet - */ - function updateCMSFields(FieldSet &$fields) { - } - - /** - * This function is used to provide modifications to the form used - * for front end forms. {@link DataObject->getFrontEndFields()} - * - * Caution: Use {@link FieldSet->push()} to add fields. - * - * @param FieldSet $fields FieldSet without TabSet nesting - */ - function updateFrontEndFields(FieldSet &$fields) { - } - - /** - * This is used to provide modifications to the form actions - * used in the CMS. {@link DataObject->getCMSActions()}. - * - * @param FieldSet $actions FieldSet - */ - function updateCMSActions(FieldSet &$actions) { - } - - /** - * this function is used to provide modifications to the summary fields in CMS - * by the decorator - * By default, the summaryField() of its owner will merge more fields defined in the decorator's - * $extra_fields['summary_fields'] - */ - function updateSummaryFields(&$fields){ - $extra_fields = $this->extraStatics(); - if(isset($extra_fields['summary_fields'])){ - $summary_fields = $extra_fields['summary_fields']; - - // if summary_fields were passed in numeric array, - // convert to an associative array - if($summary_fields && array_key_exists(0, $summary_fields)) { - $summary_fields = array_combine(array_values($summary_fields), array_values($summary_fields)); - } - if($summary_fields) $fields = array_merge($fields, $summary_fields); - } - } - - /** - * this function is used to provide modifications to the fields labels in CMS - * by the decorator - * By default, the fieldLabels() of its owner will merge more fields defined in the decorator's - * $extra_fields['field_labels'] - */ - function updateFieldLabels(&$lables){ - $extra_fields = $this->extraStatics(); - if(isset($extra_fields['field_labels'])){ - $field_labels = $extra_fields['field_labels']; - if($field_labels) $lables = array_merge($lables, $field_labels); - } - } - - /** - * Clear any internal caches. - */ - function flushCache() { - } - -} -?> +} \ No newline at end of file diff --git a/model/Hierarchy.php b/model/Hierarchy.php index 2b2c8db75..4fc7f5360 100755 --- a/model/Hierarchy.php +++ b/model/Hierarchy.php @@ -1,11 +1,11 @@ extend('canEdit', $member); if($results && is_array($results)) if(!min($results)) return false; @@ -389,7 +389,7 @@ class Group extends DataObject { public function canView($member = null) { if(!$member || !(is_a($member, 'Member')) || is_numeric($member)) $member = Member::currentUser(); - // decorated access checks + // extended access checks $results = $this->extend('canView', $member); if($results && is_array($results)) if(!min($results)) return false; @@ -402,7 +402,7 @@ class Group extends DataObject { public function canDelete($member = null) { if(!$member || !(is_a($member, 'Member')) || is_numeric($member)) $member = Member::currentUser(); - // decorated access checks + // extended access checks $results = $this->extend('canDelete', $member); if($results && is_array($results)) if(!min($results)) return false; diff --git a/security/Member.php b/security/Member.php index eee4d4bd3..3da2db87e 100755 --- a/security/Member.php +++ b/security/Member.php @@ -1264,7 +1264,7 @@ class Member extends DataObject { function canView($member = null) { if(!$member || !(is_a($member, 'Member')) || is_numeric($member)) $member = Member::currentUser(); - // decorated access checks + // extended access checks $results = $this->extend('canView', $member); if($results && is_array($results)) { if(!min($results)) return false; @@ -1291,7 +1291,7 @@ class Member extends DataObject { function canEdit($member = null) { if(!$member || !(is_a($member, 'Member')) || is_numeric($member)) $member = Member::currentUser(); - // decorated access checks + // extended access checks $results = $this->extend('canEdit', $member); if($results && is_array($results)) { if(!min($results)) return false; @@ -1318,7 +1318,7 @@ class Member extends DataObject { function canDelete($member = null) { if(!$member || !(is_a($member, 'Member')) || is_numeric($member)) $member = Member::currentUser(); - // decorated access checks + // extended access checks $results = $this->extend('canDelete', $member); if($results && is_array($results)) { if(!min($results)) return false; diff --git a/tests/core/ObjectTest.php b/tests/core/ObjectTest.php index f614bccb2..1bec01977 100755 --- a/tests/core/ObjectTest.php +++ b/tests/core/ObjectTest.php @@ -5,7 +5,7 @@ * * @todo tests for addStaticVars() * @todo tests for setting statics which are not defined on the object as built-in PHP statics - * @todo tests for setting statics through decorators (#2387) + * @todo tests for setting statics through extensions (#2387) */ class ObjectTest extends SapphireTest { diff --git a/tests/forms/FormScaffolderTest.php b/tests/forms/FormScaffolderTest.php index b5cc579c3..8a5620b32 100644 --- a/tests/forms/FormScaffolderTest.php +++ b/tests/forms/FormScaffolderTest.php @@ -38,8 +38,8 @@ class FormScaffolderTest extends SapphireTest { $article1 = $this->objFromFixture('FormScaffolderTest_Article', 'article1'); $fields = $article1->getCMSFields(); $this->assertNotNull( - $fields->dataFieldByName('AddedDecoratorField'), - 'getCMSFields() includes decorated fields' + $fields->dataFieldByName('AddedExtensionField'), + 'getCMSFields() includes extended fields' ); } @@ -102,16 +102,16 @@ class FormScaffolderTest_Tag extends DataObject implements TestOnly { 'Articles' => 'FormScaffolderTest_Article' ); } -class FormScaffolderTest_ArticleDecorator extends DataObjectDecorator implements TestOnly { +class FormScaffolderTest_ArticleExtension extends DataExtension implements TestOnly { static $db = array( - 'DecoratedField' => 'Varchar' + 'ExtendedField' => 'Varchar' ); function updateCMSFields(&$fields) { $fields->addFieldToTab('Root.Main', - new TextField('AddedDecoratorField') + new TextField('AddedExtensionField') ); } } -DataObject::add_extension('FormScaffolderTest_Article', 'FormScaffolderTest_ArticleDecorator'); +DataObject::add_extension('FormScaffolderTest_Article', 'FormScaffolderTest_ArticleExtension'); ?> \ No newline at end of file diff --git a/tests/i18n/_fakewebroot/i18nothermodule/code/i18nTestModuleDecorator.php b/tests/i18n/_fakewebroot/i18nothermodule/code/i18nTestModuleDecorator.php index 0da31253e..d14410638 100644 --- a/tests/i18n/_fakewebroot/i18nothermodule/code/i18nTestModuleDecorator.php +++ b/tests/i18n/_fakewebroot/i18nothermodule/code/i18nTestModuleDecorator.php @@ -1,5 +1,5 @@ array( diff --git a/tests/model/DataObjectDecoratorTest.php b/tests/model/DataExtensionTest.php similarity index 52% rename from tests/model/DataObjectDecoratorTest.php rename to tests/model/DataExtensionTest.php index 6db8c0993..0a8c7f4a8 100644 --- a/tests/model/DataObjectDecoratorTest.php +++ b/tests/model/DataExtensionTest.php @@ -1,26 +1,26 @@ array( 'DataObjectDecoratorTest_AppliedToDO' ), + 'DataObject' => array( 'DataExtensionTest_AppliedToDO' ), ); - function testOneToManyAssociationWithDecorator() { + function testOneToManyAssociationWithExtension() { // Fails in RestfulServerTest // Error: Object::__call() Method 'RelatedObjects' not found in class 'RestfulServerTest_Comment' - $contact = new DataObjectDecoratorTest_Member(); + $contact = new DataExtensionTest_Member(); $contact->Website = "http://www.example.com"; - $object = new DataObjectDecoratorTest_RelatedObject(); + $object = new DataExtensionTest_RelatedObject(); $object->FieldOne = "Lorem ipsum dolor"; $object->FieldTwo = "Random notes"; @@ -37,28 +37,28 @@ class DataObjectDecoratorTest extends SapphireTest { unset($contact); unset($object); - $contact = DataObject::get_one("DataObjectDecoratorTest_Member", "\"Website\"='http://www.example.com'"); - $object = DataObject::get_one('DataObjectDecoratorTest_RelatedObject', "\"ContactID\" = {$contactID}"); + $contact = DataObject::get_one("DataExtensionTest_Member", "\"Website\"='http://www.example.com'"); + $object = DataObject::get_one('DataExtensionTest_RelatedObject', "\"ContactID\" = {$contactID}"); $this->assertNotNull($object, 'Related object not null'); - $this->assertType('DataObjectDecoratorTest_Member', $object->Contact(), 'Related contact is a member dataobject'); - $this->assertType('DataObjectDecoratorTest_Member', $object->getComponent('Contact'), 'getComponent does the same thing as Contact()'); + $this->assertType('DataExtensionTest_Member', $object->Contact(), 'Related contact is a member dataobject'); + $this->assertType('DataExtensionTest_Member', $object->getComponent('Contact'), 'getComponent does the same thing as Contact()'); - $this->assertType('DataObjectDecoratorTest_RelatedObject', $contact->RelatedObjects()->First()); + $this->assertType('DataExtensionTest_RelatedObject', $contact->RelatedObjects()->First()); $this->assertEquals("Lorem ipsum dolor", $contact->RelatedObjects()->First()->FieldOne); $this->assertEquals("Random notes", $contact->RelatedObjects()->First()->FieldTwo); $contact->delete(); } - function testManyManyAssociationWithDecorator() { - $parent = new DataObjectDecoratorTest_MyObject(); + function testManyManyAssociationWithExtension() { + $parent = new DataExtensionTest_MyObject(); $parent->Title = 'My Title'; $parent->write(); $this->assertEquals(0, $parent->Faves()->Count()); - $obj1 = $this->objFromFixture('DataObjectDecoratorTest_RelatedObject', 'obj1'); - $obj2 = $this->objFromFixture('DataObjectDecoratorTest_RelatedObject', 'obj2'); + $obj1 = $this->objFromFixture('DataExtensionTest_RelatedObject', 'obj1'); + $obj2 = $this->objFromFixture('DataExtensionTest_RelatedObject', 'obj2'); $parent->Faves()->add($obj1->ID); $this->assertEquals(1, $parent->Faves()->Count()); @@ -71,17 +71,17 @@ class DataObjectDecoratorTest extends SapphireTest { } /** - * Test {@link Object::add_extension()} has loaded DataObjectDecorator statics correctly. + * Test {@link Object::add_extension()} has loaded DataExtension statics correctly. */ function testAddExtensionLoadsStatics() { - // Object::add_extension() will load DOD statics directly, so let's try adding a decorator on the fly - Object::add_extension('DataObjectDecoratorTest_Player', 'DataObjectDecoratorTest_PlayerDecorator'); + // Object::add_extension() will load DOD statics directly, so let's try adding a extension on the fly + Object::add_extension('DataExtensionTest_Player', 'DataExtensionTest_PlayerExtension'); - // Now that we've just added the decorator, we need to rebuild the database + // Now that we've just added the extension, we need to rebuild the database $this->resetDBSchema(true); - // Create a test record with decorated fields, writing to the DB - $player = new DataObjectDecoratorTest_Player(); + // Create a test record with extended fields, writing to the DB + $player = new DataExtensionTest_Player(); $player->setField('Name', 'Joe'); $player->setField('DateBirth', '1990-5-10'); $player->Address = '123 somewhere street'; @@ -89,66 +89,66 @@ class DataObjectDecoratorTest extends SapphireTest { unset($player); - // Pull the record out of the DB and examine the decorated fields - $player = DataObject::get_one('DataObjectDecoratorTest_Player', "\"Name\" = 'Joe'"); + // Pull the record out of the DB and examine the extended fields + $player = DataObject::get_one('DataExtensionTest_Player', "\"Name\" = 'Joe'"); $this->assertEquals($player->DateBirth, '1990-05-10'); $this->assertEquals($player->Address, '123 somewhere street'); $this->assertEquals($player->Status, 'Goalie'); } /** - * Test that DataObject::$api_access can be set to true via a decorator + * Test that DataObject::$api_access can be set to true via a extension */ - function testApiAccessCanBeDecorated() { - $this->assertTrue(Object::get_static('DataObjectDecoratorTest_Member', 'api_access')); + function testApiAccessCanBeExtended() { + $this->assertTrue(Object::get_static('DataExtensionTest_Member', 'api_access')); } - function testPermissionDecoration() { + function testPermissionExtension() { // testing behaviour in isolation, too many sideeffects and other checks // in SiteTree->can*() methods to test one single feature reliably with them - $obj = $this->objFromFixture('DataObjectDecoratorTest_MyObject', 'object1'); + $obj = $this->objFromFixture('DataExtensionTest_MyObject', 'object1'); $websiteuser = $this->objFromFixture('Member', 'websiteuser'); $admin = $this->objFromFixture('Member', 'admin'); $this->assertFalse( $obj->canOne($websiteuser), - 'Both decorators return true, but original method returns false' + 'Both extensions return true, but original method returns false' ); $this->assertFalse( $obj->canTwo($websiteuser), - 'One decorator returns false, original returns true, but decorator takes precedence' + 'One extension returns false, original returns true, but extension takes precedence' ); $this->assertTrue( $obj->canThree($admin), - 'Undefined decorator methods returning NULL dont influence the original method' + 'Undefined extension methods returning NULL dont influence the original method' ); } function testPopulateDefaults() { - $obj = new DataObjectDecoratorTest_Member(); + $obj = new DataExtensionTest_Member(); $this->assertEquals( $obj->Phone, '123', - 'Defaults can be populated through decorator' + 'Defaults can be populated through extension' ); } /** - * Test that DataObject::dbObject() works for fields applied by a decorator + * Test that DataObject::dbObject() works for fields applied by a extension */ - function testDbObjectOnDecoratedFields() { - $member = $this->objFromFixture('DataObjectDecoratorTest_Member', 'member1'); + function testDbObjectOnExtendedFields() { + $member = $this->objFromFixture('DataExtensionTest_Member', 'member1'); $this->assertNotNull($member->dbObject('Website')); $this->assertType('Varchar', $member->dbObject('Website')); } - function testDecoratorCanBeAppliedToDataObject() { + function testExtensionCanBeAppliedToDataObject() { $do = new DataObject(); - $mo = new DataObjectDecoratorTest_MyObject(); + $mo = new DataExtensionTest_MyObject(); $this->assertTrue($do->hasMethod('testMethodApplied')); $this->assertTrue($mo->hasMethod('testMethodApplied')); @@ -158,7 +158,7 @@ class DataObjectDecoratorTest extends SapphireTest { } } -class DataObjectDecoratorTest_Member extends DataObject implements TestOnly { +class DataExtensionTest_Member extends DataObject implements TestOnly { static $db = array( "Name" => "Varchar", @@ -167,7 +167,7 @@ class DataObjectDecoratorTest_Member extends DataObject implements TestOnly { } -class DataObjectDecoratorTest_Player extends DataObject implements TestOnly { +class DataExtensionTest_Player extends DataObject implements TestOnly { static $db = array( 'Name' => 'Varchar' @@ -175,12 +175,12 @@ class DataObjectDecoratorTest_Player extends DataObject implements TestOnly { } -class DataObjectDecoratorTest_PlayerDecorator extends DataObjectDecorator implements TestOnly { +class DataExtensionTest_PlayerExtension extends DataExtension implements TestOnly { function extraStatics($class) { - // Only add these extensions if the $class is set to DataObjectDecoratorTest_Player, to + // Only add these extensions if the $class is set to DataExtensionTest_Player, to // test that the argument works. - if($class == 'DataObjectDecoratorTest_Player') { + if($class == 'DataExtensionTest_Player') { return array( 'db' => array( 'Address' => 'Text', @@ -196,7 +196,7 @@ class DataObjectDecoratorTest_PlayerDecorator extends DataObjectDecorator implem } -class DataObjectDecoratorTest_ContactRole extends DataObjectDecorator implements TestOnly { +class DataExtensionTest_ContactRole extends DataExtension implements TestOnly { function extraStatics() { return array( @@ -205,7 +205,7 @@ class DataObjectDecoratorTest_ContactRole extends DataObjectDecorator implements 'Phone' => 'Varchar(255)', ), 'has_many' => array( - 'RelatedObjects' => 'DataObjectDecoratorTest_RelatedObject' + 'RelatedObjects' => 'DataExtensionTest_RelatedObject' ), 'defaults' => array( 'Phone' => '123' @@ -216,7 +216,7 @@ class DataObjectDecoratorTest_ContactRole extends DataObjectDecorator implements } -class DataObjectDecoratorTest_RelatedObject extends DataObject implements TestOnly { +class DataExtensionTest_RelatedObject extends DataObject implements TestOnly { static $db = array( "FieldOne" => "Varchar", @@ -224,21 +224,21 @@ class DataObjectDecoratorTest_RelatedObject extends DataObject implements TestOn ); static $has_one = array( - "Contact" => "DataObjectDecoratorTest_Member" + "Contact" => "DataExtensionTest_Member" ); } -DataObject::add_extension('DataObjectDecoratorTest_Member', 'DataObjectDecoratorTest_ContactRole'); +DataObject::add_extension('DataExtensionTest_Member', 'DataExtensionTest_ContactRole'); -class DataObjectDecoratorTest_MyObject extends DataObject implements TestOnly { +class DataExtensionTest_MyObject extends DataObject implements TestOnly { static $db = array( 'Title' => 'Varchar', ); function canOne($member = null) { - // decorated access checks + // extended access checks $results = $this->extend('canOne', $member); if($results && is_array($results)) if(!min($results)) return false; @@ -246,7 +246,7 @@ class DataObjectDecoratorTest_MyObject extends DataObject implements TestOnly { } function canTwo($member = null) { - // decorated access checks + // extended access checks $results = $this->extend('canTwo', $member); if($results && is_array($results)) if(!min($results)) return false; @@ -254,7 +254,7 @@ class DataObjectDecoratorTest_MyObject extends DataObject implements TestOnly { } function canThree($member = null) { - // decorated access checks + // extended access checks $results = $this->extend('canThree', $member); if($results && is_array($results)) if(!min($results)) return false; @@ -262,7 +262,7 @@ class DataObjectDecoratorTest_MyObject extends DataObject implements TestOnly { } } -class DataObjectDecoratorTest_Ext1 extends DataObjectDecorator implements TestOnly { +class DataExtensionTest_Ext1 extends DataExtension implements TestOnly { function canOne($member = null) { return true; @@ -277,7 +277,7 @@ class DataObjectDecoratorTest_Ext1 extends DataObjectDecorator implements TestOn } -class DataObjectDecoratorTest_Ext2 extends DataObjectDecorator implements TestOnly { +class DataExtensionTest_Ext2 extends DataExtension implements TestOnly { function canOne($member = null) { return true; @@ -292,23 +292,23 @@ class DataObjectDecoratorTest_Ext2 extends DataObjectDecorator implements TestOn } -class DataObjectDecoratorTest_Faves extends DataObjectDecorator implements TestOnly { +class DataExtensionTest_Faves extends DataExtension implements TestOnly { public function extraStatics() { return array( 'many_many' => array( - 'Faves' => 'DataObjectDecoratorTest_RelatedObject' + 'Faves' => 'DataExtensionTest_RelatedObject' ) ); } } -class DataObjectDecoratorTest_AppliedToDO extends DataObjectDecorator implements TestOnly { +class DataExtensionTest_AppliedToDO extends DataExtension implements TestOnly { public function testMethodApplied() { return "hello world"; } } -DataObject::add_extension('DataObjectDecoratorTest_MyObject', 'DataObjectDecoratorTest_Ext1'); -DataObject::add_extension('DataObjectDecoratorTest_MyObject', 'DataObjectDecoratorTest_Ext2'); -DataObject::add_extension('DataObjectDecoratorTest_MyObject', 'DataObjectDecoratorTest_Faves'); +DataObject::add_extension('DataExtensionTest_MyObject', 'DataExtensionTest_Ext1'); +DataObject::add_extension('DataExtensionTest_MyObject', 'DataExtensionTest_Ext2'); +DataObject::add_extension('DataExtensionTest_MyObject', 'DataExtensionTest_Faves'); ?> diff --git a/tests/model/DataObjectDecoratorTest.yml b/tests/model/DataExtensionTest.yml similarity index 79% rename from tests/model/DataObjectDecoratorTest.yml rename to tests/model/DataExtensionTest.yml index 651dd7016..99c05ca26 100644 --- a/tests/model/DataObjectDecoratorTest.yml +++ b/tests/model/DataExtensionTest.yml @@ -1,4 +1,4 @@ -DataObjectDecoratorTest_RelatedObject: +DataExtensionTest_RelatedObject: obj1: FieldOne: Obj1 obj2: @@ -15,10 +15,10 @@ Member: Groups: =>Group.admingroup websiteuser: Email: websiteuser@test.com -DataObjectDecoratorTest_Member: +DataExtensionTest_Member: member1: Name: Sam Website: http://www.example.org -DataObjectDecoratorTest_MyObject: +DataExtensionTest_MyObject: object1: Title: Object 1 \ No newline at end of file diff --git a/tests/model/DataObjectSetTest.yml b/tests/model/DataObjectSetTest.yml index 24d23d25e..1a251eb6c 100644 --- a/tests/model/DataObjectSetTest.yml +++ b/tests/model/DataObjectSetTest.yml @@ -22,11 +22,11 @@ DataObjectTest_SubTeam: subteam1: Title: Subteam 1 SubclassDatabaseField: Subclassed 1 - DecoratedDatabaseField: Decorated 1 + ExtendedDatabaseField: Extended 1 subteam2_with_player_relation: Title: Subteam 2 SubclassDatabaseField: Subclassed 2 - DecoratedHasOneRelationship: =>DataObjectTest_Player.player1 + ExtendeHasOneRelationship: =>DataObjectTest_Player.player1 subteam3_with_empty_fields: Title: Subteam 3 diff --git a/tests/model/DataObjectTest.php b/tests/model/DataObjectTest.php index 65998e75a..b252ba3fc 100755 --- a/tests/model/DataObjectTest.php +++ b/tests/model/DataObjectTest.php @@ -455,9 +455,9 @@ class DataObjectTest extends SapphireTest { //$this->assertFalse($teamInstance->hasField('SubclassDatabaseField'), 'hasField() doesnt find subclass fields in parentclass instances'); $this->assertTrue($teamInstance->hasField('DynamicField'), 'hasField() finds dynamic getters in instances'); $this->assertTrue($teamInstance->hasField('HasOneRelationshipID'), 'hasField() finds foreign keys in instances'); - $this->assertTrue($teamInstance->hasField('DecoratedDatabaseField'), 'hasField() finds decorated fields in instances'); - $this->assertTrue($teamInstance->hasField('DecoratedHasOneRelationshipID'), 'hasField() finds decorated foreign keys in instances'); - //$this->assertTrue($teamInstance->hasField('DecoratedDynamicField'), 'hasField() includes decorated dynamic getters in instances'); + $this->assertTrue($teamInstance->hasField('ExtendedDatabaseField'), 'hasField() finds extended fields in instances'); + $this->assertTrue($teamInstance->hasField('ExtendedHasOneRelationshipID'), 'hasField() finds extended foreign keys in instances'); + //$this->assertTrue($teamInstance->hasField('ExtendedDynamicField'), 'hasField() includes extended dynamic getters in instances'); /* hasField() subclass checks */ $this->assertTrue($subteamInstance->hasField('ID'), 'hasField() finds built-in fields in subclass instances'); @@ -466,8 +466,8 @@ class DataObjectTest extends SapphireTest { $this->assertTrue($subteamInstance->hasField('SubclassDatabaseField'), 'hasField() finds custom fields in subclass instances'); $this->assertTrue($subteamInstance->hasField('DynamicField'), 'hasField() finds dynamic getters in subclass instances'); $this->assertTrue($subteamInstance->hasField('HasOneRelationshipID'), 'hasField() finds foreign keys in subclass instances'); - $this->assertTrue($subteamInstance->hasField('DecoratedDatabaseField'), 'hasField() finds decorated fields in subclass instances'); - $this->assertTrue($subteamInstance->hasField('DecoratedHasOneRelationshipID'), 'hasField() finds decorated foreign keys in subclass instances'); + $this->assertTrue($subteamInstance->hasField('ExtendedDatabaseField'), 'hasField() finds extended fields in subclass instances'); + $this->assertTrue($subteamInstance->hasField('ExtendedHasOneRelationshipID'), 'hasField() finds extended foreign keys in subclass instances'); /* hasDatabaseField() singleton checks */ //$this->assertTrue($teamSingleton->hasDatabaseField('ID'), 'hasDatabaseField() finds built-in fields in singletons'); @@ -481,9 +481,9 @@ class DataObjectTest extends SapphireTest { $this->assertFalse($teamInstance->hasDatabaseField('SubclassDatabaseField'), 'hasDatabaseField() doesnt find subclass fields in parentclass instances'); //$this->assertFalse($teamInstance->hasDatabaseField('DynamicField'), 'hasDatabaseField() doesnt dynamic getters in instances'); $this->assertTrue($teamInstance->hasDatabaseField('HasOneRelationshipID'), 'hasDatabaseField() finds foreign keys in instances'); - $this->assertTrue($teamInstance->hasDatabaseField('DecoratedDatabaseField'), 'hasDatabaseField() finds decorated fields in instances'); - $this->assertTrue($teamInstance->hasDatabaseField('DecoratedHasOneRelationshipID'), 'hasDatabaseField() finds decorated foreign keys in instances'); - $this->assertFalse($teamInstance->hasDatabaseField('DecoratedDynamicField'), 'hasDatabaseField() doesnt include decorated dynamic getters in instances'); + $this->assertTrue($teamInstance->hasDatabaseField('ExtendedDatabaseField'), 'hasDatabaseField() finds extended fields in instances'); + $this->assertTrue($teamInstance->hasDatabaseField('ExtendedHasOneRelationshipID'), 'hasDatabaseField() finds extended foreign keys in instances'); + $this->assertFalse($teamInstance->hasDatabaseField('ExtendedDynamicField'), 'hasDatabaseField() doesnt include extended dynamic getters in instances'); /* hasDatabaseField() subclass checks */ $this->assertTrue($subteamInstance->hasField('DatabaseField'), 'hasField() finds custom fields in subclass instances'); @@ -507,12 +507,12 @@ class DataObjectTest extends SapphireTest { //'LastEdited', 'Title', 'DatabaseField', - 'DecoratedDatabaseField', + 'ExtendedDatabaseField', 'CaptainID', 'HasOneRelationshipID', - 'DecoratedHasOneRelationshipID' + 'ExtendedHasOneRelationshipID' ), - 'inheritedDatabaseFields() contains all fields defined on instance, including base fields, decorated fields and foreign keys' + 'inheritedDatabaseFields() contains all fields defined on instance, including base fields, extended fields and foreign keys' ); $this->assertEquals( @@ -524,12 +524,12 @@ class DataObjectTest extends SapphireTest { 'LastEdited', 'Title', 'DatabaseField', - 'DecoratedDatabaseField', + 'ExtendedDatabaseField', 'CaptainID', 'HasOneRelationshipID', - 'DecoratedHasOneRelationshipID' + 'ExtendedHasOneRelationshipID' ), - 'databaseFields() contains only fields defined on instance, including base fields, decorated fields and foreign keys' + 'databaseFields() contains only fields defined on instance, including base fields, extended fields and foreign keys' ); $this->assertEquals( @@ -542,12 +542,12 @@ class DataObjectTest extends SapphireTest { 'SubclassDatabaseField', 'Title', 'DatabaseField', - 'DecoratedDatabaseField', + 'ExtendedDatabaseField', 'CaptainID', 'HasOneRelationshipID', - 'DecoratedHasOneRelationshipID', + 'ExtendedHasOneRelationshipID', ), - 'inheritedDatabaseFields() on subclass contains all fields defined on instance, including base fields, decorated fields and foreign keys' + 'inheritedDatabaseFields() on subclass contains all fields defined on instance, including base fields, extended fields and foreign keys' ); $this->assertEquals( @@ -803,8 +803,8 @@ class DataObjectTest extends SapphireTest { "hasOwnDatabaseField() doesn't detect non-existend fields" ); $this->assertTrue( - $team->hasDatabaseField('DecoratedDatabaseField'), - "hasOwnDatabaseField() works with decorated fields" + $team->hasDatabaseField('ExtendedDatabaseField'), + "hasOwnDatabaseField() works with extended fields" ); $this->assertFalse( $team->hasDatabaseField('SubclassDatabaseField'), @@ -1087,21 +1087,21 @@ class DataObjectTest_FieldlessSubTable extends DataObjectTest_Team implements Te } -class DataObjectTest_Team_Decorator extends DataObjectDecorator implements TestOnly { +class DataObjectTest_Team_Extension extends DataExtension implements TestOnly { function extraStatics() { return array( 'db' => array( - 'DecoratedDatabaseField' => 'Varchar' + 'ExtendedDatabaseField' => 'Varchar' ), 'has_one' => array( - 'DecoratedHasOneRelationship' => 'DataObjectTest_Player' + 'ExtendedHasOneRelationship' => 'DataObjectTest_Player' ) ); } - function getDecoratedDynamicField() { - return "decorated dynamic field"; + function getExtendedDynamicField() { + return "extended dynamic field"; } } @@ -1159,6 +1159,6 @@ class DataObjectTest_TeamComment extends DataObject { ); } -DataObject::add_extension('DataObjectTest_Team', 'DataObjectTest_Team_Decorator'); +DataObject::add_extension('DataObjectTest_Team', 'DataObjectTest_Team_Extension'); ?> diff --git a/tests/model/DataObjectTest.yml b/tests/model/DataObjectTest.yml index 9e313f7f0..541dc8e50 100644 --- a/tests/model/DataObjectTest.yml +++ b/tests/model/DataObjectTest.yml @@ -23,11 +23,11 @@ DataObjectTest_SubTeam: subteam1: Title: Subteam 1 SubclassDatabaseField: Subclassed 1 - DecoratedDatabaseField: Decorated 1 + ExtendedDatabaseField: Extended 1 subteam2_with_player_relation: Title: Subteam 2 SubclassDatabaseField: Subclassed 2 - DecoratedHasOneRelationship: =>DataObjectTest_Player.player1 + ExtendedHasOneRelationship: =>DataObjectTest_Player.player1 subteam3_with_empty_fields: Title: Subteam 3 diff --git a/tests/security/MemberTest.php b/tests/security/MemberTest.php index aa137c76b..36e07d18c 100644 --- a/tests/security/MemberTest.php +++ b/tests/security/MemberTest.php @@ -457,7 +457,7 @@ class MemberTest extends FunctionalTest { $this->session()->inst_set('loggedInAs', null); } - public function testDecoratedCan() { + public function testExtendedCan() { $extensions = $this->removeExtensions(Object::get_extensions('Member')); $member = $this->objFromFixture('Member', 'test'); @@ -466,7 +466,7 @@ class MemberTest extends FunctionalTest { $this->assertFalse($member->canDelete()); $this->assertFalse($member->canEdit()); - /* Apply a decorator that allows viewing in any case (most likely the case for member profiles) */ + /* Apply a extension that allows viewing in any case (most likely the case for member profiles) */ Object::add_extension('Member', 'MemberTest_ViewingAllowedExtension'); $member2 = $this->objFromFixture('Member', 'staffmember'); @@ -474,7 +474,7 @@ class MemberTest extends FunctionalTest { $this->assertFalse($member2->canDelete()); $this->assertFalse($member2->canEdit()); - /* Apply a decorator that denies viewing of the Member */ + /* Apply a extension that denies viewing of the Member */ Object::remove_extension('Member', 'MemberTest_ViewingAllowedExtension'); Object::add_extension('Member', 'MemberTest_ViewingDeniedExtension'); $member3 = $this->objFromFixture('Member', 'managementmember'); @@ -483,7 +483,7 @@ class MemberTest extends FunctionalTest { $this->assertFalse($member3->canDelete()); $this->assertFalse($member3->canEdit()); - /* Apply a decorator that allows viewing and editing but denies deletion */ + /* Apply a extension that allows viewing and editing but denies deletion */ Object::remove_extension('Member', 'MemberTest_ViewingDeniedExtension'); Object::add_extension('Member', 'MemberTest_EditingAllowedDeletingDeniedExtension'); $member4 = $this->objFromFixture('Member', 'accountingmember'); @@ -589,21 +589,21 @@ class MemberTest extends FunctionalTest { } } -class MemberTest_ViewingAllowedExtension extends DataObjectDecorator implements TestOnly { +class MemberTest_ViewingAllowedExtension extends DataExtension implements TestOnly { public function canView() { return true; } } -class MemberTest_ViewingDeniedExtension extends DataObjectDecorator implements TestOnly { +class MemberTest_ViewingDeniedExtension extends DataExtension implements TestOnly { public function canView() { return false; } } -class MemberTest_EditingAllowedDeletingDeniedExtension extends DataObjectDecorator implements TestOnly { +class MemberTest_EditingAllowedDeletingDeniedExtension extends DataExtension implements TestOnly { public function canView() { return true; diff --git a/view/SSTemplateParser.php b/view/SSTemplateParser.php index 29d85fb80..a0ec2c9c2 100644 --- a/view/SSTemplateParser.php +++ b/view/SSTemplateParser.php @@ -2924,7 +2924,7 @@ class SSTemplateParser extends Parser { * 'Arguments' an array of the Argument match rule result arrays * * Once a block has successfully been matched against, it will then look for the actual handler, which should - * be on this class (either defined or decorated on) as ClosedBlock_Handler_Name(&$res), where Name is the + * be on this class (either defined or extended on) as ClosedBlock_Handler_Name(&$res), where Name is the * tag name, first letter captialized (i.e Control, Loop, With, etc). * * This function will be called with the match rule result array as it's first argument. It should return diff --git a/view/SSTemplateParser.php.inc b/view/SSTemplateParser.php.inc index a2d6d6c55..47fdca217 100644 --- a/view/SSTemplateParser.php.inc +++ b/view/SSTemplateParser.php.inc @@ -601,7 +601,7 @@ class SSTemplateParser extends Parser { * 'Arguments' an array of the Argument match rule result arrays * * Once a block has successfully been matched against, it will then look for the actual handler, which should - * be on this class (either defined or decorated on) as ClosedBlock_Handler_Name(&$res), where Name is the + * be on this class (either defined or extended on) as ClosedBlock_Handler_Name(&$res), where Name is the * tag name, first letter captialized (i.e Control, Loop, With, etc). * * This function will be called with the match rule result array as it's first argument. It should return