Completed
Push — master ( a10e39...8b1872 )
by Philip
07:15
created

EntityDefinition::isHardDeletion()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
/*
4
 * This file is part of the CRUDlex package.
5
 *
6
 * (c) Philip Lehmann-Böhm <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace CRUDlex;
13
14
/**
15
 * The class for defining a single entity.
16
 */
17
class EntityDefinition
18
{
19
20
    /**
21
     * The table where the data is stored.
22
     * @var string
23
     */
24
    protected $table;
25
26
    /**
27
     * Holds all fields in the same structure as in the CRUD YAML file.
28
     * @var array
29
     */
30
    protected $fields;
31
32
    /**
33
     * The label for the entity.
34
     * @var string
35
     */
36
    protected $label;
37
38
    /**
39
     * The labels  of the entity in the locales.
40
     * @var array
41
     */
42
    protected $localeLabels;
43
44
    /**
45
     * An array with the children referencing the entity. All entries are
46
     * arrays with three referencing elements: table, fieldName, entity
47
     * @var array
48
     */
49
    protected $children;
50
51
    /**
52
     * Labels for the fields "id", "created_at" and "updated_at".
53
     * @var array
54
     */
55
    protected $standardFieldLabels;
56
57
    /**
58
     * An array containing the fields which should appear in the list view
59
     * of the entity.
60
     * @var array
61
     */
62
    protected $listFields;
63
64
    /**
65
     * The fields used to display the children on the details page of an entity.
66
     * The keys are the entity names as in the CRUD YAML and the values are the
67
     * field names.
68
     * @var array
69
     */
70
    protected $childrenLabelFields;
71
72
    /**
73
     * Whether to delete its children when an instance is deleted.
74
     * @var bool
75
     */
76
    protected $deleteCascade;
77
78
    /**
79
     * The amount of items to display per page on the listview.
80
     * @var int
81
     */
82
    protected $pageSize;
83
84
    /**
85
     * The fields offering to be filtered.
86
     * @var array
87
     */
88
    protected $filter;
89
90
    /**
91
     * Holds the ServiceProvider.
92
     * @var ServiceProvider
93
     */
94
    protected $serviceProvider;
95
96
    /**
97
     * Holds the locale.
98
     * @var string
99
     */
100
    protected $locale;
101
102
    /**
103
     * Holds the initial sort field.
104
     * @var string
105
     */
106
    protected $initialSortField;
107
108
    /**
109
     * Holds the initial sort order.
110
     * @var bool
111
     */
112
    protected $initialSortAscending;
113
114
    /**
115
     * Holds whether hard deletion is activated.
116
     * @var bool
117
     */
118
    protected $hardDeletion;
119
120
    /**
121
     * Holds if the entity must be displayed grouped in the nav bar.
122
     * @var string
123
     */
124
    protected $navBarGroup;
125
126
    /**
127
     * Holds whether optimistic locking is switched on.
128
     * @var bool
129
     */
130
    protected $optimisticLocking;
131
132
    /**
133
     * Gets the field names exluding the given ones.
134
     *
135
     * @param string[] $exclude
136
     * the field names to exclude
137
     *
138
     * @return array
139
     * all field names excluding the given ones
140
     */
141 76
    protected function getFilteredFieldNames(array $exclude)
142
    {
143 76
        $fieldNames = $this->getFieldNames(true);
144 76
        $result     = [];
145 76
        foreach ($fieldNames as $fieldName) {
146 76
            if (!in_array($fieldName, $exclude)) {
147 76
                $result[] = $fieldName;
148
            }
149
        }
150 76
        return $result;
151
    }
152
153
    /**
154
     * Checks whether the given field names are declared and existing.
155
     *
156
     * @param string $reference
157
     * a hint towards the source of an invalid field name
158
     * @param array $fieldNames
159
     * the field names to check
160
     * @throws \InvalidArgumentException
161
     * thrown with all invalid field names
162
     */
163 76
    protected function checkFieldNames($reference, $fieldNames)
164
    {
165 76
        $validFieldNames   = $this->getPublicFieldNames();
166 76
        $invalidFieldNames = [];
167 76
        foreach ($fieldNames as $fieldName) {
168 76
            if (!in_array($fieldName, $validFieldNames)) {
169 76
                $invalidFieldNames[] = $fieldName;
170
            }
171
        }
172 76
        if (!empty($invalidFieldNames)) {
173 1
            throw new \InvalidArgumentException('Invalid fields ('.join(', ', $invalidFieldNames).') in '.$reference.', valid ones are: '.join(', ', $validFieldNames));
174
        }
175 76
    }
176
177
    /**
178
     * Constructor.
179
     *
180
     * @param string $table
181
     * the table of the entity
182
     * @param array $fields
183
     * the field structure just like the CRUD YAML
184
     * @param string $label
185
     * the label of the entity
186
     * @param array $localeLabels
187
     * the labels  of the entity in the locales
188
     * @param array $standardFieldLabels
189
     * labels for the fields "id", "created_at" and "updated_at"
190
     * @param ServiceProvider $serviceProvider
191
     * The current service provider
192
     */
193 77
    public function __construct($table, array $fields, $label, $localeLabels, array $standardFieldLabels, ServiceProvider $serviceProvider)
194
    {
195 77
        $this->table               = $table;
196 77
        $this->fields              = $fields;
197 77
        $this->label               = $label;
198 77
        $this->localeLabels        = $localeLabels;
199 77
        $this->standardFieldLabels = $standardFieldLabels;
200 77
        $this->serviceProvider     = $serviceProvider;
201
202 77
        $this->children             = [];
203 77
        $this->listFields           = [];
204 77
        $this->childrenLabelFields  = [];
205 77
        $this->filter               = [];
206 77
        $this->deleteCascade        = false;
207 77
        $this->pageSize             = 25;
208 77
        $this->locale               = null;
209 77
        $this->initialSortField     = 'created_at';
210 77
        $this->initialSortAscending = true;
211 77
        $this->hardDeletion         = false;
212 77
        $this->navBarGroup          = 'main';
213 77
        $this->optimisticLocking    = true;
214 77
    }
215
216
    /**
217
     * Gets all field names, including the implicit ones like "id" or
218
     * "created_at".
219
     *
220
     * @param boolean $includeMany
221
     * whether to include the many fields as well
222
     *
223
     * @return string[]
224
     * the field names
225
     */
226 76
    public function getFieldNames($includeMany = false)
227
    {
228 76
        $fieldNames = $this->getReadOnlyFields();
229 76
        foreach ($this->fields as $field => $value) {
230 76
            if ($includeMany || $this->getType($field) !== 'many') {
231 76
                $fieldNames[] = $field;
232
            }
233
        }
234 76
        return $fieldNames;
235
    }
236
237
    /**
238
     * Sets the field names to be used in the listview.
239
     *
240
     * @param array $listFields
241
     * the field names to be used in the listview
242
     */
243 76
    public function setListFields(array $listFields)
244
    {
245 76
        $this->checkFieldNames('listFields', $listFields);
246 76
        $this->listFields = $listFields;
247 76
    }
248
249
    /**
250
     * Gets the field names to be used in the listview. If they were not specified,
251
     * all public field names are returned.
252
     *
253
     * @return array
254
     * the field names to be used in the listview
255
     */
256 5
    public function getListFields()
257
    {
258 5
        if (!empty($this->listFields)) {
259 5
            return $this->listFields;
260
        }
261 3
        return $this->getPublicFieldNames();
262
    }
263
264
    /**
265
     * Gets the fields used to display the children on the details page of an
266
     * entity. The keys are the entity names as in the CRUD YAML and the values
267
     * are the field names.
268
     *
269
     * @return array
270
     * the fields used to display the children on the details page
271
     */
272 7
    public function getChildrenLabelFields()
273
    {
274 7
        return $this->childrenLabelFields;
275
    }
276
277
    /**
278
     * Sets the fields used to display the children on the details page of an
279
     * entity. The keys are the entity names as in the CRUD YAML and the values
280
     * are the field names.
281
     *
282
     * @param array $childrenLabelFields
283
     * the fields used to display the children on the details page
284
     */
285 76
    public function setChildrenLabelFields(array $childrenLabelFields)
286
    {
287 76
        $this->childrenLabelFields = $childrenLabelFields;
288 76
    }
289
290
    /**
291
     * Gets whether to delete its children when an instance is deleted.
292
     *
293
     * @return boolean
294
     * true if so
295
     */
296 5
    public function isDeleteCascade()
297
    {
298 5
        return $this->deleteCascade;
299
    }
300
301
    /**
302
     * Sets whether to delete its children when an instance is deleted.
303
     *
304
     * @param boolean $deleteCascade
305
     * whether to delete its children when an instance is deleted
306
     */
307 76
    public function setDeleteCascade($deleteCascade)
308
    {
309 76
        $this->deleteCascade = $deleteCascade;
310 76
    }
311
312
    /**
313
     * Gets the amount of items to display per page on the listview.
314
     *
315
     * @return integer
316
     * the amount of items to display per page on the listview
317
     */
318 5
    public function getPageSize()
319
    {
320 5
        return $this->pageSize;
321
    }
322
323
    /**
324
     * Sets the amount of items to display per page on the listview.
325
     *
326
     * @param integer $pageSize
327
     * the amount of items to display per page on the listview
328
     */
329 76
    public function setPageSize($pageSize)
330
    {
331 76
        $this->pageSize = $pageSize;
332 76
    }
333
334
    /**
335
     * Gets the fields offering a filter.
336
     *
337
     * @return array
338
     * the fields to filter
339
     */
340 5
    public function getFilter()
341
    {
342 5
        return $this->filter;
343
    }
344
345
    /**
346
     * Sets the fields offering a filter.
347
     *
348
     * @param array $filter
349
     * the fields to filter
350
     */
351 76
    public function setFilter(array $filter)
352
    {
353 76
        $this->checkFieldNames('filter', $filter);
354 76
        $this->filter = $filter;
355 76
    }
356
357
    /**
358
     * Gets the service provider.
359
     *
360
     * @return ServiceProvider
361
     * the service provider
362
     */
363 36
    public function getServiceProvider()
364
    {
365 36
        return $this->serviceProvider;
366
    }
367
368
    /**
369
     * Sets the service provider.
370
     *
371
     * @param ServiceProvider $serviceProvider
372
     * the new service provider
373
     */
374 1
    public function setServiceProvider(ServiceProvider $serviceProvider)
375
    {
376 1
        $this->serviceProvider = $serviceProvider;
377 1
    }
378
379
    /**
380
     * Gets the public field names. The internal fields "version" and
381
     * "deleted_at" are filtered.
382
     *
383
     * @return array
384
     * the public field names
385
     */
386 76
    public function getPublicFieldNames()
387
    {
388 76
        $exclude = ['version', 'deleted_at'];
389 76
        $result  = $this->getFilteredFieldNames($exclude);
390 76
        return $result;
391
    }
392
393
    /**
394
     * Gets the field names which are editable. Not editable are fields like the
395
     * id or the created_at.
396
     *
397
     * @return array
398
     * the editable field names
399
     */
400 40
    public function getEditableFieldNames()
401
    {
402 40
        $result = $this->getFilteredFieldNames($this->getReadOnlyFields());
403 40
        return $result;
404
    }
405
406
    /**
407
     * Gets the read only field names like the id or the created_at.
408
     *
409
     * @return string[]
410
     * the read only field names
411
     */
412 76
    public function getReadOnlyFields()
413
    {
414 76
        $result = ['id', 'created_at', 'updated_at'];
415 76
        if ($this->optimisticLocking) {
416 76
            $result[] = 'version';
417
        }
418 76
        if (!$this->hardDeletion) {
419 76
            $result[] = 'deleted_at';
420
        }
421 76
        return $result;
422
    }
423
424
    /**
425
     * Gets the type of a field.
426
     *
427
     * @param string $fieldName
428
     * the field name
429
     *
430
     * @return string
431
     * the type or null on invalid field name
432
     */
433 76
    public function getType($fieldName)
434
    {
435 76
        if ($fieldName === 'id') {
436 76
            return 'string';
437
        }
438 76
        if ($fieldName === 'version') {
439 75
            return 'integer';
440
        }
441 76
        if (in_array($fieldName, ['created_at', 'updated_at', 'deleted_at'])) {
442 76
            return 'datetime';
443
        }
444 76
        return $this->getField($fieldName, 'type');
445
    }
446
447
    /**
448
     * Sets the type of a field.
449
     *
450
     * @param string $fieldName
451
     * the field name
452
     * @param string $value
453
     * the new field type
454
     */
455 1
    public function setType($fieldName, $value)
456
    {
457 1
        $this->setField($fieldName, 'type', $value);
458 1
    }
459
460
    /**
461
     * Gets the label of a field.
462
     *
463
     * @param string $fieldName
464
     * the field name
465
     *
466
     * @return string
467
     * the label of the field or the field name if no label is set in the CRUD
468
     * YAML
469
     */
470 9
    public function getFieldLabel($fieldName)
471
    {
472 9
        $result = $this->getField($fieldName, 'label_'.$this->locale, $this->getField($fieldName, 'label'));
473
474 9
        if ($result === null && array_key_exists($fieldName, $this->standardFieldLabels)) {
475 8
            $result = $this->standardFieldLabels[$fieldName];
476
        }
477
478 9
        if ($result === null) {
479 1
            $result = $fieldName;
480
        }
481
482 9
        return $result;
483
    }
484
485
    /**
486
     * Gets the label of a field.
487
     *
488
     * @param string $fieldName
489
     * the field name
490
     * @param string $value
491
     * the new label of the field
492
     */
493 1
    public function setFieldLabel($fieldName, $value)
494
    {
495 1
        $this->setField($fieldName, 'label', $value);
496 1
    }
497
498
    /**
499
     * Gets the table where the data is stored.
500
     *
501
     * @return string
502
     * the table where the data is stored
503
     */
504 75
    public function getTable()
505
    {
506 75
        return $this->table;
507
    }
508
509
    /**
510
     * Sets the table where the data is stored.
511
     *
512
     * @param string $table
513
     * the new table where the data is stored
514
     */
515 1
    public function setTable($table)
516
    {
517 1
        $this->table = $table;
518 1
    }
519
520
    /**
521
     * Gets the label for the entity.
522
     *
523
     * @return string
524
     * the label for the entity
525
     */
526 11
    public function getLabel()
527
    {
528 11
        if ($this->locale && array_key_exists($this->locale, $this->localeLabels)) {
529 2
            return $this->localeLabels[$this->locale];
530
        }
531 11
        return $this->label;
532
    }
533
534
    /**
535
     * Sets the label for the entity.
536
     *
537
     * @param string $label
538
     * the new label for the entity
539
     */
540 1
    public function setLabel($label)
541
    {
542 1
        $this->label = $label;
543 1
    }
544
545
    /**
546
     * Adds a child to this definition in case the other
547
     * definition has a reference to this one.
548
     *
549
     * @param string $table
550
     * the table of the referencing definition
551
     * @param string $fieldName
552
     * the field name of the referencing definition
553
     * @param string $entity
554
     * the entity of the referencing definition
555
     */
556 75
    public function addChild($table, $fieldName, $entity)
557
    {
558 75
        $this->children[] = [$table, $fieldName, $entity];
559 75
    }
560
561
    /**
562
     * Gets the referencing children to this definition.
563
     *
564
     * @return array
565
     * an array with the children referencing the entity. All entries are arrays
566
     * with three referencing elements: table, fieldName, entity
567
     */
568 7
    public function getChildren()
569
    {
570 7
        return $this->children;
571
    }
572
573
    /**
574
     * Sets the locale to be used.
575
     *
576
     * @param string $locale
577
     * the locale to be used.
578
     */
579 13
    public function setLocale($locale)
580
    {
581 13
        $this->locale = $locale;
582 13
    }
583
584
    /**
585
     * Gets the locale to be used.
586
     *
587
     * @return null|string
588
     * the locale to be used.
589
     */
590 2
    public function getLocale()
591
    {
592 2
        return $this->locale;
593
    }
594
595
    /**
596
     * Sets the initial sort field.
597
     *
598
     * @param string $initialSortField
599
     * the new initial sort field
600
     */
601 76
    public function setInitialSortField($initialSortField)
602
    {
603 76
        $this->initialSortField = $initialSortField;
604 76
    }
605
606
    /**
607
     * Gets the initial sort field.
608
     *
609
     * @return string
610
     * the initial sort field
611
     */
612 6
    public function getInitialSortField()
613
    {
614 6
        return $this->initialSortField;
615
    }
616
617
    /**
618
     * Sets whether the initial sort order is ascending.
619
     *
620
     * @param boolean $initialSortAscending
621
     * the initial sort order, true if ascending
622
     */
623 76
    public function setInitialSortAscending($initialSortAscending)
624
    {
625 76
        $this->initialSortAscending = $initialSortAscending;
626 76
    }
627
628
    /**
629
     * Gets whether the initial sort order is ascending.
630
     *
631
     * @return boolean
632
     * the initial sort order, true if ascending
633
     */
634 6
    public function isInitialSortAscending()
635
    {
636 6
        return $this->initialSortAscending;
637
    }
638
639
    /**
640
     * Sets the hard deletion state.
641
     *
642
     * @param boolean $hardDeletion
643
     * the hard deletion state
644
     */
645 76
    public function setHardDeletion($hardDeletion)
646
    {
647 76
        $this->hardDeletion = $hardDeletion;
648 76
    }
649
650
    /**
651
     * Gets the hard deletion state.
652
     *
653
     * @return boolean
654
     * the hard deletion state
655
     */
656 36
    public function isHardDeletion()
657
    {
658 36
        return $this->hardDeletion;
659
    }
660
661
    /**
662
     * Gets the navigation bar group where the entity belongs.
663
     *
664
     * @return string
665
     * the navigation bar group where the entity belongs
666
     */
667 11
    public function getNavBarGroup()
668
    {
669 11
        return $this->navBarGroup;
670
    }
671
672
    /**
673
     * Sets the navigation bar group where the entity belongs.
674
     *
675
     * @param string $navBarGroup
676
     * the navigation bar group where the entity belongs
677
     */
678 76
    public function setNavBarGroup($navBarGroup)
679
    {
680 76
        $this->navBarGroup = $navBarGroup;
681 76
    }
682
683
    /**
684
     * Returns whether optimistic locking via the version field is activated.
685
     * @return boolean
686
     * true if optimistic locking is activated
687
     */
688 35
    public function hasOptimisticLocking()
689
    {
690 35
        return $this->optimisticLocking;
691
    }
692
693
694
    /**
695
     * Sets whether optimistic locking via the version field is activated.
696
     * @param boolean $optimisticLocking
697
     * true if optimistic locking is activated
698
     */
699 76
    public function setOptimisticLocking($optimisticLocking)
700
    {
701 76
        $this->optimisticLocking = $optimisticLocking;
702 76
    }
703
704
    /**
705
     * Gets a sub field of an field.
706
     *
707
     * @param string $fieldName
708
     * the field name of the sub type
709
     * @param string $subType
710
     * the sub type like "reference" or "many"
711
     * @param string $key
712
     * the key of the value
713
     *
714
     * @return string
715
     * the value of the sub field
716
     */
717 75
    public function getSubTypeField($fieldName, $subType, $key)
718
    {
719
720 75
        if (!isset($this->fields[$fieldName][$subType][$key])) {
721 22
            return null;
722
        }
723
724 75
        return $this->fields[$fieldName][$subType][$key];
725
    }
726
727
    /**
728
     * Gets the value of a field key.
729
     *
730
     * @param string $name
731
     * the name of the field
732
     * @param string $key
733
     * the value of the key
734
     * @param mixed $default
735
     * the default value to return if nothing is found
736
     *
737
     * @return mixed
738
     * the value of the field key or null if not existing
739
     */
740 76
    public function getField($name, $key, $default = null)
741
    {
742 76
        if (array_key_exists($name, $this->fields) && array_key_exists($key, $this->fields[$name])) {
743 75
            return $this->fields[$name][$key];
744
        }
745 41
        return $default;
746
    }
747
748
    /**
749
     * Sets the value of a field key. If the field or the key in the field
750
     * don't exist, they get created.
751
     *
752
     * @param string $name
753
     * the name of the field
754
     * @param string $key
755
     * the value of the key
756
     * @param mixed $value
757
     * the new value
758
     */
759 6
    public function setField($name, $key, $value)
760
    {
761 6
        if (!array_key_exists($name, $this->fields)) {
762 1
            $this->fields[$name] = [];
763
        }
764 6
        $this->fields[$name][$key] = $value;
765 6
    }
766
767
}
768