| 1 |  |  | <?php | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  | namespace SilverStripe\ORM; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  | use BadMethodCallException; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  | use Exception; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  | use InvalidArgumentException; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  | use LogicException; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  | use SilverStripe\Control\HTTP; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  | use SilverStripe\Core\ClassInfo; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  | use SilverStripe\Core\Config\Config; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 |  |  | use SilverStripe\Core\Injector\Injector; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 13 |  |  | use SilverStripe\Core\Resettable; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 14 |  |  | use SilverStripe\Dev\Debug; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 15 |  |  | use SilverStripe\Dev\Deprecation; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 16 |  |  | use SilverStripe\Forms\FieldList; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 17 |  |  | use SilverStripe\Forms\FormField; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 18 |  |  | use SilverStripe\Forms\FormScaffolder; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 19 |  |  | use SilverStripe\i18n\i18n; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 20 |  |  | use SilverStripe\i18n\i18nEntityProvider; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 21 |  |  | use SilverStripe\ORM\Connect\MySQLSchemaManager; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 22 |  |  | use SilverStripe\ORM\FieldType\DBClassName; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 23 |  |  | use SilverStripe\ORM\FieldType\DBComposite; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 24 |  |  | use SilverStripe\ORM\FieldType\DBDatetime; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 25 |  |  | use SilverStripe\ORM\FieldType\DBField; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 26 |  |  | use SilverStripe\ORM\Filters\SearchFilter; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 27 |  |  | use SilverStripe\ORM\Queries\SQLDelete; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 28 |  |  | use SilverStripe\ORM\Queries\SQLInsert; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 29 |  |  | use SilverStripe\ORM\Search\SearchContext; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 30 |  |  | use SilverStripe\Security\Member; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 31 |  |  | use SilverStripe\Security\Permission; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 32 |  |  | use SilverStripe\Security\Security; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 33 |  |  | use SilverStripe\View\SSViewer; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 34 |  |  | use SilverStripe\View\ViewableData; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 35 |  |  | use stdClass; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 36 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 37 |  |  | /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 38 |  |  |  * A single database record & abstract class for the data-access-model. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 39 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 40 |  |  |  * <h2>Extensions</h2> | 
            
                                                                                                            
                            
            
                                    
            
            
                | 41 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 42 |  |  |  * See {@link Extension} and {@link DataExtension}. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 43 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 44 |  |  |  * <h2>Permission Control</h2> | 
            
                                                                                                            
                            
            
                                    
            
            
                | 45 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 46 |  |  |  * Object-level access control by {@link Permission}. Permission codes are arbitrary | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 |  |  |  * strings which can be selected on a group-by-group basis. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 |  |  |  * <code> | 
            
                                                                                                            
                            
            
                                    
            
            
                | 50 |  |  |  * class Article extends DataObject implements PermissionProvider { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 51 |  |  |  *  static $api_access = true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 52 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 53 |  |  |  *  function canView($member = false) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 54 |  |  |  *    return Permission::check('ARTICLE_VIEW'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 55 |  |  |  *  } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 56 |  |  |  *  function canEdit($member = false) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 57 |  |  |  *    return Permission::check('ARTICLE_EDIT'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 58 |  |  |  *  } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 59 |  |  |  *  function canDelete() { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 60 |  |  |  *    return Permission::check('ARTICLE_DELETE'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 61 |  |  |  *  } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 62 |  |  |  *  function canCreate() { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 63 |  |  |  *    return Permission::check('ARTICLE_CREATE'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 64 |  |  |  *  } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 65 |  |  |  *  function providePermissions() { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 66 |  |  |  *    return array( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 67 |  |  |  *      'ARTICLE_VIEW' => 'Read an article object', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 68 |  |  |  *      'ARTICLE_EDIT' => 'Edit an article object', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 69 |  |  |  *      'ARTICLE_DELETE' => 'Delete an article object', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 70 |  |  |  *      'ARTICLE_CREATE' => 'Create an article object', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 71 |  |  |  *    ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 72 |  |  |  *  } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 73 |  |  |  * } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 74 |  |  |  * </code> | 
            
                                                                                                            
                            
            
                                    
            
            
                | 75 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 76 |  |  |  * Object-level access control by {@link Group} membership: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 77 |  |  |  * <code> | 
            
                                                                                                            
                            
            
                                    
            
            
                | 78 |  |  |  * class Article extends DataObject { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 79 |  |  |  *   static $api_access = true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 80 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 81 |  |  |  *   function canView($member = false) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 82 |  |  |  *     if(!$member) $member = Security::getCurrentUser(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 83 |  |  |  *     return $member->inGroup('Subscribers'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 84 |  |  |  *   } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 85 |  |  |  *   function canEdit($member = false) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 86 |  |  |  *     if(!$member) $member = Security::getCurrentUser(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 87 |  |  |  *     return $member->inGroup('Editors'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 88 |  |  |  *   } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 89 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 90 |  |  |  *   // ... | 
            
                                                                                                            
                            
            
                                    
            
            
                | 91 |  |  |  * } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 92 |  |  |  * </code> | 
            
                                                                                                            
                            
            
                                    
            
            
                | 93 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 94 |  |  |  * If any public method on this class is prefixed with an underscore, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 95 |  |  |  * the results are cached in memory through {@link cachedCall()}. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 96 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 97 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 98 |  |  |  * @todo Add instance specific removeExtension() which undos loadExtraStatics() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 99 |  |  |  *  and defineMethods() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 100 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 101 |  |  |  * @property int $ID ID of the DataObject, 0 if the DataObject doesn't exist in database. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 102 |  |  |  * @property int $OldID ID of object, if deleted | 
            
                                                                                                            
                            
            
                                    
            
            
                | 103 |  |  |  * @property string $Title | 
            
                                                                                                            
                            
            
                                    
            
            
                | 104 |  |  |  * @property string $ClassName Class name of the DataObject | 
            
                                                                                                            
                            
            
                                    
            
            
                | 105 |  |  |  * @property string $LastEdited Date and time of DataObject's last modification. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 106 |  |  |  * @property string $Created Date and time of DataObject creation. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 107 |  |  |  */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 108 |  |  | class DataObject extends ViewableData implements DataObjectInterface, i18nEntityProvider, Resettable | 
            
                                                                                                            
                            
            
                                    
            
            
                | 109 |  |  | { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 110 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 111 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 112 |  |  |      * Human-readable singular name. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 113 |  |  |      * @var string | 
            
                                                                                                            
                            
            
                                    
            
            
                | 114 |  |  |      * @config | 
            
                                                                                                            
                            
            
                                    
            
            
                | 115 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 116 |  |  |     private static $singular_name = null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 117 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 118 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 119 |  |  |      * Human-readable plural name | 
            
                                                                                                            
                            
            
                                    
            
            
                | 120 |  |  |      * @var string | 
            
                                                                                                            
                            
            
                                    
            
            
                | 121 |  |  |      * @config | 
            
                                                                                                            
                            
            
                                    
            
            
                | 122 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 123 |  |  |     private static $plural_name = null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 124 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 125 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 126 |  |  |      * Allow API access to this object? | 
            
                                                                                                            
                            
            
                                    
            
            
                | 127 |  |  |      * @todo Define the options that can be set here | 
            
                                                                                                            
                            
            
                                    
            
            
                | 128 |  |  |      * @config | 
            
                                                                                                            
                            
            
                                    
            
            
                | 129 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 130 |  |  |     private static $api_access = false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 131 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 132 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 133 |  |  |      * Allows specification of a default value for the ClassName field. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 134 |  |  |      * Configure this value only in subclasses of DataObject. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 135 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 136 |  |  |      * @config | 
            
                                                                                                            
                            
            
                                    
            
            
                | 137 |  |  |      * @var string | 
            
                                                                                                            
                            
            
                                    
            
            
                | 138 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 139 |  |  |     private static $default_classname = null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 140 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 141 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 142 |  |  |      * @deprecated 4.0..5.0 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 143 |  |  |      * @var bool | 
            
                                                                                                            
                            
            
                                    
            
            
                | 144 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 145 |  |  |     public $destroyed = false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 146 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 147 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 148 |  |  |      * Data stored in this objects database record. An array indexed by fieldname. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 149 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 150 |  |  |      * Use {@link toMap()} if you want an array representation | 
            
                                                                                                            
                            
            
                                    
            
            
                | 151 |  |  |      * of this object, as the $record array might contain lazy loaded field aliases. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 152 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 153 |  |  |      * @var array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 154 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 155 |  |  |     protected $record; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 156 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 157 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 158 |  |  |      * If selected through a many_many through relation, this is the instance of the through record | 
            
                                                                                                            
                            
            
                                    
            
            
                | 159 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 160 |  |  |      * @var DataObject | 
            
                                                                                                            
                            
            
                                    
            
            
                | 161 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 162 |  |  |     protected $joinRecord; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 163 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 164 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 165 |  |  |      * Represents a field that hasn't changed (before === after, thus before == after) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 166 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 167 |  |  |     const CHANGE_NONE = 0; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 168 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 169 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 170 |  |  |      * Represents a field that has changed type, although not the loosely defined value. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 171 |  |  |      * (before !== after && before == after) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 172 |  |  |      * E.g. change 1 to true or "true" to true, but not true to 0. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 173 |  |  |      * Value changes are by nature also considered strict changes. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 174 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 175 |  |  |     const CHANGE_STRICT = 1; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 176 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 177 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 178 |  |  |      * Represents a field that has changed the loosely defined value | 
            
                                                                                                            
                            
            
                                    
            
            
                | 179 |  |  |      * (before != after, thus, before !== after)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 180 |  |  |      * E.g. change false to true, but not false to 0 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 181 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 182 |  |  |     const CHANGE_VALUE = 2; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 183 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 184 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 185 |  |  |      * An array indexed by fieldname, true if the field has been changed. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 186 |  |  |      * Use {@link getChangedFields()} and {@link isChanged()} to inspect | 
            
                                                                                                            
                            
            
                                    
            
            
                | 187 |  |  |      * the changed state. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 188 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 189 |  |  |      * @var array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 190 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 191 |  |  |     private $changed; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 192 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 193 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 194 |  |  |      * The database record (in the same format as $record), before | 
            
                                                                                                            
                            
            
                                    
            
            
                | 195 |  |  |      * any changes. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 196 |  |  |      * @var array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 197 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 198 |  |  |     protected $original; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 199 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 200 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 201 |  |  |      * Used by onBeforeDelete() to ensure child classes call parent::onBeforeDelete() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 202 |  |  |      * @var boolean | 
            
                                                                                                            
                            
            
                                    
            
            
                | 203 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 204 |  |  |     protected $brokenOnDelete = false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 205 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 206 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 207 |  |  |      * Used by onBeforeWrite() to ensure child classes call parent::onBeforeWrite() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 208 |  |  |      * @var boolean | 
            
                                                                                                            
                            
            
                                    
            
            
                | 209 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 210 |  |  |     protected $brokenOnWrite = false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 211 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 212 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 213 |  |  |      * @config | 
            
                                                                                                            
                            
            
                                    
            
            
                | 214 |  |  |      * @var boolean Should dataobjects be validated before they are written? | 
            
                                                                                                            
                            
            
                                    
            
            
                | 215 |  |  |      * Caution: Validation can contain safeguards against invalid/malicious data, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 216 |  |  |      * and check permission levels (e.g. on {@link Group}). Therefore it is recommended | 
            
                                                                                                            
                            
            
                                    
            
            
                | 217 |  |  |      * to only disable validation for very specific use cases. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 218 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 219 |  |  |     private static $validation_enabled = true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 220 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 221 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 222 |  |  |      * Static caches used by relevant functions. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 223 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 224 |  |  |      * @var array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 225 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 226 |  |  |     protected static $_cache_get_one; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 227 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 228 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 229 |  |  |      * Cache of field labels | 
            
                                                                                                            
                            
            
                                    
            
            
                | 230 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 231 |  |  |      * @var array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 232 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 233 |  |  |     protected static $_cache_field_labels = array(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 234 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 235 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 236 |  |  |      * Base fields which are not defined in static $db | 
            
                                                                                                            
                            
            
                                    
            
            
                | 237 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 238 |  |  |      * @config | 
            
                                                                                                            
                            
            
                                    
            
            
                | 239 |  |  |      * @var array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 240 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 241 |  |  |     private static $fixed_fields = array( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 242 |  |  |         'ID' => 'PrimaryKey', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 243 |  |  |         'ClassName' => 'DBClassName', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 244 |  |  |         'LastEdited' => 'DBDatetime', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 245 |  |  |         'Created' => 'DBDatetime', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 246 |  |  |     ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 247 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 248 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 249 |  |  |      * Override table name for this class. If ignored will default to FQN of class. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 250 |  |  |      * This option is not inheritable, and must be set on each class. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 251 |  |  |      * If left blank naming will default to the legacy (3.x) behaviour. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 252 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 253 |  |  |      * @var string | 
            
                                                                                                            
                            
            
                                    
            
            
                | 254 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 255 |  |  |     private static $table_name = null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 256 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 257 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 258 |  |  |      * Non-static relationship cache, indexed by component name. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 259 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 260 |  |  |      * @var DataObject[] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 261 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 262 |  |  |     protected $components = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 263 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 264 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 265 |  |  |      * Non-static cache of has_many and many_many relations that can't be written until this object is saved. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 266 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 267 |  |  |      * @var UnsavedRelationList[] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 268 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 269 |  |  |     protected $unsavedRelations; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 270 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 271 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 272 |  |  |      * List of relations that should be cascade deleted, similar to `owns` | 
            
                                                                                                            
                            
            
                                    
            
            
                | 273 |  |  |      * Note: This will trigger delete on many_many objects, not only the mapping table. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 274 |  |  |      * For many_many through you can specify the components you want to delete separately | 
            
                                                                                                            
                            
            
                                    
            
            
                | 275 |  |  |      * (many_many or has_many sub-component) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 276 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 277 |  |  |      * @config | 
            
                                                                                                            
                            
            
                                    
            
            
                | 278 |  |  |      * @var array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 279 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 280 |  |  |     private static $cascade_deletes = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 281 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 282 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 283 |  |  |      * List of relations that should be cascade duplicate. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 284 |  |  |      * many_many duplications are shallow only. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 285 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 286 |  |  |      * Note: If duplicating a many_many through you should refer to the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 287 |  |  |      * has_many intermediary relation instead, otherwise extra fields | 
            
                                                                                                            
                            
            
                                    
            
            
                | 288 |  |  |      * will be omitted from the duplicated relation. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 289 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 290 |  |  |      * @var array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 291 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 292 |  |  |     private static $cascade_duplicates = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 293 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 294 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 295 |  |  |      * Get schema object | 
            
                                                                                                            
                            
            
                                    
            
            
                | 296 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 297 |  |  |      * @return DataObjectSchema | 
            
                                                                                                            
                            
            
                                    
            
            
                | 298 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 299 |  |  |     public static function getSchema() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 300 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 301 |  |  |         return Injector::inst()->get(DataObjectSchema::class); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 302 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 303 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 304 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 305 |  |  |      * Construct a new DataObject. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 306 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 307 |  |  |      * @param array|null $record Used internally for rehydrating an object from database content. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 308 |  |  |      *                           Bypasses setters on this class, and hence should not be used | 
            
                                                                                                            
                            
            
                                    
            
            
                | 309 |  |  |      *                           for populating data on new records. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 310 |  |  |      * @param boolean $isSingleton This this to true if this is a singleton() object, a stub for calling methods. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 311 |  |  |      *                             Singletons don't have their defaults set. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 312 |  |  |      * @param array $queryParams List of DataQuery params necessary to lazy load, or load related objects. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 313 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 314 |  |  |     public function __construct($record = null, $isSingleton = false, $queryParams = array()) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 315 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 316 |  |  |         parent::__construct(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 317 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 318 |  |  |         // Set query params on the DataObject to tell the lazy loading mechanism the context the object creation context | 
            
                                                                                                            
                            
            
                                    
            
            
                | 319 |  |  |         $this->setSourceQueryParams($queryParams); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 320 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 321 |  |  |         // Set the fields data. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 322 |  |  |         if (!$record) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 323 |  |  |             $record = array( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 324 |  |  |                 'ID' => 0, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 325 |  |  |                 'ClassName' => static::class, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 326 |  |  |                 'RecordClassName' => static::class | 
            
                                                                                                            
                            
            
                                    
            
            
                | 327 |  |  |             ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 328 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 329 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 330 |  |  |         if ($record instanceof stdClass) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 331 |  |  |             $record = (array)$record; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 332 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 333 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 334 |  |  |         if (!is_array($record)) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 335 |  |  |             if (is_object($record)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 336 |  |  |                 $passed = "an object of type '" . get_class($record) . "'"; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 337 |  |  |             } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 338 |  |  |                 $passed = "The value '$record'"; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 339 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 340 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 341 |  |  |             user_error( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 342 |  |  |                 "DataObject::__construct passed $passed.  It's supposed to be passed an array," | 
            
                                                                                                            
                            
            
                                    
            
            
                | 343 |  |  |                 . " taken straight from the database.  Perhaps you should use DataList::create()->First(); instead?", | 
            
                                                                                                            
                            
            
                                    
            
            
                | 344 |  |  |                 E_USER_WARNING | 
            
                                                                                                            
                            
            
                                    
            
            
                | 345 |  |  |             ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 346 |  |  |             $record = null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 347 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 348 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 349 |  |  |         // Set $this->record to $record, but ignore NULLs | 
            
                                                                                                            
                            
            
                                    
            
            
                | 350 |  |  |         $this->record = array(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 351 |  |  |         foreach ($record as $k => $v) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 352 |  |  |             // Ensure that ID is stored as a number and not a string | 
            
                                                                                                            
                            
            
                                    
            
            
                | 353 |  |  |             // To do: this kind of clean-up should be done on all numeric fields, in some relatively | 
            
                                                                                                            
                            
            
                                    
            
            
                | 354 |  |  |             // performant manner | 
            
                                                                                                            
                            
            
                                    
            
            
                | 355 |  |  |             if ($v !== null) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 356 |  |  |                 if ($k == 'ID' && is_numeric($v)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 357 |  |  |                     $this->record[$k] = (int)$v; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 358 |  |  |                 } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 359 |  |  |                     $this->record[$k] = $v; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 360 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 361 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 362 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 363 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 364 |  |  |         // Identify fields that should be lazy loaded, but only on existing records | 
            
                                                                                                            
                            
            
                                    
            
            
                | 365 |  |  |         if (!empty($record['ID'])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 366 |  |  |             // Get all field specs scoped to class for later lazy loading | 
            
                                                                                                            
                            
            
                                    
            
            
                | 367 |  |  |             $fields = static::getSchema()->fieldSpecs( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 368 |  |  |                 static::class, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 369 |  |  |                 DataObjectSchema::INCLUDE_CLASS | DataObjectSchema::DB_ONLY | 
            
                                                                                                            
                            
            
                                    
            
            
                | 370 |  |  |             ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 371 |  |  |             foreach ($fields as $field => $fieldSpec) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 372 |  |  |                 $fieldClass = strtok($fieldSpec, "."); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 373 |  |  |                 if (!array_key_exists($field, $record)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 374 |  |  |                     $this->record[$field . '_Lazy'] = $fieldClass; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 375 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 376 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 377 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 378 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 379 |  |  |         $this->original = $this->record; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 380 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 381 |  |  |         // Keep track of the modification date of all the data sourced to make this page | 
            
                                                                                                            
                            
            
                                    
            
            
                | 382 |  |  |         // From this we create a Last-Modified HTTP header | 
            
                                                                                                            
                            
            
                                    
            
            
                | 383 |  |  |         if (isset($record['LastEdited'])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 384 |  |  |             HTTP::register_modification_date($record['LastEdited']); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 385 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 386 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 387 |  |  |         // Must be called after parent constructor | 
            
                                                                                                            
                            
            
                                    
            
            
                | 388 |  |  |         if (!$isSingleton && (!isset($this->record['ID']) || !$this->record['ID'])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 389 |  |  |             $this->populateDefaults(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 390 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 391 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 392 |  |  |         // prevent populateDefaults() and setField() from marking overwritten defaults as changed | 
            
                                                                                                            
                            
            
                                    
            
            
                | 393 |  |  |         $this->changed = array(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 394 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 395 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 396 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 397 |  |  |      * Destroy all of this objects dependant objects and local caches. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 398 |  |  |      * You'll need to call this to get the memory of an object that has components or extensions freed. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 399 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 400 |  |  |     public function destroy() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 401 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 402 |  |  |         $this->flushCache(false); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 403 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 404 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 405 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 406 |  |  |      * Create a duplicate of this node. Can duplicate many_many relations | 
            
                                                                                                            
                            
            
                                    
            
            
                | 407 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 408 |  |  |      * @param bool $doWrite Perform a write() operation before returning the object. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 409 |  |  |      * If this is true, it will create the duplicate in the database. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 410 |  |  |      * @param array|null|false $relations List of relations to duplicate. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 411 |  |  |      * Will default to `cascade_duplicates` if null. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 412 |  |  |      * Set to 'false' to force none. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 413 |  |  |      * Set to specific array of names to duplicate to override these. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 414 |  |  |      * Note: If using versioned, this will additionally failover to `owns` config. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 415 |  |  |      * @return static A duplicate of this node. The exact type will be the type of this node. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 416 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 417 |  |  |     public function duplicate($doWrite = true, $relations = null) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 418 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 419 |  |  |         // Handle legacy behaviour | 
            
                                                                                                            
                            
            
                                    
            
            
                | 420 |  |  |         if (is_string($relations) || $relations === true) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 421 |  |  |             if ($relations === true) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 422 |  |  |                 $relations = 'many_many'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 423 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 424 |  |  |             Deprecation::notice('5.0', 'Use cascade_duplicates config instead of providing a string to duplicate()'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 425 |  |  |             $relations = array_keys($this->config()->get($relations)) ?: []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 426 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 427 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 428 |  |  |         // Get duplicates | 
            
                                                                                                            
                            
            
                                    
            
            
                | 429 |  |  |         if ($relations === null) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 430 |  |  |             $relations = $this->config()->get('cascade_duplicates'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 431 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 432 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 433 |  |  |         // Create unsaved raw duplicate | 
            
                                                                                                            
                            
            
                                    
            
            
                | 434 |  |  |         $map = $this->toMap(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 435 |  |  |         unset($map['Created']); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 436 |  |  |         /** @var static $clone */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 437 |  |  |         $clone = Injector::inst()->create(static::class, $map, false, $this->getSourceQueryParams()); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 438 |  |  |         $clone->ID = 0; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 439 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 440 |  |  |         // Note: Extensions such as versioned may update $relations here | 
            
                                                                                                            
                            
            
                                    
            
            
                | 441 |  |  |         $clone->invokeWithExtensions('onBeforeDuplicate', $this, $doWrite, $relations); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 442 |  |  |         if ($relations) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 443 |  |  |             $this->duplicateRelations($this, $clone, $relations); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 444 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 445 |  |  |         if ($doWrite) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 446 |  |  |             $clone->write(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 447 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 448 |  |  |         $clone->invokeWithExtensions('onAfterDuplicate', $this, $doWrite, $relations); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 449 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 450 |  |  |         return $clone; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 451 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 452 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 453 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 454 |  |  |      * Copies the given relations from this object to the destination | 
            
                                                                                                            
                            
            
                                    
            
            
                | 455 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 456 |  |  |      * @param DataObject $sourceObject the source object to duplicate from | 
            
                                                                                                            
                            
            
                                    
            
            
                | 457 |  |  |      * @param DataObject $destinationObject the destination object to populate with the duplicated relations | 
            
                                                                                                            
                            
            
                                    
            
            
                | 458 |  |  |      * @param array $relations List of relations | 
            
                                                                                                            
                            
            
                                    
            
            
                | 459 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 460 |  |  |     protected function duplicateRelations($sourceObject, $destinationObject, $relations) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 461 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 462 |  |  |         // Get list of duplicable relation types | 
            
                                                                                                            
                            
            
                                    
            
            
                | 463 |  |  |         $manyMany = $sourceObject->manyMany(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 464 |  |  |         $hasMany = $sourceObject->hasMany(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 465 |  |  |         $hasOne = $sourceObject->hasOne(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 466 |  |  |         $belongsTo = $sourceObject->belongsTo(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 467 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 468 |  |  |         // Duplicate each relation based on type | 
            
                                                                                                            
                            
            
                                    
            
            
                | 469 |  |  |         foreach ($relations as $relation) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 470 |  |  |             switch (true) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 471 |  |  |                 case array_key_exists($relation, $manyMany): { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 472 |  |  |                     $this->duplicateManyManyRelation($sourceObject, $destinationObject, $relation); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 473 |  |  |                     break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 474 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 475 |  |  |                 case array_key_exists($relation, $hasMany): { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 476 |  |  |                     $this->duplicateHasManyRelation($sourceObject, $destinationObject, $relation); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 477 |  |  |                     break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 478 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 479 |  |  |                 case array_key_exists($relation, $hasOne): { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 480 |  |  |                     $this->duplicateHasOneRelation($sourceObject, $destinationObject, $relation); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 481 |  |  |                     break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 482 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 483 |  |  |                 case array_key_exists($relation, $belongsTo): { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 484 |  |  |                     $this->duplicateBelongsToRelation($sourceObject, $destinationObject, $relation); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 485 |  |  |                     break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 486 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 487 |  |  |                 default: { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 488 |  |  |                     $sourceType = get_class($sourceObject); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 489 |  |  |                     throw new InvalidArgumentException( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 490 |  |  |                         "Cannot duplicate unknown relation {$relation} on parent type {$sourceType}" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 491 |  |  |                     ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 492 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 493 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 494 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 495 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 496 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 497 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 498 |  |  |      * Copies the many_many and belongs_many_many relations from one object to another instance of the name of object. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 499 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 500 |  |  |      * @deprecated 4.1...5.0 Use duplicateRelations() instead | 
            
                                                                                                            
                            
            
                                    
            
            
                | 501 |  |  |      * @param DataObject $sourceObject the source object to duplicate from | 
            
                                                                                                            
                            
            
                                    
            
            
                | 502 |  |  |      * @param DataObject $destinationObject the destination object to populate with the duplicated relations | 
            
                                                                                                            
                            
            
                                    
            
            
                | 503 |  |  |      * @param bool|string $filter | 
            
                                                                                                            
                            
            
                                    
            
            
                | 504 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 505 |  |  |     protected function duplicateManyManyRelations($sourceObject, $destinationObject, $filter) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 506 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 507 |  |  |         Deprecation::notice('5.0', 'Use duplicateRelations() instead'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 508 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 509 |  |  |         // Get list of relations to duplicate | 
            
                                                                                                            
                            
            
                                    
            
            
                | 510 |  |  |         if ($filter === 'many_many' || $filter === 'belongs_many_many') { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 511 |  |  |             $relations = $sourceObject->config()->get($filter); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 512 |  |  |         } elseif ($filter === true) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 513 |  |  |             $relations = $sourceObject->manyMany(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 514 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 515 |  |  |             throw new InvalidArgumentException("Invalid many_many duplication filter"); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 516 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 517 |  |  |         foreach ($relations as $manyManyName => $type) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 518 |  |  |             $this->duplicateManyManyRelation($sourceObject, $destinationObject, $manyManyName); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 519 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 520 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 521 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 522 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 523 |  |  |      * Duplicates a single many_many relation from one object to another. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 524 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 525 |  |  |      * @param DataObject $sourceObject | 
            
                                                                                                            
                            
            
                                    
            
            
                | 526 |  |  |      * @param DataObject $destinationObject | 
            
                                                                                                            
                            
            
                                    
            
            
                | 527 |  |  |      * @param string $relation | 
            
                                                                                                            
                            
            
                                    
            
            
                | 528 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 529 |  |  |     protected function duplicateManyManyRelation($sourceObject, $destinationObject, $relation) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 530 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 531 |  |  |         // Copy all components from source to destination | 
            
                                                                                                            
                            
            
                                    
            
            
                | 532 |  |  |         $source = $sourceObject->getManyManyComponents($relation); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 533 |  |  |         $dest = $destinationObject->getManyManyComponents($relation); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 534 |  |  |         $extraFieldNames = $source->getExtraFields(); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 535 |  |  |         foreach ($source as $item) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 536 |  |  |             // Merge extra fields | 
            
                                                                                                            
                            
            
                                    
            
            
                | 537 |  |  |             $extraFields = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 538 |  |  |             foreach ($extraFieldNames as $fieldName => $fieldType) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 539 |  |  |                 $extraFields[$fieldName] = $item->getField($fieldName); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 540 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 541 |  |  |             $dest->add($item, $extraFields); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 542 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 543 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 544 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 545 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 546 |  |  |      * Duplicates a single many_many relation from one object to another. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 547 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 548 |  |  |      * @param DataObject $sourceObject | 
            
                                                                                                            
                            
            
                                    
            
            
                | 549 |  |  |      * @param DataObject $destinationObject | 
            
                                                                                                            
                            
            
                                    
            
            
                | 550 |  |  |      * @param string $relation | 
            
                                                                                                            
                            
            
                                    
            
            
                | 551 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 552 |  |  |     protected function duplicateHasManyRelation($sourceObject, $destinationObject, $relation) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 553 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 554 |  |  |         // Copy all components from source to destination | 
            
                                                                                                            
                            
            
                                    
            
            
                | 555 |  |  |         $source = $sourceObject->getComponents($relation); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 556 |  |  |         $dest = $destinationObject->getComponents($relation); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 557 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 558 |  |  |         /** @var DataObject $item */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 559 |  |  |         foreach ($source as $item) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 560 |  |  |             // Don't write on duplicate; Wait until ParentID is available later. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 561 |  |  |             // writeRelations() will eventually write these records when converting | 
            
                                                                                                            
                            
            
                                    
            
            
                | 562 |  |  |             // from UnsavedRelationList | 
            
                                                                                                            
                            
            
                                    
            
            
                | 563 |  |  |             $clonedItem = $item->duplicate(false); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 564 |  |  |             $dest->add($clonedItem); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 565 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 566 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 567 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 568 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 569 |  |  |      * Duplicates a single has_one relation from one object to another. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 570 |  |  |      * Note: Child object will be force written. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 571 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 572 |  |  |      * @param DataObject $sourceObject | 
            
                                                                                                            
                            
            
                                    
            
            
                | 573 |  |  |      * @param DataObject $destinationObject | 
            
                                                                                                            
                            
            
                                    
            
            
                | 574 |  |  |      * @param string $relation | 
            
                                                                                                            
                            
            
                                    
            
            
                | 575 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 576 |  |  |     protected function duplicateHasOneRelation($sourceObject, $destinationObject, $relation) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 577 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 578 |  |  |         // Check if original object exists | 
            
                                                                                                            
                            
            
                                    
            
            
                | 579 |  |  |         $item = $sourceObject->getComponent($relation); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 580 |  |  |         if (!$item->isInDB()) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 581 |  |  |             return; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 582 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 583 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 584 |  |  |         $clonedItem = $item->duplicate(false); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 585 |  |  |         $destinationObject->setComponent($relation, $clonedItem); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 586 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 587 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 588 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 589 |  |  |      * Duplicates a single belongs_to relation from one object to another. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 590 |  |  |      * Note: This will force a write on both parent / child objects. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 591 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 592 |  |  |      * @param DataObject $sourceObject | 
            
                                                                                                            
                            
            
                                    
            
            
                | 593 |  |  |      * @param DataObject $destinationObject | 
            
                                                                                                            
                            
            
                                    
            
            
                | 594 |  |  |      * @param string $relation | 
            
                                                                                                            
                            
            
                                    
            
            
                | 595 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 596 |  |  |     protected function duplicateBelongsToRelation($sourceObject, $destinationObject, $relation) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 597 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 598 |  |  |         // Check if original object exists | 
            
                                                                                                            
                            
            
                                    
            
            
                | 599 |  |  |         $item = $sourceObject->getComponent($relation); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 600 |  |  |         if (!$item->isInDB()) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 601 |  |  |             return; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 602 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 603 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 604 |  |  |         $clonedItem = $item->duplicate(false); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 605 |  |  |         $destinationObject->setComponent($relation, $clonedItem); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 606 |  |  |         // After $clonedItem is assigned the appropriate FieldID / FieldClass, force write | 
            
                                                                                                            
                            
            
                                    
            
            
                | 607 |  |  |         // @todo Write this component in onAfterWrite instead, assigning the FieldID then | 
            
                                                                                                            
                            
            
                                    
            
            
                | 608 |  |  |         // https://github.com/silverstripe/silverstripe-framework/issues/7818 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 609 |  |  |         $clonedItem->write(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 610 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 611 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 612 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 613 |  |  |      * Return obsolete class name, if this is no longer a valid class | 
            
                                                                                                            
                            
            
                                    
            
            
                | 614 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 615 |  |  |      * @return string | 
            
                                                                                                            
                            
            
                                    
            
            
                | 616 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 617 |  |  |     public function getObsoleteClassName() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 618 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 619 |  |  |         $className = $this->getField("ClassName"); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 620 |  |  |         if (!ClassInfo::exists($className)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 621 |  |  |             return $className; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 622 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 623 |  |  |         return null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 624 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 625 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 626 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 627 |  |  |      * Gets name of this class | 
            
                                                                                                            
                            
            
                                    
            
            
                | 628 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 629 |  |  |      * @return string | 
            
                                                                                                            
                            
            
                                    
            
            
                | 630 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 631 |  |  |     public function getClassName() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 632 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 633 |  |  |         $className = $this->getField("ClassName"); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 634 |  |  |         if (!ClassInfo::exists($className)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 635 |  |  |             return static::class; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 636 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 637 |  |  |         return $className; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 638 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 639 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 640 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 641 |  |  |      * Set the ClassName attribute. {@link $class} is also updated. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 642 |  |  |      * Warning: This will produce an inconsistent record, as the object | 
            
                                                                                                            
                            
            
                                    
            
            
                | 643 |  |  |      * instance will not automatically switch to the new subclass. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 644 |  |  |      * Please use {@link newClassInstance()} for this purpose, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 645 |  |  |      * or destroy and reinstanciate the record. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 646 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 647 |  |  |      * @param string $className The new ClassName attribute (a subclass of {@link DataObject}) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 648 |  |  |      * @return $this | 
            
                                                                                                            
                            
            
                                    
            
            
                | 649 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 650 |  |  |     public function setClassName($className) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 651 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 652 |  |  |         $className = trim($className); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 653 |  |  |         if (!$className || !is_subclass_of($className, self::class)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 654 |  |  |             return $this; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 655 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 656 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 657 |  |  |         $this->setField("ClassName", $className); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 658 |  |  |         $this->setField('RecordClassName', $className); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 659 |  |  |         return $this; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 660 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 661 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 662 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 663 |  |  |      * Create a new instance of a different class from this object's record. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 664 |  |  |      * This is useful when dynamically changing the type of an instance. Specifically, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 665 |  |  |      * it ensures that the instance of the class is a match for the className of the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 666 |  |  |      * record. Don't set the {@link DataObject->class} or {@link DataObject->ClassName} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 667 |  |  |      * property manually before calling this method, as it will confuse change detection. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 668 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 669 |  |  |      * If the new class is different to the original class, defaults are populated again | 
            
                                                                                                            
                            
            
                                    
            
            
                | 670 |  |  |      * because this will only occur automatically on instantiation of a DataObject if | 
            
                                                                                                            
                            
            
                                    
            
            
                | 671 |  |  |      * there is no record, or the record has no ID. In this case, we do have an ID but | 
            
                                                                                                            
                            
            
                                    
            
            
                | 672 |  |  |      * we still need to repopulate the defaults. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 673 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 674 |  |  |      * @param string $newClassName The name of the new class | 
            
                                                                                                            
                            
            
                                    
            
            
                | 675 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 676 |  |  |      * @return DataObject The new instance of the new class, The exact type will be of the class name provided. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 677 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 678 |  |  |     public function newClassInstance($newClassName) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 679 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 680 |  |  |         if (!is_subclass_of($newClassName, self::class)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 681 |  |  |             throw new InvalidArgumentException("$newClassName is not a valid subclass of DataObject"); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 682 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 683 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 684 |  |  |         $originalClass = $this->ClassName; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 685 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 686 |  |  |         /** @var DataObject $newInstance */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 687 |  |  |         $newInstance = Injector::inst()->create($newClassName, $this->record, false); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 688 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 689 |  |  |         // Modify ClassName | 
            
                                                                                                            
                            
            
                                    
            
            
                | 690 |  |  |         if ($newClassName != $originalClass) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 691 |  |  |             $newInstance->setClassName($newClassName); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 692 |  |  |             $newInstance->populateDefaults(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 693 |  |  |             $newInstance->forceChange(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 694 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 695 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 696 |  |  |         return $newInstance; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 697 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 698 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 699 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 700 |  |  |      * Adds methods from the extensions. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 701 |  |  |      * Called by Object::__construct() once per class. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 702 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 703 |  |  |     public function defineMethods() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 704 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 705 |  |  |         parent::defineMethods(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 706 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 707 |  |  |         if (static::class === self::class) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 708 |  |  |             return; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 709 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 710 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 711 |  |  |         // Set up accessors for joined items | 
            
                                                                                                            
                            
            
                                    
            
            
                | 712 |  |  |         if ($manyMany = $this->manyMany()) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 713 |  |  |             foreach ($manyMany as $relationship => $class) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 714 |  |  |                 $this->addWrapperMethod($relationship, 'getManyManyComponents'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 715 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 716 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 717 |  |  |         if ($hasMany = $this->hasMany()) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 718 |  |  |             foreach ($hasMany as $relationship => $class) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 719 |  |  |                 $this->addWrapperMethod($relationship, 'getComponents'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 720 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 721 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 722 |  |  |         if ($hasOne = $this->hasOne()) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 723 |  |  |             foreach ($hasOne as $relationship => $class) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 724 |  |  |                 $this->addWrapperMethod($relationship, 'getComponent'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 725 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 726 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 727 |  |  |         if ($belongsTo = $this->belongsTo()) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 728 |  |  |             foreach (array_keys($belongsTo) as $relationship) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 729 |  |  |                 $this->addWrapperMethod($relationship, 'getComponent'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 730 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 731 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 732 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 733 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 734 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 735 |  |  |      * Returns true if this object "exists", i.e., has a sensible value. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 736 |  |  |      * The default behaviour for a DataObject is to return true if | 
            
                                                                                                            
                            
            
                                    
            
            
                | 737 |  |  |      * the object exists in the database, you can override this in subclasses. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 738 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 739 |  |  |      * @return boolean true if this object exists | 
            
                                                                                                            
                            
            
                                    
            
            
                | 740 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 741 |  |  |     public function exists() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 742 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 743 |  |  |         return (isset($this->record['ID']) && $this->record['ID'] > 0); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 744 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 745 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 746 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 747 |  |  |      * Returns TRUE if all values (other than "ID") are | 
            
                                                                                                            
                            
            
                                    
            
            
                | 748 |  |  |      * considered empty (by weak boolean comparison). | 
            
                                                                                                            
                            
            
                                    
            
            
                | 749 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 750 |  |  |      * @return boolean | 
            
                                                                                                            
                            
            
                                    
            
            
                | 751 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 752 |  |  |     public function isEmpty() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 753 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 754 |  |  |         $fixed = DataObject::config()->uninherited('fixed_fields'); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 755 |  |  |         foreach ($this->toMap() as $field => $value) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 756 |  |  |             // only look at custom fields | 
            
                                                                                                            
                            
            
                                    
            
            
                | 757 |  |  |             if (isset($fixed[$field])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 758 |  |  |                 continue; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 759 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 760 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 761 |  |  |             $dbObject = $this->dbObject($field); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 762 |  |  |             if (!$dbObject) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 763 |  |  |                 continue; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 764 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 765 |  |  |             if ($dbObject->exists()) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 766 |  |  |                 return false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 767 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 768 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 769 |  |  |         return true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 770 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 771 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 772 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 773 |  |  |      * Pluralise this item given a specific count. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 774 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 775 |  |  |      * E.g. "0 Pages", "1 File", "3 Images" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 776 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 777 |  |  |      * @param string $count | 
            
                                                                                                            
                            
            
                                    
            
            
                | 778 |  |  |      * @return string | 
            
                                                                                                            
                            
            
                                    
            
            
                | 779 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 780 |  |  |     public function i18n_pluralise($count) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 781 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 782 |  |  |         $default = 'one ' . $this->i18n_singular_name() . '|{count} ' . $this->i18n_plural_name(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 783 |  |  |         return i18n::_t( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 784 |  |  |             static::class . '.PLURALS', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 785 |  |  |             $default, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 786 |  |  |             ['count' => $count] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 787 |  |  |         ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 788 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 789 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 790 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 791 |  |  |      * Get the user friendly singular name of this DataObject. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 792 |  |  |      * If the name is not defined (by redefining $singular_name in the subclass), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 793 |  |  |      * this returns the class name. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 794 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 795 |  |  |      * @return string User friendly singular name of this DataObject | 
            
                                                                                                            
                            
            
                                    
            
            
                | 796 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 797 |  |  |     public function singular_name() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 798 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 799 |  |  |         $name = $this->config()->get('singular_name'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 800 |  |  |         if ($name) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 801 |  |  |             return $name; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 802 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 803 |  |  |         return ucwords(trim(strtolower(preg_replace( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 804 |  |  |             '/_?([A-Z])/', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 805 |  |  |             ' $1', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 806 |  |  |             ClassInfo::shortName($this) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 807 |  |  |         )))); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 808 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 809 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 810 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 811 |  |  |      * Get the translated user friendly singular name of this DataObject | 
            
                                                                                                            
                            
            
                                    
            
            
                | 812 |  |  |      * same as singular_name() but runs it through the translating function | 
            
                                                                                                            
                            
            
                                    
            
            
                | 813 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 814 |  |  |      * Translating string is in the form: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 815 |  |  |      *     $this->class.SINGULARNAME | 
            
                                                                                                            
                            
            
                                    
            
            
                | 816 |  |  |      * Example: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 817 |  |  |      *     Page.SINGULARNAME | 
            
                                                                                                            
                            
            
                                    
            
            
                | 818 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 819 |  |  |      * @return string User friendly translated singular name of this DataObject | 
            
                                                                                                            
                            
            
                                    
            
            
                | 820 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 821 |  |  |     public function i18n_singular_name() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 822 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 823 |  |  |         return _t(static::class . '.SINGULARNAME', $this->singular_name()); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 824 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 825 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 826 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 827 |  |  |      * Get the user friendly plural name of this DataObject | 
            
                                                                                                            
                            
            
                                    
            
            
                | 828 |  |  |      * If the name is not defined (by renaming $plural_name in the subclass), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 829 |  |  |      * this returns a pluralised version of the class name. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 830 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 831 |  |  |      * @return string User friendly plural name of this DataObject | 
            
                                                                                                            
                            
            
                                    
            
            
                | 832 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 833 |  |  |     public function plural_name() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 834 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 835 |  |  |         if ($name = $this->config()->get('plural_name')) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 836 |  |  |             return $name; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 837 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 838 |  |  |         $name = $this->singular_name(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 839 |  |  |         //if the penultimate character is not a vowel, replace "y" with "ies" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 840 |  |  |         if (preg_match('/[^aeiou]y$/i', $name)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 841 |  |  |             $name = substr($name, 0, -1) . 'ie'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 842 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 843 |  |  |         return ucfirst($name . 's'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 844 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 845 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 846 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 847 |  |  |      * Get the translated user friendly plural name of this DataObject | 
            
                                                                                                            
                            
            
                                    
            
            
                | 848 |  |  |      * Same as plural_name but runs it through the translation function | 
            
                                                                                                            
                            
            
                                    
            
            
                | 849 |  |  |      * Translation string is in the form: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 850 |  |  |      *      $this->class.PLURALNAME | 
            
                                                                                                            
                            
            
                                    
            
            
                | 851 |  |  |      * Example: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 852 |  |  |      *      Page.PLURALNAME | 
            
                                                                                                            
                            
            
                                    
            
            
                | 853 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 854 |  |  |      * @return string User friendly translated plural name of this DataObject | 
            
                                                                                                            
                            
            
                                    
            
            
                | 855 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 856 |  |  |     public function i18n_plural_name() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 857 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 858 |  |  |         return _t(static::class . '.PLURALNAME', $this->plural_name()); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 859 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 860 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 861 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 862 |  |  |      * Standard implementation of a title/label for a specific | 
            
                                                                                                            
                            
            
                                    
            
            
                | 863 |  |  |      * record. Tries to find properties 'Title' or 'Name', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 864 |  |  |      * and falls back to the 'ID'. Useful to provide | 
            
                                                                                                            
                            
            
                                    
            
            
                | 865 |  |  |      * user-friendly identification of a record, e.g. in errormessages | 
            
                                                                                                            
                            
            
                                    
            
            
                | 866 |  |  |      * or UI-selections. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 867 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 868 |  |  |      * Overload this method to have a more specialized implementation, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 869 |  |  |      * e.g. for an Address record this could be: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 870 |  |  |      * <code> | 
            
                                                                                                            
                            
            
                                    
            
            
                | 871 |  |  |      * function getTitle() { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 872 |  |  |      *   return "{$this->StreetNumber} {$this->StreetName} {$this->City}"; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 873 |  |  |      * } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 874 |  |  |      * </code> | 
            
                                                                                                            
                            
            
                                    
            
            
                | 875 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 876 |  |  |      * @return string | 
            
                                                                                                            
                            
            
                                    
            
            
                | 877 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 878 |  |  |     public function getTitle() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 879 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 880 |  |  |         $schema = static::getSchema(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 881 |  |  |         if ($schema->fieldSpec($this, 'Title')) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 882 |  |  |             return $this->getField('Title'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 883 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 884 |  |  |         if ($schema->fieldSpec($this, 'Name')) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 885 |  |  |             return $this->getField('Name'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 886 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 887 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 888 |  |  |         return "#{$this->ID}"; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 889 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 890 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 891 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 892 |  |  |      * Returns the associated database record - in this case, the object itself. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 893 |  |  |      * This is included so that you can call $dataOrController->data() and get a DataObject all the time. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 894 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 895 |  |  |      * @return DataObject Associated database record | 
            
                                                                                                            
                            
            
                                    
            
            
                | 896 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 897 |  |  |     public function data() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 898 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 899 |  |  |         return $this; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 900 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 901 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 902 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 903 |  |  |      * Convert this object to a map. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 904 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 905 |  |  |      * @return array The data as a map. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 906 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 907 |  |  |     public function toMap() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 908 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 909 |  |  |         $this->loadLazyFields(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 910 |  |  |         return $this->record; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 911 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 912 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 913 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 914 |  |  |      * Return all currently fetched database fields. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 915 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 916 |  |  |      * This function is similar to toMap() but doesn't trigger the lazy-loading of all unfetched fields. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 917 |  |  |      * Obviously, this makes it a lot faster. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 918 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 919 |  |  |      * @return array The data as a map. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 920 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 921 |  |  |     public function getQueriedDatabaseFields() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 922 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 923 |  |  |         return $this->record; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 924 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 925 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 926 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 927 |  |  |      * Update a number of fields on this object, given a map of the desired changes. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 928 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 929 |  |  |      * The field names can be simple names, or you can use a dot syntax to access $has_one relations. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 930 |  |  |      * For example, array("Author.FirstName" => "Jim") will set $this->Author()->FirstName to "Jim". | 
            
                                                                                                            
                            
            
                                    
            
            
                | 931 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 932 |  |  |      * update() doesn't write the main object, but if you use the dot syntax, it will write() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 933 |  |  |      * the related objects that it alters. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 934 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 935 |  |  |      * @param array $data A map of field name to data values to update. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 936 |  |  |      * @return DataObject $this | 
            
                                                                                                            
                            
            
                                    
            
            
                | 937 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 938 |  |  |     public function update($data) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 939 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 940 |  |  |         foreach ($data as $key => $value) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 941 |  |  |             // Implement dot syntax for updates | 
            
                                                                                                            
                            
            
                                    
            
            
                | 942 |  |  |             if (strpos($key, '.') !== false) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 943 |  |  |                 $relations = explode('.', $key); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 944 |  |  |                 $fieldName = array_pop($relations); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 945 |  |  |                 /** @var static $relObj */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 946 |  |  |                 $relObj = $this; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 947 |  |  |                 $relation = null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 948 |  |  |                 foreach ($relations as $i => $relation) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 949 |  |  |                     // no support for has_many or many_many relationships, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 950 |  |  |                     // as the updater wouldn't know which object to write to (or create) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 951 |  |  |                     if ($relObj->$relation() instanceof DataObject) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 952 |  |  |                         $parentObj = $relObj; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 953 |  |  |                         $relObj = $relObj->$relation(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 954 |  |  |                         // If the intermediate relationship objects haven't been created, then write them | 
            
                                                                                                            
                            
            
                                    
            
            
                | 955 |  |  |                         if ($i < sizeof($relations) - 1 && !$relObj->ID || (!$relObj->ID && $parentObj !== $this)) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 956 |  |  |                             $relObj->write(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 957 |  |  |                             $relatedFieldName = $relation . "ID"; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 958 |  |  |                             $parentObj->$relatedFieldName = $relObj->ID; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 959 |  |  |                             $parentObj->write(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 960 |  |  |                         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 961 |  |  |                     } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 962 |  |  |                         user_error( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 963 |  |  |                             "DataObject::update(): Can't traverse relationship '$relation'," . | 
            
                                                                                                            
                            
            
                                    
            
            
                | 964 |  |  |                             "it has to be a has_one relationship or return a single DataObject", | 
            
                                                                                                            
                            
            
                                    
            
            
                | 965 |  |  |                             E_USER_NOTICE | 
            
                                                                                                            
                            
            
                                    
            
            
                | 966 |  |  |                         ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 967 |  |  |                         // unset relation object so we don't write properties to the wrong object | 
            
                                                                                                            
                            
            
                                    
            
            
                | 968 |  |  |                         $relObj = null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 969 |  |  |                         break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 970 |  |  |                     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 971 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 972 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 973 |  |  |                 if ($relObj) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 974 |  |  |                     $relObj->$fieldName = $value; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 975 |  |  |                     $relObj->write(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 976 |  |  |                     $relatedFieldName = $relation . "ID"; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 977 |  |  |                     $this->$relatedFieldName = $relObj->ID; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 978 |  |  |                     $relObj->flushCache(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 979 |  |  |                 } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 980 |  |  |                     $class = static::class; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 981 |  |  |                     user_error("Couldn't follow dot syntax '{$key}' on '{$class}' object", E_USER_WARNING); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 982 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 983 |  |  |             } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 984 |  |  |                 $this->$key = $value; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 985 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 986 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 987 |  |  |         return $this; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 988 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 989 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 990 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 991 |  |  |      * Pass changes as a map, and try to | 
            
                                                                                                            
                            
            
                                    
            
            
                | 992 |  |  |      * get automatic casting for these fields. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 993 |  |  |      * Doesn't write to the database. To write the data, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 994 |  |  |      * use the write() method. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 995 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 996 |  |  |      * @param array $data A map of field name to data values to update. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 997 |  |  |      * @return DataObject $this | 
            
                                                                                                            
                            
            
                                    
            
            
                | 998 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 999 |  |  |     public function castedUpdate($data) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1000 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1001 |  |  |         foreach ($data as $k => $v) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1002 |  |  |             $this->setCastedField($k, $v); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1003 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1004 |  |  |         return $this; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1005 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1006 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1007 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1008 |  |  |      * Merges data and relations from another object of same class, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1009 |  |  |      * without conflict resolution. Allows to specify which | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1010 |  |  |      * dataset takes priority in case its not empty. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1011 |  |  |      * has_one-relations are just transferred with priority 'right'. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1012 |  |  |      * has_many and many_many-relations are added regardless of priority. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1013 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1014 |  |  |      * Caution: has_many/many_many relations are moved rather than duplicated, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1015 |  |  |      * meaning they are not connected to the merged object any longer. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1016 |  |  |      * Caution: Just saves updated has_many/many_many relations to the database, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1017 |  |  |      * doesn't write the updated object itself (just writes the object-properties). | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1018 |  |  |      * Caution: Does not delete the merged object. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1019 |  |  |      * Caution: Does now overwrite Created date on the original object. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1020 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1021 |  |  |      * @param DataObject $rightObj | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1022 |  |  |      * @param string $priority left|right Determines who wins in case of a conflict (optional) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1023 |  |  |      * @param bool $includeRelations Merge any existing relations (optional) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1024 |  |  |      * @param bool $overwriteWithEmpty Overwrite existing left values with empty right values. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1025 |  |  |      *                            Only applicable with $priority='right'. (optional) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1026 |  |  |      * @return Boolean | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1027 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1028 |  |  |     public function merge($rightObj, $priority = 'right', $includeRelations = true, $overwriteWithEmpty = false) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1029 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1030 |  |  |         $leftObj = $this; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1031 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1032 |  |  |         if ($leftObj->ClassName != $rightObj->ClassName) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1033 |  |  |             // we can't merge similiar subclasses because they might have additional relations | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1034 |  |  |             user_error("DataObject->merge(): Invalid object class '{$rightObj->ClassName}' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1035 |  |  | 			(expected '{$leftObj->ClassName}').", E_USER_WARNING); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1036 |  |  |             return false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1037 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1038 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1039 |  |  |         if (!$rightObj->ID) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1040 |  |  |             user_error("DataObject->merge(): Please write your merged-in object to the database before merging, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1041 |  |  | 				to make sure all relations are transferred properly.').", E_USER_WARNING); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1042 |  |  |             return false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1043 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1044 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1045 |  |  |         // makes sure we don't merge data like ID or ClassName | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1046 |  |  |         $rightData = DataObject::getSchema()->fieldSpecs(get_class($rightObj)); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1047 |  |  |         foreach ($rightData as $key => $rightSpec) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1048 |  |  |             // Don't merge ID | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1049 |  |  |             if ($key === 'ID') { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1050 |  |  |                 continue; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1051 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1052 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1053 |  |  |             // Only merge relations if allowed | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1054 |  |  |             if ($rightSpec === 'ForeignKey' && !$includeRelations) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1055 |  |  |                 continue; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1056 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1057 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1058 |  |  |             // don't merge conflicting values if priority is 'left' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1059 |  |  |             if ($priority == 'left' && $leftObj->{$key} !== $rightObj->{$key}) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1060 |  |  |                 continue; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1061 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1062 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1063 |  |  |             // don't overwrite existing left values with empty right values (if $overwriteWithEmpty is set) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1064 |  |  |             if ($priority == 'right' && !$overwriteWithEmpty && empty($rightObj->{$key})) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1065 |  |  |                 continue; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1066 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1067 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1068 |  |  |             // TODO remove redundant merge of has_one fields | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1069 |  |  |             $leftObj->{$key} = $rightObj->{$key}; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1070 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1071 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1072 |  |  |         // merge relations | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1073 |  |  |         if ($includeRelations) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1074 |  |  |             if ($manyMany = $this->manyMany()) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1075 |  |  |                 foreach ($manyMany as $relationship => $class) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1076 |  |  |                     /** @var DataObject $leftComponents */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1077 |  |  |                     $leftComponents = $leftObj->getManyManyComponents($relationship); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1078 |  |  |                     $rightComponents = $rightObj->getManyManyComponents($relationship); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1079 |  |  |                     if ($rightComponents && $rightComponents->exists()) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1080 |  |  |                         $leftComponents->addMany($rightComponents->column('ID')); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1081 |  |  |                     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1082 |  |  |                     $leftComponents->write(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1083 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1084 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1085 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1086 |  |  |             if ($hasMany = $this->hasMany()) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1087 |  |  |                 foreach ($hasMany as $relationship => $class) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1088 |  |  |                     $leftComponents = $leftObj->getComponents($relationship); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1089 |  |  |                     $rightComponents = $rightObj->getComponents($relationship); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1090 |  |  |                     if ($rightComponents && $rightComponents->exists()) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1091 |  |  |                         $leftComponents->addMany($rightComponents->column('ID')); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1092 |  |  |                     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1093 |  |  |                     $leftComponents->write(); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                            
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1094 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1095 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1096 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1097 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1098 |  |  |         return true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1099 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1100 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1101 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1102 |  |  |      * Forces the record to think that all its data has changed. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1103 |  |  |      * Doesn't write to the database. Only sets fields as changed | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1104 |  |  |      * if they are not already marked as changed. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1105 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1106 |  |  |      * @return $this | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1107 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1108 |  |  |     public function forceChange() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1109 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1110 |  |  |         // Ensure lazy fields loaded | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1111 |  |  |         $this->loadLazyFields(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1112 |  |  |         $fields = static::getSchema()->fieldSpecs(static::class); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1113 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1114 |  |  |         // $this->record might not contain the blank values so we loop on $this->inheritedDatabaseFields() as well | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1115 |  |  |         $fieldNames = array_unique(array_merge( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1116 |  |  |             array_keys($this->record), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1117 |  |  |             array_keys($fields) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1118 |  |  |         )); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1119 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1120 |  |  |         foreach ($fieldNames as $fieldName) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1121 |  |  |             if (!isset($this->changed[$fieldName])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1122 |  |  |                 $this->changed[$fieldName] = self::CHANGE_STRICT; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1123 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1124 |  |  |             // Populate the null values in record so that they actually get written | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1125 |  |  |             if (!isset($this->record[$fieldName])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1126 |  |  |                 $this->record[$fieldName] = null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1127 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1128 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1129 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1130 |  |  |         // @todo Find better way to allow versioned to write a new version after forceChange | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1131 |  |  |         if ($this->isChanged('Version')) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1132 |  |  |             unset($this->changed['Version']); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1133 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1134 |  |  |         return $this; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1135 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1136 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1137 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1138 |  |  |      * Validate the current object. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1139 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1140 |  |  |      * By default, there is no validation - objects are always valid!  However, you can overload this method in your | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1141 |  |  |      * DataObject sub-classes to specify custom validation, or use the hook through DataExtension. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1142 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1143 |  |  |      * Invalid objects won't be able to be written - a warning will be thrown and no write will occur.  onBeforeWrite() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1144 |  |  |      * and onAfterWrite() won't get called either. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1145 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1146 |  |  |      * It is expected that you call validate() in your own application to test that an object is valid before | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1147 |  |  |      * attempting a write, and respond appropriately if it isn't. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1148 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1149 |  |  |      * @see {@link ValidationResult} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1150 |  |  |      * @return ValidationResult | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1151 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1152 |  |  |     public function validate() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1153 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1154 |  |  |         $result = ValidationResult::create(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1155 |  |  |         $this->extend('validate', $result); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1156 |  |  |         return $result; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1157 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1158 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1159 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1160 |  |  |      * Public accessor for {@see DataObject::validate()} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1161 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1162 |  |  |      * @return ValidationResult | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1163 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1164 |  |  |     public function doValidate() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1165 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1166 |  |  |         Deprecation::notice('5.0', 'Use validate'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1167 |  |  |         return $this->validate(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1168 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1169 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1170 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1171 |  |  |      * Event handler called before writing to the database. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1172 |  |  |      * You can overload this to clean up or otherwise process data before writing it to the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1173 |  |  |      * database.  Don't forget to call parent::onBeforeWrite(), though! | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1174 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1175 |  |  |      * This called after {@link $this->validate()}, so you can be sure that your data is valid. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1176 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1177 |  |  |      * @uses DataExtension->onBeforeWrite() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1178 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1179 |  |  |     protected function onBeforeWrite() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1180 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1181 |  |  |         $this->brokenOnWrite = false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1182 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1183 |  |  |         $dummy = null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1184 |  |  |         $this->extend('onBeforeWrite', $dummy); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1185 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1186 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1187 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1188 |  |  |      * Event handler called after writing to the database. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1189 |  |  |      * You can overload this to act upon changes made to the data after it is written. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1190 |  |  |      * $this->changed will have a record | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1191 |  |  |      * database.  Don't forget to call parent::onAfterWrite(), though! | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1192 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1193 |  |  |      * @uses DataExtension->onAfterWrite() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1194 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1195 |  |  |     protected function onAfterWrite() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1196 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1197 |  |  |         $dummy = null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1198 |  |  |         $this->extend('onAfterWrite', $dummy); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1199 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1200 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1201 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1202 |  |  |      * Find all objects that will be cascade deleted if this object is deleted | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1203 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1204 |  |  |      * Notes: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1205 |  |  |      *   - If this object is versioned, objects will only be searched in the same stage as the given record. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1206 |  |  |      *   - This will only be useful prior to deletion, as post-deletion this record will no longer exist. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1207 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1208 |  |  |      * @param bool $recursive True if recursive | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1209 |  |  |      * @param ArrayList $list Optional list to add items to | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1210 |  |  |      * @return ArrayList list of objects | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1211 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1212 |  |  |     public function findCascadeDeletes($recursive = true, $list = null) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1213 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1214 |  |  |         // Find objects in these relationships | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1215 |  |  |         return $this->findRelatedObjects('cascade_deletes', $recursive, $list); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1216 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1217 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1218 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1219 |  |  |      * Event handler called before deleting from the database. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1220 |  |  |      * You can overload this to clean up or otherwise process data before delete this | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1221 |  |  |      * record.  Don't forget to call parent::onBeforeDelete(), though! | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1222 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1223 |  |  |      * @uses DataExtension->onBeforeDelete() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1224 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1225 |  |  |     protected function onBeforeDelete() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1226 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1227 |  |  |         $this->brokenOnDelete = false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1228 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1229 |  |  |         $dummy = null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1230 |  |  |         $this->extend('onBeforeDelete', $dummy); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1231 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1232 |  |  |         // Cascade deletes | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1233 |  |  |         $deletes = $this->findCascadeDeletes(false); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1234 |  |  |         foreach ($deletes as $delete) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1235 |  |  |             $delete->delete(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1236 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1237 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1238 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1239 |  |  |     protected function onAfterDelete() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1240 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1241 |  |  |         $this->extend('onAfterDelete'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1242 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1243 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1244 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1245 |  |  |      * Load the default values in from the self::$defaults array. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1246 |  |  |      * Will traverse the defaults of the current class and all its parent classes. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1247 |  |  |      * Called by the constructor when creating new records. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1248 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1249 |  |  |      * @uses DataExtension->populateDefaults() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1250 |  |  |      * @return DataObject $this | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1251 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1252 |  |  |     public function populateDefaults() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1253 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1254 |  |  |         $classes = array_reverse(ClassInfo::ancestry($this)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1255 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1256 |  |  |         foreach ($classes as $class) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1257 |  |  |             $defaults = Config::inst()->get($class, 'defaults', Config::UNINHERITED); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1258 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1259 |  |  |             if ($defaults && !is_array($defaults)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1260 |  |  |                 user_error( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1261 |  |  |                     "Bad '" . static::class . "' defaults given: " . var_export($defaults, true), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1262 |  |  |                     E_USER_WARNING | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1263 |  |  |                 ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1264 |  |  |                 $defaults = null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1265 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1266 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1267 |  |  |             if ($defaults) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1268 |  |  |                 foreach ($defaults as $fieldName => $fieldValue) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1269 |  |  |                     // SRM 2007-03-06: Stricter check | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1270 |  |  |                     if (!isset($this->$fieldName) || $this->$fieldName === null) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1271 |  |  |                         $this->$fieldName = $fieldValue; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1272 |  |  |                     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1273 |  |  |                     // Set many-many defaults with an array of ids | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1274 |  |  |                     if (is_array($fieldValue) && $this->getSchema()->manyManyComponent(static::class, $fieldName)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1275 |  |  |                         /** @var ManyManyList $manyManyJoin */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1276 |  |  |                         $manyManyJoin = $this->$fieldName(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1277 |  |  |                         $manyManyJoin->setByIDList($fieldValue); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1278 |  |  |                     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1279 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1280 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1281 |  |  |             if ($class == self::class) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1282 |  |  |                 break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1283 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1284 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1285 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1286 |  |  |         $this->extend('populateDefaults'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1287 |  |  |         return $this; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1288 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1289 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1290 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1291 |  |  |      * Determine validation of this object prior to write | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1292 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1293 |  |  |      * @return ValidationException Exception generated by this write, or null if valid | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1294 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1295 |  |  |     protected function validateWrite() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1296 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1297 |  |  |         if ($this->ObsoleteClassName) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1298 |  |  |             return new ValidationException( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1299 |  |  |                 "Object is of class '{$this->ObsoleteClassName}' which doesn't exist - " . | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1300 |  |  |                 "you need to change the ClassName before you can write it" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1301 |  |  |             ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1302 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1303 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1304 |  |  |         // Note: Validation can only be disabled at the global level, not per-model | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1305 |  |  |         if (DataObject::config()->uninherited('validation_enabled')) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1306 |  |  |             $result = $this->validate(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1307 |  |  |             if (!$result->isValid()) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1308 |  |  |                 return new ValidationException($result); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1309 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1310 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1311 |  |  |         return null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1312 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1313 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1314 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1315 |  |  |      * Prepare an object prior to write | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1316 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1317 |  |  |      * @throws ValidationException | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1318 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1319 |  |  |     protected function preWrite() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1320 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1321 |  |  |         // Validate this object | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1322 |  |  |         if ($writeException = $this->validateWrite()) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1323 |  |  |             // Used by DODs to clean up after themselves, eg, Versioned | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1324 |  |  |             $this->invokeWithExtensions('onAfterSkippedWrite'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1325 |  |  |             throw $writeException; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1326 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1327 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1328 |  |  |         // Check onBeforeWrite | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1329 |  |  |         $this->brokenOnWrite = true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1330 |  |  |         $this->onBeforeWrite(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1331 |  |  |         if ($this->brokenOnWrite) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1332 |  |  |             user_error(static::class . " has a broken onBeforeWrite() function." | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1333 |  |  |                 . " Make sure that you call parent::onBeforeWrite().", E_USER_ERROR); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1334 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1335 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1336 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1337 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1338 |  |  |      * Detects and updates all changes made to this object | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1339 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1340 |  |  |      * @param bool $forceChanges If set to true, force all fields to be treated as changed | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1341 |  |  |      * @return bool True if any changes are detected | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1342 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1343 |  |  |     protected function updateChanges($forceChanges = false) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1344 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1345 |  |  |         if ($forceChanges) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1346 |  |  |             // Force changes, but only for loaded fields | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1347 |  |  |             foreach ($this->record as $field => $value) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1348 |  |  |                 $this->changed[$field] = static::CHANGE_VALUE; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1349 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1350 |  |  |             return true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1351 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1352 |  |  |         return $this->isChanged(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1353 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1354 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1355 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1356 |  |  |      * Writes a subset of changes for a specific table to the given manipulation | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1357 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1358 |  |  |      * @param string $baseTable Base table | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1359 |  |  |      * @param string $now Timestamp to use for the current time | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1360 |  |  |      * @param bool $isNewRecord Whether this should be treated as a new record write | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1361 |  |  |      * @param array $manipulation Manipulation to write to | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1362 |  |  |      * @param string $class Class of table to manipulate | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1363 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1364 |  |  |     protected function prepareManipulationTable($baseTable, $now, $isNewRecord, &$manipulation, $class) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1365 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1366 |  |  |         $schema = $this->getSchema(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1367 |  |  |         $table = $schema->tableName($class); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1368 |  |  |         $manipulation[$table] = array(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1369 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1370 |  |  |         // Extract records for this table | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1371 |  |  |         foreach ($this->record as $fieldName => $fieldValue) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1372 |  |  |             // we're not attempting to reset the BaseTable->ID | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1373 |  |  |             // Ignore unchanged fields or attempts to reset the BaseTable->ID | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1374 |  |  |             if (empty($this->changed[$fieldName]) || ($table === $baseTable && $fieldName === 'ID')) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1375 |  |  |                 continue; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1376 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1377 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1378 |  |  |             // Ensure this field pertains to this table | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1379 |  |  |             $specification = $schema->fieldSpec( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1380 |  |  |                 $class, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1381 |  |  |                 $fieldName, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1382 |  |  |                 DataObjectSchema::DB_ONLY | DataObjectSchema::UNINHERITED | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1383 |  |  |             ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1384 |  |  |             if (!$specification) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1385 |  |  |                 continue; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1386 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1387 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1388 |  |  |             // if database column doesn't correlate to a DBField instance... | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1389 |  |  |             $fieldObj = $this->dbObject($fieldName); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1390 |  |  |             if (!$fieldObj) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1391 |  |  |                 $fieldObj = DBField::create_field('Varchar', $fieldValue, $fieldName); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1392 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1393 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1394 |  |  |             // Write to manipulation | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1395 |  |  |             $fieldObj->writeToManipulation($manipulation[$table]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1396 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1397 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1398 |  |  |         // Ensure update of Created and LastEdited columns | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1399 |  |  |         if ($baseTable === $table) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1400 |  |  |             $manipulation[$table]['fields']['LastEdited'] = $now; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1401 |  |  |             if ($isNewRecord) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1402 |  |  |                 $manipulation[$table]['fields']['Created'] = empty($this->record['Created']) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1403 |  |  |                     ? $now | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1404 |  |  |                     : $this->record['Created']; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1405 |  |  |                 $manipulation[$table]['fields']['ClassName'] = static::class; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1406 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1407 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1408 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1409 |  |  |         // Inserts done one the base table are performed in another step, so the manipulation should instead | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1410 |  |  |         // attempt an update, as though it were a normal update. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1411 |  |  |         $manipulation[$table]['command'] = $isNewRecord ? 'insert' : 'update'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1412 |  |  |         $manipulation[$table]['id'] = $this->record['ID']; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1413 |  |  |         $manipulation[$table]['class'] = $class; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1414 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1415 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1416 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1417 |  |  |      * Ensures that a blank base record exists with the basic fixed fields for this dataobject | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1418 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1419 |  |  |      * Does nothing if an ID is already assigned for this record | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1420 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1421 |  |  |      * @param string $baseTable Base table | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1422 |  |  |      * @param string $now Timestamp to use for the current time | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1423 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1424 |  |  |     protected function writeBaseRecord($baseTable, $now) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1425 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1426 |  |  |         // Generate new ID if not specified | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1427 |  |  |         if ($this->isInDB()) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1428 |  |  |             return; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1429 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1430 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1431 |  |  |         // Perform an insert on the base table | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1432 |  |  |         $insert = new SQLInsert('"' . $baseTable . '"'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1433 |  |  |         $insert | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1434 |  |  |             ->assign('"Created"', $now) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1435 |  |  |             ->execute(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1436 |  |  |         $this->changed['ID'] = self::CHANGE_VALUE; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1437 |  |  |         $this->record['ID'] = DB::get_generated_id($baseTable); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1438 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1439 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1440 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1441 |  |  |      * Generate and write the database manipulation for all changed fields | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1442 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1443 |  |  |      * @param string $baseTable Base table | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1444 |  |  |      * @param string $now Timestamp to use for the current time | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1445 |  |  |      * @param bool $isNewRecord If this is a new record | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1446 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1447 |  |  |     protected function writeManipulation($baseTable, $now, $isNewRecord) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1448 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1449 |  |  |         // Generate database manipulations for each class | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1450 |  |  |         $manipulation = array(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1451 |  |  |         foreach (ClassInfo::ancestry(static::class, true) as $class) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1452 |  |  |             $this->prepareManipulationTable($baseTable, $now, $isNewRecord, $manipulation, $class); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1453 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1454 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1455 |  |  |         // Allow extensions to extend this manipulation | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1456 |  |  |         $this->extend('augmentWrite', $manipulation); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1457 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1458 |  |  |         // New records have their insert into the base data table done first, so that they can pass the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1459 |  |  |         // generated ID on to the rest of the manipulation | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1460 |  |  |         if ($isNewRecord) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1461 |  |  |             $manipulation[$baseTable]['command'] = 'update'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1462 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1463 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1464 |  |  |         // Perform the manipulation | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1465 |  |  |         DB::manipulate($manipulation); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1466 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1467 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1468 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1469 |  |  |      * Writes all changes to this object to the database. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1470 |  |  |      *  - It will insert a record whenever ID isn't set, otherwise update. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1471 |  |  |      *  - All relevant tables will be updated. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1472 |  |  |      *  - $this->onBeforeWrite() gets called beforehand. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1473 |  |  |      *  - Extensions such as Versioned will ammend the database-write to ensure that a version is saved. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1474 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1475 |  |  |      * @uses DataExtension->augmentWrite() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1476 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1477 |  |  |      * @param boolean $showDebug Show debugging information | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1478 |  |  |      * @param boolean $forceInsert Run INSERT command rather than UPDATE, even if record already exists | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1479 |  |  |      * @param boolean $forceWrite Write to database even if there are no changes | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1480 |  |  |      * @param boolean $writeComponents Call write() on all associated component instances which were previously | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1481 |  |  |      *                                 retrieved through {@link getComponent()}, {@link getComponents()} or | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1482 |  |  |      *                                 {@link getManyManyComponents()} (Default: false) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1483 |  |  |      * @return int The ID of the record | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1484 |  |  |      * @throws ValidationException Exception that can be caught and handled by the calling function | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1485 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1486 |  |  |     public function write($showDebug = false, $forceInsert = false, $forceWrite = false, $writeComponents = false) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1487 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1488 |  |  |         $now = DBDatetime::now()->Rfc2822(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1489 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1490 |  |  |         // Execute pre-write tasks | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1491 |  |  |         $this->preWrite(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1492 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1493 |  |  |         // Check if we are doing an update or an insert | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1494 |  |  |         $isNewRecord = !$this->isInDB() || $forceInsert; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1495 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1496 |  |  |         // Check changes exist, abort if there are none | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1497 |  |  |         $hasChanges = $this->updateChanges($isNewRecord); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1498 |  |  |         if ($hasChanges || $forceWrite || $isNewRecord) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1499 |  |  |             // Ensure Created and LastEdited are populated | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1500 |  |  |             if (!isset($this->record['Created'])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1501 |  |  |                 $this->record['Created'] = $now; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1502 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1503 |  |  |             $this->record['LastEdited'] = $now; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1504 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1505 |  |  |             // New records have their insert into the base data table done first, so that they can pass the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1506 |  |  |             // generated primary key on to the rest of the manipulation | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1507 |  |  |             $baseTable = $this->baseTable(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1508 |  |  |             $this->writeBaseRecord($baseTable, $now); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1509 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1510 |  |  |             // Write the DB manipulation for all changed fields | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1511 |  |  |             $this->writeManipulation($baseTable, $now, $isNewRecord); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1512 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1513 |  |  |             // If there's any relations that couldn't be saved before, save them now (we have an ID here) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1514 |  |  |             $this->writeRelations(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1515 |  |  |             $this->onAfterWrite(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1516 |  |  |             $this->changed = array(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1517 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1518 |  |  |             if ($showDebug) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1519 |  |  |                 Debug::message("no changes for DataObject"); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1520 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1521 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1522 |  |  |             // Used by DODs to clean up after themselves, eg, Versioned | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1523 |  |  |             $this->invokeWithExtensions('onAfterSkippedWrite'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1524 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1525 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1526 |  |  |         // Write relations as necessary | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1527 |  |  |         if ($writeComponents) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1528 |  |  |             $this->writeComponents(true); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1529 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1530 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1531 |  |  |         // Clears the cache for this object so get_one returns the correct object. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1532 |  |  |         $this->flushCache(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1533 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1534 |  |  |         return $this->record['ID']; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1535 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1536 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1537 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1538 |  |  |      * Writes cached relation lists to the database, if possible | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1539 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1540 |  |  |     public function writeRelations() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1541 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1542 |  |  |         if (!$this->isInDB()) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1543 |  |  |             return; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1544 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1545 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1546 |  |  |         // If there's any relations that couldn't be saved before, save them now (we have an ID here) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1547 |  |  |         if ($this->unsavedRelations) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1548 |  |  |             foreach ($this->unsavedRelations as $name => $list) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1549 |  |  |                 $list->changeToList($this->$name()); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1550 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1551 |  |  |             $this->unsavedRelations = array(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1552 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1553 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1554 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1555 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1556 |  |  |      * Write the cached components to the database. Cached components could refer to two different instances of the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1557 |  |  |      * same record. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1558 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1559 |  |  |      * @param bool $recursive Recursively write components | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1560 |  |  |      * @return DataObject $this | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1561 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1562 |  |  |     public function writeComponents($recursive = false) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1563 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1564 |  |  |         foreach ($this->components as $component) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1565 |  |  |             $component->write(false, false, false, $recursive); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1566 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1567 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1568 |  |  |         if ($join = $this->getJoin()) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1569 |  |  |             $join->write(false, false, false, $recursive); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1570 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1571 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1572 |  |  |         return $this; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1573 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1574 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1575 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1576 |  |  |      * Delete this data object. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1577 |  |  |      * $this->onBeforeDelete() gets called. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1578 |  |  |      * Note that in Versioned objects, both Stage and Live will be deleted. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1579 |  |  |      * @uses DataExtension->augmentSQL() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1580 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1581 |  |  |     public function delete() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1582 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1583 |  |  |         $this->brokenOnDelete = true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1584 |  |  |         $this->onBeforeDelete(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1585 |  |  |         if ($this->brokenOnDelete) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1586 |  |  |             user_error(static::class . " has a broken onBeforeDelete() function." | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1587 |  |  |                 . " Make sure that you call parent::onBeforeDelete().", E_USER_ERROR); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1588 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1589 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1590 |  |  |         // Deleting a record without an ID shouldn't do anything | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1591 |  |  |         if (!$this->ID) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1592 |  |  |             throw new LogicException("DataObject::delete() called on a DataObject without an ID"); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1593 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1594 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1595 |  |  |         // TODO: This is quite ugly.  To improve: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1596 |  |  |         //  - move the details of the delete code in the DataQuery system | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1597 |  |  |         //  - update the code to just delete the base table, and rely on cascading deletes in the DB to do the rest | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1598 |  |  |         //    obviously, that means getting requireTable() to configure cascading deletes ;-) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1599 |  |  |         $srcQuery = DataList::create(static::class) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1600 |  |  |             ->filter('ID', $this->ID) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1601 |  |  |             ->dataQuery() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1602 |  |  |             ->query(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1603 |  |  |         $queriedTables = $srcQuery->queriedTables(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1604 |  |  |         $this->extend('updateDeleteTables', $queriedTables, $srcQuery); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1605 |  |  |         foreach ($queriedTables as $table) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1606 |  |  |             $delete = SQLDelete::create("\"$table\"", array('"ID"' => $this->ID)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1607 |  |  |             $this->extend('updateDeleteTable', $delete, $table, $queriedTables, $srcQuery); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1608 |  |  |             $delete->execute(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1609 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1610 |  |  |         // Remove this item out of any caches | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1611 |  |  |         $this->flushCache(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1612 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1613 |  |  |         $this->onAfterDelete(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1614 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1615 |  |  |         $this->OldID = $this->ID; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1616 |  |  |         $this->ID = 0; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1617 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1618 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1619 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1620 |  |  |      * Delete the record with the given ID. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1621 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1622 |  |  |      * @param string $className The class name of the record to be deleted | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1623 |  |  |      * @param int $id ID of record to be deleted | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1624 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1625 |  |  |     public static function delete_by_id($className, $id) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1626 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1627 |  |  |         $obj = DataObject::get_by_id($className, $id); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1628 |  |  |         if ($obj) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1629 |  |  |             $obj->delete(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1630 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1631 |  |  |             user_error("$className object #$id wasn't found when calling DataObject::delete_by_id", E_USER_WARNING); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1632 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1633 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1634 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1635 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1636 |  |  |      * Get the class ancestry, including the current class name. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1637 |  |  |      * The ancestry will be returned as an array of class names, where the 0th element | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1638 |  |  |      * will be the class that inherits directly from DataObject, and the last element | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1639 |  |  |      * will be the current class. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1640 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1641 |  |  |      * @return array Class ancestry | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1642 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1643 |  |  |     public function getClassAncestry() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1644 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1645 |  |  |         return ClassInfo::ancestry(static::class); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1646 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1647 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1648 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1649 |  |  |      * Return a unary component object from a one to one relationship, as a DataObject. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1650 |  |  |      * If no component is available, an 'empty component' will be returned for | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1651 |  |  |      * non-polymorphic relations, or for polymorphic relations with a class set. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1652 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1653 |  |  |      * @param string $componentName Name of the component | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1654 |  |  |      * @return DataObject The component object. It's exact type will be that of the component. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1655 |  |  |      * @throws Exception | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1656 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1657 |  |  |     public function getComponent($componentName) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1658 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1659 |  |  |         if (isset($this->components[$componentName])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1660 |  |  |             return $this->components[$componentName]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1661 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1662 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1663 |  |  |         $schema = static::getSchema(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1664 |  |  |         if ($class = $schema->hasOneComponent(static::class, $componentName)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1665 |  |  |             $joinField = $componentName . 'ID'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1666 |  |  |             $joinID = $this->getField($joinField); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1667 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1668 |  |  |             // Extract class name for polymorphic relations | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1669 |  |  |             if ($class === self::class) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1670 |  |  |                 $class = $this->getField($componentName . 'Class'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1671 |  |  |                 if (empty($class)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1672 |  |  |                     return null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1673 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1674 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1675 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1676 |  |  |             if ($joinID) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1677 |  |  |                 // Ensure that the selected object originates from the same stage, subsite, etc | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1678 |  |  |                 $component = DataObject::get($class) | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1679 |  |  |                     ->filter('ID', $joinID) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1680 |  |  |                     ->setDataQueryParam($this->getInheritableQueryParams()) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1681 |  |  |                     ->first(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1682 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1683 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1684 |  |  |             if (empty($component)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1685 |  |  |                 $component = Injector::inst()->create($class); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1686 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1687 |  |  |         } elseif ($class = $schema->belongsToComponent(static::class, $componentName)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1688 |  |  |             $joinField = $schema->getRemoteJoinField(static::class, $componentName, 'belongs_to', $polymorphic); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1689 |  |  |             $joinID = $this->ID; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1690 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1691 |  |  |             if ($joinID) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1692 |  |  |                 // Prepare filter for appropriate join type | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1693 |  |  |                 if ($polymorphic) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1694 |  |  |                     $filter = array( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1695 |  |  |                         "{$joinField}ID" => $joinID, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1696 |  |  |                         "{$joinField}Class" => static::class, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1697 |  |  |                     ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1698 |  |  |                 } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1699 |  |  |                     $filter = array( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1700 |  |  |                         $joinField => $joinID | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1701 |  |  |                     ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1702 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1703 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1704 |  |  |                 // Ensure that the selected object originates from the same stage, subsite, etc | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1705 |  |  |                 $component = DataObject::get($class) | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1706 |  |  |                     ->filter($filter) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1707 |  |  |                     ->setDataQueryParam($this->getInheritableQueryParams()) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1708 |  |  |                     ->first(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1709 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1710 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1711 |  |  |             if (empty($component)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1712 |  |  |                 $component = Injector::inst()->create($class); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1713 |  |  |                 if ($polymorphic) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1714 |  |  |                     $component->{$joinField . 'ID'} = $this->ID; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1715 |  |  |                     $component->{$joinField . 'Class'} = static::class; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1716 |  |  |                 } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1717 |  |  |                     $component->$joinField = $this->ID; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1718 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1719 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1720 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1721 |  |  |             throw new InvalidArgumentException( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1722 |  |  |                 "DataObject->getComponent(): Could not find component '$componentName'." | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1723 |  |  |             ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1724 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1725 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1726 |  |  |         $this->components[$componentName] = $component; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1727 |  |  |         return $component; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1728 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1729 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1730 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1731 |  |  |      * Assign an item to the given component | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1732 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1733 |  |  |      * @param string $componentName | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1734 |  |  |      * @param DataObject|null $item | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1735 |  |  |      * @return $this | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1736 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1737 |  |  |     public function setComponent($componentName, $item) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1738 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1739 |  |  |         // Validate component | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1740 |  |  |         $schema = static::getSchema(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1741 |  |  |         if ($class = $schema->hasOneComponent(static::class, $componentName)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1742 |  |  |             // Force item to be written if not by this point | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1743 |  |  |             // @todo This could be lazy-written in a beforeWrite hook, but force write here for simplicity | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1744 |  |  |             // https://github.com/silverstripe/silverstripe-framework/issues/7818 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1745 |  |  |             if ($item && !$item->isInDB()) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1746 |  |  |                 $item->write(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1747 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1748 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1749 |  |  |             // Update local ID | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1750 |  |  |             $joinField = $componentName . 'ID'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1751 |  |  |             $this->setField($joinField, $item ? $item->ID : null); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1752 |  |  |             // Update Class (Polymorphic has_one) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1753 |  |  |             // Extract class name for polymorphic relations | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1754 |  |  |             if ($class === self::class) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1755 |  |  |                 $this->setField($componentName . 'Class', $item ? get_class($item) : null); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1756 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1757 |  |  |         } elseif ($class = $schema->belongsToComponent(static::class, $componentName)) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1758 |  |  |             if ($item) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1759 |  |  |                 // For belongs_to, add to has_one on other component | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1760 |  |  |                 $joinField = $schema->getRemoteJoinField(static::class, $componentName, 'belongs_to', $polymorphic); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1761 |  |  |                 if (!$polymorphic) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1762 |  |  |                     $joinField = substr($joinField, 0, -2); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1763 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1764 |  |  |                 $item->setComponent($joinField, $this); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1765 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1766 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1767 |  |  |             throw new InvalidArgumentException( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1768 |  |  |                 "DataObject->setComponent(): Could not find component '$componentName'." | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1769 |  |  |             ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1770 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1771 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1772 |  |  |         $this->components[$componentName] = $item; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1773 |  |  |         return $this; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1774 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1775 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1776 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1777 |  |  |      * Returns a one-to-many relation as a HasManyList | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1778 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1779 |  |  |      * @param string $componentName Name of the component | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1780 |  |  |      * @param int|array $id Optional ID(s) for parent of this relation, if not the current record | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1781 |  |  |      * @return HasManyList|UnsavedRelationList The components of the one-to-many relationship. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1782 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1783 |  |  |     public function getComponents($componentName, $id = null) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1784 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1785 |  |  |         if (!isset($id)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1786 |  |  |             $id = $this->ID; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1787 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1788 |  |  |         $result = null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1789 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1790 |  |  |         $schema = $this->getSchema(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1791 |  |  |         $componentClass = $schema->hasManyComponent(static::class, $componentName); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1792 |  |  |         if (!$componentClass) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1793 |  |  |             throw new InvalidArgumentException(sprintf( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1794 |  |  |                 "DataObject::getComponents(): Unknown 1-to-many component '%s' on class '%s'", | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1795 |  |  |                 $componentName, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1796 |  |  |                 static::class | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1797 |  |  |             )); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1798 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1799 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1800 |  |  |         // If we haven't been written yet, we can't save these relations, so use a list that handles this case | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1801 |  |  |         if (!$id) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1802 |  |  |             if (!isset($this->unsavedRelations[$componentName])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1803 |  |  |                 $this->unsavedRelations[$componentName] = | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1804 |  |  |                     new UnsavedRelationList(static::class, $componentName, $componentClass); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1805 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1806 |  |  |             return $this->unsavedRelations[$componentName]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1807 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1808 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1809 |  |  |         // Determine type and nature of foreign relation | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1810 |  |  |         $joinField = $schema->getRemoteJoinField(static::class, $componentName, 'has_many', $polymorphic); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1811 |  |  |         /** @var HasManyList $result */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1812 |  |  |         if ($polymorphic) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1813 |  |  |             $result = PolymorphicHasManyList::create($componentClass, $joinField, static::class); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1814 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1815 |  |  |             $result = HasManyList::create($componentClass, $joinField); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1816 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1817 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1818 |  |  |         return $result | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1819 |  |  |             ->setDataQueryParam($this->getInheritableQueryParams()) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1820 |  |  |             ->forForeignID($id); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1821 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1822 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1823 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1824 |  |  |      * Find the foreign class of a relation on this DataObject, regardless of the relation type. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1825 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1826 |  |  |      * @param string $relationName Relation name. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1827 |  |  |      * @return string Class name, or null if not found. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1828 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1829 |  |  |     public function getRelationClass($relationName) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1830 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1831 |  |  |         // Parse many_many | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1832 |  |  |         $manyManyComponent = $this->getSchema()->manyManyComponent(static::class, $relationName); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1833 |  |  |         if ($manyManyComponent) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1834 |  |  |             return $manyManyComponent['childClass']; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1835 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1836 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1837 |  |  |         // Go through all relationship configuration fields. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1838 |  |  |         $config = $this->config(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1839 |  |  |         $candidates = array_merge( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1840 |  |  |             ($relations = $config->get('has_one')) ? $relations : array(), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1841 |  |  |             ($relations = $config->get('has_many')) ? $relations : array(), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1842 |  |  |             ($relations = $config->get('belongs_to')) ? $relations : array() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1843 |  |  |         ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1844 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1845 |  |  |         if (isset($candidates[$relationName])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1846 |  |  |             $remoteClass = $candidates[$relationName]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1847 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1848 |  |  |             // If dot notation is present, extract just the first part that contains the class. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1849 |  |  |             if (($fieldPos = strpos($remoteClass, '.')) !== false) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1850 |  |  |                 return substr($remoteClass, 0, $fieldPos); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1851 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1852 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1853 |  |  |             // Otherwise just return the class | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1854 |  |  |             return $remoteClass; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1855 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1856 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1857 |  |  |         return null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1858 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1859 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1860 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1861 |  |  |      * Given a relation name, determine the relation type | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1862 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1863 |  |  |      * @param string $component Name of component | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1864 |  |  |      * @return string has_one, has_many, many_many, belongs_many_many or belongs_to | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1865 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1866 |  |  |     public function getRelationType($component) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1867 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1868 |  |  |         $types = array('has_one', 'has_many', 'many_many', 'belongs_many_many', 'belongs_to'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1869 |  |  |         $config = $this->config(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1870 |  |  |         foreach ($types as $type) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1871 |  |  |             $relations = $config->get($type); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1872 |  |  |             if ($relations && isset($relations[$component])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1873 |  |  |                 return $type; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1874 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1875 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1876 |  |  |         return null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1877 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1878 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1879 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1880 |  |  |      * Given a relation declared on a remote class, generate a substitute component for the opposite | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1881 |  |  |      * side of the relation. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1882 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1883 |  |  |      * Notes on behaviour: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1884 |  |  |      *  - This can still be used on components that are defined on both sides, but do not need to be. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1885 |  |  |      *  - All has_ones on remote class will be treated as local has_many, even if they are belongs_to | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1886 |  |  |      *  - Cannot be used on polymorphic relationships | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1887 |  |  |      *  - Cannot be used on unsaved objects. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1888 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1889 |  |  |      * @param string $remoteClass | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1890 |  |  |      * @param string $remoteRelation | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1891 |  |  |      * @return DataList|DataObject The component, either as a list or single object | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1892 |  |  |      * @throws BadMethodCallException | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1893 |  |  |      * @throws InvalidArgumentException | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1894 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1895 |  |  |     public function inferReciprocalComponent($remoteClass, $remoteRelation) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1896 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1897 |  |  |         $remote = DataObject::singleton($remoteClass); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1898 |  |  |         $class = $remote->getRelationClass($remoteRelation); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1899 |  |  |         $schema = static::getSchema(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1900 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1901 |  |  |         // Validate arguments | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1902 |  |  |         if (!$this->isInDB()) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1903 |  |  |             throw new BadMethodCallException(__METHOD__ . " cannot be called on unsaved objects"); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1904 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1905 |  |  |         if (empty($class)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1906 |  |  |             throw new InvalidArgumentException(sprintf( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1907 |  |  |                 "%s invoked with invalid relation %s.%s", | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1908 |  |  |                 __METHOD__, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1909 |  |  |                 $remoteClass, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1910 |  |  |                 $remoteRelation | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1911 |  |  |             )); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1912 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1913 |  |  |         if ($class === self::class) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1914 |  |  |             throw new InvalidArgumentException(sprintf( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1915 |  |  |                 "%s cannot generate opposite component of relation %s.%s as it is polymorphic. " . | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1916 |  |  |                 "This method does not support polymorphic relationships", | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1917 |  |  |                 __METHOD__, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1918 |  |  |                 $remoteClass, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1919 |  |  |                 $remoteRelation | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1920 |  |  |             )); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1921 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1922 |  |  |         if (!is_a($this, $class, true)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1923 |  |  |             throw new InvalidArgumentException(sprintf( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1924 |  |  |                 "Relation %s on %s does not refer to objects of type %s", | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1925 |  |  |                 $remoteRelation, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1926 |  |  |                 $remoteClass, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1927 |  |  |                 static::class | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1928 |  |  |             )); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1929 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1930 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1931 |  |  |         // Check the relation type to mock | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1932 |  |  |         $relationType = $remote->getRelationType($remoteRelation); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1933 |  |  |         switch ($relationType) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1934 |  |  |             case 'has_one': { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1935 |  |  |                 // Mock has_many | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1936 |  |  |                 $joinField = "{$remoteRelation}ID"; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1937 |  |  |                 $componentClass = $schema->classForField($remoteClass, $joinField); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1938 |  |  |                 $result = HasManyList::create($componentClass, $joinField); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1939 |  |  |                 return $result | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1940 |  |  |                     ->setDataQueryParam($this->getInheritableQueryParams()) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1941 |  |  |                     ->forForeignID($this->ID); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1942 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1943 |  |  |             case 'belongs_to': | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1944 |  |  |             case 'has_many': { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1945 |  |  |                 // These relations must have a has_one on the other end, so find it | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1946 |  |  |                 $joinField = $schema->getRemoteJoinField( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1947 |  |  |                     $remoteClass, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1948 |  |  |                     $remoteRelation, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1949 |  |  |                     $relationType, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1950 |  |  |                     $polymorphic | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1951 |  |  |                 ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1952 |  |  |                 if ($polymorphic) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1953 |  |  |                     throw new InvalidArgumentException(sprintf( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1954 |  |  |                         "%s cannot generate opposite component of relation %s.%s, as the other end appears" . | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1955 |  |  |                         "to be a has_one polymorphic. This method does not support polymorphic relationships", | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1956 |  |  |                         __METHOD__, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1957 |  |  |                         $remoteClass, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1958 |  |  |                         $remoteRelation | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1959 |  |  |                     )); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1960 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1961 |  |  |                 $joinID = $this->getField($joinField); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1962 |  |  |                 if (empty($joinID)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1963 |  |  |                     return null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1964 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1965 |  |  |                 // Get object by joined ID | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1966 |  |  |                 return DataObject::get($remoteClass) | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1967 |  |  |                     ->filter('ID', $joinID) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1968 |  |  |                     ->setDataQueryParam($this->getInheritableQueryParams()) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1969 |  |  |                     ->first(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1970 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1971 |  |  |             case 'many_many': | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1972 |  |  |             case 'belongs_many_many': { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1973 |  |  |                 // Get components and extra fields from parent | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1974 |  |  |                 $manyMany = $remote->getSchema()->manyManyComponent($remoteClass, $remoteRelation); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1975 |  |  |                 $extraFields = $schema->manyManyExtraFieldsForComponent($remoteClass, $remoteRelation) ?: array(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1976 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1977 |  |  |                 // Reverse parent and component fields and create an inverse ManyManyList | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1978 |  |  |                 /** @var RelationList $result */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1979 |  |  |                 $result = Injector::inst()->create( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1980 |  |  |                     $manyMany['relationClass'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1981 |  |  |                     $manyMany['parentClass'], // Substitute parent class for dataClass | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1982 |  |  |                     $manyMany['join'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1983 |  |  |                     $manyMany['parentField'], // Reversed parent / child field | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1984 |  |  |                     $manyMany['childField'], // Reversed parent / child field | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1985 |  |  |                     $extraFields | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1986 |  |  |                 ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1987 |  |  |                 $this->extend('updateManyManyComponents', $result); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1988 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1989 |  |  |                 // If this is called on a singleton, then we return an 'orphaned relation' that can have the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1990 |  |  |                 // foreignID set elsewhere. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1991 |  |  |                 return $result | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1992 |  |  |                     ->setDataQueryParam($this->getInheritableQueryParams()) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1993 |  |  |                     ->forForeignID($this->ID); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1994 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1995 |  |  |             default: { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1996 |  |  |                 return null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1997 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1998 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1999 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2000 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2001 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2002 |  |  |      * Returns a many-to-many component, as a ManyManyList. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2003 |  |  |      * @param string $componentName Name of the many-many component | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2004 |  |  |      * @param int|array $id Optional ID for parent of this relation, if not the current record | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2005 |  |  |      * @return ManyManyList|UnsavedRelationList The set of components | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2006 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2007 |  |  |     public function getManyManyComponents($componentName, $id = null) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2008 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2009 |  |  |         if (!isset($id)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2010 |  |  |             $id = $this->ID; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2011 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2012 |  |  |         $schema = static::getSchema(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2013 |  |  |         $manyManyComponent = $schema->manyManyComponent(static::class, $componentName); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2014 |  |  |         if (!$manyManyComponent) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2015 |  |  |             throw new InvalidArgumentException(sprintf( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2016 |  |  |                 "DataObject::getComponents(): Unknown many-to-many component '%s' on class '%s'", | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2017 |  |  |                 $componentName, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2018 |  |  |                 static::class | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2019 |  |  |             )); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2020 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2021 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2022 |  |  |         // If we haven't been written yet, we can't save these relations, so use a list that handles this case | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2023 |  |  |         if (!$id) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2024 |  |  |             if (!isset($this->unsavedRelations[$componentName])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2025 |  |  |                 $this->unsavedRelations[$componentName] = | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2026 |  |  |                     new UnsavedRelationList( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2027 |  |  |                         $manyManyComponent['parentClass'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2028 |  |  |                         $componentName, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2029 |  |  |                         $manyManyComponent['childClass'] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2030 |  |  |                     ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2031 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2032 |  |  |             return $this->unsavedRelations[$componentName]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2033 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2034 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2035 |  |  |         $extraFields = $schema->manyManyExtraFieldsForComponent(static::class, $componentName) ?: array(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2036 |  |  |         /** @var RelationList $result */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2037 |  |  |         $result = Injector::inst()->create( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2038 |  |  |             $manyManyComponent['relationClass'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2039 |  |  |             $manyManyComponent['childClass'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2040 |  |  |             $manyManyComponent['join'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2041 |  |  |             $manyManyComponent['childField'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2042 |  |  |             $manyManyComponent['parentField'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2043 |  |  |             $extraFields | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2044 |  |  |         ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2045 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2046 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2047 |  |  |         // Store component data in query meta-data | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2048 |  |  |         $result = $result->alterDataQuery(function ($query) use ($extraFields) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2049 |  |  |             /** @var DataQuery $query */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2050 |  |  |             $query->setQueryParam('Component.ExtraFields', $extraFields); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2051 |  |  |         }); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2052 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2053 |  |  |         $this->extend('updateManyManyComponents', $result); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2054 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2055 |  |  |         // If this is called on a singleton, then we return an 'orphaned relation' that can have the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2056 |  |  |         // foreignID set elsewhere. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2057 |  |  |         return $result | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2058 |  |  |             ->setDataQueryParam($this->getInheritableQueryParams()) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2059 |  |  |             ->forForeignID($id); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2060 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2061 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2062 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2063 |  |  |      * Return the class of a one-to-one component.  If $component is null, return all of the one-to-one components and | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2064 |  |  |      * their classes. If the selected has_one is a polymorphic field then 'DataObject' will be returned for the type. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2065 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2066 |  |  |      * @return string|array The class of the one-to-one component, or an array of all one-to-one components and | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2067 |  |  |      *                          their classes. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2068 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2069 |  |  |     public function hasOne() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2070 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2071 |  |  |         return (array)$this->config()->get('has_one'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2072 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2073 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2074 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2075 |  |  |      * Returns the class of a remote belongs_to relationship. If no component is specified a map of all components and | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2076 |  |  |      * their class name will be returned. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2077 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2078 |  |  |      * @param bool $classOnly If this is TRUE, than any has_many relationships in the form "ClassName.Field" will have | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2079 |  |  |      *        the field data stripped off. It defaults to TRUE. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2080 |  |  |      * @return string|array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2081 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2082 |  |  |     public function belongsTo($classOnly = true) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2083 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2084 |  |  |         $belongsTo = (array)$this->config()->get('belongs_to'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2085 |  |  |         if ($belongsTo && $classOnly) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2086 |  |  |             return preg_replace('/(.+)?\..+/', '$1', $belongsTo); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2087 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2088 |  |  |             return $belongsTo ? $belongsTo : array(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2089 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2090 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2091 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2092 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2093 |  |  |      * Gets the class of a one-to-many relationship. If no $component is specified then an array of all the one-to-many | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2094 |  |  |      * relationships and their classes will be returned. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2095 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2096 |  |  |      * @param bool $classOnly If this is TRUE, than any has_many relationships in the form "ClassName.Field" will have | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2097 |  |  |      *        the field data stripped off. It defaults to TRUE. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2098 |  |  |      * @return string|array|false | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2099 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2100 |  |  |     public function hasMany($classOnly = true) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2101 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2102 |  |  |         $hasMany = (array)$this->config()->get('has_many'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2103 |  |  |         if ($hasMany && $classOnly) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2104 |  |  |             return preg_replace('/(.+)?\..+/', '$1', $hasMany); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2105 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2106 |  |  |             return $hasMany ? $hasMany : array(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2107 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2108 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2109 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2110 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2111 |  |  |      * Return the many-to-many extra fields specification. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2112 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2113 |  |  |      * If you don't specify a component name, it returns all | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2114 |  |  |      * extra fields for all components available. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2115 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2116 |  |  |      * @return array|null | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2117 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2118 |  |  |     public function manyManyExtraFields() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2119 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2120 |  |  |         return $this->config()->get('many_many_extraFields'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2121 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2122 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2123 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2124 |  |  |      * Return information about a many-to-many component. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2125 |  |  |      * The return value is an array of (parentclass, childclass).  If $component is null, then all many-many | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2126 |  |  |      * components are returned. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2127 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2128 |  |  |      * @see DataObjectSchema::manyManyComponent() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2129 |  |  |      * @return array|null An array of (parentclass, childclass), or an array of all many-many components | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2130 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2131 |  |  |     public function manyMany() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2132 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2133 |  |  |         $config = $this->config(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2134 |  |  |         $manyManys = (array)$config->get('many_many'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2135 |  |  |         $belongsManyManys = (array)$config->get('belongs_many_many'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2136 |  |  |         $items = array_merge($manyManys, $belongsManyManys); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2137 |  |  |         return $items; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2138 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2139 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2140 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2141 |  |  |      * This returns an array (if it exists) describing the database extensions that are required, or false if none | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2142 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2143 |  |  |      * This is experimental, and is currently only a Postgres-specific enhancement. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2144 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2145 |  |  |      * @param string $class | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2146 |  |  |      * @return array|false | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2147 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2148 |  |  |     public function database_extensions($class) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2149 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2150 |  |  |         $extensions = Config::inst()->get($class, 'database_extensions', Config::UNINHERITED); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2151 |  |  |         if ($extensions) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2152 |  |  |             return $extensions; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2153 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2154 |  |  |             return false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2155 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2156 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2157 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2158 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2159 |  |  |      * Generates a SearchContext to be used for building and processing | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2160 |  |  |      * a generic search form for properties on this object. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2161 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2162 |  |  |      * @return SearchContext | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2163 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2164 |  |  |     public function getDefaultSearchContext() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2165 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2166 |  |  |         return new SearchContext( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2167 |  |  |             static::class, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2168 |  |  |             $this->scaffoldSearchFields(), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2169 |  |  |             $this->defaultSearchFilters() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2170 |  |  |         ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2171 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2172 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2173 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2174 |  |  |      * Determine which properties on the DataObject are | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2175 |  |  |      * searchable, and map them to their default {@link FormField} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2176 |  |  |      * representations. Used for scaffolding a searchform for {@link ModelAdmin}. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2177 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2178 |  |  |      * Some additional logic is included for switching field labels, based on | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2179 |  |  |      * how generic or specific the field type is. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2180 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2181 |  |  |      * Used by {@link SearchContext}. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2182 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2183 |  |  |      * @param array $_params | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2184 |  |  |      *   'fieldClasses': Associative array of field names as keys and FormField classes as values | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2185 |  |  |      *   'restrictFields': Numeric array of a field name whitelist | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2186 |  |  |      * @return FieldList | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2187 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2188 |  |  |     public function scaffoldSearchFields($_params = null) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2189 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2190 |  |  |         $params = array_merge( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2191 |  |  |             array( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2192 |  |  |                 'fieldClasses' => false, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2193 |  |  |                 'restrictFields' => false | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2194 |  |  |             ), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2195 |  |  |             (array)$_params | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2196 |  |  |         ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2197 |  |  |         $fields = new FieldList(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2198 |  |  |         foreach ($this->searchableFields() as $fieldName => $spec) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2199 |  |  |             if ($params['restrictFields'] && !in_array($fieldName, $params['restrictFields'])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2200 |  |  |                 continue; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2201 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2202 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2203 |  |  |             // If a custom fieldclass is provided as a string, use it | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2204 |  |  |             $field = null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2205 |  |  |             if ($params['fieldClasses'] && isset($params['fieldClasses'][$fieldName])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2206 |  |  |                 $fieldClass = $params['fieldClasses'][$fieldName]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2207 |  |  |                 $field = new $fieldClass($fieldName); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2208 |  |  |             // If we explicitly set a field, then construct that | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2209 |  |  |             } elseif (isset($spec['field'])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2210 |  |  |                 // If it's a string, use it as a class name and construct | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2211 |  |  |                 if (is_string($spec['field'])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2212 |  |  |                     $fieldClass = $spec['field']; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2213 |  |  |                     $field = new $fieldClass($fieldName); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2214 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2215 |  |  |                 // If it's a FormField object, then just use that object directly. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2216 |  |  |                 } elseif ($spec['field'] instanceof FormField) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2217 |  |  |                     $field = $spec['field']; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2218 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2219 |  |  |                 // Otherwise we have a bug | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2220 |  |  |                 } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2221 |  |  |                     user_error("Bad value for searchable_fields, 'field' value: " | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2222 |  |  |                         . var_export($spec['field'], true), E_USER_WARNING); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2223 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2224 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2225 |  |  |             // Otherwise, use the database field's scaffolder | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2226 |  |  |             } elseif ($object = $this->relObject($fieldName)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2227 |  |  |                 $field = $object->scaffoldSearchField(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2228 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2229 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2230 |  |  |             // Allow fields to opt out of search | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2231 |  |  |             if (!$field) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2232 |  |  |                 continue; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2233 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2234 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2235 |  |  |             if (strstr($fieldName, '.')) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2236 |  |  |                 $field->setName(str_replace('.', '__', $fieldName)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2237 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2238 |  |  |             $field->setTitle($spec['title']); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2239 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2240 |  |  |             $fields->push($field); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2241 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2242 |  |  |         return $fields; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2243 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2244 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2245 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2246 |  |  |      * Scaffold a simple edit form for all properties on this dataobject, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2247 |  |  |      * based on default {@link FormField} mapping in {@link DBField::scaffoldFormField()}. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2248 |  |  |      * Field labels/titles will be auto generated from {@link DataObject::fieldLabels()}. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2249 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2250 |  |  |      * @uses FormScaffolder | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2251 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2252 |  |  |      * @param array $_params Associative array passing through properties to {@link FormScaffolder}. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2253 |  |  |      * @return FieldList | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2254 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2255 |  |  |     public function scaffoldFormFields($_params = null) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2256 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2257 |  |  |         $params = array_merge( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2258 |  |  |             array( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2259 |  |  |                 'tabbed' => false, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2260 |  |  |                 'includeRelations' => false, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2261 |  |  |                 'restrictFields' => false, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2262 |  |  |                 'fieldClasses' => false, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2263 |  |  |                 'ajaxSafe' => false | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2264 |  |  |             ), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2265 |  |  |             (array)$_params | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2266 |  |  |         ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2267 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2268 |  |  |         $fs = FormScaffolder::create($this); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2269 |  |  |         $fs->tabbed = $params['tabbed']; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2270 |  |  |         $fs->includeRelations = $params['includeRelations']; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2271 |  |  |         $fs->restrictFields = $params['restrictFields']; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2272 |  |  |         $fs->fieldClasses = $params['fieldClasses']; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2273 |  |  |         $fs->ajaxSafe = $params['ajaxSafe']; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2274 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2275 |  |  |         return $fs->getFieldList(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2276 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2277 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2278 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2279 |  |  |      * Allows user code to hook into DataObject::getCMSFields prior to updateCMSFields | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2280 |  |  |      * being called on extensions | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2281 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2282 |  |  |      * @param callable $callback The callback to execute | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2283 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2284 |  |  |     protected function beforeUpdateCMSFields($callback) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2285 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2286 |  |  |         $this->beforeExtending('updateCMSFields', $callback); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2287 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2288 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2289 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2290 |  |  |      * Centerpiece of every data administration interface in Silverstripe, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2291 |  |  |      * which returns a {@link FieldList} suitable for a {@link Form} object. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2292 |  |  |      * If not overloaded, we're using {@link scaffoldFormFields()} to automatically | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2293 |  |  |      * generate this set. To customize, overload this method in a subclass | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2294 |  |  |      * or extended onto it by using {@link DataExtension->updateCMSFields()}. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2295 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2296 |  |  |      * <code> | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2297 |  |  |      * class MyCustomClass extends DataObject { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2298 |  |  |      *  static $db = array('CustomProperty'=>'Boolean'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2299 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2300 |  |  |      *  function getCMSFields() { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2301 |  |  |      *    $fields = parent::getCMSFields(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2302 |  |  |      *    $fields->addFieldToTab('Root.Content',new CheckboxField('CustomProperty')); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2303 |  |  |      *    return $fields; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2304 |  |  |      *  } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2305 |  |  |      * } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2306 |  |  |      * </code> | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2307 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2308 |  |  |      * @see Good example of complex FormField building: SiteTree::getCMSFields() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2309 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2310 |  |  |      * @return FieldList Returns a TabSet for usage within the CMS - don't use for frontend forms. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2311 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2312 |  |  |     public function getCMSFields() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2313 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2314 |  |  |         $tabbedFields = $this->scaffoldFormFields(array( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2315 |  |  |             // Don't allow has_many/many_many relationship editing before the record is first saved | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2316 |  |  |             'includeRelations' => ($this->ID > 0), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2317 |  |  |             'tabbed' => true, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2318 |  |  |             'ajaxSafe' => true | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2319 |  |  |         )); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2320 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2321 |  |  |         $this->extend('updateCMSFields', $tabbedFields); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2322 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2323 |  |  |         return $tabbedFields; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2324 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2325 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2326 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2327 |  |  |      * need to be overload by solid dataobject, so that the customised actions of that dataobject, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2328 |  |  |      * including that dataobject's extensions customised actions could be added to the EditForm. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2329 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2330 |  |  |      * @return FieldList an Empty FieldList(); need to be overload by solid subclass | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2331 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2332 |  |  |     public function getCMSActions() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2333 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2334 |  |  |         $actions = new FieldList(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2335 |  |  |         $this->extend('updateCMSActions', $actions); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2336 |  |  |         return $actions; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2337 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2338 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2339 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2340 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2341 |  |  |      * Used for simple frontend forms without relation editing | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2342 |  |  |      * or {@link TabSet} behaviour. Uses {@link scaffoldFormFields()} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2343 |  |  |      * by default. To customize, either overload this method in your | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2344 |  |  |      * subclass, or extend it by {@link DataExtension->updateFrontEndFields()}. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2345 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2346 |  |  |      * @todo Decide on naming for "website|frontend|site|page" and stick with it in the API | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2347 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2348 |  |  |      * @param array $params See {@link scaffoldFormFields()} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2349 |  |  |      * @return FieldList Always returns a simple field collection without TabSet. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2350 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2351 |  |  |     public function getFrontEndFields($params = null) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2352 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2353 |  |  |         $untabbedFields = $this->scaffoldFormFields($params); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2354 |  |  |         $this->extend('updateFrontEndFields', $untabbedFields); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2355 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2356 |  |  |         return $untabbedFields; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2357 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2358 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2359 |  |  |     public function getViewerTemplates($suffix = '') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2360 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2361 |  |  |         return SSViewer::get_templates_by_class(static::class, $suffix, $this->baseClass()); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2362 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2363 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2364 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2365 |  |  |      * Gets the value of a field. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2366 |  |  |      * Called by {@link __get()} and any getFieldName() methods you might create. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2367 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2368 |  |  |      * @param string $field The name of the field | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2369 |  |  |      * @return mixed The field value | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2370 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2371 |  |  |     public function getField($field) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2372 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2373 |  |  |         // If we already have a value in $this->record, then we should just return that | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2374 |  |  |         if (isset($this->record[$field])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2375 |  |  |             return $this->record[$field]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2376 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2377 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2378 |  |  |         // Do we have a field that needs to be lazy loaded? | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2379 |  |  |         if (isset($this->record[$field . '_Lazy'])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2380 |  |  |             $tableClass = $this->record[$field . '_Lazy']; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2381 |  |  |             $this->loadLazyFields($tableClass); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2382 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2383 |  |  |         $schema = static::getSchema(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2384 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2385 |  |  |         // Support unary relations as fields | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2386 |  |  |         if ($schema->unaryComponent(static::class, $field)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2387 |  |  |             return $this->getComponent($field); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2388 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2389 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2390 |  |  |         // In case of complex fields, return the DBField object | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2391 |  |  |         if ($schema->compositeField(static::class, $field)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2392 |  |  |             $this->record[$field] = $this->dbObject($field); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2393 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2394 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2395 |  |  |         return isset($this->record[$field]) ? $this->record[$field] : null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2396 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2397 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2398 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2399 |  |  |      * Loads all the stub fields that an initial lazy load didn't load fully. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2400 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2401 |  |  |      * @param string $class Class to load the values from. Others are joined as required. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2402 |  |  |      * Not specifying a tableClass will load all lazy fields from all tables. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2403 |  |  |      * @return bool Flag if lazy loading succeeded | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2404 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2405 |  |  |     protected function loadLazyFields($class = null) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2406 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2407 |  |  |         if (!$this->isInDB() || !is_numeric($this->ID)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2408 |  |  |             return false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2409 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2410 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2411 |  |  |         if (!$class) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2412 |  |  |             $loaded = array(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2413 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2414 |  |  |             foreach ($this->record as $key => $value) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2415 |  |  |                 if (strlen($key) > 5 && substr($key, -5) == '_Lazy' && !array_key_exists($value, $loaded)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2416 |  |  |                     $this->loadLazyFields($value); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2417 |  |  |                     $loaded[$value] = $value; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2418 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2419 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2420 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2421 |  |  |             return false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2422 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2423 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2424 |  |  |         $dataQuery = new DataQuery($class); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2425 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2426 |  |  |         // Reset query parameter context to that of this DataObject | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2427 |  |  |         if ($params = $this->getSourceQueryParams()) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2428 |  |  |             foreach ($params as $key => $value) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2429 |  |  |                 $dataQuery->setQueryParam($key, $value); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2430 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2431 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2432 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2433 |  |  |         // Limit query to the current record, unless it has the Versioned extension, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2434 |  |  |         // in which case it requires special handling through augmentLoadLazyFields() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2435 |  |  |         $schema = static::getSchema(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2436 |  |  |         $baseIDColumn = $schema->sqlColumnForField($this, 'ID'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2437 |  |  |         $dataQuery->where([ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2438 |  |  |             $baseIDColumn => $this->record['ID'] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2439 |  |  |         ])->limit(1); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2440 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2441 |  |  |         $columns = array(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2442 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2443 |  |  |         // Add SQL for fields, both simple & multi-value | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2444 |  |  |         // TODO: This is copy & pasted from buildSQL(), it could be moved into a method | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2445 |  |  |         $databaseFields = $schema->databaseFields($class, false); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2446 |  |  |         foreach ($databaseFields as $k => $v) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2447 |  |  |             if (!isset($this->record[$k]) || $this->record[$k] === null) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2448 |  |  |                 $columns[] = $k; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2449 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2450 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2451 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2452 |  |  |         if ($columns) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2453 |  |  |             $query = $dataQuery->query(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2454 |  |  |             $this->extend('augmentLoadLazyFields', $query, $dataQuery, $this); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2455 |  |  |             $this->extend('augmentSQL', $query, $dataQuery); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2456 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2457 |  |  |             $dataQuery->setQueriedColumns($columns); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2458 |  |  |             $newData = $dataQuery->execute()->record(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2459 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2460 |  |  |             // Load the data into record | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2461 |  |  |             if ($newData) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2462 |  |  |                 foreach ($newData as $k => $v) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2463 |  |  |                     if (in_array($k, $columns)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2464 |  |  |                         $this->record[$k] = $v; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2465 |  |  |                         $this->original[$k] = $v; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2466 |  |  |                         unset($this->record[$k . '_Lazy']); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2467 |  |  |                     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2468 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2469 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2470 |  |  |             // No data means that the query returned nothing; assign 'null' to all the requested fields | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2471 |  |  |             } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2472 |  |  |                 foreach ($columns as $k) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2473 |  |  |                     $this->record[$k] = null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2474 |  |  |                     $this->original[$k] = null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2475 |  |  |                     unset($this->record[$k . '_Lazy']); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2476 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2477 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2478 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2479 |  |  |         return true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2480 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2481 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2482 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2483 |  |  |      * Return the fields that have changed. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2484 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2485 |  |  |      * The change level affects what the functions defines as "changed": | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2486 |  |  |      * - Level CHANGE_STRICT (integer 1) will return strict changes, even !== ones. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2487 |  |  |      * - Level CHANGE_VALUE (integer 2) is more lenient, it will only return real data changes, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2488 |  |  |      *   for example a change from 0 to null would not be included. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2489 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2490 |  |  |      * Example return: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2491 |  |  |      * <code> | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2492 |  |  |      * array( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2493 |  |  |      *   'Title' = array('before' => 'Home', 'after' => 'Home-Changed', 'level' => DataObject::CHANGE_VALUE) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2494 |  |  |      * ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2495 |  |  |      * </code> | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2496 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2497 |  |  |      * @param boolean|array $databaseFieldsOnly Filter to determine which fields to return. Set to true | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2498 |  |  |      * to return all database fields, or an array for an explicit filter. false returns all fields. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2499 |  |  |      * @param int $changeLevel The strictness of what is defined as change. Defaults to strict | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2500 |  |  |      * @return array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2501 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2502 |  |  |     public function getChangedFields($databaseFieldsOnly = false, $changeLevel = self::CHANGE_STRICT) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2503 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2504 |  |  |         $changedFields = array(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2505 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2506 |  |  |         // Update the changed array with references to changed obj-fields | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2507 |  |  |         foreach ($this->record as $k => $v) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2508 |  |  |             // Prevents DBComposite infinite looping on isChanged | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2509 |  |  |             if (is_array($databaseFieldsOnly) && !in_array($k, $databaseFieldsOnly)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2510 |  |  |                 continue; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2511 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2512 |  |  |             if (is_object($v) && method_exists($v, 'isChanged') && $v->isChanged()) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2513 |  |  |                 $this->changed[$k] = self::CHANGE_VALUE; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2514 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2515 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2516 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2517 |  |  |         if (is_array($databaseFieldsOnly)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2518 |  |  |             $fields = array_intersect_key((array)$this->changed, array_flip($databaseFieldsOnly)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2519 |  |  |         } elseif ($databaseFieldsOnly) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2520 |  |  |             $fieldsSpecs = static::getSchema()->fieldSpecs(static::class); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2521 |  |  |             $fields = array_intersect_key((array)$this->changed, $fieldsSpecs); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2522 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2523 |  |  |             $fields = $this->changed; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2524 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2525 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2526 |  |  |         // Filter the list to those of a certain change level | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2527 |  |  |         if ($changeLevel > self::CHANGE_STRICT) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2528 |  |  |             if ($fields) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2529 |  |  |                 foreach ($fields as $name => $level) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2530 |  |  |                     if ($level < $changeLevel) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2531 |  |  |                         unset($fields[$name]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2532 |  |  |                     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2533 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2534 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2535 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2536 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2537 |  |  |         if ($fields) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2538 |  |  |             foreach ($fields as $name => $level) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2539 |  |  |                 $changedFields[$name] = array( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2540 |  |  |                     'before' => array_key_exists($name, $this->original) ? $this->original[$name] : null, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2541 |  |  |                     'after' => array_key_exists($name, $this->record) ? $this->record[$name] : null, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2542 |  |  |                     'level' => $level | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2543 |  |  |                 ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2544 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2545 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2546 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2547 |  |  |         return $changedFields; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2548 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2549 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2550 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2551 |  |  |      * Uses {@link getChangedFields()} to determine if fields have been changed | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2552 |  |  |      * since loading them from the database. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2553 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2554 |  |  |      * @param string $fieldName Name of the database field to check, will check for any if not given | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2555 |  |  |      * @param int $changeLevel See {@link getChangedFields()} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2556 |  |  |      * @return boolean | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2557 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2558 |  |  |     public function isChanged($fieldName = null, $changeLevel = self::CHANGE_STRICT) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2559 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2560 |  |  |         $fields = $fieldName ? array($fieldName) : true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2561 |  |  |         $changed = $this->getChangedFields($fields, $changeLevel); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2562 |  |  |         if (!isset($fieldName)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2563 |  |  |             return !empty($changed); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2564 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2565 |  |  |             return array_key_exists($fieldName, $changed); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2566 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2567 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2568 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2569 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2570 |  |  |      * Set the value of the field | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2571 |  |  |      * Called by {@link __set()} and any setFieldName() methods you might create. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2572 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2573 |  |  |      * @param string $fieldName Name of the field | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2574 |  |  |      * @param mixed $val New field value | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2575 |  |  |      * @return $this | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2576 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2577 |  |  |     public function setField($fieldName, $val) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2578 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2579 |  |  |         $this->objCacheClear(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2580 |  |  |         //if it's a has_one component, destroy the cache | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2581 |  |  |         if (substr($fieldName, -2) == 'ID') { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2582 |  |  |             unset($this->components[substr($fieldName, 0, -2)]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2583 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2584 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2585 |  |  |         // If we've just lazy-loaded the column, then we need to populate the $original array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2586 |  |  |         if (isset($this->record[$fieldName . '_Lazy'])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2587 |  |  |             $tableClass = $this->record[$fieldName . '_Lazy']; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2588 |  |  |             $this->loadLazyFields($tableClass); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2589 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2590 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2591 |  |  |         // Support component assignent via field setter | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2592 |  |  |         $schema = static::getSchema(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2593 |  |  |         if ($schema->unaryComponent(static::class, $fieldName)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2594 |  |  |             unset($this->components[$fieldName]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2595 |  |  |             // Assign component directly | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2596 |  |  |             if (is_null($val) || $val instanceof DataObject) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2597 |  |  |                 return $this->setComponent($fieldName, $val); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2598 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2599 |  |  |             // Assign by ID instead of object | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2600 |  |  |             if (is_numeric($val)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2601 |  |  |                 $fieldName .= 'ID'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2602 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2603 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2604 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2605 |  |  |         // Situation 1: Passing an DBField | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2606 |  |  |         if ($val instanceof DBField) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2607 |  |  |             $val->setName($fieldName); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2608 |  |  |             $val->saveInto($this); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2609 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2610 |  |  |             // Situation 1a: Composite fields should remain bound in case they are | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2611 |  |  |             // later referenced to update the parent dataobject | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2612 |  |  |             if ($val instanceof DBComposite) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2613 |  |  |                 $val->bindTo($this); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2614 |  |  |                 $this->record[$fieldName] = $val; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2615 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2616 |  |  |         // Situation 2: Passing a literal or non-DBField object | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2617 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2618 |  |  |             // If this is a proper database field, we shouldn't be getting non-DBField objects | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2619 |  |  |             if (is_object($val) && $schema->fieldSpec(static::class, $fieldName)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2620 |  |  |                 throw new InvalidArgumentException('DataObject::setField: passed an object that is not a DBField'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2621 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2622 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2623 |  |  |             // if a field is not existing or has strictly changed | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2624 |  |  |             if (!isset($this->record[$fieldName]) || $this->record[$fieldName] !== $val) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2625 |  |  |                 // TODO Add check for php-level defaults which are not set in the db | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2626 |  |  |                 // TODO Add check for hidden input-fields (readonly) which are not set in the db | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2627 |  |  |                 // At the very least, the type has changed | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2628 |  |  |                 $this->changed[$fieldName] = self::CHANGE_STRICT; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2629 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2630 |  |  |                 if ((!isset($this->record[$fieldName]) && $val) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2631 |  |  |                     || (isset($this->record[$fieldName]) && $this->record[$fieldName] != $val) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2632 |  |  |                 ) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2633 |  |  |                     // Value has changed as well, not just the type | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2634 |  |  |                     $this->changed[$fieldName] = self::CHANGE_VALUE; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2635 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2636 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2637 |  |  |                 // Value is always saved back when strict check succeeds. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2638 |  |  |                 $this->record[$fieldName] = $val; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2639 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2640 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2641 |  |  |         return $this; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2642 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2643 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2644 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2645 |  |  |      * Set the value of the field, using a casting object. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2646 |  |  |      * This is useful when you aren't sure that a date is in SQL format, for example. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2647 |  |  |      * setCastedField() can also be used, by forms, to set related data.  For example, uploaded images | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2648 |  |  |      * can be saved into the Image table. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2649 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2650 |  |  |      * @param string $fieldName Name of the field | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2651 |  |  |      * @param mixed $value New field value | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2652 |  |  |      * @return $this | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2653 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2654 |  |  |     public function setCastedField($fieldName, $value) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2655 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2656 |  |  |         if (!$fieldName) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2657 |  |  |             user_error("DataObject::setCastedField: Called without a fieldName", E_USER_ERROR); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2658 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2659 |  |  |         $fieldObj = $this->dbObject($fieldName); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2660 |  |  |         if ($fieldObj) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2661 |  |  |             $fieldObj->setValue($value); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2662 |  |  |             $fieldObj->saveInto($this); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2663 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2664 |  |  |             $this->$fieldName = $value; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2665 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2666 |  |  |         return $this; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2667 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2668 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2669 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2670 |  |  |      * {@inheritdoc} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2671 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2672 |  |  |     public function castingHelper($field) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2673 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2674 |  |  |         $fieldSpec = static::getSchema()->fieldSpec(static::class, $field); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2675 |  |  |         if ($fieldSpec) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2676 |  |  |             return $fieldSpec; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2677 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2678 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2679 |  |  |         // many_many_extraFields aren't presented by db(), so we check if the source query params | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2680 |  |  |         // provide us with meta-data for a many_many relation we can inspect for extra fields. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2681 |  |  |         $queryParams = $this->getSourceQueryParams(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2682 |  |  |         if (!empty($queryParams['Component.ExtraFields'])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2683 |  |  |             $extraFields = $queryParams['Component.ExtraFields']; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2684 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2685 |  |  |             if (isset($extraFields[$field])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2686 |  |  |                 return $extraFields[$field]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2687 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2688 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2689 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2690 |  |  |         return parent::castingHelper($field); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2691 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2692 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2693 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2694 |  |  |      * Returns true if the given field exists in a database column on any of | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2695 |  |  |      * the objects tables and optionally look up a dynamic getter with | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2696 |  |  |      * get<fieldName>(). | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2697 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2698 |  |  |      * @param string $field Name of the field | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2699 |  |  |      * @return boolean True if the given field exists | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2700 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2701 |  |  |     public function hasField($field) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2702 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2703 |  |  |         $schema = static::getSchema(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2704 |  |  |         return ( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2705 |  |  |             array_key_exists($field, $this->record) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2706 |  |  |             || array_key_exists($field, $this->components) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2707 |  |  |             || $schema->fieldSpec(static::class, $field) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2708 |  |  |             || $schema->unaryComponent(static::class, $field) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2709 |  |  |             || $this->hasMethod("get{$field}") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2710 |  |  |         ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2711 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2712 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2713 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2714 |  |  |      * Returns true if the given field exists as a database column | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2715 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2716 |  |  |      * @param string $field Name of the field | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2717 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2718 |  |  |      * @return boolean | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2719 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2720 |  |  |     public function hasDatabaseField($field) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2721 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2722 |  |  |         $spec = static::getSchema()->fieldSpec(static::class, $field, DataObjectSchema::DB_ONLY); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2723 |  |  |         return !empty($spec); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2724 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2725 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2726 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2727 |  |  |      * Returns true if the member is allowed to do the given action. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2728 |  |  |      * See {@link extendedCan()} for a more versatile tri-state permission control. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2729 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2730 |  |  |      * @param string $perm The permission to be checked, such as 'View'. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2731 |  |  |      * @param Member $member The member whose permissions need checking.  Defaults to the currently logged | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2732 |  |  |      * in user. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2733 |  |  |      * @param array $context Additional $context to pass to extendedCan() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2734 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2735 |  |  |      * @return boolean True if the the member is allowed to do the given action | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2736 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2737 |  |  |     public function can($perm, $member = null, $context = array()) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2738 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2739 |  |  |         if (!$member) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2740 |  |  |             $member = Security::getCurrentUser(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2741 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2742 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2743 |  |  |         if ($member && Permission::checkMember($member, "ADMIN")) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2744 |  |  |             return true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2745 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2746 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2747 |  |  |         if (is_string($perm) && method_exists($this, 'can' . ucfirst($perm))) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2748 |  |  |             $method = 'can' . ucfirst($perm); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2749 |  |  |             return $this->$method($member); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2750 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2751 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2752 |  |  |         $results = $this->extendedCan('can', $member); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2753 |  |  |         if (isset($results)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2754 |  |  |             return $results; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2755 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2756 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2757 |  |  |         return ($member && Permission::checkMember($member, $perm)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2758 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2759 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2760 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2761 |  |  |      * Process tri-state responses from permission-alterting extensions.  The extensions are | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2762 |  |  |      * expected to return one of three values: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2763 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2764 |  |  |      *  - false: Disallow this permission, regardless of what other extensions say | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2765 |  |  |      *  - true: Allow this permission, as long as no other extensions return false | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2766 |  |  |      *  - NULL: Don't affect the outcome | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2767 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2768 |  |  |      * This method itself returns a tri-state value, and is designed to be used like this: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2769 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2770 |  |  |      * <code> | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2771 |  |  |      * $extended = $this->extendedCan('canDoSomething', $member); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2772 |  |  |      * if($extended !== null) return $extended; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2773 |  |  |      * else return $normalValue; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2774 |  |  |      * </code> | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2775 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2776 |  |  |      * @param string $methodName Method on the same object, e.g. {@link canEdit()} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2777 |  |  |      * @param Member|int $member | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2778 |  |  |      * @param array $context Optional context | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2779 |  |  |      * @return boolean|null | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2780 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2781 |  |  |     public function extendedCan($methodName, $member, $context = array()) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2782 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2783 |  |  |         $results = $this->extend($methodName, $member, $context); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2784 |  |  |         if ($results && is_array($results)) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2785 |  |  |             // Remove NULLs | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2786 |  |  |             $results = array_filter($results, function ($v) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2787 |  |  |                 return !is_null($v); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2788 |  |  |             }); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2789 |  |  |             // If there are any non-NULL responses, then return the lowest one of them. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2790 |  |  |             // If any explicitly deny the permission, then we don't get access | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2791 |  |  |             if ($results) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2792 |  |  |                 return min($results); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2793 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2794 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2795 |  |  |         return null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2796 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2797 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2798 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2799 |  |  |      * @param Member $member | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2800 |  |  |      * @return boolean | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2801 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2802 |  |  |     public function canView($member = null) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2803 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2804 |  |  |         $extended = $this->extendedCan(__FUNCTION__, $member); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2805 |  |  |         if ($extended !== null) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2806 |  |  |             return $extended; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2807 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2808 |  |  |         return Permission::check('ADMIN', 'any', $member); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2809 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2810 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2811 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2812 |  |  |      * @param Member $member | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2813 |  |  |      * @return boolean | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2814 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2815 |  |  |     public function canEdit($member = null) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2816 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2817 |  |  |         $extended = $this->extendedCan(__FUNCTION__, $member); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2818 |  |  |         if ($extended !== null) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2819 |  |  |             return $extended; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2820 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2821 |  |  |         return Permission::check('ADMIN', 'any', $member); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2822 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2823 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2824 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2825 |  |  |      * @param Member $member | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2826 |  |  |      * @return boolean | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2827 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2828 |  |  |     public function canDelete($member = null) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2829 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2830 |  |  |         $extended = $this->extendedCan(__FUNCTION__, $member); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2831 |  |  |         if ($extended !== null) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2832 |  |  |             return $extended; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2833 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2834 |  |  |         return Permission::check('ADMIN', 'any', $member); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2835 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2836 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2837 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2838 |  |  |      * @param Member $member | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2839 |  |  |      * @param array $context Additional context-specific data which might | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2840 |  |  |      * affect whether (or where) this object could be created. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2841 |  |  |      * @return boolean | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2842 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2843 |  |  |     public function canCreate($member = null, $context = array()) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2844 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2845 |  |  |         $extended = $this->extendedCan(__FUNCTION__, $member, $context); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2846 |  |  |         if ($extended !== null) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2847 |  |  |             return $extended; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2848 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2849 |  |  |         return Permission::check('ADMIN', 'any', $member); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2850 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2851 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2852 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2853 |  |  |      * Debugging used by Debug::show() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2854 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2855 |  |  |      * @return string HTML data representing this object | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2856 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2857 |  |  |     public function debug() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2858 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2859 |  |  |         $class = static::class; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2860 |  |  |         $val = "<h3>Database record: {$class}</h3>\n<ul>\n"; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2861 |  |  |         if ($this->record) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2862 |  |  |             foreach ($this->record as $fieldName => $fieldVal) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2863 |  |  |                 $val .= "\t<li>$fieldName: " . Debug::text($fieldVal) . "</li>\n"; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2864 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2865 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2866 |  |  |         $val .= "</ul>\n"; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2867 |  |  |         return $val; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2868 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2869 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2870 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2871 |  |  |      * Return the DBField object that represents the given field. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2872 |  |  |      * This works similarly to obj() with 2 key differences: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2873 |  |  |      *   - it still returns an object even when the field has no value. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2874 |  |  |      *   - it only matches fields and not methods | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2875 |  |  |      *   - it matches foreign keys generated by has_one relationships, eg, "ParentID" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2876 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2877 |  |  |      * @param string $fieldName Name of the field | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2878 |  |  |      * @return DBField The field as a DBField object | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2879 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2880 |  |  |     public function dbObject($fieldName) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2881 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2882 |  |  |         // Check for field in DB | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2883 |  |  |         $schema = static::getSchema(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2884 |  |  |         $helper = $schema->fieldSpec(static::class, $fieldName, DataObjectSchema::INCLUDE_CLASS); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2885 |  |  |         if (!$helper) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2886 |  |  |             return null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2887 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2888 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2889 |  |  |         if (!isset($this->record[$fieldName]) && isset($this->record[$fieldName . '_Lazy'])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2890 |  |  |             $tableClass = $this->record[$fieldName . '_Lazy']; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2891 |  |  |             $this->loadLazyFields($tableClass); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2892 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2893 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2894 |  |  |         $value = isset($this->record[$fieldName]) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2895 |  |  |             ? $this->record[$fieldName] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2896 |  |  |             : null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2897 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2898 |  |  |         // If we have a DBField object in $this->record, then return that | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2899 |  |  |         if ($value instanceof DBField) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2900 |  |  |             return $value; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2901 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2902 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2903 |  |  |         list($class, $spec) = explode('.', $helper); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2904 |  |  |         /** @var DBField $obj */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2905 |  |  |         $table = $schema->tableName($class); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2906 |  |  |         $obj = Injector::inst()->create($spec, $fieldName); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2907 |  |  |         $obj->setTable($table); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2908 |  |  |         $obj->setValue($value, $this, false); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2909 |  |  |         return $obj; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2910 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2911 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2912 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2913 |  |  |      * Traverses to a DBField referenced by relationships between data objects. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2914 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2915 |  |  |      * The path to the related field is specified with dot separated syntax | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2916 |  |  |      * (eg: Parent.Child.Child.FieldName). | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2917 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2918 |  |  |      * If a relation is blank, this will return null instead. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2919 |  |  |      * If a relation name is invalid (e.g. non-relation on a parent) this | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2920 |  |  |      * can throw a LogicException. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2921 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2922 |  |  |      * @param string $fieldPath List of paths on this object. All items in this path | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2923 |  |  |      * must be ViewableData implementors | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2924 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2925 |  |  |      * @return mixed DBField of the field on the object or a DataList instance. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2926 |  |  |      * @throws LogicException If accessing invalid relations | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2927 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2928 |  |  |     public function relObject($fieldPath) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2929 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2930 |  |  |         $object = null; | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2931 |  |  |         $component = $this; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2932 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2933 |  |  |         // Parse all relations | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2934 |  |  |         foreach (explode('.', $fieldPath) as $relation) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2935 |  |  |             if (!$component) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2936 |  |  |                 return null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2937 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2938 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2939 |  |  |             // Inspect relation type | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2940 |  |  |             if (ClassInfo::hasMethod($component, $relation)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2941 |  |  |                 $component = $component->$relation(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2942 |  |  |             } elseif ($component instanceof Relation || $component instanceof DataList) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2943 |  |  |                 // $relation could either be a field (aggregate), or another relation | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2944 |  |  |                 $singleton = DataObject::singleton($component->dataClass()); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                            
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2945 |  |  |                 $component = $singleton->dbObject($relation) ?: $component->relation($relation); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2946 |  |  |             } elseif ($component instanceof DataObject && ($dbObject = $component->dbObject($relation))) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2947 |  |  |                 $component = $dbObject; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2948 |  |  |             } elseif ($component instanceof ViewableData && $component->hasField($relation)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2949 |  |  |                 $component = $component->obj($relation); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2950 |  |  |             } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2951 |  |  |                 throw new LogicException( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2952 |  |  |                     "$relation is not a relation/field on " . get_class($component) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2953 |  |  |                 ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2954 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2955 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2956 |  |  |         return $component; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2957 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2958 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2959 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2960 |  |  |      * Traverses to a field referenced by relationships between data objects, returning the value | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2961 |  |  |      * The path to the related field is specified with dot separated syntax (eg: Parent.Child.Child.FieldName) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2962 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2963 |  |  |      * @param string $fieldName string | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2964 |  |  |      * @return mixed Will return null on a missing value | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2965 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2966 |  |  |     public function relField($fieldName) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2967 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2968 |  |  |         // Navigate to relative parent using relObject() if needed | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2969 |  |  |         $component = $this; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2970 |  |  |         if (($pos = strrpos($fieldName, '.')) !== false) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2971 |  |  |             $relation = substr($fieldName, 0, $pos); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2972 |  |  |             $fieldName = substr($fieldName, $pos + 1); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2973 |  |  |             $component = $this->relObject($relation); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2974 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2975 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2976 |  |  |         // Bail if the component is null | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2977 |  |  |         if (!$component) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2978 |  |  |             return null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2979 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2980 |  |  |         if (ClassInfo::hasMethod($component, $fieldName)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2981 |  |  |             return $component->$fieldName(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2982 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2983 |  |  |         return $component->$fieldName; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2984 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2985 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2986 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2987 |  |  |      * Temporary hack to return an association name, based on class, to get around the mangle | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2988 |  |  |      * of having to deal with reverse lookup of relationships to determine autogenerated foreign keys. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2989 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2990 |  |  |      * @param string $className | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2991 |  |  |      * @return string | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2992 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2993 |  |  |     public function getReverseAssociation($className) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2994 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2995 |  |  |         if (is_array($this->manyMany())) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2996 |  |  |             $many_many = array_flip($this->manyMany()); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2997 |  |  |             if (array_key_exists($className, $many_many)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2998 |  |  |                 return $many_many[$className]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2999 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3000 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3001 |  |  |         if (is_array($this->hasMany())) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3002 |  |  |             $has_many = array_flip($this->hasMany()); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3003 |  |  |             if (array_key_exists($className, $has_many)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3004 |  |  |                 return $has_many[$className]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3005 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3006 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3007 |  |  |         if (is_array($this->hasOne())) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3008 |  |  |             $has_one = array_flip($this->hasOne()); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3009 |  |  |             if (array_key_exists($className, $has_one)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3010 |  |  |                 return $has_one[$className]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3011 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3012 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3013 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3014 |  |  |         return false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3015 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3016 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3017 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3018 |  |  |      * Return all objects matching the filter | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3019 |  |  |      * sub-classes are automatically selected and included | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3020 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3021 |  |  |      * @param string $callerClass The class of objects to be returned | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3022 |  |  |      * @param string|array $filter A filter to be inserted into the WHERE clause. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3023 |  |  |      * Supports parameterised queries. See SQLSelect::addWhere() for syntax examples. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3024 |  |  |      * @param string|array $sort A sort expression to be inserted into the ORDER | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3025 |  |  |      * BY clause.  If omitted, self::$default_sort will be used. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3026 |  |  |      * @param string $join Deprecated 3.0 Join clause. Use leftJoin($table, $joinClause) instead. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3027 |  |  |      * @param string|array $limit A limit expression to be inserted into the LIMIT clause. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3028 |  |  |      * @param string $containerClass The container class to return the results in. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3029 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3030 |  |  |      * @todo $containerClass is Ignored, why? | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3031 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3032 |  |  |      * @return DataList The objects matching the filter, in the class specified by $containerClass | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3033 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3034 |  |  |     public static function get( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3035 |  |  |         $callerClass = null, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3036 |  |  |         $filter = "", | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3037 |  |  |         $sort = "", | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3038 |  |  |         $join = "", | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3039 |  |  |         $limit = null, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3040 |  |  |         $containerClass = DataList::class | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3041 |  |  |     ) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3042 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3043 |  |  |         if ($callerClass == null) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3044 |  |  |             $callerClass = get_called_class(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3045 |  |  |             if ($callerClass == self::class) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3046 |  |  |                 throw new \InvalidArgumentException('Call <classname>::get() instead of DataObject::get()'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3047 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3048 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3049 |  |  |             if ($filter || $sort || $join || $limit || ($containerClass != DataList::class)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3050 |  |  |                 throw new \InvalidArgumentException('If calling <classname>::get() then you shouldn\'t pass any other' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3051 |  |  |                     . ' arguments'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3052 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3053 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3054 |  |  |             return DataList::create(get_called_class()); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3055 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3056 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3057 |  |  |         if ($join) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3058 |  |  |             throw new \InvalidArgumentException( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3059 |  |  |                 'The $join argument has been removed. Use leftJoin($table, $joinClause) instead.' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3060 |  |  |             ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3061 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3062 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3063 |  |  |         $result = DataList::create($callerClass)->where($filter)->sort($sort); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3064 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3065 |  |  |         if ($limit && strpos($limit, ',') !== false) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3066 |  |  |             $limitArguments = explode(',', $limit); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3067 |  |  |             $result = $result->limit($limitArguments[1], $limitArguments[0]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3068 |  |  |         } elseif ($limit) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3069 |  |  |             $result = $result->limit($limit); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3070 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3071 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3072 |  |  |         return $result; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3073 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3074 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3075 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3076 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3077 |  |  |      * Return the first item matching the given query. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3078 |  |  |      * All calls to get_one() are cached. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3079 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3080 |  |  |      * @param string $callerClass The class of objects to be returned | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3081 |  |  |      * @param string|array $filter A filter to be inserted into the WHERE clause. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3082 |  |  |      * Supports parameterised queries. See SQLSelect::addWhere() for syntax examples. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3083 |  |  |      * @param boolean $cache Use caching | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3084 |  |  |      * @param string $orderby A sort expression to be inserted into the ORDER BY clause. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3085 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3086 |  |  |      * @return DataObject|null The first item matching the query | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3087 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3088 |  |  |     public static function get_one($callerClass, $filter = "", $cache = true, $orderby = "") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3089 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3090 |  |  |         $SNG = singleton($callerClass); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3091 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3092 |  |  |         $cacheComponents = array($filter, $orderby, $SNG->extend('cacheKeyComponent')); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3093 |  |  |         $cacheKey = md5(serialize($cacheComponents)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3094 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3095 |  |  |         $item = null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3096 |  |  |         if (!$cache || !isset(self::$_cache_get_one[$callerClass][$cacheKey])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3097 |  |  |             $dl = DataObject::get($callerClass)->where($filter)->sort($orderby); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3098 |  |  |             $item = $dl->first(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3099 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3100 |  |  |             if ($cache) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3101 |  |  |                 self::$_cache_get_one[$callerClass][$cacheKey] = $item; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3102 |  |  |                 if (!self::$_cache_get_one[$callerClass][$cacheKey]) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3103 |  |  |                     self::$_cache_get_one[$callerClass][$cacheKey] = false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3104 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3105 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3106 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3107 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3108 |  |  |         if ($cache) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3109 |  |  |             return self::$_cache_get_one[$callerClass][$cacheKey] ?: null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3110 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3111 |  |  |             return $item; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3112 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3113 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3114 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3115 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3116 |  |  |      * Flush the cached results for all relations (has_one, has_many, many_many) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3117 |  |  |      * Also clears any cached aggregate data. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3118 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3119 |  |  |      * @param boolean $persistent When true will also clear persistent data stored in the Cache system. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3120 |  |  |      *                            When false will just clear session-local cached data | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3121 |  |  |      * @return DataObject $this | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3122 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3123 |  |  |     public function flushCache($persistent = true) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3124 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3125 |  |  |         if (static::class == self::class) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3126 |  |  |             self::$_cache_get_one = array(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3127 |  |  |             return $this; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3128 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3129 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3130 |  |  |         $classes = ClassInfo::ancestry(static::class); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3131 |  |  |         foreach ($classes as $class) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3132 |  |  |             if (isset(self::$_cache_get_one[$class])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3133 |  |  |                 unset(self::$_cache_get_one[$class]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3134 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3135 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3136 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3137 |  |  |         $this->extend('flushCache'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3138 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3139 |  |  |         $this->components = array(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3140 |  |  |         return $this; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3141 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3142 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3143 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3144 |  |  |      * Flush the get_one global cache and destroy associated objects. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3145 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3146 |  |  |     public static function flush_and_destroy_cache() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3147 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3148 |  |  |         if (self::$_cache_get_one) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3149 |  |  |             foreach (self::$_cache_get_one as $class => $items) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3150 |  |  |                 if (is_array($items)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3151 |  |  |                     foreach ($items as $item) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3152 |  |  |                         if ($item) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3153 |  |  |                             $item->destroy(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3154 |  |  |                         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3155 |  |  |                     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3156 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3157 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3158 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3159 |  |  |         self::$_cache_get_one = array(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3160 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3161 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3162 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3163 |  |  |      * Reset all global caches associated with DataObject. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3164 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3165 |  |  |     public static function reset() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3166 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3167 |  |  |         // @todo Decouple these | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3168 |  |  |         DBClassName::clear_classname_cache(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3169 |  |  |         ClassInfo::reset_db_cache(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3170 |  |  |         static::getSchema()->reset(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3171 |  |  |         self::$_cache_get_one = array(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3172 |  |  |         self::$_cache_field_labels = array(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3173 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3174 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3175 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3176 |  |  |      * Return the given element, searching by ID | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3177 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3178 |  |  |      * @param string $callerClass The class of the object to be returned | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3179 |  |  |      * @param int $id The id of the element | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3180 |  |  |      * @param boolean $cache See {@link get_one()} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3181 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3182 |  |  |      * @return DataObject The element | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3183 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3184 |  |  |     public static function get_by_id($callerClass, $id, $cache = true) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3185 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3186 |  |  |         if (!is_numeric($id)) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3187 |  |  |             user_error("DataObject::get_by_id passed a non-numeric ID #$id", E_USER_WARNING); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3188 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3189 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3190 |  |  |         // Pass to get_one | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3191 |  |  |         $column = static::getSchema()->sqlColumnForField($callerClass, 'ID'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3192 |  |  |         return DataObject::get_one($callerClass, array($column => $id), $cache); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3193 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3194 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3195 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3196 |  |  |      * Get the name of the base table for this object | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3197 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3198 |  |  |      * @return string | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3199 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3200 |  |  |     public function baseTable() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3201 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3202 |  |  |         return static::getSchema()->baseDataTable($this); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3203 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3204 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3205 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3206 |  |  |      * Get the base class for this object | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3207 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3208 |  |  |      * @return string | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3209 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3210 |  |  |     public function baseClass() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3211 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3212 |  |  |         return static::getSchema()->baseDataClass($this); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3213 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3214 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3215 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3216 |  |  |      * @var array Parameters used in the query that built this object. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3217 |  |  |      * This can be used by decorators (e.g. lazy loading) to | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3218 |  |  |      * run additional queries using the same context. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3219 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3220 |  |  |     protected $sourceQueryParams; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3221 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3222 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3223 |  |  |      * @see $sourceQueryParams | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3224 |  |  |      * @return array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3225 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3226 |  |  |     public function getSourceQueryParams() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3227 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3228 |  |  |         return $this->sourceQueryParams; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3229 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3230 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3231 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3232 |  |  |      * Get list of parameters that should be inherited to relations on this object | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3233 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3234 |  |  |      * @return array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3235 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3236 |  |  |     public function getInheritableQueryParams() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3237 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3238 |  |  |         $params = $this->getSourceQueryParams(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3239 |  |  |         $this->extend('updateInheritableQueryParams', $params); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3240 |  |  |         return $params; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3241 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3242 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3243 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3244 |  |  |      * @see $sourceQueryParams | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3245 |  |  |      * @param array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3246 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3247 |  |  |     public function setSourceQueryParams($array) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3248 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3249 |  |  |         $this->sourceQueryParams = $array; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3250 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3251 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3252 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3253 |  |  |      * @see $sourceQueryParams | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3254 |  |  |      * @param string $key | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3255 |  |  |      * @param string $value | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3256 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3257 |  |  |     public function setSourceQueryParam($key, $value) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3258 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3259 |  |  |         $this->sourceQueryParams[$key] = $value; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3260 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3261 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3262 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3263 |  |  |      * @see $sourceQueryParams | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3264 |  |  |      * @param string $key | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3265 |  |  |      * @return string | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3266 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3267 |  |  |     public function getSourceQueryParam($key) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3268 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3269 |  |  |         if (isset($this->sourceQueryParams[$key])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3270 |  |  |             return $this->sourceQueryParams[$key]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3271 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3272 |  |  |         return null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3273 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3274 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3275 |  |  |     //-------------------------------------------------------------------------------------------// | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3276 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3277 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3278 |  |  |      * Check the database schema and update it as necessary. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3279 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3280 |  |  |      * @uses DataExtension->augmentDatabase() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3281 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3282 |  |  |     public function requireTable() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3283 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3284 |  |  |         // Only build the table if we've actually got fields | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3285 |  |  |         $schema = static::getSchema(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3286 |  |  |         $table = $schema->tableName(static::class); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3287 |  |  |         $fields = $schema->databaseFields(static::class, false); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3288 |  |  |         $indexes = $schema->databaseIndexes(static::class, false); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3289 |  |  |         $extensions = self::database_extensions(static::class); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3290 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3291 |  |  |         if (empty($table)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3292 |  |  |             throw new LogicException( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3293 |  |  |                 "Class " . static::class . " not loaded by manifest, or no database table configured" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3294 |  |  |             ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3295 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3296 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3297 |  |  |         if ($fields) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3298 |  |  |             $hasAutoIncPK = get_parent_class($this) === self::class; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3299 |  |  |             DB::require_table( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3300 |  |  |                 $table, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3301 |  |  |                 $fields, | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3302 |  |  |                 $indexes, | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3303 |  |  |                 $hasAutoIncPK, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3304 |  |  |                 $this->config()->get('create_table_options'), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3305 |  |  |                 $extensions | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3306 |  |  |             ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3307 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3308 |  |  |             DB::dont_require_table($table); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3309 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3310 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3311 |  |  |         // Build any child tables for many_many items | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3312 |  |  |         if ($manyMany = $this->uninherited('many_many')) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3313 |  |  |             $extras = $this->uninherited('many_many_extraFields'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3314 |  |  |             foreach ($manyMany as $component => $spec) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3315 |  |  |                 // Get many_many spec | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3316 |  |  |                 $manyManyComponent = $schema->manyManyComponent(static::class, $component); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3317 |  |  |                 $parentField = $manyManyComponent['parentField']; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3318 |  |  |                 $childField = $manyManyComponent['childField']; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3319 |  |  |                 $tableOrClass = $manyManyComponent['join']; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3320 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3321 |  |  |                 // Skip if backed by actual class | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3322 |  |  |                 if (class_exists($tableOrClass)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3323 |  |  |                     continue; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3324 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3325 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3326 |  |  |                 // Build fields | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3327 |  |  |                 $manymanyFields = array( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3328 |  |  |                     $parentField => "Int", | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3329 |  |  |                     $childField => "Int", | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3330 |  |  |                 ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3331 |  |  |                 if (isset($extras[$component])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3332 |  |  |                     $manymanyFields = array_merge($manymanyFields, $extras[$component]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3333 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3334 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3335 |  |  |                 // Build index list | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3336 |  |  |                 $manymanyIndexes = [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3337 |  |  |                     $parentField => [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3338 |  |  |                         'type' => 'index', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3339 |  |  |                         'name' => $parentField, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3340 |  |  |                         'columns' => [$parentField], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3341 |  |  |                     ], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3342 |  |  |                     $childField => [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3343 |  |  |                         'type' => 'index', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3344 |  |  |                         'name' => $childField, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3345 |  |  |                         'columns' => [$childField], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3346 |  |  |                     ], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3347 |  |  |                 ]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3348 |  |  |                 DB::require_table($tableOrClass, $manymanyFields, $manymanyIndexes, true, null, $extensions); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                            
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3349 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3350 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3351 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3352 |  |  |         // Let any extentions make their own database fields | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3353 |  |  |         $this->extend('augmentDatabase', $dummy); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3354 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3355 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3356 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3357 |  |  |      * Add default records to database. This function is called whenever the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3358 |  |  |      * database is built, after the database tables have all been created. Overload | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3359 |  |  |      * this to add default records when the database is built, but make sure you | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3360 |  |  |      * call parent::requireDefaultRecords(). | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3361 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3362 |  |  |      * @uses DataExtension->requireDefaultRecords() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3363 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3364 |  |  |     public function requireDefaultRecords() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3365 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3366 |  |  |         $defaultRecords = $this->config()->uninherited('default_records'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3367 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3368 |  |  |         if (!empty($defaultRecords)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3369 |  |  |             $hasData = DataObject::get_one(static::class); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3370 |  |  |             if (!$hasData) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3371 |  |  |                 $className = static::class; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3372 |  |  |                 foreach ($defaultRecords as $record) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3373 |  |  |                     $obj = Injector::inst()->create($className, $record); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3374 |  |  |                     $obj->write(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3375 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3376 |  |  |                 DB::alteration_message("Added default records to $className table", "created"); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3377 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3378 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3379 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3380 |  |  |         // Let any extentions make their own database default data | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3381 |  |  |         $this->extend('requireDefaultRecords', $dummy); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3382 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3383 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3384 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3385 |  |  |      * Get the default searchable fields for this object, as defined in the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3386 |  |  |      * $searchable_fields list. If searchable fields are not defined on the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3387 |  |  |      * data object, uses a default selection of summary fields. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3388 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3389 |  |  |      * @return array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3390 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3391 |  |  |     public function searchableFields() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3392 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3393 |  |  |         // can have mixed format, need to make consistent in most verbose form | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3394 |  |  |         $fields = $this->config()->get('searchable_fields'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3395 |  |  |         $labels = $this->fieldLabels(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3396 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3397 |  |  |         // fallback to summary fields (unless empty array is explicitly specified) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3398 |  |  |         if (!$fields && !is_array($fields)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3399 |  |  |             $summaryFields = array_keys($this->summaryFields()); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3400 |  |  |             $fields = array(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3401 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3402 |  |  |             // remove the custom getters as the search should not include them | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3403 |  |  |             $schema = static::getSchema(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3404 |  |  |             if ($summaryFields) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3405 |  |  |                 foreach ($summaryFields as $key => $name) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3406 |  |  |                     $spec = $name; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3407 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3408 |  |  |                     // Extract field name in case this is a method called on a field (e.g. "Date.Nice") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3409 |  |  |                     if (($fieldPos = strpos($name, '.')) !== false) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3410 |  |  |                         $name = substr($name, 0, $fieldPos); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3411 |  |  |                     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3412 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3413 |  |  |                     if ($schema->fieldSpec($this, $name)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3414 |  |  |                         $fields[] = $name; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3415 |  |  |                     } elseif ($this->relObject($spec)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3416 |  |  |                         $fields[] = $spec; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3417 |  |  |                     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3418 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3419 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3420 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3421 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3422 |  |  |         // we need to make sure the format is unified before | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3423 |  |  |         // augmenting fields, so extensions can apply consistent checks | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3424 |  |  |         // but also after augmenting fields, because the extension | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3425 |  |  |         // might use the shorthand notation as well | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3426 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3427 |  |  |         // rewrite array, if it is using shorthand syntax | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3428 |  |  |         $rewrite = array(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3429 |  |  |         foreach ($fields as $name => $specOrName) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3430 |  |  |             $identifer = (is_int($name)) ? $specOrName : $name; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3431 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3432 |  |  |             if (is_int($name)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3433 |  |  |                 // Format: array('MyFieldName') | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3434 |  |  |                 $rewrite[$identifer] = array(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3435 |  |  |             } elseif (is_array($specOrName) && ($relObject = $this->relObject($identifer))) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3436 |  |  |                 // Format: array('MyFieldName' => array( | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3437 |  |  |                 //   'filter => 'ExactMatchFilter', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3438 |  |  |                 //   'field' => 'NumericField', // optional | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3439 |  |  |                 //   'title' => 'My Title', // optional | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3440 |  |  |                 // )) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3441 |  |  |                 $rewrite[$identifer] = array_merge( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3442 |  |  |                     array('filter' => $relObject->config()->get('default_search_filter_class')), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3443 |  |  |                     (array)$specOrName | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3444 |  |  |                 ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3445 |  |  |             } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3446 |  |  |                 // Format: array('MyFieldName' => 'ExactMatchFilter') | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3447 |  |  |                 $rewrite[$identifer] = array( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3448 |  |  |                     'filter' => $specOrName, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3449 |  |  |                 ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3450 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3451 |  |  |             if (!isset($rewrite[$identifer]['title'])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3452 |  |  |                 $rewrite[$identifer]['title'] = (isset($labels[$identifer])) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3453 |  |  |                     ? $labels[$identifer] : FormField::name_to_label($identifer); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3454 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3455 |  |  |             if (!isset($rewrite[$identifer]['filter'])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3456 |  |  |                 /** @skipUpgrade */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3457 |  |  |                 $rewrite[$identifer]['filter'] = 'PartialMatchFilter'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3458 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3459 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3460 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3461 |  |  |         $fields = $rewrite; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3462 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3463 |  |  |         // apply DataExtensions if present | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3464 |  |  |         $this->extend('updateSearchableFields', $fields); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3465 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3466 |  |  |         return $fields; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3467 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3468 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3469 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3470 |  |  |      * Get any user defined searchable fields labels that | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3471 |  |  |      * exist. Allows overriding of default field names in the form | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3472 |  |  |      * interface actually presented to the user. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3473 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3474 |  |  |      * The reason for keeping this separate from searchable_fields, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3475 |  |  |      * which would be a logical place for this functionality, is to | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3476 |  |  |      * avoid bloating and complicating the configuration array. Currently | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3477 |  |  |      * much of this system is based on sensible defaults, and this property | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3478 |  |  |      * would generally only be set in the case of more complex relationships | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3479 |  |  |      * between data object being required in the search interface. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3480 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3481 |  |  |      * Generates labels based on name of the field itself, if no static property | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3482 |  |  |      * {@link self::field_labels} exists. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3483 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3484 |  |  |      * @uses $field_labels | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3485 |  |  |      * @uses FormField::name_to_label() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3486 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3487 |  |  |      * @param boolean $includerelations a boolean value to indicate if the labels returned include relation fields | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3488 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3489 |  |  |      * @return array|string Array of all element labels if no argument given, otherwise the label of the field | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3490 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3491 |  |  |     public function fieldLabels($includerelations = true) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3492 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3493 |  |  |         $cacheKey = static::class . '_' . $includerelations; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3494 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3495 |  |  |         if (!isset(self::$_cache_field_labels[$cacheKey])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3496 |  |  |             $customLabels = $this->config()->get('field_labels'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3497 |  |  |             $autoLabels = array(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3498 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3499 |  |  |             // get all translated static properties as defined in i18nCollectStatics() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3500 |  |  |             $ancestry = ClassInfo::ancestry(static::class); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3501 |  |  |             $ancestry = array_reverse($ancestry); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3502 |  |  |             if ($ancestry) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3503 |  |  |                 foreach ($ancestry as $ancestorClass) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3504 |  |  |                     if ($ancestorClass === ViewableData::class) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3505 |  |  |                         break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3506 |  |  |                     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3507 |  |  |                     $types = [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3508 |  |  |                         'db' => (array)Config::inst()->get($ancestorClass, 'db', Config::UNINHERITED) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3509 |  |  |                     ]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3510 |  |  |                     if ($includerelations) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3511 |  |  |                         $types['has_one'] = (array)Config::inst()->get($ancestorClass, 'has_one', Config::UNINHERITED); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3512 |  |  |                         $types['has_many'] = (array)Config::inst()->get( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3513 |  |  |                             $ancestorClass, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3514 |  |  |                             'has_many', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3515 |  |  |                             Config::UNINHERITED | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3516 |  |  |                         ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3517 |  |  |                         $types['many_many'] = (array)Config::inst()->get( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3518 |  |  |                             $ancestorClass, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3519 |  |  |                             'many_many', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3520 |  |  |                             Config::UNINHERITED | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3521 |  |  |                         ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3522 |  |  |                         $types['belongs_many_many'] = (array)Config::inst()->get( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3523 |  |  |                             $ancestorClass, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3524 |  |  |                             'belongs_many_many', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3525 |  |  |                             Config::UNINHERITED | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3526 |  |  |                         ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3527 |  |  |                     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3528 |  |  |                     foreach ($types as $type => $attrs) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3529 |  |  |                         foreach ($attrs as $name => $spec) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3530 |  |  |                             $autoLabels[$name] = _t( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3531 |  |  |                                 "{$ancestorClass}.{$type}_{$name}", | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3532 |  |  |                                 FormField::name_to_label($name) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3533 |  |  |                             ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3534 |  |  |                         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3535 |  |  |                     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3536 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3537 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3538 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3539 |  |  |             $labels = array_merge((array)$autoLabels, (array)$customLabels); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3540 |  |  |             $this->extend('updateFieldLabels', $labels); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3541 |  |  |             self::$_cache_field_labels[$cacheKey] = $labels; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3542 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3543 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3544 |  |  |         return self::$_cache_field_labels[$cacheKey]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3545 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3546 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3547 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3548 |  |  |      * Get a human-readable label for a single field, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3549 |  |  |      * see {@link fieldLabels()} for more details. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3550 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3551 |  |  |      * @uses fieldLabels() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3552 |  |  |      * @uses FormField::name_to_label() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3553 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3554 |  |  |      * @param string $name Name of the field | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3555 |  |  |      * @return string Label of the field | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3556 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3557 |  |  |     public function fieldLabel($name) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3558 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3559 |  |  |         $labels = $this->fieldLabels(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3560 |  |  |         return (isset($labels[$name])) ? $labels[$name] : FormField::name_to_label($name); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3561 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3562 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3563 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3564 |  |  |      * Get the default summary fields for this object. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3565 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3566 |  |  |      * @todo use the translation apparatus to return a default field selection for the language | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3567 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3568 |  |  |      * @return array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3569 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3570 |  |  |     public function summaryFields() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3571 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3572 |  |  |         $rawFields = $this->config()->get('summary_fields'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3573 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3574 |  |  |         // Merge associative / numeric keys | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3575 |  |  |         $fields = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3576 |  |  |         foreach ($rawFields as $key => $value) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3577 |  |  |             if (is_int($key)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3578 |  |  |                 $key = $value; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3579 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3580 |  |  |             $fields[$key] = $value; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3581 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3582 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3583 |  |  |         if (!$fields) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3584 |  |  |             $fields = array(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3585 |  |  |             // try to scaffold a couple of usual suspects | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3586 |  |  |             if ($this->hasField('Name')) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3587 |  |  |                 $fields['Name'] = 'Name'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3588 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3589 |  |  |             if (static::getSchema()->fieldSpec($this, 'Title')) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3590 |  |  |                 $fields['Title'] = 'Title'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3591 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3592 |  |  |             if ($this->hasField('Description')) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3593 |  |  |                 $fields['Description'] = 'Description'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3594 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3595 |  |  |             if ($this->hasField('FirstName')) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3596 |  |  |                 $fields['FirstName'] = 'First Name'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3597 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3598 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3599 |  |  |         $this->extend("updateSummaryFields", $fields); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3600 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3601 |  |  |         // Final fail-over, just list ID field | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3602 |  |  |         if (!$fields) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3603 |  |  |             $fields['ID'] = 'ID'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3604 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3605 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3606 |  |  |         // Localize fields (if possible) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3607 |  |  |         foreach ($this->fieldLabels(false) as $name => $label) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3608 |  |  |             // only attempt to localize if the label definition is the same as the field name. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3609 |  |  |             // this will preserve any custom labels set in the summary_fields configuration | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3610 |  |  |             if (isset($fields[$name]) && $name === $fields[$name]) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3611 |  |  |                 $fields[$name] = $label; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3612 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3613 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3614 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3615 |  |  |         return $fields; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3616 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3617 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3618 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3619 |  |  |      * Defines a default list of filters for the search context. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3620 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3621 |  |  |      * If a filter class mapping is defined on the data object, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3622 |  |  |      * it is constructed here. Otherwise, the default filter specified in | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3623 |  |  |      * {@link DBField} is used. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3624 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3625 |  |  |      * @todo error handling/type checking for valid FormField and SearchFilter subclasses? | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3626 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3627 |  |  |      * @return array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3628 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3629 |  |  |     public function defaultSearchFilters() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3630 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3631 |  |  |         $filters = array(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3632 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3633 |  |  |         foreach ($this->searchableFields() as $name => $spec) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3634 |  |  |             if (empty($spec['filter'])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3635 |  |  |                 /** @skipUpgrade */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3636 |  |  |                 $filters[$name] = 'PartialMatchFilter'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3637 |  |  |             } elseif ($spec['filter'] instanceof SearchFilter) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3638 |  |  |                 $filters[$name] = $spec['filter']; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3639 |  |  |             } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3640 |  |  |                 $filters[$name] = Injector::inst()->create($spec['filter'], $name); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3641 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3642 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3643 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3644 |  |  |         return $filters; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3645 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3646 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3647 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3648 |  |  |      * @return boolean True if the object is in the database | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3649 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3650 |  |  |     public function isInDB() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3651 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3652 |  |  |         return is_numeric($this->ID) && $this->ID > 0; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3653 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3654 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3655 |  |  |     /* | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3656 |  |  |      * @ignore | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3657 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3658 |  |  |     private static $subclass_access = true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3659 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3660 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3661 |  |  |      * Temporarily disable subclass access in data object qeur | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3662 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3663 |  |  |     public static function disable_subclass_access() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3664 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3665 |  |  |         self::$subclass_access = false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3666 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3667 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3668 |  |  |     public static function enable_subclass_access() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3669 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3670 |  |  |         self::$subclass_access = true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3671 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3672 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3673 |  |  |     //-------------------------------------------------------------------------------------------// | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3674 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3675 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3676 |  |  |      * Database field definitions. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3677 |  |  |      * This is a map from field names to field type. The field | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3678 |  |  |      * type should be a class that extends . | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3679 |  |  |      * @var array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3680 |  |  |      * @config | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3681 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3682 |  |  |     private static $db = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3683 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3684 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3685 |  |  |      * Use a casting object for a field. This is a map from | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3686 |  |  |      * field name to class name of the casting object. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3687 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3688 |  |  |      * @var array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3689 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3690 |  |  |     private static $casting = array( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3691 |  |  |         "Title" => 'Text', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3692 |  |  |     ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3693 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3694 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3695 |  |  |      * Specify custom options for a CREATE TABLE call. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3696 |  |  |      * Can be used to specify a custom storage engine for specific database table. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3697 |  |  |      * All options have to be keyed for a specific database implementation, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3698 |  |  |      * identified by their class name (extending from {@link SS_Database}). | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3699 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3700 |  |  |      * <code> | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3701 |  |  |      * array( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3702 |  |  |      *  'MySQLDatabase' => 'ENGINE=MyISAM' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3703 |  |  |      * ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3704 |  |  |      * </code> | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3705 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3706 |  |  |      * Caution: This API is experimental, and might not be | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3707 |  |  |      * included in the next major release. Please use with care. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3708 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3709 |  |  |      * @var array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3710 |  |  |      * @config | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3711 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3712 |  |  |     private static $create_table_options = array( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3713 |  |  |         MySQLSchemaManager::ID => 'ENGINE=InnoDB' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3714 |  |  |     ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3715 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3716 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3717 |  |  |      * If a field is in this array, then create a database index | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3718 |  |  |      * on that field. This is a map from fieldname to index type. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3719 |  |  |      * See {@link SS_Database->requireIndex()} and custom subclasses for details on the array notation. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3720 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3721 |  |  |      * @var array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3722 |  |  |      * @config | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3723 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3724 |  |  |     private static $indexes = null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3725 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3726 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3727 |  |  |      * Inserts standard column-values when a DataObject | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3728 |  |  |      * is instanciated. Does not insert default records {@see $default_records}. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3729 |  |  |      * This is a map from fieldname to default value. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3730 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3731 |  |  |      *  - If you would like to change a default value in a sub-class, just specify it. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3732 |  |  |      *  - If you would like to disable the default value given by a parent class, set the default value to 0,'', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3733 |  |  |      *    or false in your subclass.  Setting it to null won't work. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3734 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3735 |  |  |      * @var array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3736 |  |  |      * @config | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3737 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3738 |  |  |     private static $defaults = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3739 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3740 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3741 |  |  |      * Multidimensional array which inserts default data into the database | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3742 |  |  |      * on a db/build-call as long as the database-table is empty. Please use this only | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3743 |  |  |      * for simple constructs, not for SiteTree-Objects etc. which need special | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3744 |  |  |      * behaviour such as publishing and ParentNodes. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3745 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3746 |  |  |      * Example: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3747 |  |  |      * array( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3748 |  |  |      *  array('Title' => "DefaultPage1", 'PageTitle' => 'page1'), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3749 |  |  |      *  array('Title' => "DefaultPage2") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3750 |  |  |      * ). | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3751 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3752 |  |  |      * @var array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3753 |  |  |      * @config | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3754 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3755 |  |  |     private static $default_records = null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3756 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3757 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3758 |  |  |      * One-to-zero relationship defintion. This is a map of component name to data type. In order to turn this into a | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3759 |  |  |      * true one-to-one relationship you can add a {@link DataObject::$belongs_to} relationship on the child class. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3760 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3761 |  |  |      * Note that you cannot have a has_one and belongs_to relationship with the same name. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3762 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3763 |  |  |      * @var array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3764 |  |  |      * @config | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3765 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3766 |  |  |     private static $has_one = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3767 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3768 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3769 |  |  |      * A meta-relationship that allows you to define the reverse side of a {@link DataObject::$has_one}. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3770 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3771 |  |  |      * This does not actually create any data structures, but allows you to query the other object in a one-to-one | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3772 |  |  |      * relationship from the child object. If you have multiple belongs_to links to another object you can use the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3773 |  |  |      * syntax "ClassName.HasOneName" to specify which foreign has_one key on the other object to use. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3774 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3775 |  |  |      * Note that you cannot have a has_one and belongs_to relationship with the same name. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3776 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3777 |  |  |      * @var array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3778 |  |  |      * @config | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3779 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3780 |  |  |     private static $belongs_to = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3781 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3782 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3783 |  |  |      * This defines a one-to-many relationship. It is a map of component name to the remote data class. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3784 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3785 |  |  |      * This relationship type does not actually create a data structure itself - you need to define a matching $has_one | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3786 |  |  |      * relationship on the child class. Also, if the $has_one relationship on the child class has multiple links to this | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3787 |  |  |      * class you can use the syntax "ClassName.HasOneRelationshipName" in the remote data class definition to show | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3788 |  |  |      * which foreign key to use. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3789 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3790 |  |  |      * @var array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3791 |  |  |      * @config | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3792 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3793 |  |  |     private static $has_many = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3794 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3795 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3796 |  |  |      * many-many relationship definitions. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3797 |  |  |      * This is a map from component name to data type. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3798 |  |  |      * @var array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3799 |  |  |      * @config | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3800 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3801 |  |  |     private static $many_many = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3802 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3803 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3804 |  |  |      * Extra fields to include on the connecting many-many table. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3805 |  |  |      * This is a map from field name to field type. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3806 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3807 |  |  |      * Example code: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3808 |  |  |      * <code> | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3809 |  |  |      * public static $many_many_extraFields = array( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3810 |  |  |      *  'Members' => array( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3811 |  |  |      *          'Role' => 'Varchar(100)' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3812 |  |  |      *      ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3813 |  |  |      * ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3814 |  |  |      * </code> | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3815 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3816 |  |  |      * @var array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3817 |  |  |      * @config | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3818 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3819 |  |  |     private static $many_many_extraFields = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3820 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3821 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3822 |  |  |      * The inverse side of a many-many relationship. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3823 |  |  |      * This is a map from component name to data type. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3824 |  |  |      * @var array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3825 |  |  |      * @config | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3826 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3827 |  |  |     private static $belongs_many_many = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3828 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3829 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3830 |  |  |      * The default sort expression. This will be inserted in the ORDER BY | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3831 |  |  |      * clause of a SQL query if no other sort expression is provided. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3832 |  |  |      * @var string | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3833 |  |  |      * @config | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3834 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3835 |  |  |     private static $default_sort = null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3836 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3837 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3838 |  |  |      * Default list of fields that can be scaffolded by the ModelAdmin | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3839 |  |  |      * search interface. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3840 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3841 |  |  |      * Overriding the default filter, with a custom defined filter: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3842 |  |  |      * <code> | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3843 |  |  |      *  static $searchable_fields = array( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3844 |  |  |      *     "Name" => "PartialMatchFilter" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3845 |  |  |      *  ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3846 |  |  |      * </code> | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3847 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3848 |  |  |      * Overriding the default form fields, with a custom defined field. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3849 |  |  |      * The 'filter' parameter will be generated from {@link DBField::$default_search_filter_class}. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3850 |  |  |      * The 'title' parameter will be generated from {@link DataObject->fieldLabels()}. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3851 |  |  |      * <code> | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3852 |  |  |      *  static $searchable_fields = array( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3853 |  |  |      *    "Name" => array( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3854 |  |  |      *      "field" => "TextField" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3855 |  |  |      *    ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3856 |  |  |      *  ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3857 |  |  |      * </code> | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3858 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3859 |  |  |      * Overriding the default form field, filter and title: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3860 |  |  |      * <code> | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3861 |  |  |      *  static $searchable_fields = array( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3862 |  |  |      *    "Organisation.ZipCode" => array( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3863 |  |  |      *      "field" => "TextField", | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3864 |  |  |      *      "filter" => "PartialMatchFilter", | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3865 |  |  |      *      "title" => 'Organisation ZIP' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3866 |  |  |      *    ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3867 |  |  |      *  ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3868 |  |  |      * </code> | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3869 |  |  |      * @config | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3870 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3871 |  |  |     private static $searchable_fields = null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3872 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3873 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3874 |  |  |      * User defined labels for searchable_fields, used to override | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3875 |  |  |      * default display in the search form. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3876 |  |  |      * @config | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3877 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3878 |  |  |     private static $field_labels = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3879 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3880 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3881 |  |  |      * Provides a default list of fields to be used by a 'summary' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3882 |  |  |      * view of this object. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3883 |  |  |      * @config | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3884 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3885 |  |  |     private static $summary_fields = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3886 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3887 |  |  |     public function provideI18nEntities() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3888 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3889 |  |  |         // Note: see http://guides.rubyonrails.org/i18n.html#pluralization for rules | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3890 |  |  |         // Best guess for a/an rule. Better guesses require overriding in subclasses | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3891 |  |  |         $pluralName = $this->plural_name(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3892 |  |  |         $singularName = $this->singular_name(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3893 |  |  |         $conjunction = preg_match('/^[aeiou]/i', $singularName) ? 'An ' : 'A '; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3894 |  |  |         return [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3895 |  |  |             static::class . '.SINGULARNAME' => $this->singular_name(), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3896 |  |  |             static::class . '.PLURALNAME' => $pluralName, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3897 |  |  |             static::class . '.PLURALS' => [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3898 |  |  |                 'one' => $conjunction . $singularName, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3899 |  |  |                 'other' => '{count} ' . $pluralName | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3900 |  |  |             ] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3901 |  |  |         ]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3902 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3903 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3904 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3905 |  |  |      * Returns true if the given method/parameter has a value | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3906 |  |  |      * (Uses the DBField::hasValue if the parameter is a database field) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3907 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3908 |  |  |      * @param string $field The field name | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3909 |  |  |      * @param array $arguments | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3910 |  |  |      * @param bool $cache | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3911 |  |  |      * @return boolean | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3912 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3913 |  |  |     public function hasValue($field, $arguments = null, $cache = true) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3914 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3915 |  |  |         // has_one fields should not use dbObject to check if a value is given | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3916 |  |  |         $hasOne = static::getSchema()->hasOneComponent(static::class, $field); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3917 |  |  |         if (!$hasOne && ($obj = $this->dbObject($field))) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3918 |  |  |             return $obj->exists(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3919 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3920 |  |  |             return parent::hasValue($field, $arguments, $cache); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3921 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3922 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3923 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3924 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3925 |  |  |      * If selected through a many_many through relation, this is the instance of the joined record | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3926 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3927 |  |  |      * @return DataObject | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3928 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3929 |  |  |     public function getJoin() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3930 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3931 |  |  |         return $this->joinRecord; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3932 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3933 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3934 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3935 |  |  |      * Set joining object | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3936 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3937 |  |  |      * @param DataObject $object | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3938 |  |  |      * @param string $alias Alias | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3939 |  |  |      * @return $this | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3940 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3941 |  |  |     public function setJoin(DataObject $object, $alias = null) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3942 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3943 |  |  |         $this->joinRecord = $object; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3944 |  |  |         if ($alias) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3945 |  |  |             if (static::getSchema()->fieldSpec(static::class, $alias)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3946 |  |  |                 throw new InvalidArgumentException( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3947 |  |  |                     "Joined record $alias cannot also be a db field" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3948 |  |  |                 ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3949 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3950 |  |  |             $this->record[$alias] = $object; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3951 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3952 |  |  |         return $this; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3953 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3954 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3955 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3956 |  |  |      * Find objects in the given relationships, merging them into the given list | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3957 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3958 |  |  |      * @param string $source Config property to extract relationships from | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3959 |  |  |      * @param bool $recursive True if recursive | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3960 |  |  |      * @param ArrayList $list If specified, items will be added to this list. If not, a new | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3961 |  |  |      * instance of ArrayList will be constructed and returned | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3962 |  |  |      * @return ArrayList The list of related objects | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3963 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3964 |  |  |     public function findRelatedObjects($source, $recursive = true, $list = null) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3965 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3966 |  |  |         if (!$list) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3967 |  |  |             $list = new ArrayList(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3968 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3969 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3970 |  |  |         // Skip search for unsaved records | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3971 |  |  |         if (!$this->isInDB()) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3972 |  |  |             return $list; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3973 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3974 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3975 |  |  |         $relationships = $this->config()->get($source) ?: []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3976 |  |  |         foreach ($relationships as $relationship) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3977 |  |  |             // Warn if invalid config | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3978 |  |  |             if (!$this->hasMethod($relationship)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3979 |  |  |                 trigger_error(sprintf( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3980 |  |  |                     "Invalid %s config value \"%s\" on object on class \"%s\"", | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3981 |  |  |                     $source, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3982 |  |  |                     $relationship, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3983 |  |  |                     get_class($this) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3984 |  |  |                 ), E_USER_WARNING); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3985 |  |  |                 continue; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3986 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3987 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3988 |  |  |             // Inspect value of this relationship | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3989 |  |  |             $items = $this->{$relationship}(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3990 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3991 |  |  |             // Merge any new item | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3992 |  |  |             $newItems = $this->mergeRelatedObjects($list, $items); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3993 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3994 |  |  |             // Recurse if necessary | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3995 |  |  |             if ($recursive) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3996 |  |  |                 foreach ($newItems as $item) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3997 |  |  |                     /** @var DataObject $item */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3998 |  |  |                     $item->findRelatedObjects($source, true, $list); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3999 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4000 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4001 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4002 |  |  |         return $list; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4003 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4004 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4005 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4006 |  |  |      * Helper method to merge owned/owning items into a list. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4007 |  |  |      * Items already present in the list will be skipped. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4008 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4009 |  |  |      * @param ArrayList $list Items to merge into | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4010 |  |  |      * @param mixed $items List of new items to merge | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4011 |  |  |      * @return ArrayList List of all newly added items that did not already exist in $list | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 4012 |  |  |      */ | 
            
                                                                        
                            
            
                                    
            
            
                | 4013 |  |  |     public function mergeRelatedObjects($list, $items) | 
            
                                                                        
                            
            
                                    
            
            
                | 4014 |  |  |     { | 
            
                                                                        
                            
            
                                    
            
            
                | 4015 |  |  |         $added = new ArrayList(); | 
            
                                                                        
                            
            
                                    
            
            
                | 4016 |  |  |         if (!$items) { | 
            
                                                                        
                            
            
                                    
            
            
                | 4017 |  |  |             return $added; | 
            
                                                                        
                            
            
                                    
            
            
                | 4018 |  |  |         } | 
            
                                                                        
                            
            
                                    
            
            
                | 4019 |  |  |         if ($items instanceof DataObject) { | 
            
                                                                        
                            
            
                                    
            
            
                | 4020 |  |  |             $items = [$items]; | 
            
                                                                        
                            
            
                                    
            
            
                | 4021 |  |  |         } | 
            
                                                                        
                            
            
                                    
            
            
                | 4022 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 4023 |  |  |         /** @var DataObject $item */ | 
            
                                                                        
                            
            
                                    
            
            
                | 4024 |  |  |         foreach ($items as $item) { | 
            
                                                                        
                            
            
                                    
            
            
                | 4025 |  |  |             $this->mergeRelatedObject($list, $added, $item); | 
            
                                                                        
                            
            
                                    
            
            
                | 4026 |  |  |         } | 
            
                                                                        
                            
            
                                    
            
            
                | 4027 |  |  |         return $added; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4028 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4029 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4030 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4031 |  |  |      * Merge single object into a list, but ensures that existing objects are not | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4032 |  |  |      * re-added. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4033 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4034 |  |  |      * @param ArrayList $list Global list | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4035 |  |  |      * @param ArrayList $added Additional list to insert into | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4036 |  |  |      * @param DataObject $item Item to add | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4037 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4038 |  |  |     protected function mergeRelatedObject($list, $added, $item) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4039 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4040 |  |  |         // Identify item | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4041 |  |  |         $itemKey = get_class($item) . '/' . $item->ID; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4042 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4043 |  |  |         // Write if saved, versioned, and not already added | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4044 |  |  |         if ($item->isInDB() && !isset($list[$itemKey])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4045 |  |  |             $list[$itemKey] = $item; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4046 |  |  |             $added[$itemKey] = $item; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4047 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4048 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4049 |  |  |         // Add joined record (from many_many through) automatically | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4050 |  |  |         $joined = $item->getJoin(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4051 |  |  |         if ($joined) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4052 |  |  |             $this->mergeRelatedObject($list, $added, $joined); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4053 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4054 |  |  |     } | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 4055 |  |  | } | 
            
                                                        
            
                                    
            
            
                | 4056 |  |  |  |