1 <?php
2
3 class ManyManyFileDataObjectManager extends HasManyFileDataObjectManager {
4
5 protected static $only_related;
6 private $manyManyParentClass;
7 public $RelationType = "ManyMany";
8 public $itemClass = 'ManyManyFileDataObjectManager_Item';
9 protected $OnlyRelated = false;
10
11 12 13 14
15
16
17
18 function __construct($controller, $name, $sourceClass, $fileFieldName, $fieldList = null, $detailFormFields = null, $sourceFilter = "", $sourceSort = "Created DESC", $sourceJoin = "") {
19
20 parent::__construct($controller, $name, $sourceClass, $fileFieldName, $fieldList, $detailFormFields, $sourceFilter, $sourceSort, $sourceJoin);
21 $manyManyTable = false;
22 $classes = array_reverse(ClassInfo::ancestry($this->controllerClass()));
23 foreach($classes as $class) {
24 if($class != "Object") {
25 $singleton = singleton($class);
26 $manyManyRelations = $singleton->uninherited('many_many', true);
27 if(isset($manyManyRelations) && array_key_exists($this->name, $manyManyRelations)) {
28 $this->manyManyParentClass = $class;
29 $manyManyTable = $class . '_' . $this->name;
30 break;
31 }
32 $belongsManyManyRelations = $singleton->uninherited( 'belongs_many_many', true );
33 if( isset( $belongsManyManyRelations ) && array_key_exists( $this->name, $belongsManyManyRelations ) ) {
34 $this->manyManyParentClass = $class;
35
36
37 $manyManyClass = $belongsManyManyRelations[$this->name];
38 $manyManyRelations = singleton($manyManyClass)->uninherited('many_many', true);
39 foreach($manyManyRelations as $manyManyRelationship => $manyManyChildClass)
40 if ($manyManyChildClass == $class)
41 break;
42
43 $manyManyTable = $manyManyClass . '_' . $manyManyRelationship;
44 break;
45 }
46 }
47 }
48 if(!$manyManyTable) user_error("I could not find the relation $this->name in " . $this->controllerClass() . " or any of its ancestors.",E_USER_WARNING);
49 $tableClasses = ClassInfo::dataClassesFor($this->sourceClass);
50 $source = array_shift($tableClasses);
51 $sourceField = $this->sourceClass;
52 if($this->manyManyParentClass == $sourceField)
53 $sourceField = 'Child';
54 $parentID = $this->controller->ID;
55
56 $this->sourceJoin .= " LEFT JOIN `$manyManyTable` ON (`$source`.`ID` = `{$sourceField}ID` AND `{$this->manyManyParentClass}ID` = '$parentID')";
57
58 $this->joinField = 'Checked';
59 if(isset($_REQUEST['ctf'][$this->Name()]['only_related']))
60 $this->OnlyRelated = $_REQUEST['ctf'][$this->Name()]['only_related'];
61
62 $this->addPermission('only_related');
63
64
65 if($this->ShowAll() && SortableDataObject::is_sortable_many_many($this->sourceClass()))
66 $this->OnlyRelated = '1';
67
68 }
69
70 public function setParentClass($class) {
71 parent::setParentClass($class);
72 $this->joinField = "Checked";
73 }
74
75
76 protected function loadSort() {
77
78 if($this->ShowAll())
79 $this->setPageSize(999);
80
81 if(SortableDataObject::is_sortable_many_many($this->sourceClass(), $this->manyManyParentClass)) {
82 list($parentClass, $componentClass, $parentField, $componentField, $table) = singleton($this->controllerClass())->many_many($this->Name());
83 $sort_column = "`$table`.SortOrder";
84 if(!isset($_REQUEST['ctf'][$this->Name()]['sort']) || $_REQUEST['ctf'][$this->Name()]['sort'] == $sort_column) {
85 $this->sort = $sort_column;
86 $this->sourceSort = "$sort_column " . SortableDataObject::$sort_dir;
87 }
88 }
89
90 elseif($this->Sortable() && (!isset($_REQUEST['ctf'][$this->Name()]['sort']) || $_REQUEST['ctf'][$this->Name()]['sort'] == "SortOrder")) {
91 $this->sort = "SortOrder";
92 $this->sourceSort = "SortOrder " . SortableDataObject::$sort_dir;
93 }
94
95 elseif(isset($_REQUEST['ctf'][$this->Name()]['sort']))
96 $this->sourceSort = $_REQUEST['ctf'][$this->Name()]['sort'] . " " . $this->sort_dir;
97 }
98
99
100 public function setOnlyRelated($bool) {
101 if(!isset($_REQUEST['ctf'][$this->Name()]['only_related']))
102 $this->OnlyRelated = $bool;
103 }
104
105 public function OnlyRelated() {
106 return self::$only_related !== null ? self::$only_related : $this->OnlyRelated;
107 }
108
109 public function getQueryString($params = array()) {
110 $only_related = isset($params['only_related'])? $params['only_related'] : $this->OnlyRelated();
111 return parent::getQueryString($params)."&ctf[{$this->Name()}][only_related]={$only_related}";
112 }
113
114 public function OnlyRelatedLink() {
115 return $this->RelativeLink(array('only_related' => '1'));
116 }
117
118 public function AllRecordsLink() {
119 return $this->RelativeLink(array('only_related' => '0'));
120 }
121
122
123 function getQuery($limitClause = null) {
124 if($this->customQuery) {
125 $query = $this->customQuery;
126 $query->select[] = "{$this->sourceClass}.ID AS ID";
127 $query->select[] = "{$this->sourceClass}.ClassName AS ClassName";
128 $query->select[] = "{$this->sourceClass}.ClassName AS RecordClassName";
129 }
130 else {
131 $query = singleton($this->sourceClass)->extendedSQL($this->sourceFilter, $this->sourceSort, $limitClause, $this->sourceJoin);
132
133
134
135 $SNG = singleton($this->sourceClass);
136 foreach($this->FieldList() as $k => $title) {
137 if(! $SNG->hasField($k) && ! $SNG->hasMethod('get' . $k))
138 $query->select[] = $k;
139 }
140 $parent = $this->controllerClass();
141 $if_clause = "IF(`{$this->manyManyParentClass}ID` IS NULL, '0', '1')";
142 $query->select[] = "$if_clause AS Checked";
143
144 if($this->OnlyRelated())
145 $query->where[] = $if_clause;
146 }
147 return clone $query;
148 }
149
150
151 function getParentIdName($parentClass, $childClass) {
152 return $this->getParentIdNameRelation($parentClass, $childClass, 'many_many');
153 }
154
155 function () {
156 $items = array();
157 foreach($this->unpagedSourceItems as $item) {
158 if($item->{$this->joinField})
159 $items[] = $item->ID;
160 }
161 $list = implode(',', $items);
162 $value = ",";
163 $value .= !empty($list) ? $list."," : "";
164 $inputId = $this->id() . '_' . $this->htmlListEndName;
165 $controllerID = $this->controller->ID;
166 return <<<HTML
167 <input name="controllerID" type="hidden" value="$controllerID" />
168 <input id="$inputId" name="{$this->name}[{$this->htmlListField}]" type="hidden" value="$value"/>
169 HTML;
170 }
171
172 protected function getSortableOwner() {
173 if($this->sortableOwner) return $this->sortableOwner;
174
175
176 $parent = null;
177 foreach(array_reverse(ClassInfo::ancestry($this->controllerClass())) as $class) {
178 if(SortableDataObject::is_sortable_many_many($this->sourceClass(), $class)) {
179 $this->sortableOwner = $class;
180 return $this->sortableOwner;
181 }
182 }
183 return false;
184 }
185
186 public function Sortable() {
187 return (SortableDataObject::is_sortable_many_many($this->sourceClass())) || (SortableDataObject::is_sortable_class($this->sourceClass()));
188 }
189
190 public function SortableClass() {
191 return $this->manyManyParentClass."-".$this->sourceClass();
192 }
193 }
194
195 class ManyManyFileDataObjectManager_Item extends FileDataObjectManager_Item {
196
197 function MarkingCheckbox() {
198 $name = $this->parent->Name() . '[]';
199 $disabled = $this->parent->hasMarkingPermission() ? "" : "disabled='disabled'";
200
201 if($this->parent->IsReadOnly)
202 return "<input class=\"checkbox\" type=\"checkbox\" name=\"$name\" value=\"{$this->item->ID}\" disabled=\"disabled\"/>";
203 else if($this->item->{$this->parent->joinField})
204 return "<input class=\"checkbox\" type=\"checkbox\" name=\"$name\" value=\"{$this->item->ID}\" checked=\"checked\" $disabled />";
205 else
206 return "<input class=\"checkbox\" type=\"checkbox\" name=\"$name\" value=\"{$this->item->ID}\" $disabled />";
207 }
208 }
209
210
211
212
213 ?>
[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.
-