CollectionContainerTrait::hasFilters()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
3
namespace Charcoal\Admin\Ui;
4
5
use Exception;
6
use InvalidArgumentException;
7
8
// From 'charcoal-factory'
9
use Charcoal\Factory\FactoryInterface;
10
11
// From 'charcoal-core'
12
use Charcoal\Loader\CollectionLoader;
13
use Charcoal\Model\Collection;
14
use Charcoal\Model\ModelInterface;
15
use Charcoal\Source\Filter;
16
use Charcoal\Source\FilterInterface;
17
use Charcoal\Source\Order;
18
use Charcoal\Source\OrderInterface;
19
use Charcoal\Source\Pagination;
20
use Charcoal\Source\PaginationInterface;
21
22
// From 'charcoal-property'
23
use Charcoal\Property\PropertyInterface;
24
25
// From 'charcoal-view'
26
use Charcoal\View\ViewInterface;
27
28
/**
29
 * Fully implements CollectionContainerInterface
30
 */
31
trait CollectionContainerTrait
32
{
33
    /**
34
     * @var FactoryInterface $modelFactory
35
     */
36
    private $modelFactory;
37
38
    /**
39
     * @var CollectionLoader $collectionLoader
40
     */
41
    private $collectionLoader;
42
43
    /**
44
     * @var string $objType
45
     */
46
    private $objType;
47
48
    /**
49
     * @var string $collectionIdent
50
     */
51
    private $collectionIdent;
52
53
    /**
54
     * Collection configuration.
55
     *
56
     * @var array|null
57
     */
58
    private $collectionConfig;
59
60
    /**
61
     * Default collection configuration.
62
     *
63
     * @var array|null
64
     */
65
    private $defaultCollectionConfig;
66
67
    /**
68
     * Object labels.
69
     *
70
     * @var array|null
71
     */
72
    private $objLabels;
73
74
    /**
75
     * @var integer $numTotal
76
     */
77
    private $numTotal;
78
79
    /**
80
     * The collection's prepared filters.
81
     *
82
     * @var FilterInterface[]
83
     */
84
    protected $filters;
85
86
    /**
87
     * The collection's prepared orders.
88
     *
89
     * @var OrderInterface[]
90
     */
91
    protected $orders;
92
93
    /**
94
     * The collection's prepared pagiantion.
95
     *
96
     * @var PaginationInterface
97
     */
98
    protected $pagination;
99
100
    /**
101
     * @var Collection $collection
102
     */
103
    private $collection;
104
105
    /**
106
     * @var FactoryInterface $propertyDisplayFactory
107
     */
108
    private $propertyDisplayFactory;
109
110
    /**
111
     * @var mixed $currentObjId
112
     */
113
    protected $currentObjId;
114
115
    /**
116
     * @var mixed $currentObj
117
     */
118
    protected $currentObj;
119
120
    /**
121
     * @var ModelInterface $proto
122
     */
123
    private $proto;
124
125
    /**
126
     * In memory copy of the PropertyDisplay object
127
     * @var PropertyInputInterface $display
0 ignored issues
show
Bug introduced by
The type Charcoal\Admin\Ui\PropertyInputInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
128
     */
129
    protected $display;
130
131
    /**
132
     * @var ViewInterface $view
133
     */
134
    private $view;
135
136
    /**
137
     * @param ViewInterface|array $view The view instance.
138
     * @return CollectionContainerInterface Chainable
139
     */
140
    public function setView(ViewInterface $view)
141
    {
142
        $this->view = $view;
143
144
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Charcoal\Admin\Ui\CollectionContainerTrait which is incompatible with the documented return type Charcoal\Admin\Ui\CollectionContainerInterface.
Loading history...
145
    }
146
147
    /**
148
     * @throws Exception If the view instance is not previously set / injected.
149
     * @return ViewInterface The object's view.
150
     */
151
    public function view()
152
    {
153
        if ($this->view === null) {
154
            throw new Exception(
155
                'View instance is not set for table widget'
156
            );
157
        }
158
159
        return $this->view;
160
    }
161
162
    /**
163
     * @param FactoryInterface $factory The model factory, to create model objects.
164
     * @return CollectionContainerInterface Chainable
165
     */
166
    public function setModelFactory(FactoryInterface $factory)
167
    {
168
        $this->modelFactory = $factory;
169
170
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Charcoal\Admin\Ui\CollectionContainerTrait which is incompatible with the documented return type Charcoal\Admin\Ui\CollectionContainerInterface.
Loading history...
171
    }
172
173
    /**
174
     * Model Factory getter.
175
     *
176
     * @throws Exception If the model factory was not previously set.
177
     * @return FactoryInterface
178
     */
179
    protected function modelFactory()
180
    {
181
        if ($this->modelFactory === null) {
182
            throw new Exception(sprintf(
183
                'Model Factory is not defined for "%s"',
184
                get_class($this)
185
            ));
186
        }
187
188
        return $this->modelFactory;
189
    }
190
191
    /**
192
     * @param FactoryInterface $factory The property display factory.
193
     * @return CollectionContainerInterface Chainable
194
     */
195
    private function setPropertyDisplayFactory(FactoryInterface $factory)
196
    {
197
        $this->propertyDisplayFactory = $factory;
198
199
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Charcoal\Admin\Ui\CollectionContainerTrait which is incompatible with the documented return type Charcoal\Admin\Ui\CollectionContainerInterface.
Loading history...
200
    }
201
202
    /**
203
     * @throws Exception If the property display factory was not previously injected / set.
204
     * @return FactoryInterface
205
     */
206
    private function propertyDisplayFactory()
207
    {
208
        if ($this->propertyDisplayFactory === null) {
209
            throw new Exception(sprintf(
210
                'Property display factory is not defined for "%s"',
211
                get_class($this)
212
            ));
213
        }
214
215
        return $this->propertyDisplayFactory;
216
    }
217
218
    /**
219
     * @param CollectionLoader $loader The collection loader.
220
     * @return CollectionContainerInterface Chainable
221
     */
222
    public function setCollectionLoader(CollectionLoader $loader)
223
    {
224
        $this->collectionLoader = $loader;
225
226
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Charcoal\Admin\Ui\CollectionContainerTrait which is incompatible with the documented return type Charcoal\Admin\Ui\CollectionContainerInterface.
Loading history...
227
    }
228
229
    /**
230
     * Safe Collection Loader getter.
231
     * Create the loader if it was not set / injected.
232
     *
233
     * @return CollectionLoader
234
     */
235
    protected function collectionLoader()
236
    {
237
        if ($this->collectionLoader === null) {
238
            $this->collectionLoader = $this->createCollectionLoader();
239
        }
240
241
        return $this->collectionLoader;
242
    }
243
244
    /**
245
     * Create a collection loader.
246
     *
247
     * @return CollectionLoader
248
     */
249
    protected function createCollectionLoader()
250
    {
251
        return new CollectionLoader([
252
            'logger'  => $this->logger,
253
            'factory' => $this->modelFactory()
254
        ]);
255
    }
256
257
    /**
258
     * @param string $objType The collection's object type.
259
     * @throws InvalidArgumentException If provided argument is not of type 'string'.
260
     * @return CollectionContainerInterface Chainable
261
     */
262
    public function setObjType($objType)
263
    {
264
        if (!is_string($objType)) {
0 ignored issues
show
introduced by
The condition is_string($objType) is always true.
Loading history...
265
            throw new InvalidArgumentException(
266
                'Obj type must be a string'
267
            );
268
        }
269
        $this->objType = str_replace([ '.', '_' ], '/', $objType);
270
271
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Charcoal\Admin\Ui\CollectionContainerTrait which is incompatible with the documented return type Charcoal\Admin\Ui\CollectionContainerInterface.
Loading history...
272
    }
273
274
    /**
275
     * @return string
276
     */
277
    public function objType()
278
    {
279
        return $this->objType;
280
    }
281
282
    /**
283
     * Set the key for the collection structure to use.
284
     *
285
     * @param  string $collectionIdent The collection identifier.
286
     * @throws InvalidArgumentException If the identifier argument is not a string.
287
     * @return CollectionContainerInterface Chainable
288
     */
289
    public function setCollectionIdent($collectionIdent)
290
    {
291
        if (!is_string($collectionIdent)) {
0 ignored issues
show
introduced by
The condition is_string($collectionIdent) is always true.
Loading history...
292
            throw new InvalidArgumentException(
293
                'Collection identifier must be a string'
294
            );
295
        }
296
        $this->collectionIdent = $collectionIdent;
297
298
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Charcoal\Admin\Ui\CollectionContainerTrait which is incompatible with the documented return type Charcoal\Admin\Ui\CollectionContainerInterface.
Loading history...
299
    }
300
301
    /**
302
     * Retrieve a key for the collection structure to use.
303
     *
304
     * If the collection key is undefined, resolve a fallback.
305
     *
306
     * @return string
307
     */
308
    public function collectionIdentFallback()
309
    {
310
        $metadata = $this->proto()->metadata();
311
312
        if (isset($metadata['admin']['default_list'])) {
313
            return $metadata['admin']['default_list'];
314
        }
315
316
        return $this->collectionIdent;
317
    }
318
319
    /**
320
     * Retrieve the key for the collection structure to use.
321
     *
322
     * @return string|null
323
     */
324
    public function collectionIdent()
325
    {
326
        return $this->collectionIdent;
327
    }
328
329
    /**
330
     * Return the current collection metadata.
331
     *
332
     * @return array
333
     */
334
    public function collectionMetadata()
335
    {
336
        $proto = $this->proto();
337
        $collectionIdent = $this->collectionIdent();
338
339
        if (!$collectionIdent) {
340
            $collectionIdent = $this->collectionIdentFallback();
341
        }
342
343
        if ($collectionIdent && $proto->view()) {
344
            $collectionIdent = $proto->render($collectionIdent);
345
        }
346
347
        if (!$collectionIdent) {
348
            return [];
349
        }
350
351
        $objMeta = $proto->metadata();
352
353
        if (isset($objMeta['admin']['lists'][$collectionIdent])) {
354
            return $objMeta['admin']['lists'][$collectionIdent];
355
        } else {
356
            return [];
357
        }
358
    }
359
360
    /**
361
     * Retrieve the collection configset.
362
     *
363
     * @return array|null
364
     */
365
    public function collectionConfig()
366
    {
367
        if ($this->collectionConfig === null) {
368
            $this->collectionConfig = $this->createCollectionConfig();
369
        }
370
371
        return $this->collectionConfig;
372
    }
373
374
    /**
375
     * Replace the collection's configset with the given parameters.
376
     *
377
     * @param  mixed $config New collection config values.
378
     * @return CollectionContainerInterface Chainable
379
     */
380
    public function setCollectionConfig($config)
381
    {
382
        if (empty($config) || !is_array($config)) {
383
            $config = [];
384
        }
385
386
        $this->collectionConfig = array_replace_recursive(
387
            $this->defaultCollectionConfig(),
388
            $this->parseCollectionConfig($config)
389
        );
390
391
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Charcoal\Admin\Ui\CollectionContainerTrait which is incompatible with the documented return type Charcoal\Admin\Ui\CollectionContainerInterface.
Loading history...
392
    }
393
394
    /**
395
     * Merge given parameters into the collection's configset.
396
     *
397
     * @param  array $config New collection config values.
398
     * @return self
399
     */
400
    public function mergeCollectionConfig(array $config)
401
    {
402
        if ($this->collectionConfig === null) {
403
            $this->setCollectionConfig($config);
404
405
            return $this;
406
        }
407
408
        $this->collectionConfig = array_replace_recursive(
409
            $this->defaultCollectionConfig(),
410
            $this->collectionConfig,
411
            $this->parseCollectionConfig($config)
412
        );
413
414
        return $this;
415
    }
416
417
    /**
418
     * Stub: Parse given parameters into the collection's config set.
419
     *
420
     * @param  array $config New collection config values.
421
     * @return array
422
     */
423
    protected function parseCollectionConfig(array $config)
424
    {
425
        return array_filter($config, function ($val) {
426
            return !empty($val) || is_numeric($val);
427
        });
428
    }
429
430
    /**
431
     * Retrieve the default collection configuration.
432
     *
433
     * The default configset is determined by the collection ident and object type, if assigned.
434
     *
435
     * @return array|null
436
     */
437
    protected function defaultCollectionConfig()
438
    {
439
        if ($this->defaultCollectionConfig === null) {
440
            $this->defaultCollectionConfig = $this->collectionMetadata();
441
        }
442
443
        return $this->defaultCollectionConfig;
444
    }
445
446
    /**
447
     * Stub: reimplement in classes using this trait.
448
     *
449
     * @return mixed
450
     */
451
    protected function createCollectionConfig()
452
    {
453
        return $this->collectionMetadata();
454
    }
455
456
    /**
457
     * @return boolean
458
     */
459
    public function hasPagination()
460
    {
461
        return ($this->pagination() instanceof Pagination);
462
    }
463
464
    /**
465
     * @return PaginationInterface
466
     */
467
    public function pagination()
468
    {
469
        if ($this->pagination === null || !$this->pagination instanceof PaginationInterface) {
470
            $this->pagination = $this->createPagination();
471
            $collectionConfig = $this->collectionConfig();
472
            if (isset($collectionConfig['pagination'])) {
473
                $this->pagination->setData($collectionConfig['pagination']);
474
            }
475
        }
476
477
        return $this->pagination;
478
    }
479
480
    /**
481
     * @return PaginationInterface
482
     */
483
    protected function createPagination()
484
    {
485
        $pagination = new Pagination();
486
        return $pagination;
487
    }
488
489
    /**
490
     * @return integer
491
     */
492
    public function page()
493
    {
494
        return $this->pagination()->page();
495
    }
496
497
    /**
498
     * @return integer
499
     */
500
    public function numPerPage()
501
    {
502
        return $this->pagination()->numPerPage();
503
    }
504
505
    /**
506
     * @return integer
507
     */
508
    public function numPages()
509
    {
510
        if ($this->numPerPage() === 0) {
511
            return 0;
512
        }
513
514
        return ceil($this->numTotal() / $this->numPerPage());
515
    }
516
517
    /**
518
     * @return boolean
519
     */
520
    public function hasFilters()
521
    {
522
        return count($this->filters()) > 0;
523
    }
524
525
    /**
526
     * @return FilterInterface[]
527
     */
528
    public function filters()
529
    {
530
        if ($this->filters === null) {
531
            $this->filters = [];
532
            $collectionConfig = $this->collectionConfig();
533
            if (isset($collectionConfig['filters'])) {
534
                foreach ($collectionConfig['filters'] as $key => $data) {
535
                    if ($data instanceof FilterInterface) {
536
                        $filter = $data;
537
                    } elseif (is_array($data)) {
538
                        $filter = $this->createFilter();
539
                        $filter->setData($data);
540
                    }
541
                    $this->filters[$key] = $filter;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $filter does not seem to be defined for all execution paths leading up to this point.
Loading history...
542
                }
543
            }
544
        }
545
546
        return $this->filters;
547
    }
548
549
    /**
550
     * @return FilterInterface
551
     */
552
    protected function createFilter()
553
    {
554
        $filter = new Filter();
555
        return $filter;
556
    }
557
558
    /**
559
     * @return boolean
560
     */
561
    public function hasOrders()
562
    {
563
        return count($this->orders()) > 0;
564
    }
565
566
    /**
567
     * @return OrderInterface[]
568
     */
569
    public function orders()
570
    {
571
        if ($this->orders === null) {
572
            $this->orders = [];
573
            $collectionConfig = $this->collectionConfig();
574
            if (isset($collectionConfig['orders'])) {
575
                foreach ($collectionConfig['orders'] as $key => $data) {
576
                    if ($data instanceof OrderInterface) {
577
                        $order = $data;
578
                    } elseif (is_array($data)) {
579
                        $order = $this->createOrder();
580
                        $order->setData($data);
581
                    }
582
                    $this->orders[$key] = $order;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $order does not seem to be defined for all execution paths leading up to this point.
Loading history...
583
                }
584
            }
585
        }
586
587
        return $this->orders;
588
    }
589
590
    /**
591
     * @return OrderInterface
592
     */
593
    protected function createOrder()
594
    {
595
        $order = new Order();
596
        return $order;
597
    }
598
599
    /**
600
     * @param mixed $collection The collection.
601
     * @return CollectionContainerInterface Chainable
602
     */
603
    public function setCollection($collection)
604
    {
605
        $this->collection = $collection;
606
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Charcoal\Admin\Ui\CollectionContainerTrait which is incompatible with the documented return type Charcoal\Admin\Ui\CollectionContainerInterface.
Loading history...
607
    }
608
609
    /**
610
     * @return CollectionLoader
611
     */
612
    public function collection()
613
    {
614
        if ($this->collection === null) {
615
            $this->collection = $this->createCollection();
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->createCollection() of type Charcoal\Loader\CollectionLoader is incompatible with the declared type Charcoal\Model\Collection of property $collection.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
616
        }
617
618
        return $this->collection;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->collection also could return the type Charcoal\Model\Collection which is incompatible with the documented return type Charcoal\Loader\CollectionLoader.
Loading history...
619
    }
620
621
    /**
622
     * @todo Integrate $data; merge with $collectionConfig
623
     * @param array $data Optional collection data.
624
     * @throws Exception If the object type of the colletion has not been set.
625
     * @return CollectionLoader
626
     */
627
    public function createCollection(array $data = null)
628
    {
629
        $objType = $this->objType();
630
        if (!$objType) {
631
            throw new Exception(sprintf(
632
                '%1$s cannot create collection. Object type is not defined.',
633
                get_class($this)
634
            ));
635
        }
636
637
        $loader = $this->collectionLoader();
638
        $loader->setModel($this->proto());
639
640
        $collectionConfig = $this->collectionConfig();
641
        if (is_array($collectionConfig) && !empty($collectionConfig)) {
642
            unset($collectionConfig['properties']);
643
            $loader->setData($collectionConfig);
644
        }
645
646
        if ($data) {
647
            $loader->setData($data);
648
        }
649
650
        $collection = $loader->load();
651
652
        return $collection;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $collection returns the type Charcoal\Model\ModelInterface[]&ArrayAccess which is incompatible with the documented return type Charcoal\Loader\CollectionLoader.
Loading history...
653
    }
654
655
    /**
656
     * @return array
657
     */
658
    public function objects()
659
    {
660
        return $this->collection()->objects();
0 ignored issues
show
Bug introduced by
The method objects() does not exist on Charcoal\Loader\CollectionLoader. ( Ignorable by Annotation )

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

660
        return $this->collection()->/** @scrutinizer ignore-call */ objects();

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...
661
    }
662
663
    /**
664
     * Sort the objects before they are displayed as rows.
665
     *
666
     * This method is useful for classes using this trait.
667
     *
668
     * @return array
669
     */
670
    public function sortObjects()
671
    {
672
        return $this->objects();
673
    }
674
675
    /**
676
     * Sort the properties before they are displayed as columns.
677
     *
678
     * This method is useful for classes using this trait.
679
     *
680
     * @return array
681
     */
682
    public function sortProperties()
683
    {
684
        return $this->properties();
0 ignored issues
show
Bug introduced by
It seems like properties() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

684
        return $this->/** @scrutinizer ignore-call */ properties();
Loading history...
685
    }
686
687
    /**
688
     * Supplies properties for objects in table template specific to object configuration.
689
     *
690
     * @return array This metod is a generator.
691
     */
692
    public function objectRows()
693
    {
694
        // Get properties as defined in object's list metadata
695
        $properties  = $this->sortProperties();
696
        $propOptions = $this->propertiesOptions();
0 ignored issues
show
Bug introduced by
It seems like propertiesOptions() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

696
        /** @scrutinizer ignore-call */ 
697
        $propOptions = $this->propertiesOptions();
Loading history...
697
698
        // Collection objects
699
        $objects = $this->sortObjects();
700
701
        // Go through each object to generate an array of properties listed in object's list metadata
702
        foreach ($objects as $object) {
703
            if (isset($object['requiredAclPermissions']) && !empty($object['requiredAclPermissions'])) {
704
                if ($this->hasPermissions($object['requiredAclPermissions']) === false) {
0 ignored issues
show
Bug introduced by
It seems like hasPermissions() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

704
                if ($this->/** @scrutinizer ignore-call */ hasPermissions($object['requiredAclPermissions']) === false) {
Loading history...
705
                    continue;
706
                }
707
            }
708
709
            $objectProperties = [];
710
            foreach ($properties as $propertyIdent => $propertyData) {
711
                $property = $object->property($propertyIdent);
712
713
                if (isset($propOptions[$propertyIdent]) && is_array($propOptions[$propertyIdent])) {
714
                    $property->setData($propOptions[$propertyIdent]);
715
                }
716
717
                $this->setupDisplayPropertyValue($object, $property);
718
719
                $displayType = $this->display->displayType();
720
                $this->display->setPropertyVal($object->propertyValue($propertyIdent));
721
722
                $propertyValue = $this->view()->renderTemplate($displayType, $this->display);
723
724
                $cell = $this->parsePropertyCell($object, $property, $propertyValue);
725
                $objectProperties[] = $cell;
726
            };
727
728
            $this->currentObj = $object;
729
            $this->currentObjId = $object->id();
730
731
            $row = $this->parseObjectRow($object, $objectProperties);
732
733
            yield $row;
0 ignored issues
show
Bug Best Practice introduced by
The expression yield $row returns the type Generator which is incompatible with the documented return type array.
Loading history...
734
        }
735
736
        $this->currentObj = null;
737
        $this->currentObjId = null;
738
    }
739
740
    /**
741
     * Setup the property's display value before its assigned to the object row.
742
     *
743
     * This method is useful for classes using this trait.
744
     *
745
     * @param  ModelInterface    $object   The current row's object.
746
     * @param  PropertyInterface $property The current property.
747
     * @return void
748
     */
749
    protected function setupDisplayPropertyValue(ModelInterface $object, PropertyInterface $property)
750
    {
751
        $displayType = $property->displayType();
0 ignored issues
show
Bug introduced by
The method displayType() does not exist on Charcoal\Property\PropertyInterface. Did you maybe mean displayVal()? ( Ignorable by Annotation )

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

751
        /** @scrutinizer ignore-call */ 
752
        $displayType = $property->displayType();

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...
752
753
        $this->display = $this->propertyDisplayFactory()->create($displayType);
754
        $this->display->setDisplayType($displayType);
755
        $this->display->setProperty($property);
756
757
        $metadata = $property->metadata();
758
        $objMetadata = $object->metadata()->property($property->ident());
759
        if ($objMetadata) {
760
            $metadata->setData($objMetadata);
761
        }
762
763
        $this->display->setData($metadata->data());
764
765
        $viewOptions = $property->viewOptions($displayType);
766
        $this->display->setData($viewOptions);
767
768
        $propertyIdent = $property->ident();
769
        $propertiesOptions = $this->propertiesOptions();
770
        if (isset($propertiesOptions[$propertyIdent])) {
771
            $this->display->setData(array_diff_key($propertiesOptions[$propertyIdent], [ 'view_options' => true ]));
772
        }
773
    }
774
775
    /**
776
     * Filter the property before its assigned to the object row.
777
     *
778
     * This method is useful for classes using this trait.
779
     *
780
     * @param  ModelInterface    $object        The current row's object.
781
     * @param  PropertyInterface $property      The current property.
782
     * @param  string            $propertyValue The property $key's display value.
783
     * @return array
784
     */
785
    protected function parsePropertyCell(
786
        ModelInterface $object,
787
        PropertyInterface $property,
788
        $propertyValue
789
    ) {
790
        unset($object);
791
792
        return [
793
            'ident' => $property->ident(),
794
            'val'   => trim($propertyValue)
795
        ];
796
    }
797
798
    /**
799
     * Filter the object before its assigned to the row.
800
     *
801
     * This method is useful for classes using this trait.
802
     *
803
     * @param  ModelInterface $object           The current row's object.
804
     * @param  array          $objectProperties The $object's display properties.
805
     * @return array
806
     */
807
    protected function parseObjectRow(ModelInterface $object, array $objectProperties)
808
    {
809
        return [
810
            'object'           => $object,
811
            'objectId'         => $object->id(),
812
            'objectType'       => $object->objType(),
0 ignored issues
show
Bug introduced by
The method objType() does not exist on Charcoal\Model\ModelInterface. It seems like you code against a sub-type of said class. However, the method does not exist in Charcoal\Queue\QueueItemInterface or Charcoal\Object\ContentInterface or Charcoal\Object\UserDataInterface or Charcoal\User\UserInterface. Are you sure you never get one of those? ( Ignorable by Annotation )

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

812
            'objectType'       => $object->/** @scrutinizer ignore-call */ objType(),
Loading history...
813
            'objectProperties' => $objectProperties
814
        ];
815
    }
816
817
    /**
818
     * @return boolean
819
     */
820
    public function hasObjects()
821
    {
822
        return (count($this->objects()) > 0);
823
    }
824
825
    /**
826
     * @return integer
827
     */
828
    public function numObjects()
829
    {
830
        return count($this->objects());
831
    }
832
833
    /**
834
     * @throws Exception If obj type was not set.
835
     * @return integer
836
     */
837
    public function numTotal()
838
    {
839
        if ($this->numTotal === null) {
840
            $objType = $this->objType();
841
            if (!$objType) {
842
                throw new Exception(sprintf(
843
                    '%1$s cannot create collection. Object type is not defined.',
844
                    get_class($this)
845
                ));
846
            }
847
848
            $loader = $this->collectionLoader();
849
            $loader->setModel($this->proto());
850
851
            $collectionConfig = $this->collectionConfig();
852
            if (is_array($collectionConfig) && !empty($collectionConfig)) {
853
                unset($collectionConfig['properties']);
854
                $loader->setData($collectionConfig);
855
            }
856
857
            $this->numTotal = $loader->loadCount();
858
        }
859
860
        return $this->numTotal;
861
    }
862
863
    /**
864
     * Retrieve the object's labelling.
865
     *
866
     * @return array
867
     */
868
869
    /**
870
     * Retrieve the object's labels.
871
     *
872
     * @return array|null
873
     */
874
    public function objLabels()
875
    {
876
        if ($this->objLabels === null) {
877
            $objLabels = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $objLabels is dead and can be removed.
Loading history...
878
            $proto = $this->proto();
879
            $objMetadata = $proto->metadata();
880
            if (isset($objMetadata['labels']) && !empty($objMetadata['labels'])) {
881
                $objLabels = $objMetadata['labels'];
882
                array_walk($objLabels, function(&$value) {
883
                    $value = $this->translator()->translation($value);
0 ignored issues
show
Bug introduced by
It seems like translator() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

883
                    $value = $this->/** @scrutinizer ignore-call */ translator()->translation($value);
Loading history...
884
                });
885
                $this->objLabels = $objLabels;
886
            }
887
        }
888
889
        return $this->objLabels;
890
    }
891
892
    /**
893
     * @param boolean $reload If true, reload will be forced.
894
     * @throws InvalidArgumentException If the object type is not defined / can not create prototype.
895
     * @return object
896
     */
897
    public function proto($reload = false)
898
    {
899
        if ($this->proto === null || $reload) {
900
            $objType = $this->objType();
901
            if ($objType === null) {
0 ignored issues
show
introduced by
The condition $objType === null is always false.
Loading history...
902
                throw new InvalidArgumentException(sprintf(
903
                    '%s Can not create an object prototype: object type is null.',
904
                    get_class($this)
905
                ));
906
            }
907
            $this->proto = $this->modelFactory()->create($objType);
908
        }
909
910
        return $this->proto;
911
    }
912
}
913