Version: current

      1 <?php
      2
      3 class HasManyDataObjectManager extends DataObjectManager {
      4     public $joinField;
      5     public $addTitle;
      6     public $RelationType = "HasMany";
      7     protected $htmlListEndName = 'CheckedList';
      8     protected $htmlListField = 'selected';
      9     public $template = 'RelationDataObjectManager';
     10     public $itemClass = 'HasManyDataObjectManager_Item';
     11     protected $relationAutoSetting = false;
     12     protected $markingPermission;
     13     /**
     14      * Most of the code below was copied from HasManyComplexTableField.
     15      * Painful, but necessary, until PHP supports multiple inheritance.
     16      */
     17
     18     function __construct($controller, $name, $sourceClass, $fieldList = null, $detailFormFields = null, $sourceFilter = "", $sourceSort = "Created DESC", $sourceJoin = "") {
     19         parent::__construct($controller, $name, $sourceClass, $fieldList, $detailFormFields, $sourceFilter, $sourceSort, $sourceJoin);
     20
     21         $this->Markable = true;
     22
     23         if($controllerClass = $this->controllerClass()) {
     24             $this->joinField = $this->getParentIdName($controllerClass, $this->sourceClass);
     25         } else {
     26             user_error("Can't figure out the data class of $controller", E_USER_WARNING);
     27         }
     28
     29     }
     30
     31
     32     /**
     33      * Try to determine the DataObject that this field is built on top of
     34      */
     35     function controllerClass() {
     36         if($this->controller instanceof DataObject) return $this->controller->class;
     37         elseif($this->controller instanceof ContentController) return $this->controller->data()->class;
     38     }
     39
     40     public function setMarkingPermission($perm) {
     41         $this->markingPermission = $perm;
     42     }
     43
     44     public function hasMarkingPermission() {
     45         if(is_bool($this->markingPermission))
     46             return $this->markingPermission;
     47         elseif($this->markingPermission)
     48             return Permission::check($this->markingPermission);
     49         return true;
     50     }
     51
     52     public function setParentClass($class) {
     53         parent::setParentClass($class);
     54         $this->joinField = $this->getParentIdName($class, $this->sourceClass);
     55     }
     56
     57     function getQuery($limitClause = null) {
     58         if($this->customQuery) {
     59             $query = $this->customQuery;
     60             $query->select[] = "{$this->sourceClass}.ID AS ID";
     61             $query->select[] = "{$this->sourceClass}.ClassName AS ClassName";
     62             $query->select[] = "{$this->sourceClass}.ClassName AS RecordClassName";
     63         }
     64         else {
     65             $query = singleton($this->sourceClass)->extendedSQL($this->sourceFilter, $this->sourceSort, $limitClause, $this->sourceJoin);
     66
     67             // Add more selected fields if they are from joined table.
     68
     69             $SNG = singleton($this->sourceClass);
     70             foreach($this->FieldList() as $k => $title) {
     71                 if(! $SNG->hasField($k) && ! $SNG->hasMethod('get' . $k))
     72                     $query->select[] = $k;
     73             }
     74         }
     75         return clone $query;
     76     }
     77
     78     function sourceItems() {
     79         if($this->sourceItems)
     80             return $this->sourceItems;
     81
     82         $limitClause = '';
     83         if(isset($_REQUEST[ 'ctf' ][ $this->Name() ][ 'start' ]) && is_numeric($_REQUEST[ 'ctf' ][ $this->Name() ][ 'start' ]))
     84             $limitClause = $_REQUEST[ 'ctf' ][ $this->Name() ][ 'start' ] . ", $this->pageSize";
     85         else
     86             $limitClause = "0, $this->pageSize";
     87
     88         $dataQuery = $this->getQuery($limitClause);
     89         $records = $dataQuery->execute();
     90         $items = new DataObjectSet();
     91         foreach($records as $record) {
     92             if(! is_object($record))
     93                 $class = $this->sourceClass;
     94             $record = new $class($record);
     95             $items->push($record);
     96         }
     97
     98         $dataQuery = $this->getQuery();
     99         $records = $dataQuery->execute();
    100         $unpagedItems = new DataObjectSet();
    101         foreach($records as $record) {
    102             if(! is_object($record)) {
    103                 $class = $this->sourceClass;
    104                 $record = new $class($record);
    105             }
    106             $unpagedItems->push($record);
    107         }
    108         $this->unpagedSourceItems = $unpagedItems;
    109
    110         $this->totalCount = ($this->unpagedSourceItems) ? $this->unpagedSourceItems->TotalItems() : null;
    111
    112         return $items;
    113     }
    114
    115     function getControllerID() {
    116         return $this->controller->ID;
    117     }
    118
    119     public function SortableClass() {
    120         return $this->sourceClass();
    121     }
    122
    123     function saveInto(DataObject $record) {
    124         $fieldName = $this->name;
    125         $saveDest = $record->$fieldName();
    126
    127         if(! $saveDest)
    128             user_error("HasManyDataObjectManager::saveInto() Field '$fieldName' not found on $record->class.$record->ID", E_USER_ERROR);
    129
    130         $items = array();
    131
    132         if($list = $this->value[ $this->htmlListField ]) {
    133             if($list != 'undefined')
    134                 $items = explode(',', trim($list,","));
    135         }
    136
    137         $saveDest->setByIDList($items);
    138     }
    139
    140     function ExtraData() {
    141         $items = array();
    142         foreach($this->unpagedSourceItems as $item) {
    143             if($item->{$this->joinField} == $this->controller->ID)
    144                 $items[] = $item->ID;
    145         }
    146         $list = implode(',', $items);
    147         $value = ",";
    148         $value .= !empty($list) ? $list."," : "";
    149         $inputId = $this->id() . '_' . $this->htmlListEndName;
    150         return <<<HTML
    151         <input id="$inputId" name="{$this->name}[{$this->htmlListField}]" type="hidden" value="{$value}"/>
    152 HTML;
    153     }
    154
    155 }
    156
    157
    158 class HasManyDataObjectManager_Item extends DataObjectManager_Item {
    159
    160     function MarkingCheckbox() {
    161         $name = $this->parent->Name() . '[]';
    162         $joinVal = $this->item->{$this->parent->joinField};
    163         $parentID = $this->parent->getControllerID();
    164         $disabled = $this->parent->hasMarkingPermission() ? "" : "disabled='disabled'";
    165
    166         if($this->parent->IsReadOnly || ($joinVal > 0 && $joinVal != $parentID))
    167             return "<input class=\"checkbox\" type=\"checkbox\" name=\"$name\" value=\"{$this->item->ID}\" disabled=\"disabled\"/>";
    168         else if($joinVal == $parentID)
    169             return "<input class=\"checkbox\" type=\"checkbox\" name=\"$name\" value=\"{$this->item->ID}\" checked=\"checked\" $disabled />";
    170         else
    171             return "<input class=\"checkbox\" type=\"checkbox\" name=\"$name\" value=\"{$this->item->ID}\" $disabled />";
    172     }
    173 }
    174
    175
    176
    177 ?>

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