1 <?php
2 3 4 5 6 7
8 class ComponentSet extends DataObjectSet {
9 10 11 12
13 protected $type;
14
15 16 17 18
19 protected $ownerObj;
20
21 22 23 24
25 protected $ownerClass;
26
27 28 29 30
31 protected $tableName;
32
33 34 35 36
37 protected $childClass;
38
39 40 41 42
43 protected $joinField;
44
45 46 47 48 49 50 51 52 53
54 function setComponentInfo($type, $ownerObj, $ownerClass, $tableName, $childClass, $joinField = null) {
55 $this->type = $type;
56 $this->ownerObj = $ownerObj;
57 $this->ownerClass = $ownerClass ? $ownerClass : $ownerObj->class;
58 $this->tableName = $tableName;
59 $this->childClass = $childClass;
60 $this->joinField = $joinField;
61 }
62
63 64 65 66 67 68 69 70 71 72 73 74 75
76 public function getComponentInfo() {
77 return array(
78 'type' => $this->type,
79 'ownerObj' => $this->ownerObj,
80 'ownerClass' => $this->ownerClass,
81 'tableName' => $this->tableName,
82 'childClass' => $this->childClass,
83 'joinField' => $this->joinField
84 );
85 }
86
87 88 89 90 91
92 function getIdList() {
93 $list = array();
94 foreach($this->items as $item) {
95 $list[$item->ID] = $item->ID;
96 }
97 return $list;
98 }
99
100 101 102 103 104
105 function add($item, $extraFields = null) {
106 if(!isset($item)) {
107 user_error("ComponentSet::add() Not passed an object or ID", E_USER_ERROR);
108 }
109
110 if(is_object($item)) {
111 if(!is_a($item, $this->childClass)) {
112 user_error("ComponentSet::add() Tried to add an '{$item->class}' object, but a '{$this->childClass}' object expected", E_USER_ERROR);
113 }
114 } else {
115 if(!$this->childClass) {
116 user_error("ComponentSet::add() \$this->childClass not set", E_USER_ERROR);
117 }
118
119 $item = DataObject::get_by_id($this->childClass, $item);
120 if(!$item) return;
121 }
122
123
124 if($this->ownerObj->ID && is_numeric($this->ownerObj->ID)) {
125 $this->loadChildIntoDatabase($item, $extraFields);
126 }
127
128
129 $this->items[] = $item;
130 }
131
132 133 134 135 136 137
138 protected function loadChildIntoDatabase($item, $extraFields = null) {
139 if($this->type == '1-to-many') {
140 $child = DataObject::get_by_id($this->childClass,$item->ID);
141 if (!$child) $child = $item;
142 $joinField = $this->joinField;
143 $child->$joinField = $this->ownerObj->ID;
144 $child->write();
145
146 } else {
147 $parentField = $this->ownerClass . 'ID';
148 $childField = ($this->childClass == $this->ownerClass) ? "ChildID" : ($this->childClass . 'ID');
149
150 DB::query( "DELETE FROM \"$this->tableName\" WHERE \"$parentField\" = {$this->ownerObj->ID} AND \"$childField\" = {$item->ID}" );
151
152 $extraKeys = $extraValues = '';
153 if($extraFields) foreach($extraFields as $k => $v) {
154 $extraKeys .= ", \"$k\"";
155 $extraValues .= ", '" . DB::getConn()->addslashes($v) . "'";
156 }
157
158 DB::query("INSERT INTO \"$this->tableName\" (\"$parentField\",\"$childField\" $extraKeys) VALUES ({$this->ownerObj->ID}, {$item->ID} $extraValues)");
159 }
160 }
161
162 163 164 165
166 function addMany($items) {
167 foreach($items as $item) {
168 $this->add($item);
169 }
170 }
171
172 173 174 175 176
177 function setByIDList($idList) {
178 $has = array();
179
180 if($this->items) foreach($this->items as $item) {
181 $has[$item->ID] = true;
182 }
183
184
185 $itemsToDelete = $has;
186
187
188
189 if($idList) foreach($idList as $id) {
190 $itemsToDelete[$id] = false;
191 if($id && !isset($has[$id])) $this->add($id);
192 }
193
194
195 $removeList = array();
196 foreach($itemsToDelete as $id => $actuallyDelete) {
197 if($actuallyDelete) $removeList[] = $id;
198 }
199 $this->removeMany($removeList);
200 }
201
202 203 204 205 206
207 function remove($item) {
208 if(is_object($item)) {
209 if(!is_a($item, $this->childClass)) {
210 user_error("ComponentSet::remove() Tried to remove an '{$item->class}' object, but a '{$this->childClass}' object expected", E_USER_ERROR);
211 }
212 } else {
213 $item = DataObject::get_by_id($this->childClass, $item);
214 }
215
216
217 if($this->ownerObj->ID && is_numeric($this->ownerObj->ID)) {
218 if($this->type == '1-to-many') {
219 $child = DataObject::get_by_id($this->childClass,$item->ID);
220 $joinField = $this->joinField;
221 if($child->$joinField == $this->ownerObj->ID) {
222 $child->$joinField = null;
223 $child->write();
224 }
225
226 } else {
227 $parentField = $this->ownerClass . 'ID';
228 $childField = ($this->childClass == $this->ownerClass) ? "ChildID" : ($this->childClass . 'ID');
229 DB::query("DELETE FROM \"$this->tableName\" WHERE \"$parentField\" = {$this->ownerObj->ID} AND \"$childField\" = {$item->ID}");
230 }
231 }
232
233
234 if($this->items) foreach($this->items as $i => $candidateItem) {
235 if($candidateItem->ID == $item->ID) {
236 unset($this->items[$i]);
237 break;
238 }
239 }
240 }
241
242 243 244 245
246 function removeMany($itemList) {
247 if(!count($itemList)) return false;
248
249 if($this->type == '1-to-many') {
250 foreach($itemList as $item) $this->remove($item);
251 } else {
252 $itemCSV = implode(", ", $itemList);
253 $parentField = $this->ownerClass . 'ID';
254 $childField = ($this->childClass == $this->ownerClass) ? "ChildID" : ($this->childClass . 'ID');
255 DB::query("DELETE FROM \"$this->tableName\" WHERE \"$parentField\" = {$this->ownerObj->ID} AND \"$childField\" IN ($itemCSV)");
256 }
257 }
258
259 260 261
262 function removeAll() {
263 if(!empty($this->tableName)) {
264 $parentField = $this->ownerClass . 'ID';
265 DB::query("DELETE FROM \"$this->tableName\" WHERE \"$parentField\" = {$this->ownerObj->ID}");
266 } else {
267 foreach($this->items as $item) {
268 $this->remove($item);
269 }
270 }
271 }
272
273 274 275 276 277
278 function write($firstWrite = false) {
279 if($firstWrite) {
280 foreach($this->items as $item) {
281 $this->loadChildIntoDatabase($item);
282 }
283 }
284 }
285
286 287 288 289 290
291 function debug() {
292 $size = count($this->items);
293
294 $output = <<<OUT
295 <h3>ComponentSet</h3>
296 <ul>
297 <li>Type: {$this->type}</li>
298 <li>Size: $size</li>
299 </ul>
300
301 OUT;
302
303 return $output;
304 }
305 }
306
307 ?>
308
[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.
-