1 <?php
2 3 4 5 6 7 8
9 class CompositeField extends FormField {
10
11 12 13
14 protected $children;
15
16 17 18
19 protected $readonly;
20
21 22 23 24 25 26 27 28
29 protected $columnCount = null;
30
31 public function __construct($children = null) {
32 if($children instanceof FieldSet) {
33 $this->children = $children;
34 } elseif(is_array($children)) {
35 $this->children = new FieldSet($children);
36 } else {
37 $children = is_array(func_get_args()) ? func_get_args() : array();
38 $this->children = new FieldSet($children);
39 }
40 $this->children->setContainerField($this);
41
42
43
44 $this->brokenOnConstruct = false;
45 Object::__construct();
46 }
47
48 49 50
51 public function FieldSet() {
52 return $this->children;
53 }
54
55 public function setID($id) {
56 $this->id = $id;
57 }
58
59 public function Field() {
60 $attributes = array(
61 'class' => ($this->columnCount) ? "field {$this->class} {$this->extraClass()} multicolumn" : "field {$this->class} {$this->extraClass()}",
62 );
63 if (isset($this->id)) {
64 $attributes['id'] = $this->id;
65 }
66 return $this->createTag('input', $attributes);
67 }
68
69 70 71 72
73 public function getChildren() {
74 return $this->children;
75 }
76
77 78 79
80 public function setChildren($children) {
81 $this->children = $children;
82 }
83
84 85 86
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
108
109 110 111
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
133 134 135 136
137 public function collateDataFields(&$list, $saveableOnly = false) {
138 foreach($this->children as $field) {
139 if(is_object($field)) {
140 if($field->isComposite()) $field->collateDataFields($list, $saveableOnly);
141 if($saveableOnly) {
142 $isIncluded = ($field->hasData() && !$field->isReadonly() && !$field->isDisabled());
143 } else {
144 $isIncluded = ($field->hasData());
145 }
146 if($isIncluded) {
147 $name = $field->Name();
148 if($name) {
149 $formName = (isset($this->form)) ? $this->form->FormName() : '(unknown form)';
150 if(isset($list[$name])) user_error("collateDataFields() I noticed that a field called '$name' appears twice in your form: '{$formName}'. One is a '{$field->class}' and the other is a '{$list[$name]->class}'", E_USER_ERROR);
151 $list[$name] = $field;
152 }
153 }
154 }
155 }
156 }
157
158 function setForm($form) {
159 foreach($this->children as $f) if(is_object($f)) $f->setForm($form);
160 parent::setForm($form);
161 }
162
163 function setColumnCount($columnCount) {
164 $this->columnCount = $columnCount;
165 }
166
167 function isComposite() { return true; }
168 function hasData() { return false; }
169
170 public function fieldByName($name) {
171 return $this->children->fieldByName($name);
172 }
173 174 175
176 public function push(FormField $field) {
177 $this->children->push($field);
178 }
179
180 181 182
183 public function insertBefore($field, $insertBefore) {
184 $ret = $this->children->insertBefore($field, $insertBefore);
185 $this->sequentialSet = null;
186 return $ret;
187 }
188
189 public function insertAfter($field, $insertAfter) {
190 $ret = $this->children->insertAfter($field, $insertAfter);
191 $this->sequentialSet = null;
192 return $ret;
193 }
194
195 196 197 198 199 200 201 202 203
204 public function removeByName($fieldName, $dataFieldOnly = false) {
205 $this->children->removeByName($fieldName, $dataFieldOnly);
206 }
207
208 public function replaceField($fieldName, $newField) {
209 return $this->children->replaceField($fieldName, $newField);
210 }
211
212 function rootFieldSet() {
213 if(is_object($this->containerFieldSet)) return $this->containerFieldSet->rootFieldSet();
214 else return $this->children;
215 }
216
217 218 219 220
221 public function performReadonlyTransformation() {
222 $newChildren = new FieldSet();
223 $clone = clone $this;
224 foreach($clone->getChildren() as $idx => $child) {
225 if(is_object($child)) $child = $child->transform(new ReadonlyTransformation());
226 $newChildren->push($child, $idx);
227 }
228
229 $clone->children = $newChildren;
230 $clone->readonly = true;
231 return $clone;
232 }
233
234 235 236 237
238 public function performDisabledTransformation($trans) {
239 $newChildren = new FieldSet();
240 $clone = clone $this;
241 if($clone->getChildren()) foreach($clone->getChildren() as $idx => $child) {
242 if(is_object($child)) {
243 $child = $child->transform($trans);
244 }
245 $newChildren->push($child, $idx);
246 }
247
248 $clone->children = $newChildren;
249 $clone->readonly = true;
250
251 return $clone;
252 }
253
254 function IsReadonly() {
255 return $this->readonly;
256 }
257
258 259 260 261 262 263 264
265 function fieldPosition($field) {
266 if(is_string($field)) $field = $this->fieldByName($field);
267 if(!$field) return false;
268
269 $i = 0;
270 foreach($this->children as $child) {
271 if($child->Name() == $field->Name()) return $i;
272 $i++;
273 }
274
275 return false;
276 }
277
278 279 280 281 282
283 function makeFieldReadonly($field) {
284 $fieldName = ($field instanceof FormField) ? $field->Name() : $field;
285
286
287 foreach($this->children as $i => $item) {
288 if($item->isComposite()) {
289 $item->makeFieldReadonly($fieldName);
290 } else {
291
292 if($item->Name() == $fieldName) {
293 $this->children->replaceField($fieldName, $item->transform(new ReadonlyTransformation()));
294
295
296 $this->sequentialSet = null;
297
298
299 return true;
300 }
301 }
302 }
303 return false;
304 }
305
306 function debug() {
307 $result = "$this->class ($this->name) <ul>";
308 foreach($this->children as $child) {
309 $result .= "<li>" . Debug::text($child) . " </li>";
310 }
311 $result .= "</ul>";
312 return $result;
313 }
314
315 function validate($validator){
316
317 $valid = true;
318 foreach($this->children as $idx => $child){
319 $valid = ($child && $child->validate($validator) && $valid);
320 }
321
322 return $valid;
323 }
324 }
325
326 ?>
[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.
-