SelectizeInput::defaultSelectizeOptions()   F
last analyzed

Complexity

Conditions 12
Paths 642

Size

Total Lines 58
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 12
eloc 31
nc 642
nop 0
dl 0
loc 58
rs 3.2972
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Charcoal\Admin\Property\Input;
4
5
use RuntimeException;
6
use InvalidArgumentException;
7
8
// From Pimple
9
use Pimple\Container;
10
11
// From 'charcoal-core'
12
use Charcoal\Model\ModelInterface;
13
use Charcoal\Model\Collection;
14
use Charcoal\Loader\CollectionLoader;
15
16
// From 'charcoal-object'
17
use Charcoal\Object\HierarchicalCollection;
18
19
// From 'charcoal-factory'
20
use Charcoal\Factory\FactoryInterface;
21
22
// From 'charcoal-property'
23
use Charcoal\Property\ObjectProperty;
24
use Charcoal\Property\SelectablePropertyInterface;
25
use Charcoal\Property\AbstractProperty;
26
27
// From 'charcoal-admin'
28
use Charcoal\Admin\Service\SelectizeRenderer;
29
use Charcoal\Admin\Property\HierarchicalObjectProperty;
30
31
/**
32
 * Tags Input Property
33
 *
34
 * The HTML form control can be either an `<input type="text">` (for multiple values)
35
 * or a `<select>` (single value).
36
 */
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;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Charcoal\Admin\Property\Input\SelectizeInput which is incompatible with the return type mandated by Charcoal\Admin\Property\...putInterface::setData() of Charcoal\Admin\Property\Input.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
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;
0 ignored issues
show
Bug Best Practice introduced by
The expression yield $prepend returns the type Generator which is incompatible with the return type mandated by Charcoal\Admin\Property\...putInterface::choices() of Charcoal\Admin\Property\Generator|array.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
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());
0 ignored issues
show
Bug introduced by
The method choices() does not exist on Charcoal\Property\PropertyInterface. It seems like you code against a sub-type of Charcoal\Property\PropertyInterface such as Charcoal\Property\ObjectProperty or Charcoal\Property\BooleanProperty or Charcoal\Property\StringProperty or Charcoal\Property\LangProperty or Charcoal\Property\SpriteProperty. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

224
            $choices = $this->selectizeVal($this->p()->/** @scrutinizer ignore-call */ choices());
Loading history...
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)
400
    {
401
        if (!is_string($key)) {
0 ignored issues
show
introduced by
The condition is_string($key) is always true.
Loading history...
402
            throw new InvalidArgumentException(
403
                'Setting key must be a string.'
404
            );
405
        }
406
407
        // Make sure default options are loaded.
408
        if ($this->selectizeOptions === null) {
409
            $this->selectizeOptions();
410
        }
411
412
        $this->selectizeOptions[$key] = $val;
413
414
        return $this;
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;
0 ignored issues
show
Documentation Bug introduced by
It seems like $selectizeTemplates can also be of type object. However, the property $selectizeTemplates is declared as type array. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
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) {
0 ignored issues
show
introduced by
$objProperties is never a sub-type of Iterator.
Loading history...
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(),
0 ignored issues
show
Bug introduced by
The method multipleSeparator() does not exist on Charcoal\Property\PropertyInterface. Did you maybe mean multiple()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

786
            'multiple_separator'       => $this->property()->/** @scrutinizer ignore-call */ multipleSeparator(),

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
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)
864
    {
865
        $this->modelFactory = $factory;
866
    }
867
}
868