Total Complexity | 101 |
Total Lines | 829 |
Duplicated Lines | 0 % |
Changes | 0 |
Complex classes like SelectizeInput often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use SelectizeInput, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
37 | class SelectizeInput extends SelectInput |
||
38 | { |
||
39 | /** |
||
40 | * Settings for {@link http://selectize.github.io/selectize.js/ Selectize.js} |
||
41 | * |
||
42 | * @var array |
||
43 | */ |
||
44 | private $selectizeOptions; |
||
45 | |||
46 | /** |
||
47 | * Whether to show a button to copy items to clipboard. |
||
48 | * |
||
49 | * @var boolean |
||
50 | */ |
||
51 | protected $allowClipboardCopy; |
||
52 | |||
53 | /** |
||
54 | * Store the factory instance for the current class. |
||
55 | * |
||
56 | * @var FactoryInterface |
||
57 | */ |
||
58 | private $modelFactory; |
||
59 | |||
60 | /** |
||
61 | * Store the collection loader for the current class. |
||
62 | * |
||
63 | * @var CollectionLoader |
||
64 | */ |
||
65 | private $collectionLoader; |
||
66 | |||
67 | /** |
||
68 | * Should the object be loaded in deferred mode. |
||
69 | * |
||
70 | * @var boolean |
||
71 | */ |
||
72 | private $deferred; |
||
73 | |||
74 | /** |
||
75 | * Whether to show a button to allow update items. |
||
76 | * |
||
77 | * @var boolean |
||
78 | */ |
||
79 | protected $allowUpdate; |
||
80 | |||
81 | /** |
||
82 | * Whether to show a button to allow item create. |
||
83 | * |
||
84 | * @var boolean |
||
85 | */ |
||
86 | protected $allowCreate; |
||
87 | |||
88 | /** |
||
89 | * The form idents to use while creating objects through Selectize. |
||
90 | * |
||
91 | * Can either be a single value, |
||
92 | * or an array of values for these idents |
||
93 | * - 'create' |
||
94 | * - 'update' |
||
95 | * |
||
96 | * @var mixed |
||
97 | */ |
||
98 | private $formIdent; |
||
99 | |||
100 | /** |
||
101 | * Check used to parse multi Choice map against the obj properties. |
||
102 | * |
||
103 | * @var boolean |
||
104 | */ |
||
105 | protected $isChoiceObjMapFinalized = false; |
||
106 | |||
107 | /** |
||
108 | * @var array |
||
109 | */ |
||
110 | private $selectizeTemplates; |
||
111 | |||
112 | /** |
||
113 | * @var SelectizeRenderer |
||
114 | */ |
||
115 | private $selectizeRenderer; |
||
116 | |||
117 | /** |
||
118 | * @var array |
||
119 | */ |
||
120 | private $disabledFields = []; |
||
121 | |||
122 | /** |
||
123 | * @var string $remoteSource |
||
124 | */ |
||
125 | private $remoteSource; |
||
126 | |||
127 | /** |
||
128 | * This function takes an array and fill the model object with its value. |
||
129 | * |
||
130 | * This method either calls a setter for each key (`set_{$key}()`) or sets a public member. |
||
131 | * |
||
132 | * For example, calling with `setData(['properties'=>$properties])` would call |
||
133 | * `setProperties($properties)`, becasue `setProperties()` exists. |
||
134 | * |
||
135 | * But calling with `setData(['foobar'=>$foo])` would set the `$foobar` member |
||
136 | * on the metadata object, because the method `set_foobar()` does not exist. |
||
137 | * |
||
138 | * @param array $data The input data. |
||
139 | * @return self |
||
140 | */ |
||
141 | public function setData(array $data) |
||
142 | { |
||
143 | // Push selectize options back at the end of the data container. |
||
144 | if (isset($data['selectizeOptions'])) { |
||
145 | $selectizeOptions = $data['selectizeOptions']; |
||
146 | unset($data['selectizeOptions']); |
||
147 | $data['selectizeOptions'] = $selectizeOptions; |
||
148 | } |
||
149 | |||
150 | parent::setData($data); |
||
151 | |||
152 | return $this; |
||
|
|||
153 | } |
||
154 | |||
155 | /** |
||
156 | * Retrieve the object model factory. |
||
157 | * |
||
158 | * @throws RuntimeException If the model factory was not previously set. |
||
159 | * @return FactoryInterface |
||
160 | */ |
||
161 | public function modelFactory() |
||
162 | { |
||
163 | if (!isset($this->modelFactory)) { |
||
164 | throw new RuntimeException(sprintf( |
||
165 | 'Model Factory is not defined for "%s"', |
||
166 | get_class($this) |
||
167 | )); |
||
168 | } |
||
169 | |||
170 | return $this->modelFactory; |
||
171 | } |
||
172 | |||
173 | /** |
||
174 | * Set a model collection loader. |
||
175 | * |
||
176 | * @param CollectionLoader $loader The collection loader. |
||
177 | * @return self |
||
178 | */ |
||
179 | private function setCollectionLoader(CollectionLoader $loader) |
||
180 | { |
||
181 | $this->collectionLoader = $loader; |
||
182 | |||
183 | return $this; |
||
184 | } |
||
185 | |||
186 | /** |
||
187 | * Retrieve the model collection loader. |
||
188 | * |
||
189 | * @throws RuntimeException If the collection loader was not previously set. |
||
190 | * @return CollectionLoader |
||
191 | */ |
||
192 | protected function collectionLoader() |
||
193 | { |
||
194 | if (!isset($this->collectionLoader)) { |
||
195 | throw new RuntimeException(sprintf( |
||
196 | 'Collection Loader is not defined for "%s"', |
||
197 | get_class($this) |
||
198 | )); |
||
199 | } |
||
200 | |||
201 | return $this->collectionLoader; |
||
202 | } |
||
203 | |||
204 | /** |
||
205 | * Retrieve the selectable options. |
||
206 | * |
||
207 | * Note: This method is also featured in {@see \Charcoal\Admin\Property\Input\SelectInput}. |
||
208 | * |
||
209 | * @todo [^1]: With PHP7 we can simply do `yield from $choices;`. |
||
210 | * @return \Generator|array |
||
211 | */ |
||
212 | public function choices() |
||
213 | { |
||
214 | if ($this->p()->allowNull() && !$this->p()->multiple()) { |
||
215 | $prepend = $this->parseChoice('', $this->emptyChoice()); |
||
216 | |||
217 | yield $prepend; |
||
218 | } |
||
219 | |||
220 | // When deferred, we want to fetch choices for current values only. |
||
221 | if ($this->deferred()) { |
||
222 | $choices = $this->selectizeVal($this->propertyVal()); |
||
223 | } else { |
||
224 | $choices = $this->selectizeVal($this->p()->choices()); |
||
225 | } |
||
226 | |||
227 | /* Pass along the Generator from the parent method [^1] */ |
||
228 | /* Filter the all options down to those *not* selected */ |
||
229 | foreach ($choices as $ident => $choice) { |
||
230 | $choice = $this->parseChoice($ident, $choice); |
||
231 | if (($choice['selected'] && $this->deferred()) || !$this->deferred()) { |
||
232 | yield $choice; |
||
233 | } |
||
234 | } |
||
235 | } |
||
236 | |||
237 | /** |
||
238 | * Create an input group to nest extra inputs alongside selectize |
||
239 | * @return boolean |
||
240 | */ |
||
241 | public function inputGroup() |
||
242 | { |
||
243 | return !!($this->allowClipboardCopy() || $this->allowUpdate() || $this->allowCreate()); |
||
244 | } |
||
245 | |||
246 | /** |
||
247 | * Show/hide the "Copy to Clipboard" button. |
||
248 | * |
||
249 | * @param boolean $flag Show (TRUE) or hide (FALSE) the copy button. |
||
250 | * @return self |
||
251 | */ |
||
252 | public function setAllowClipboardCopy($flag) |
||
253 | { |
||
254 | $this->allowClipboardCopy = !!$flag; |
||
255 | |||
256 | return $this; |
||
257 | } |
||
258 | |||
259 | /** |
||
260 | * Determine if the property allows "Copy to Clipboard". |
||
261 | * |
||
262 | * @return boolean |
||
263 | */ |
||
264 | public function allowClipboardCopy() |
||
265 | { |
||
266 | return $this->allowClipboardCopy; |
||
267 | } |
||
268 | |||
269 | /** |
||
270 | * @param boolean $allowUpdate Show (TRUE) or hide (FALSE) the update button. |
||
271 | * @return self |
||
272 | */ |
||
273 | public function setAllowUpdate($allowUpdate) |
||
274 | { |
||
275 | $this->allowUpdate = !!$allowUpdate; |
||
276 | |||
277 | return $this; |
||
278 | } |
||
279 | |||
280 | /** |
||
281 | * Determine if the property allows "Update items". |
||
282 | * |
||
283 | * @return boolean |
||
284 | */ |
||
285 | public function allowUpdate() |
||
286 | { |
||
287 | return $this->allowUpdate; |
||
288 | } |
||
289 | |||
290 | /** |
||
291 | * @param boolean $allowCreate Show (TRUE) or hide (FALSE) the create button. |
||
292 | * @return self |
||
293 | */ |
||
294 | public function setAllowCreate($allowCreate) |
||
295 | { |
||
296 | $this->allowCreate = !!$allowCreate; |
||
297 | |||
298 | return $this; |
||
299 | } |
||
300 | |||
301 | /** |
||
302 | * Determine if the property allows "Update items". |
||
303 | * |
||
304 | * @return boolean |
||
305 | */ |
||
306 | public function allowCreate() |
||
307 | { |
||
308 | return $this->allowCreate; |
||
309 | } |
||
310 | |||
311 | /** |
||
312 | * @return boolean |
||
313 | */ |
||
314 | public function deferred() |
||
315 | { |
||
316 | return $this->deferred; |
||
317 | } |
||
318 | |||
319 | /** |
||
320 | * @param boolean $deferred Should the object be loaded in deferred mode. |
||
321 | * @return self |
||
322 | */ |
||
323 | public function setDeferred($deferred) |
||
324 | { |
||
325 | $this->deferred = ($this->property() instanceof ObjectProperty || $this->remoteSource()) ? $deferred : false; |
||
326 | |||
327 | return $this; |
||
328 | } |
||
329 | |||
330 | /** |
||
331 | * @return mixed |
||
332 | */ |
||
333 | public function formIdent() |
||
334 | { |
||
335 | return $this->formIdent; |
||
336 | } |
||
337 | |||
338 | /** |
||
339 | * @param mixed $formIdent The form ident(s) for object creation and modification. |
||
340 | * @return self |
||
341 | */ |
||
342 | public function setFormIdent($formIdent) |
||
343 | { |
||
344 | $this->formIdent = $formIdent; |
||
345 | |||
346 | return $this; |
||
347 | } |
||
348 | |||
349 | /** |
||
350 | * @return string Returns data serialized with {@see json_encode()}. |
||
351 | */ |
||
352 | public function formIdentAsJson() |
||
353 | { |
||
354 | return json_encode($this->formIdent()); |
||
355 | } |
||
356 | |||
357 | /** |
||
358 | * Set the selectize picker's options. |
||
359 | * |
||
360 | * This method overwrites existing helpers. |
||
361 | * |
||
362 | * @param array $settings The selectize picker options. |
||
363 | * @return self Chainable |
||
364 | */ |
||
365 | public function setSelectizeOptions(array $settings) |
||
366 | { |
||
367 | $this->selectizeOptions = array_merge( |
||
368 | $this->defaultSelectizeOptions(), |
||
369 | $this->parseSelectizeOptions($settings) |
||
370 | ); |
||
371 | |||
372 | return $this; |
||
373 | } |
||
374 | |||
375 | /** |
||
376 | * Merge (replacing or adding) selectize picker options. |
||
377 | * |
||
378 | * @param array $settings The selectize picker options. |
||
379 | * @return self Chainable |
||
380 | */ |
||
381 | public function mergeSelectizeOptions(array $settings) |
||
382 | { |
||
383 | $this->selectizeOptions = array_merge( |
||
384 | $this->selectizeOptions, |
||
385 | $this->parseSelectizeOptions($settings) |
||
386 | ); |
||
387 | |||
388 | return $this; |
||
389 | } |
||
390 | |||
391 | /** |
||
392 | * Add (or replace) an selectize picker option. |
||
393 | * |
||
394 | * @param string $key The setting to add/replace. |
||
395 | * @param mixed $val The setting's value to apply. |
||
396 | * @throws InvalidArgumentException If the identifier is not a string. |
||
397 | * @return self Chainable |
||
398 | */ |
||
399 | public function addSelectizeOption($key, $val) |
||
415 | } |
||
416 | |||
417 | /** |
||
418 | * Retrieve the selectize picker's options. |
||
419 | * |
||
420 | * @return array |
||
421 | */ |
||
422 | public function selectizeOptions() |
||
423 | { |
||
424 | if ($this->selectizeOptions === null) { |
||
425 | $this->selectizeOptions = $this->defaultSelectizeOptions(); |
||
426 | } |
||
427 | |||
428 | return $this->selectizeOptions; |
||
429 | } |
||
430 | |||
431 | /** |
||
432 | * Retrieve the default selectize picker options. |
||
433 | * |
||
434 | * @return array |
||
435 | */ |
||
436 | public function defaultSelectizeOptions() |
||
437 | { |
||
438 | $metadata = $this->metadata(); |
||
439 | $options = []; |
||
440 | |||
441 | if (isset($metadata['data']['selectize_options'])) { |
||
442 | $options = $metadata['data']['selectize_options']; |
||
443 | $options = $this->parseSelectizeOptions($options); |
||
444 | } |
||
445 | |||
446 | $prop = $this->property(); |
||
447 | if ($prop instanceof SelectablePropertyInterface) { |
||
448 | $choices = iterator_to_array($this->choices()); |
||
449 | |||
450 | if (isset($options['options'])) { |
||
451 | $options['options'] = array_merge($options['options'], $choices); |
||
452 | } else { |
||
453 | $options['options'] = $choices; |
||
454 | } |
||
455 | |||
456 | $items = $this->propertyVal(); |
||
457 | |||
458 | if ($prop instanceof AbstractProperty) { |
||
459 | $items = $prop->parseVal($items); |
||
460 | |||
461 | if ($prop->l10n()) { |
||
462 | $items = (string)$this->translator()->translation($items); |
||
463 | } |
||
464 | |||
465 | if (is_string($items)) { |
||
466 | $items = explode($prop->multipleSeparator(), $items); |
||
467 | } |
||
468 | } |
||
469 | |||
470 | if (!$prop->multiple()) { |
||
471 | $items = (array)$items; |
||
472 | } |
||
473 | |||
474 | if (!$items) { |
||
475 | $items = []; |
||
476 | } |
||
477 | |||
478 | // workaround for object setter casting the property as object. |
||
479 | if ($items instanceof ModelInterface) { |
||
480 | $items = $this->mapObjToChoice($items)['value']; |
||
481 | } |
||
482 | |||
483 | if (is_scalar($items)) { |
||
484 | $items = [$items]; |
||
485 | } |
||
486 | |||
487 | if (!isset($options['items'])) { |
||
488 | $options['items'] = []; |
||
489 | } |
||
490 | $options['items'] = array_merge($options['items'], $items); |
||
491 | } |
||
492 | |||
493 | return $options; |
||
494 | } |
||
495 | |||
496 | /** |
||
497 | * Retrieve the selectize picker's options as a JSON string. |
||
498 | * |
||
499 | * @return string Returns data serialized with {@see json_encode()}. |
||
500 | */ |
||
501 | public function selectizeOptionsAsJson() |
||
502 | { |
||
503 | return json_encode($this->selectizeOptions()); |
||
504 | } |
||
505 | |||
506 | /** |
||
507 | * Parse the selectize picker's options. |
||
508 | * |
||
509 | * @param array $settings The selectize picker options. |
||
510 | * @return array Returns the parsed options. |
||
511 | */ |
||
512 | protected function parseSelectizeOptions(array $settings) |
||
513 | { |
||
514 | return $settings; |
||
515 | } |
||
516 | |||
517 | /** |
||
518 | * @return boolean |
||
519 | */ |
||
520 | public function isObject() |
||
521 | { |
||
522 | return !!($this->p() instanceof ObjectProperty); |
||
523 | } |
||
524 | |||
525 | /** |
||
526 | * @return array |
||
527 | */ |
||
528 | public function selectizeTemplates() |
||
529 | { |
||
530 | return $this->selectizeTemplates; |
||
531 | } |
||
532 | |||
533 | /** |
||
534 | * @param array|object|mixed $selectizeTemplates Selectize Templates array. |
||
535 | * @throws \InvalidArgumentException If the supplied argument is not of type object. |
||
536 | * @return self |
||
537 | */ |
||
538 | public function setSelectizeTemplates($selectizeTemplates) |
||
539 | { |
||
540 | if (!is_object($selectizeTemplates) && !is_array($selectizeTemplates)) { |
||
541 | $selectizeTemplates = [ |
||
542 | 'item' => $selectizeTemplates, |
||
543 | 'option' => $selectizeTemplates, |
||
544 | 'controller' => class_exists($selectizeTemplates) ? $selectizeTemplates : null |
||
545 | ]; |
||
546 | } |
||
547 | |||
548 | $this->selectizeTemplates = $selectizeTemplates; |
||
549 | |||
550 | return $this; |
||
551 | } |
||
552 | |||
553 | /** |
||
554 | * @return string |
||
555 | */ |
||
556 | public function selectizeTemplatesAsJson() |
||
557 | { |
||
558 | return json_encode($this->selectizeTemplates()); |
||
559 | } |
||
560 | |||
561 | /** |
||
562 | * Convert the given value into selectize picker choices. |
||
563 | * |
||
564 | * @param mixed $val The value to parse into selectize choices. |
||
565 | * @param array $options Optional structure options. |
||
566 | * @throws InvalidArgumentException If the choice structure is missing a value. |
||
567 | * @return array |
||
568 | */ |
||
569 | public function selectizeVal($val, array $options = []) |
||
570 | { |
||
571 | /** @todo Find a use for this */ |
||
572 | unset($options); |
||
573 | $choices = []; |
||
574 | |||
575 | if ($val === null || $val === '') { |
||
576 | return []; |
||
577 | } |
||
578 | |||
579 | $prop = $this->property(); |
||
580 | |||
581 | if ($prop instanceof AbstractProperty) { |
||
582 | $val = $prop->parseVal($val); |
||
583 | |||
584 | if (is_string($val)) { |
||
585 | $val = explode($prop->multipleSeparator(), $val); |
||
586 | } |
||
587 | } |
||
588 | |||
589 | if (!$prop->multiple()) { |
||
590 | $val = (array)$val; |
||
591 | } |
||
592 | |||
593 | $selectizeTemplates = $this->selectizeTemplates(); |
||
594 | $itemTemplate = isset($selectizeTemplates['item']) ? $selectizeTemplates['item'] : null; |
||
595 | $optionTemplate = isset($selectizeTemplates['option']) ? $selectizeTemplates['option'] : null; |
||
596 | $selectizeController = isset($selectizeTemplates['controller']) ? $selectizeTemplates['controller'] : null; |
||
597 | $selectizeData = isset($selectizeTemplates['data']) ? $selectizeTemplates['data'] : []; |
||
598 | |||
599 | if ($prop instanceof ObjectProperty) { |
||
600 | foreach ($val as &$v) { |
||
601 | if (is_array($v)) { |
||
602 | if (!isset($v['value'])) { |
||
603 | throw new InvalidArgumentException('Missing [value] on choice structure.'); |
||
604 | } |
||
605 | $v = $v['value']; |
||
606 | } |
||
607 | } |
||
608 | |||
609 | $model = $this->modelFactory()->get($prop->objType()); |
||
610 | if (!$model->source()->tableExists()) { |
||
611 | return $choices; |
||
612 | } |
||
613 | $loader = $this->collectionLoader(); |
||
614 | $loader->reset() |
||
615 | ->setModel($model) |
||
616 | ->addFilter([ |
||
617 | 'property' => $model->key(), |
||
618 | 'value' => $val, |
||
619 | 'operator' => 'IN' |
||
620 | ]); |
||
621 | |||
622 | $collection = $loader->load(); |
||
623 | |||
624 | if ($prop instanceof HierarchicalObjectProperty) { |
||
625 | $collection = $this->sortObjects($collection); |
||
626 | } |
||
627 | |||
628 | $choices = []; |
||
629 | foreach ($collection as $obj) { |
||
630 | $c = $this->mapObjToChoice($obj); |
||
631 | $obj->setData($selectizeData); |
||
632 | |||
633 | if (in_array($c['value'], $this->disabledFields())) { |
||
634 | $c['disabled'] = 'disabled'; |
||
635 | } |
||
636 | |||
637 | if ($itemTemplate) { |
||
638 | $c['item_render'] = $this->selectizeRenderer->renderTemplate( |
||
639 | $itemTemplate, |
||
640 | $obj, |
||
641 | $selectizeController |
||
642 | ); |
||
643 | } |
||
644 | |||
645 | if ($optionTemplate) { |
||
646 | $c['option_render'] = $this->selectizeRenderer->renderTemplate( |
||
647 | $optionTemplate, |
||
648 | $obj, |
||
649 | $selectizeController |
||
650 | ); |
||
651 | } |
||
652 | |||
653 | $choices[] = $c; |
||
654 | } |
||
655 | } else { |
||
656 | foreach ($val as $value) { |
||
657 | $pChoices = $value; |
||
658 | |||
659 | $c = $pChoices; |
||
660 | $context = array_replace_recursive($selectizeData, $pChoices); |
||
661 | |||
662 | if ($itemTemplate) { |
||
663 | $c['item_render'] = $this->selectizeRenderer->renderTemplate( |
||
664 | $itemTemplate, |
||
665 | $context, |
||
666 | $selectizeController |
||
667 | ); |
||
668 | } |
||
669 | |||
670 | if ($optionTemplate) { |
||
671 | $c['option_render'] = $this->selectizeRenderer->renderTemplate( |
||
672 | $optionTemplate, |
||
673 | $context, |
||
674 | $selectizeController |
||
675 | ); |
||
676 | } |
||
677 | |||
678 | $choices[] = $c; |
||
679 | } |
||
680 | } |
||
681 | |||
682 | return $choices; |
||
683 | } |
||
684 | |||
685 | /** |
||
686 | * Sort the objects before they are displayed as rows. |
||
687 | * |
||
688 | * @param ModelInterface[]|Collection $objects The objects collection to sort. |
||
689 | * @see \Charcoal\Admin\Ui\CollectionContainerTrait::sortObjects() |
||
690 | * @return array |
||
691 | */ |
||
692 | public function sortObjects($objects) |
||
693 | { |
||
694 | $collection = new HierarchicalCollection($objects, false); |
||
695 | $collection->sortTree(); |
||
696 | |||
697 | return $collection->all(); |
||
698 | } |
||
699 | |||
700 | /** |
||
701 | * Retrieve the object-to-choice data map. |
||
702 | * |
||
703 | * @return array Returns a data map to abide. |
||
704 | */ |
||
705 | public function choiceObjMap() |
||
706 | { |
||
707 | $map = parent::choiceObjMap(); |
||
708 | |||
709 | if (!$this->isChoiceObjMapFinalized) { |
||
710 | $this->isChoiceObjMapFinalized = true; |
||
711 | |||
712 | $prop = $this->property(); |
||
713 | if ($prop instanceof ObjectProperty) { |
||
714 | /** @var ModelInterface $model */ |
||
715 | $model = $this->modelFactory()->get($prop->objType()); |
||
716 | $objProperties = $model->properties(); |
||
717 | |||
718 | if ($objProperties instanceof \Iterator) { |
||
719 | $objProperties = iterator_to_array($objProperties); |
||
720 | } |
||
721 | |||
722 | foreach ($map as &$mapProp) { |
||
723 | $props = explode(':', $mapProp); |
||
724 | foreach ($props as $p) { |
||
725 | if (isset($objProperties[$p])) { |
||
726 | $mapProp = $p; |
||
727 | break; |
||
728 | } |
||
729 | } |
||
730 | } |
||
731 | } |
||
732 | |||
733 | $this->choiceObjMap = $map; |
||
734 | } |
||
735 | |||
736 | return $this->choiceObjMap; |
||
737 | } |
||
738 | |||
739 | /** |
||
740 | * Retrieve the default object-to-choice data map. |
||
741 | * |
||
742 | * @return array |
||
743 | */ |
||
744 | public function defaultChoiceObjMap() |
||
745 | { |
||
746 | return [ |
||
747 | 'value' => 'id', |
||
748 | 'label' => 'name:title:label:id', |
||
749 | 'color' => 'color' |
||
750 | ]; |
||
751 | } |
||
752 | |||
753 | /** |
||
754 | * Retrieve the control's data options for JavaScript components. |
||
755 | * |
||
756 | * @return array |
||
757 | */ |
||
758 | public function controlDataForJs() |
||
759 | { |
||
760 | $prop = $this->property(); |
||
761 | |||
762 | $data = [ |
||
763 | // Selectize Control |
||
764 | 'title' => (string)$prop->label(), |
||
765 | 'translations' => [ |
||
766 | 'statusTemplate' => $this->translator()->translate('Step [[ current ]] of [[ total ]]'), |
||
767 | ], |
||
768 | 'copy_items' => $this->allowClipboardCopy(), |
||
769 | 'allow_update' => $this->allowUpdate(), |
||
770 | 'allow_create' => $this->allowCreate(), |
||
771 | |||
772 | 'form_ident' => $this->formIdent(), |
||
773 | 'selectize_selector' => '#'.$this->inputId(), |
||
774 | 'selectize_options' => $this->selectizeOptions(), |
||
775 | 'choice_obj_map' => $this->choiceObjMap(), |
||
776 | 'selectize_property_ident' => $prop->ident(), |
||
777 | 'selectize_obj_type' => $this->render('{{& objType }}'), |
||
778 | 'selectize_templates' => $this->selectizeTemplates(), |
||
779 | 'selectize_property' => json_encode($this->property()), |
||
780 | 'remote_source' => $this->remoteSource(), |
||
781 | |||
782 | // Base Property |
||
783 | 'required' => $this->required(), |
||
784 | 'l10n' => $this->property()->l10n(), |
||
785 | 'multiple' => $this->multiple(), |
||
786 | 'multiple_separator' => $this->property()->multipleSeparator(), |
||
787 | 'multiple_options' => $this->property()->multipleOptions(), |
||
788 | ]; |
||
789 | |||
790 | if ($prop instanceof ObjectProperty) { |
||
791 | if ($prop->objType()) { |
||
792 | $data['pattern'] = $prop->pattern(); |
||
793 | $data['obj_type'] = $prop->objType(); |
||
794 | } |
||
795 | } |
||
796 | |||
797 | return $data; |
||
798 | } |
||
799 | |||
800 | /** |
||
801 | * @return array |
||
802 | */ |
||
803 | public function disabledFields() |
||
804 | { |
||
805 | return $this->disabledFields; |
||
806 | } |
||
807 | |||
808 | /** |
||
809 | * @param array $disabledFields DisabledFields for SelectizeInput. |
||
810 | * @return self |
||
811 | */ |
||
812 | public function setDisabledFields(array $disabledFields) |
||
813 | { |
||
814 | $this->disabledFields = $disabledFields; |
||
815 | |||
816 | return $this; |
||
817 | } |
||
818 | |||
819 | /** |
||
820 | * @return string |
||
821 | */ |
||
822 | public function remoteSource() |
||
823 | { |
||
824 | return $this->remoteSource; |
||
825 | } |
||
826 | |||
827 | /** |
||
828 | * @param string $remoteSource RemoteSource for SelectizeInput. |
||
829 | * @return self |
||
830 | */ |
||
831 | public function setRemoteSource($remoteSource) |
||
832 | { |
||
833 | $this->remoteSource = $remoteSource; |
||
834 | |||
835 | if ($this->remoteSource) { |
||
836 | $this->remoteSource = $this->renderTemplate($this->remoteSource); |
||
837 | } |
||
838 | |||
839 | return $this; |
||
840 | } |
||
841 | |||
842 | /** |
||
843 | * Inject dependencies from a DI Container. |
||
844 | * |
||
845 | * @param Container $container A dependencies container instance. |
||
846 | * @return void |
||
847 | */ |
||
848 | protected function setDependencies(Container $container) |
||
849 | { |
||
850 | parent::setDependencies($container); |
||
851 | |||
852 | $this->setModelFactory($container['model/factory']); |
||
853 | $this->setCollectionLoader($container['model/collection/loader']); |
||
854 | $this->selectizeRenderer = $container['selectize/renderer']; |
||
855 | } |
||
856 | |||
857 | /** |
||
858 | * Set an object model factory. |
||
859 | * |
||
860 | * @param FactoryInterface $factory The model factory, to create objects. |
||
861 | * @return void |
||
862 | */ |
||
863 | protected function setModelFactory(FactoryInterface $factory) |
||
866 | } |
||
867 | } |
||
868 |
In the issue above, the returned value is violating the contract defined by the mentioned interface.
Let's take a look at an example: