Version: current

      1 <?php
      2 /**
      3  * Plug-ins for additional functionality in your DataObjects.
      4  *
      5  * Note: DataObjectDecorators are not actually Decorators in the GoF Design Patterns sense of the
      6  * word.  A better name for this class would be DataExtension.  However, in the interests of
      7  * backward compatibility we haven't renamed the class.
      8  *
      9  * @package sapphire
     10  * @subpackage model
     11  */
     12 abstract class DataObjectDecorator extends Extension {
     13
     14     /**
     15      * Statics on a {@link DataObject} subclass
     16      * which can be decorated onto. This list is
     17      * limited for security and performance reasons.
     18      *
     19      * Keys are the static names, and the values are whether or not the value is an array that should
     20      * be merged.
     21      *
     22      * @var array
     23      */
     24     protected static $decoratable_statics = array(
     25         'db' => true,
     26         'has_one' => true,
     27         'belongs_to' => true,
     28         'indexes' => true,
     29         'defaults' => true,
     30         'has_many' => true,
     31         'many_many' => true,
     32         'belongs_many_many' => true,
     33         'many_many_extraFields' => true,
     34         'searchable_fields' => true,
     35         'api_access' => false,
     36     );
     37
     38     private static $extra_statics_loaded = array();
     39
     40     /**
     41      * Load the extra static definitions for the given extension
     42      * class name, called by {@link Object::add_extension()}
     43      *
     44      * @param string $class Class name of the owner class (or owner base class)
     45      * @param string $extension Class name of the extension class
     46      */
     47     public static function load_extra_statics($class, $extension) {
     48         if(!empty(self::$extra_statics_loaded[$class][$extension])) return;
     49         self::$extra_statics_loaded[$class][$extension] = true;
     50
     51         if(preg_match('/^([^(]*)/', $extension, $matches)) {
     52             $extensionClass = $matches[1];
     53         } else {
     54             user_error("Bad extenion '$extension' - can't find classname", E_USER_WARNING);
     55             return;
     56         }
     57
     58         // @deprecated 2.4 - use extraStatics() now, not extraDBFields()
     59         if(method_exists($extensionClass, 'extraDBFields')) {
     60             user_error('DataObjectDecorator::extraDBFields() is deprecated. Please use extraStatics() instead.', E_USER_NOTICE);
     61             $extraStaticsMethod = 'extraDBFields';
     62         } else {
     63             $extraStaticsMethod = 'extraStatics';
     64         }
     65
     66         // If the extension has been manually applied to a subclass, we should ignore that.
     67         if(Object::has_extension(get_parent_class($class), $extensionClass)) return;
     68
     69         $statics = call_user_func(array($extensionClass, $extraStaticsMethod), $class, $extension);
     70
     71         if($statics) {
     72             foreach($statics as $name => $newVal) {
     73                 if(isset(self::$decoratable_statics[$name])) {
     74
     75                     // Array to be merged
     76                     if(self::$decoratable_statics[$name]) {
     77                         $origVal = Object::uninherited_static($class, $name);
     78                         // Can't use add_static_var() here as it would merge the array rather than replacing
     79                         Object::set_static($class, $name, array_merge((array)$origVal, $newVal));
     80
     81                         // Value to be overwritten
     82                     } else {
     83                         Object::set_static($class, $name, $newVal);
     84                     }
     85                 }
     86             }
     87
     88             DataObject::$cache_has_own_table[$class]       = null;
     89             DataObject::$cache_has_own_table_field[$class] = null;
     90         }
     91     }
     92
     93     /**
     94      * Edit the given query object to support queries for this extension
     95      *
     96      * @param SQLQuery $query Query to augment.
     97      */
     98     function augmentSQL(SQLQuery &$query) {
     99     }
    100
    101     /**
    102      * Update the database schema as required by this extension.
    103      */
    104     function augmentDatabase() {
    105     }
    106
    107     /**
    108      * Augment a write-record request.
    109      *
    110      * @param SQLQuery $manipulation Query to augment.
    111      */
    112     function augmentWrite(&$manipulation) {
    113     }
    114
    115     function onBeforeWrite() {
    116     }
    117
    118     function onAfterWrite() {
    119     }
    120
    121     function onBeforeDelete() {
    122     }
    123
    124     function onAfterDelete() {
    125     }
    126
    127     function requireDefaultRecords() {
    128     }
    129
    130     function populateDefaults() {
    131     }
    132
    133     function can($member) {
    134     }
    135
    136     function canEdit($member) {
    137     }
    138
    139     function canDelete($member) {
    140     }
    141
    142     function canCreate($member) {
    143     }
    144
    145     /**
    146      * Define extra database fields
    147      *
    148      * Return a map where the keys are db, has_one, etc, and the values are
    149      * additional fields/relations to be defined.
    150      *
    151      * @return array Returns a map where the keys are db, has_one, etc, and
    152      *               the values are additional fields/relations to be defined.
    153      */
    154     function extraStatics() {
    155         return array();
    156     }
    157
    158     /**
    159      * This function is used to provide modifications to the form in the CMS
    160      * by the decorator. By default, no changes are made. {@link DataObject->getCMSFields()}.
    161      *
    162      * Please consider using {@link updateFormFields()} to globally add
    163      * formfields to the record. The method {@link updateCMSFields()}
    164      * should just be used to add or modify tabs, or fields which
    165      * are specific to the CMS-context.
    166      *
    167      * Caution: Use {@link FieldSet->addFieldToTab()} to add fields.
    168      *
    169      * @param FieldSet $fields FieldSet with a contained TabSet
    170      */
    171     function updateCMSFields(FieldSet &$fields) {
    172     }
    173
    174     /**
    175      * This function is used to provide modifications to the form used
    176      * for front end forms. {@link DataObject->getFrontEndFields()}
    177      *
    178      * Caution: Use {@link FieldSet->push()} to add fields.
    179      *
    180      * @param FieldSet $fields FieldSet without TabSet nesting
    181      */
    182     function updateFrontEndFields(FieldSet &$fields) {
    183     }
    184
    185     /**
    186      * This is used to provide modifications to the form actions
    187      * used in the CMS. {@link DataObject->getCMSActions()}.
    188      *
    189      * @param FieldSet $actions FieldSet
    190      */
    191     function updateCMSActions(FieldSet &$actions) {
    192     }
    193
    194     /**
    195      * this function is used to provide modifications to the summary fields in CMS
    196      * by the decorator
    197      * By default, the summaryField() of its owner will merge more fields defined in the decorator's
    198      * $extra_fields['summary_fields']
    199      */
    200     function updateSummaryFields(&$fields){
    201         $extra_fields = $this->extraStatics();
    202         if(isset($extra_fields['summary_fields'])){
    203             $summary_fields = $extra_fields['summary_fields'];
    204
    205             // if summary_fields were passed in numeric array,
    206             // convert to an associative array
    207             if($summary_fields && array_key_exists(0, $summary_fields)) {
    208                 $summary_fields = array_combine(array_values($summary_fields), array_values($summary_fields));
    209             }
    210             if($summary_fields) $fields = array_merge($fields, $summary_fields);
    211         }
    212     }
    213
    214     /**
    215      * this function is used to provide modifications to the fields labels in CMS
    216      * by the decorator
    217      * By default, the fieldLabels() of its owner will merge more fields defined in the decorator's
    218      * $extra_fields['field_labels']
    219      */
    220     function updateFieldLabels(&$lables){
    221         $extra_fields = $this->extraStatics();
    222         if(isset($extra_fields['field_labels'])){
    223             $field_labels = $extra_fields['field_labels'];
    224             if($field_labels) $lables = array_merge($lables, $field_labels);
    225         }
    226     }
    227
    228     /**
    229      * Clear any internal caches.
    230      */
    231     function flushCache() {
    232     }
    233
    234 }
    235 ?>
    236

[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the Silverstripe Forums to ask development related questions. -