Completed
Push — master ( a3895d...ee9fc9 )
by Fabien
02:51
created
Classes/Tca/GridService.php 1 patch
Indentation   +690 added lines, -690 removed lines patch added patch discarded remove patch
@@ -23,695 +23,695 @@
 block discarded – undo
23 23
 class GridService extends AbstractTca
24 24
 {
25 25
 
26
-    /**
27
-     * @var array
28
-     */
29
-    protected $tca;
30
-
31
-    /**
32
-     * @var string
33
-     */
34
-    protected $tableName;
35
-
36
-    /**
37
-     * All fields available in the Grid.
38
-     *
39
-     * @var array
40
-     */
41
-    protected $fields;
42
-
43
-    /**
44
-     * All fields regardless whether they have been excluded or not.
45
-     *
46
-     * @var array
47
-     */
48
-    protected $allFields;
49
-
50
-    /**
51
-     * @var array
52
-     */
53
-    protected $instances;
54
-
55
-    /**
56
-     * @var array
57
-     */
58
-    protected $facets;
59
-
60
-    /**
61
-     * __construct
62
-     *
63
-     * @throws InvalidKeyInArrayException
64
-     * @param string $tableName
65
-     * @return \Fab\Vidi\Tca\GridService
66
-     */
67
-    public function __construct($tableName)
68
-    {
69
-
70
-        $this->tableName = $tableName;
71
-
72
-        if (empty($GLOBALS['TCA'][$this->tableName])) {
73
-            throw new InvalidKeyInArrayException('No TCA existence for table name: ' . $this->tableName, 1356945108);
74
-        }
75
-
76
-        $this->tca = $GLOBALS['TCA'][$this->tableName]['grid'];
77
-    }
78
-
79
-    /**
80
-     * Returns an array containing column names.
81
-     *
82
-     * @return array
83
-     */
84
-    public function getFieldNames()
85
-    {
86
-        $fields = $this->getFields();
87
-        return array_keys($fields);
88
-    }
89
-
90
-    /**
91
-     * Returns an array containing column names.
92
-     *
93
-     * @return array
94
-     */
95
-    public function getAllFieldNames()
96
-    {
97
-        $allFields = $this->getAllFields();
98
-        return array_keys($allFields);
99
-    }
100
-
101
-    /**
102
-     * Get the label key.
103
-     *
104
-     * @param string $fieldNameAndPath
105
-     * @return string
106
-     * @throws \Fab\Vidi\Exception\InvalidKeyInArrayException
107
-     */
108
-    public function getLabelKey($fieldNameAndPath)
109
-    {
110
-
111
-        $field = $this->getField($fieldNameAndPath);
112
-
113
-        // First option is to get the label from the Grid TCA.
114
-        $rawLabel = '';
115
-        if (isset($field['label'])) {
116
-            $rawLabel = $field['label'];
117
-        }
118
-
119
-        // Second option is to fetch the label from the Column Renderer object.
120
-        if (!$rawLabel && $this->hasRenderers($fieldNameAndPath)) {
121
-            $renderers = $this->getRenderers($fieldNameAndPath);
122
-            /** @var $renderer ColumnRendererInterface */
123
-            foreach ($renderers as $renderer) {
124
-                if (isset($renderer['label'])) {
125
-                    $rawLabel = $renderer['label'];
126
-                    break;
127
-                }
128
-            }
129
-        }
130
-        return $rawLabel;
131
-    }
132
-
133
-    /**
134
-     * Get the translation of a label given a column name.
135
-     *
136
-     * @param string $fieldNameAndPath
137
-     * @return string
138
-     */
139
-    public function getLabel($fieldNameAndPath)
140
-    {
141
-        $label = '';
142
-        if ($this->hasLabel($fieldNameAndPath)) {
143
-            $labelKey = $this->getLabelKey($fieldNameAndPath);
144
-            try {
145
-                $label = LocalizationUtility::translate($labelKey, '');
146
-            } catch (\InvalidArgumentException $e) {
147
-            }
148
-            if (empty($label)) {
149
-                $label = $labelKey;
150
-            }
151
-        } else {
152
-
153
-            // Important to notice the label can contains a path, e.g. metadata.categories and must be resolved.
154
-            $dataType = $this->getFieldPathResolver()->getDataType($fieldNameAndPath, $this->tableName);
155
-            $fieldName = $this->getFieldPathResolver()->stripFieldPath($fieldNameAndPath, $this->tableName);
156
-            $table = Tca::table($dataType);
157
-
158
-            if ($table->hasField($fieldName) && $table->field($fieldName)->hasLabel()) {
159
-                $label = $table->field($fieldName)->getLabel();
160
-            }
161
-        }
162
-
163
-        return $label;
164
-    }
165
-
166
-    /**
167
-     * Returns the field name given its position.
168
-     *
169
-     * @param string $position the position of the field in the grid
170
-     * @throws InvalidKeyInArrayException
171
-     * @return int
172
-     */
173
-    public function getFieldNameByPosition($position)
174
-    {
175
-        $fields = array_keys($this->getFields());
176
-        if (empty($fields[$position])) {
177
-            throw new InvalidKeyInArrayException('No field exist for position: ' . $position, 1356945119);
178
-        }
179
-
180
-        return $fields[$position];
181
-    }
182
-
183
-    /**
184
-     * Returns a field name.
185
-     *
186
-     * @param string $fieldName
187
-     * @return array
188
-     * @throws InvalidKeyInArrayException
189
-     */
190
-    public function getField($fieldName)
191
-    {
192
-        $fields = $this->getFields();
193
-        return $fields[$fieldName];
194
-    }
195
-
196
-    /**
197
-     * Returns an array containing column names for the Grid.
198
-     *
199
-     * @return array
200
-     * @throws \Exception
201
-     */
202
-    public function getFields()
203
-    {
204
-        // Cache this operation since it can take some time.
205
-        if (is_null($this->fields)) {
206
-
207
-            // Fetch all available fields first.
208
-            $fields = $this->getAllFields();
209
-
210
-            if ($this->isBackendMode()) {
211
-
212
-                // Then remove the not allowed.
213
-                $fields = $this->filterByIncludedFields($fields);
214
-                $fields = $this->filterByBackendUser($fields);
215
-                $fields = $this->filterByExcludedFields($fields);
216
-            }
217
-
218
-            $this->fields = $fields;
219
-        }
220
-
221
-        return $this->fields;
222
-    }
223
-
224
-    /**
225
-     * Remove fields according to Grid configuration.
226
-     *
227
-     * @param $fields
228
-     * @return array
229
-     */
230
-    protected function filterByIncludedFields($fields)
231
-    {
232
-
233
-        $filteredFields = $fields;
234
-        $includedFields = $this->getIncludedFields();
235
-        if (count($includedFields) > 0) {
236
-            $filteredFields = [];
237
-            foreach ($fields as $fieldNameAndPath => $configuration) {
238
-                if (in_array($fieldNameAndPath, $includedFields, true) || !Tca::table($this->tableName)->hasField($fieldNameAndPath)) {
239
-                    $filteredFields[$fieldNameAndPath] = $configuration;
240
-                }
241
-            }
242
-        }
243
-        return $filteredFields;
244
-    }
245
-
246
-    /**
247
-     * Remove fields according to BE User permission.
248
-     *
249
-     * @param $fields
250
-     * @return array
251
-     * @throws \Exception
252
-     */
253
-    protected function filterByBackendUser($fields)
254
-    {
255
-        if (!$this->getBackendUser()->isAdmin()) {
256
-            foreach ($fields as $fieldName => $field) {
257
-                if (Tca::table($this->tableName)->hasField($fieldName) && !Tca::table($this->tableName)->field($fieldName)->hasAccess()) {
258
-                    unset($fields[$fieldName]);
259
-                }
260
-            }
261
-        }
262
-        return $fields;
263
-    }
264
-
265
-    /**
266
-     * Remove fields according to Grid configuration.
267
-     *
268
-     * @param $fields
269
-     * @return array
270
-     */
271
-    protected function filterByExcludedFields($fields)
272
-    {
273
-
274
-        // Unset excluded fields.
275
-        foreach ($this->getExcludedFields() as $excludedField) {
276
-            if (isset($fields[$excludedField])) {
277
-                unset($fields[$excludedField]);
278
-            }
279
-        }
280
-
281
-        return $fields;
282
-    }
283
-
284
-    /**
285
-     * Returns an array containing column names for the Grid.
286
-     *
287
-     * @return array
288
-     */
289
-    public function getAllFields()
290
-    {
291
-
292
-        // Cache this operation since it can take some time.
293
-        if (is_null($this->allFields)) {
294
-
295
-            $fields = is_array($this->tca['columns']) ? $this->tca['columns'] : [];
296
-            $gridFieldNames = array_keys($fields);
297
-
298
-            // Fetch all fields of the TCA and merge it back to the fields configured for Grid.
299
-            $tableFieldNames = Tca::table($this->tableName)->getFields();
300
-
301
-            // Just remove system fields from the Grid.
302
-            foreach ($tableFieldNames as $key => $fieldName) {
303
-                if (in_array($fieldName, Tca::getSystemFields())) {
304
-                    unset($tableFieldNames[$key]);
305
-                }
306
-            }
307
-
308
-            $additionalFields = array_diff($tableFieldNames, $gridFieldNames);
309
-
310
-            if (!empty($additionalFields)) {
311
-
312
-                // Pop out last element of the key
313
-                // Idea is to place new un-configured columns in between. By default, they will be hidden.
314
-                end($fields);
315
-                $lastColumnKey = key($fields);
316
-                $lastColumn = array_pop($fields);
317
-
318
-                // Feed up the grid fields with un configured elements
319
-                foreach ($additionalFields as $additionalField) {
320
-                    $fields[$additionalField] = array(
321
-                        'visible' => false
322
-                    );
323
-
324
-                    // Try to guess the format of the field.
325
-                    $fieldType = Tca::table($this->tableName)->field($additionalField)->getType();
326
-                    if ($fieldType === FieldType::DATE) {
327
-                        $fields[$additionalField]['format'] = 'Fab\Vidi\Formatter\Date';
328
-                    } elseif ($fieldType === FieldType::DATETIME) {
329
-                        $fields[$additionalField]['format'] = 'Fab\Vidi\Formatter\Datetime';
330
-                    }
331
-                }
332
-                $fields[$lastColumnKey] = $lastColumn;
333
-            }
334
-
335
-            $this->allFields = $fields;
336
-        }
337
-
338
-        return $this->allFields;
339
-    }
340
-
341
-    /**
342
-     * Tell whether the field exists in the grid or not.
343
-     *
344
-     * @param string $fieldName
345
-     * @return bool
346
-     */
347
-    public function hasField($fieldName)
348
-    {
349
-        $fields = $this->getFields();
350
-        return isset($fields[$fieldName]);
351
-    }
352
-
353
-    /**
354
-     * Tell whether the facet exists in the grid or not.
355
-     *
356
-     * @param string $facetName
357
-     * @return bool
358
-     */
359
-    public function hasFacet($facetName)
360
-    {
361
-        $facets = $this->getFacets();
362
-        return isset($facets[$facetName]);
363
-    }
364
-
365
-    /**
366
-     * Returns an array containing facets fields.
367
-     *
368
-     * @return FacetInterface[]
369
-     */
370
-    public function getFacets()
371
-    {
372
-        if (is_null($this->facets)) {
373
-            $this->facets = [];
374
-
375
-            if (is_array($this->tca['facets'])) {
376
-                foreach ($this->tca['facets'] as $facetNameOrObject) {
377
-                    if ($facetNameOrObject instanceof FacetInterface) {
378
-                        $this->facets[$facetNameOrObject->getName()] = $facetNameOrObject;
379
-                    } else {
380
-                        $this->facets[$facetNameOrObject] = $this->instantiateStandardFacet($facetNameOrObject);
381
-                    }
382
-                }
383
-            }
384
-        }
385
-        return $this->facets;
386
-    }
387
-
388
-    /**
389
-     * Returns the "sortable" value of the column.
390
-     *
391
-     * @param string $fieldName
392
-     * @return int|string
393
-     */
394
-    public function isSortable($fieldName)
395
-    {
396
-        $defaultValue = true;
397
-        $hasSortableField = Tca::table($this->tableName)->hasSortableField();
398
-        if ($hasSortableField) {
399
-            $isSortable = false;
400
-        } else {
401
-            $isSortable = $this->get($fieldName, 'sortable', $defaultValue);
402
-        }
403
-        return $isSortable;
404
-    }
405
-
406
-    /**
407
-     * Returns the "canBeHidden" value of the column.
408
-     *
409
-     * @param string $fieldName
410
-     * @return bool
411
-     */
412
-    public function canBeHidden($fieldName)
413
-    {
414
-        $defaultValue = true;
415
-        return $this->get($fieldName, 'canBeHidden', $defaultValue);
416
-    }
417
-
418
-    /**
419
-     * Returns the "width" value of the column.
420
-     *
421
-     * @param string $fieldName
422
-     * @return int|string
423
-     */
424
-    public function getWidth($fieldName)
425
-    {
426
-        $defaultValue = 'auto';
427
-        return $this->get($fieldName, 'width', $defaultValue);
428
-    }
429
-
430
-    /**
431
-     * Returns the "visible" value of the column.
432
-     *
433
-     * @param string $fieldName
434
-     * @return bool
435
-     */
436
-    public function isVisible($fieldName)
437
-    {
438
-        $defaultValue = true;
439
-        return $this->get($fieldName, 'visible', $defaultValue);
440
-    }
441
-
442
-    /**
443
-     * Returns the "editable" value of the column.
444
-     *
445
-     * @param string $columnName
446
-     * @return bool
447
-     */
448
-    public function isEditable($columnName)
449
-    {
450
-        $defaultValue = false;
451
-        return $this->get($columnName, 'editable', $defaultValue);
452
-    }
453
-
454
-    /**
455
-     * Returns the "localized" value of the column.
456
-     *
457
-     * @param string $columnName
458
-     * @return bool
459
-     */
460
-    public function isLocalized($columnName)
461
-    {
462
-        $defaultValue = true;
463
-        return $this->get($columnName, 'localized', $defaultValue);
464
-    }
465
-
466
-    /**
467
-     *
468
-     * Returns the "html" value of the column.
469
-     *
470
-     * @param string $fieldName
471
-     * @return string
472
-     */
473
-    public function getHeader($fieldName)
474
-    {
475
-        $defaultValue = '';
476
-        return $this->get($fieldName, 'html', $defaultValue);
477
-    }
478
-
479
-    /**
480
-     * Fetch a possible from a Grid Renderer. If no value is found, returns null
481
-     *
482
-     * @param string $fieldName
483
-     * @param string $key
484
-     * @param mixed $defaultValue
485
-     * @return null|mixed
486
-     */
487
-    public function get($fieldName, $key, $defaultValue = null)
488
-    {
489
-        $value = $defaultValue;
490
-
491
-        $field = $this->getField($fieldName);
492
-        if (isset($field[$key])) {
493
-            $value = $field[$key];
494
-        } elseif ($this->hasRenderers($fieldName)) {
495
-            $renderers = $this->getRenderers($fieldName);
496
-            foreach ($renderers as $rendererConfiguration) {
497
-                if (isset($rendererConfiguration[$key])) {
498
-                    $value = $rendererConfiguration[$key];
499
-                }
500
-            }
501
-        }
502
-        return $value;
503
-    }
504
-
505
-    /**
506
-     * Returns whether the column has a renderer.
507
-     *
508
-     * @param string $fieldName
509
-     * @return bool
510
-     */
511
-    public function hasRenderers($fieldName)
512
-    {
513
-        $field = $this->getField($fieldName);
514
-        return empty($field['renderer']) && empty($field['renderers']) ? false : true;
515
-    }
516
-
517
-    /**
518
-     * Returns a renderer.
519
-     *
520
-     * @param string $fieldName
521
-     * @return array
522
-     */
523
-    public function getRenderers($fieldName)
524
-    {
525
-        $field = $this->getField($fieldName);
526
-        $renderers = [];
527
-        if (!empty($field['renderer'])) {
528
-            $renderers = $this->convertRendererToArray($field['renderer'], $field);
529
-        } elseif (!empty($field['renderers']) && is_array($field['renderers'])) {
530
-            foreach ($field['renderers'] as $renderer) {
531
-                $rendererNameAndConfiguration = $this->convertRendererToArray($renderer, $field);
532
-                $renderers = array_merge($renderers, $rendererNameAndConfiguration);
533
-            }
534
-        }
535
-
536
-        return $renderers;
537
-    }
538
-
539
-    /**
540
-     * @param string $renderer
541
-     * @return array
542
-     */
543
-    protected function convertRendererToArray($renderer, array $field)
544
-    {
545
-        $result = [];
546
-        if (is_string($renderer)) {
547
-            $configuration = empty($field['rendererConfiguration'])
548
-                ? []
549
-                : $field['rendererConfiguration'];
550
-
551
-            /** @var ColumnRendererInterface $rendererObject */
552
-            $rendererObject = GeneralUtility::makeInstance($renderer);
553
-
554
-            $result[$renderer] = array_merge($rendererObject->getConfiguration(), $configuration);
555
-            // TODO: throw alert message because this is not compatible anymore as of TYPO3 8.7.7
556
-        } elseif ($renderer instanceof ColumnRendererInterface) {
557
-            /** @var ColumnRendererInterface $renderer */
558
-            $result[get_class($renderer)] = $renderer->getConfiguration();
559
-        }
560
-        return $result;
561
-    }
562
-
563
-    /**
564
-     * Returns the class names applied to a cell
565
-     *
566
-     * @param string $fieldName
567
-     * @return bool
568
-     */
569
-    public function getClass($fieldName)
570
-    {
571
-        $field = $this->getField($fieldName);
572
-        return isset($field['class']) ? $field['class'] : '';
573
-    }
574
-
575
-    /**
576
-     * Returns whether the column has a label.
577
-     *
578
-     * @param string $fieldNameAndPath
579
-     * @return bool
580
-     */
581
-    public function hasLabel($fieldNameAndPath)
582
-    {
583
-        $field = $this->getField($fieldNameAndPath);
584
-
585
-        $hasLabel = empty($field['label']) ? false : true;
586
-
587
-        if (!$hasLabel && $this->hasRenderers($fieldNameAndPath)) {
588
-            $renderers = $this->getRenderers($fieldNameAndPath);
589
-            /** @var $renderer ColumnRendererInterface */
590
-            foreach ($renderers as $renderer) {
591
-                if (isset($renderer['label'])) {
592
-                    $hasLabel = true;
593
-                    break;
594
-                }
595
-            }
596
-        }
597
-        return $hasLabel;
598
-    }
599
-
600
-    /**
601
-     * @return array
602
-     */
603
-    public function getTca()
604
-    {
605
-        return $this->tca;
606
-    }
607
-
608
-    /**
609
-     * @return array
610
-     */
611
-    public function getIncludedFields()
612
-    {
613
-        return empty($this->tca['included_fields']) ? [] : GeneralUtility::trimExplode(',', $this->tca['included_fields'], true);
614
-    }
615
-
616
-    /**
617
-     * Return excluded fields from configuration + preferences.
618
-     *
619
-     * @return array
620
-     */
621
-    public function getExcludedFields()
622
-    {
623
-        $configurationFields = $this->getExcludedFieldsFromConfiguration();
624
-        $preferencesFields = $this->getExcludedFieldsFromPreferences();
625
-
626
-        return array_merge($configurationFields, $preferencesFields);
627
-    }
628
-
629
-    /**
630
-     * Fetch excluded fields from configuration.
631
-     *
632
-     * @return array
633
-     */
634
-    protected function getExcludedFieldsFromConfiguration()
635
-    {
636
-        $excludedFields = [];
637
-        if (!empty($this->tca['excluded_fields'])) {
638
-            $excludedFields = GeneralUtility::trimExplode(',', $this->tca['excluded_fields'], true);
639
-        } elseif (!empty($this->tca['export']['excluded_fields'])) { // only for export for legacy reason.
640
-            $excludedFields = GeneralUtility::trimExplode(',', $this->tca['export']['excluded_fields'], true);
641
-        }
642
-        return $excludedFields;
643
-
644
-    }
645
-
646
-    /**
647
-     * Fetch excluded fields from preferences.
648
-     *
649
-     * @return array
650
-     */
651
-    protected function getExcludedFieldsFromPreferences()
652
-    {
653
-        $excludedFields = $this->getModulePreferences()->get(ConfigurablePart::EXCLUDED_FIELDS, $this->tableName);
654
-        return is_array($excludedFields) ? $excludedFields : [];
655
-    }
656
-
657
-    /**
658
-     * @return array
659
-     */
660
-    public function areFilesIncludedInExport()
661
-    {
662
-        $isIncluded = true;
663
-
664
-        if (isset($this->tca['export']['include_files'])) {
665
-            $isIncluded = $this->tca['export']['include_files'];
666
-        }
667
-        return $isIncluded;
668
-    }
669
-
670
-    /**
671
-     * Returns a "facet" service instance.
672
-     *
673
-     * @param string|FacetInterface $facetName
674
-     * @return StandardFacet
675
-     */
676
-    protected function instantiateStandardFacet($facetName)
677
-    {
678
-        $label = $this->getLabel($facetName);
679
-
680
-        /** @var StandardFacet $facetName */
681
-        $facet = GeneralUtility::makeInstance('Fab\Vidi\Facet\StandardFacet', $facetName, $label);
682
-
683
-        if (!$facet instanceof StandardFacet) {
684
-            throw new \RuntimeException('I could not instantiate a facet for facet name "' . (string)$facet . '""', 1445856345);
685
-        }
686
-        return $facet;
687
-    }
688
-
689
-    /**
690
-     * Returns a "facet" service instance.
691
-     *
692
-     * @param string|FacetInterface $facetName
693
-     * @return FacetInterface
694
-     */
695
-    public function facet($facetName = '')
696
-    {
697
-        $facets = $this->getFacets();
698
-        return $facets[$facetName];
699
-    }
700
-
701
-    /**
702
-     * @return \Fab\Vidi\Resolver\FieldPathResolver
703
-     */
704
-    protected function getFieldPathResolver()
705
-    {
706
-        return GeneralUtility::makeInstance('Fab\Vidi\Resolver\FieldPathResolver');
707
-    }
708
-
709
-    /**
710
-     * @return ModulePreferences
711
-     */
712
-    protected function getModulePreferences()
713
-    {
714
-        return GeneralUtility::makeInstance('Fab\Vidi\Module\ModulePreferences');
715
-    }
26
+	/**
27
+	 * @var array
28
+	 */
29
+	protected $tca;
30
+
31
+	/**
32
+	 * @var string
33
+	 */
34
+	protected $tableName;
35
+
36
+	/**
37
+	 * All fields available in the Grid.
38
+	 *
39
+	 * @var array
40
+	 */
41
+	protected $fields;
42
+
43
+	/**
44
+	 * All fields regardless whether they have been excluded or not.
45
+	 *
46
+	 * @var array
47
+	 */
48
+	protected $allFields;
49
+
50
+	/**
51
+	 * @var array
52
+	 */
53
+	protected $instances;
54
+
55
+	/**
56
+	 * @var array
57
+	 */
58
+	protected $facets;
59
+
60
+	/**
61
+	 * __construct
62
+	 *
63
+	 * @throws InvalidKeyInArrayException
64
+	 * @param string $tableName
65
+	 * @return \Fab\Vidi\Tca\GridService
66
+	 */
67
+	public function __construct($tableName)
68
+	{
69
+
70
+		$this->tableName = $tableName;
71
+
72
+		if (empty($GLOBALS['TCA'][$this->tableName])) {
73
+			throw new InvalidKeyInArrayException('No TCA existence for table name: ' . $this->tableName, 1356945108);
74
+		}
75
+
76
+		$this->tca = $GLOBALS['TCA'][$this->tableName]['grid'];
77
+	}
78
+
79
+	/**
80
+	 * Returns an array containing column names.
81
+	 *
82
+	 * @return array
83
+	 */
84
+	public function getFieldNames()
85
+	{
86
+		$fields = $this->getFields();
87
+		return array_keys($fields);
88
+	}
89
+
90
+	/**
91
+	 * Returns an array containing column names.
92
+	 *
93
+	 * @return array
94
+	 */
95
+	public function getAllFieldNames()
96
+	{
97
+		$allFields = $this->getAllFields();
98
+		return array_keys($allFields);
99
+	}
100
+
101
+	/**
102
+	 * Get the label key.
103
+	 *
104
+	 * @param string $fieldNameAndPath
105
+	 * @return string
106
+	 * @throws \Fab\Vidi\Exception\InvalidKeyInArrayException
107
+	 */
108
+	public function getLabelKey($fieldNameAndPath)
109
+	{
110
+
111
+		$field = $this->getField($fieldNameAndPath);
112
+
113
+		// First option is to get the label from the Grid TCA.
114
+		$rawLabel = '';
115
+		if (isset($field['label'])) {
116
+			$rawLabel = $field['label'];
117
+		}
118
+
119
+		// Second option is to fetch the label from the Column Renderer object.
120
+		if (!$rawLabel && $this->hasRenderers($fieldNameAndPath)) {
121
+			$renderers = $this->getRenderers($fieldNameAndPath);
122
+			/** @var $renderer ColumnRendererInterface */
123
+			foreach ($renderers as $renderer) {
124
+				if (isset($renderer['label'])) {
125
+					$rawLabel = $renderer['label'];
126
+					break;
127
+				}
128
+			}
129
+		}
130
+		return $rawLabel;
131
+	}
132
+
133
+	/**
134
+	 * Get the translation of a label given a column name.
135
+	 *
136
+	 * @param string $fieldNameAndPath
137
+	 * @return string
138
+	 */
139
+	public function getLabel($fieldNameAndPath)
140
+	{
141
+		$label = '';
142
+		if ($this->hasLabel($fieldNameAndPath)) {
143
+			$labelKey = $this->getLabelKey($fieldNameAndPath);
144
+			try {
145
+				$label = LocalizationUtility::translate($labelKey, '');
146
+			} catch (\InvalidArgumentException $e) {
147
+			}
148
+			if (empty($label)) {
149
+				$label = $labelKey;
150
+			}
151
+		} else {
152
+
153
+			// Important to notice the label can contains a path, e.g. metadata.categories and must be resolved.
154
+			$dataType = $this->getFieldPathResolver()->getDataType($fieldNameAndPath, $this->tableName);
155
+			$fieldName = $this->getFieldPathResolver()->stripFieldPath($fieldNameAndPath, $this->tableName);
156
+			$table = Tca::table($dataType);
157
+
158
+			if ($table->hasField($fieldName) && $table->field($fieldName)->hasLabel()) {
159
+				$label = $table->field($fieldName)->getLabel();
160
+			}
161
+		}
162
+
163
+		return $label;
164
+	}
165
+
166
+	/**
167
+	 * Returns the field name given its position.
168
+	 *
169
+	 * @param string $position the position of the field in the grid
170
+	 * @throws InvalidKeyInArrayException
171
+	 * @return int
172
+	 */
173
+	public function getFieldNameByPosition($position)
174
+	{
175
+		$fields = array_keys($this->getFields());
176
+		if (empty($fields[$position])) {
177
+			throw new InvalidKeyInArrayException('No field exist for position: ' . $position, 1356945119);
178
+		}
179
+
180
+		return $fields[$position];
181
+	}
182
+
183
+	/**
184
+	 * Returns a field name.
185
+	 *
186
+	 * @param string $fieldName
187
+	 * @return array
188
+	 * @throws InvalidKeyInArrayException
189
+	 */
190
+	public function getField($fieldName)
191
+	{
192
+		$fields = $this->getFields();
193
+		return $fields[$fieldName];
194
+	}
195
+
196
+	/**
197
+	 * Returns an array containing column names for the Grid.
198
+	 *
199
+	 * @return array
200
+	 * @throws \Exception
201
+	 */
202
+	public function getFields()
203
+	{
204
+		// Cache this operation since it can take some time.
205
+		if (is_null($this->fields)) {
206
+
207
+			// Fetch all available fields first.
208
+			$fields = $this->getAllFields();
209
+
210
+			if ($this->isBackendMode()) {
211
+
212
+				// Then remove the not allowed.
213
+				$fields = $this->filterByIncludedFields($fields);
214
+				$fields = $this->filterByBackendUser($fields);
215
+				$fields = $this->filterByExcludedFields($fields);
216
+			}
217
+
218
+			$this->fields = $fields;
219
+		}
220
+
221
+		return $this->fields;
222
+	}
223
+
224
+	/**
225
+	 * Remove fields according to Grid configuration.
226
+	 *
227
+	 * @param $fields
228
+	 * @return array
229
+	 */
230
+	protected function filterByIncludedFields($fields)
231
+	{
232
+
233
+		$filteredFields = $fields;
234
+		$includedFields = $this->getIncludedFields();
235
+		if (count($includedFields) > 0) {
236
+			$filteredFields = [];
237
+			foreach ($fields as $fieldNameAndPath => $configuration) {
238
+				if (in_array($fieldNameAndPath, $includedFields, true) || !Tca::table($this->tableName)->hasField($fieldNameAndPath)) {
239
+					$filteredFields[$fieldNameAndPath] = $configuration;
240
+				}
241
+			}
242
+		}
243
+		return $filteredFields;
244
+	}
245
+
246
+	/**
247
+	 * Remove fields according to BE User permission.
248
+	 *
249
+	 * @param $fields
250
+	 * @return array
251
+	 * @throws \Exception
252
+	 */
253
+	protected function filterByBackendUser($fields)
254
+	{
255
+		if (!$this->getBackendUser()->isAdmin()) {
256
+			foreach ($fields as $fieldName => $field) {
257
+				if (Tca::table($this->tableName)->hasField($fieldName) && !Tca::table($this->tableName)->field($fieldName)->hasAccess()) {
258
+					unset($fields[$fieldName]);
259
+				}
260
+			}
261
+		}
262
+		return $fields;
263
+	}
264
+
265
+	/**
266
+	 * Remove fields according to Grid configuration.
267
+	 *
268
+	 * @param $fields
269
+	 * @return array
270
+	 */
271
+	protected function filterByExcludedFields($fields)
272
+	{
273
+
274
+		// Unset excluded fields.
275
+		foreach ($this->getExcludedFields() as $excludedField) {
276
+			if (isset($fields[$excludedField])) {
277
+				unset($fields[$excludedField]);
278
+			}
279
+		}
280
+
281
+		return $fields;
282
+	}
283
+
284
+	/**
285
+	 * Returns an array containing column names for the Grid.
286
+	 *
287
+	 * @return array
288
+	 */
289
+	public function getAllFields()
290
+	{
291
+
292
+		// Cache this operation since it can take some time.
293
+		if (is_null($this->allFields)) {
294
+
295
+			$fields = is_array($this->tca['columns']) ? $this->tca['columns'] : [];
296
+			$gridFieldNames = array_keys($fields);
297
+
298
+			// Fetch all fields of the TCA and merge it back to the fields configured for Grid.
299
+			$tableFieldNames = Tca::table($this->tableName)->getFields();
300
+
301
+			// Just remove system fields from the Grid.
302
+			foreach ($tableFieldNames as $key => $fieldName) {
303
+				if (in_array($fieldName, Tca::getSystemFields())) {
304
+					unset($tableFieldNames[$key]);
305
+				}
306
+			}
307
+
308
+			$additionalFields = array_diff($tableFieldNames, $gridFieldNames);
309
+
310
+			if (!empty($additionalFields)) {
311
+
312
+				// Pop out last element of the key
313
+				// Idea is to place new un-configured columns in between. By default, they will be hidden.
314
+				end($fields);
315
+				$lastColumnKey = key($fields);
316
+				$lastColumn = array_pop($fields);
317
+
318
+				// Feed up the grid fields with un configured elements
319
+				foreach ($additionalFields as $additionalField) {
320
+					$fields[$additionalField] = array(
321
+						'visible' => false
322
+					);
323
+
324
+					// Try to guess the format of the field.
325
+					$fieldType = Tca::table($this->tableName)->field($additionalField)->getType();
326
+					if ($fieldType === FieldType::DATE) {
327
+						$fields[$additionalField]['format'] = 'Fab\Vidi\Formatter\Date';
328
+					} elseif ($fieldType === FieldType::DATETIME) {
329
+						$fields[$additionalField]['format'] = 'Fab\Vidi\Formatter\Datetime';
330
+					}
331
+				}
332
+				$fields[$lastColumnKey] = $lastColumn;
333
+			}
334
+
335
+			$this->allFields = $fields;
336
+		}
337
+
338
+		return $this->allFields;
339
+	}
340
+
341
+	/**
342
+	 * Tell whether the field exists in the grid or not.
343
+	 *
344
+	 * @param string $fieldName
345
+	 * @return bool
346
+	 */
347
+	public function hasField($fieldName)
348
+	{
349
+		$fields = $this->getFields();
350
+		return isset($fields[$fieldName]);
351
+	}
352
+
353
+	/**
354
+	 * Tell whether the facet exists in the grid or not.
355
+	 *
356
+	 * @param string $facetName
357
+	 * @return bool
358
+	 */
359
+	public function hasFacet($facetName)
360
+	{
361
+		$facets = $this->getFacets();
362
+		return isset($facets[$facetName]);
363
+	}
364
+
365
+	/**
366
+	 * Returns an array containing facets fields.
367
+	 *
368
+	 * @return FacetInterface[]
369
+	 */
370
+	public function getFacets()
371
+	{
372
+		if (is_null($this->facets)) {
373
+			$this->facets = [];
374
+
375
+			if (is_array($this->tca['facets'])) {
376
+				foreach ($this->tca['facets'] as $facetNameOrObject) {
377
+					if ($facetNameOrObject instanceof FacetInterface) {
378
+						$this->facets[$facetNameOrObject->getName()] = $facetNameOrObject;
379
+					} else {
380
+						$this->facets[$facetNameOrObject] = $this->instantiateStandardFacet($facetNameOrObject);
381
+					}
382
+				}
383
+			}
384
+		}
385
+		return $this->facets;
386
+	}
387
+
388
+	/**
389
+	 * Returns the "sortable" value of the column.
390
+	 *
391
+	 * @param string $fieldName
392
+	 * @return int|string
393
+	 */
394
+	public function isSortable($fieldName)
395
+	{
396
+		$defaultValue = true;
397
+		$hasSortableField = Tca::table($this->tableName)->hasSortableField();
398
+		if ($hasSortableField) {
399
+			$isSortable = false;
400
+		} else {
401
+			$isSortable = $this->get($fieldName, 'sortable', $defaultValue);
402
+		}
403
+		return $isSortable;
404
+	}
405
+
406
+	/**
407
+	 * Returns the "canBeHidden" value of the column.
408
+	 *
409
+	 * @param string $fieldName
410
+	 * @return bool
411
+	 */
412
+	public function canBeHidden($fieldName)
413
+	{
414
+		$defaultValue = true;
415
+		return $this->get($fieldName, 'canBeHidden', $defaultValue);
416
+	}
417
+
418
+	/**
419
+	 * Returns the "width" value of the column.
420
+	 *
421
+	 * @param string $fieldName
422
+	 * @return int|string
423
+	 */
424
+	public function getWidth($fieldName)
425
+	{
426
+		$defaultValue = 'auto';
427
+		return $this->get($fieldName, 'width', $defaultValue);
428
+	}
429
+
430
+	/**
431
+	 * Returns the "visible" value of the column.
432
+	 *
433
+	 * @param string $fieldName
434
+	 * @return bool
435
+	 */
436
+	public function isVisible($fieldName)
437
+	{
438
+		$defaultValue = true;
439
+		return $this->get($fieldName, 'visible', $defaultValue);
440
+	}
441
+
442
+	/**
443
+	 * Returns the "editable" value of the column.
444
+	 *
445
+	 * @param string $columnName
446
+	 * @return bool
447
+	 */
448
+	public function isEditable($columnName)
449
+	{
450
+		$defaultValue = false;
451
+		return $this->get($columnName, 'editable', $defaultValue);
452
+	}
453
+
454
+	/**
455
+	 * Returns the "localized" value of the column.
456
+	 *
457
+	 * @param string $columnName
458
+	 * @return bool
459
+	 */
460
+	public function isLocalized($columnName)
461
+	{
462
+		$defaultValue = true;
463
+		return $this->get($columnName, 'localized', $defaultValue);
464
+	}
465
+
466
+	/**
467
+	 *
468
+	 * Returns the "html" value of the column.
469
+	 *
470
+	 * @param string $fieldName
471
+	 * @return string
472
+	 */
473
+	public function getHeader($fieldName)
474
+	{
475
+		$defaultValue = '';
476
+		return $this->get($fieldName, 'html', $defaultValue);
477
+	}
478
+
479
+	/**
480
+	 * Fetch a possible from a Grid Renderer. If no value is found, returns null
481
+	 *
482
+	 * @param string $fieldName
483
+	 * @param string $key
484
+	 * @param mixed $defaultValue
485
+	 * @return null|mixed
486
+	 */
487
+	public function get($fieldName, $key, $defaultValue = null)
488
+	{
489
+		$value = $defaultValue;
490
+
491
+		$field = $this->getField($fieldName);
492
+		if (isset($field[$key])) {
493
+			$value = $field[$key];
494
+		} elseif ($this->hasRenderers($fieldName)) {
495
+			$renderers = $this->getRenderers($fieldName);
496
+			foreach ($renderers as $rendererConfiguration) {
497
+				if (isset($rendererConfiguration[$key])) {
498
+					$value = $rendererConfiguration[$key];
499
+				}
500
+			}
501
+		}
502
+		return $value;
503
+	}
504
+
505
+	/**
506
+	 * Returns whether the column has a renderer.
507
+	 *
508
+	 * @param string $fieldName
509
+	 * @return bool
510
+	 */
511
+	public function hasRenderers($fieldName)
512
+	{
513
+		$field = $this->getField($fieldName);
514
+		return empty($field['renderer']) && empty($field['renderers']) ? false : true;
515
+	}
516
+
517
+	/**
518
+	 * Returns a renderer.
519
+	 *
520
+	 * @param string $fieldName
521
+	 * @return array
522
+	 */
523
+	public function getRenderers($fieldName)
524
+	{
525
+		$field = $this->getField($fieldName);
526
+		$renderers = [];
527
+		if (!empty($field['renderer'])) {
528
+			$renderers = $this->convertRendererToArray($field['renderer'], $field);
529
+		} elseif (!empty($field['renderers']) && is_array($field['renderers'])) {
530
+			foreach ($field['renderers'] as $renderer) {
531
+				$rendererNameAndConfiguration = $this->convertRendererToArray($renderer, $field);
532
+				$renderers = array_merge($renderers, $rendererNameAndConfiguration);
533
+			}
534
+		}
535
+
536
+		return $renderers;
537
+	}
538
+
539
+	/**
540
+	 * @param string $renderer
541
+	 * @return array
542
+	 */
543
+	protected function convertRendererToArray($renderer, array $field)
544
+	{
545
+		$result = [];
546
+		if (is_string($renderer)) {
547
+			$configuration = empty($field['rendererConfiguration'])
548
+				? []
549
+				: $field['rendererConfiguration'];
550
+
551
+			/** @var ColumnRendererInterface $rendererObject */
552
+			$rendererObject = GeneralUtility::makeInstance($renderer);
553
+
554
+			$result[$renderer] = array_merge($rendererObject->getConfiguration(), $configuration);
555
+			// TODO: throw alert message because this is not compatible anymore as of TYPO3 8.7.7
556
+		} elseif ($renderer instanceof ColumnRendererInterface) {
557
+			/** @var ColumnRendererInterface $renderer */
558
+			$result[get_class($renderer)] = $renderer->getConfiguration();
559
+		}
560
+		return $result;
561
+	}
562
+
563
+	/**
564
+	 * Returns the class names applied to a cell
565
+	 *
566
+	 * @param string $fieldName
567
+	 * @return bool
568
+	 */
569
+	public function getClass($fieldName)
570
+	{
571
+		$field = $this->getField($fieldName);
572
+		return isset($field['class']) ? $field['class'] : '';
573
+	}
574
+
575
+	/**
576
+	 * Returns whether the column has a label.
577
+	 *
578
+	 * @param string $fieldNameAndPath
579
+	 * @return bool
580
+	 */
581
+	public function hasLabel($fieldNameAndPath)
582
+	{
583
+		$field = $this->getField($fieldNameAndPath);
584
+
585
+		$hasLabel = empty($field['label']) ? false : true;
586
+
587
+		if (!$hasLabel && $this->hasRenderers($fieldNameAndPath)) {
588
+			$renderers = $this->getRenderers($fieldNameAndPath);
589
+			/** @var $renderer ColumnRendererInterface */
590
+			foreach ($renderers as $renderer) {
591
+				if (isset($renderer['label'])) {
592
+					$hasLabel = true;
593
+					break;
594
+				}
595
+			}
596
+		}
597
+		return $hasLabel;
598
+	}
599
+
600
+	/**
601
+	 * @return array
602
+	 */
603
+	public function getTca()
604
+	{
605
+		return $this->tca;
606
+	}
607
+
608
+	/**
609
+	 * @return array
610
+	 */
611
+	public function getIncludedFields()
612
+	{
613
+		return empty($this->tca['included_fields']) ? [] : GeneralUtility::trimExplode(',', $this->tca['included_fields'], true);
614
+	}
615
+
616
+	/**
617
+	 * Return excluded fields from configuration + preferences.
618
+	 *
619
+	 * @return array
620
+	 */
621
+	public function getExcludedFields()
622
+	{
623
+		$configurationFields = $this->getExcludedFieldsFromConfiguration();
624
+		$preferencesFields = $this->getExcludedFieldsFromPreferences();
625
+
626
+		return array_merge($configurationFields, $preferencesFields);
627
+	}
628
+
629
+	/**
630
+	 * Fetch excluded fields from configuration.
631
+	 *
632
+	 * @return array
633
+	 */
634
+	protected function getExcludedFieldsFromConfiguration()
635
+	{
636
+		$excludedFields = [];
637
+		if (!empty($this->tca['excluded_fields'])) {
638
+			$excludedFields = GeneralUtility::trimExplode(',', $this->tca['excluded_fields'], true);
639
+		} elseif (!empty($this->tca['export']['excluded_fields'])) { // only for export for legacy reason.
640
+			$excludedFields = GeneralUtility::trimExplode(',', $this->tca['export']['excluded_fields'], true);
641
+		}
642
+		return $excludedFields;
643
+
644
+	}
645
+
646
+	/**
647
+	 * Fetch excluded fields from preferences.
648
+	 *
649
+	 * @return array
650
+	 */
651
+	protected function getExcludedFieldsFromPreferences()
652
+	{
653
+		$excludedFields = $this->getModulePreferences()->get(ConfigurablePart::EXCLUDED_FIELDS, $this->tableName);
654
+		return is_array($excludedFields) ? $excludedFields : [];
655
+	}
656
+
657
+	/**
658
+	 * @return array
659
+	 */
660
+	public function areFilesIncludedInExport()
661
+	{
662
+		$isIncluded = true;
663
+
664
+		if (isset($this->tca['export']['include_files'])) {
665
+			$isIncluded = $this->tca['export']['include_files'];
666
+		}
667
+		return $isIncluded;
668
+	}
669
+
670
+	/**
671
+	 * Returns a "facet" service instance.
672
+	 *
673
+	 * @param string|FacetInterface $facetName
674
+	 * @return StandardFacet
675
+	 */
676
+	protected function instantiateStandardFacet($facetName)
677
+	{
678
+		$label = $this->getLabel($facetName);
679
+
680
+		/** @var StandardFacet $facetName */
681
+		$facet = GeneralUtility::makeInstance('Fab\Vidi\Facet\StandardFacet', $facetName, $label);
682
+
683
+		if (!$facet instanceof StandardFacet) {
684
+			throw new \RuntimeException('I could not instantiate a facet for facet name "' . (string)$facet . '""', 1445856345);
685
+		}
686
+		return $facet;
687
+	}
688
+
689
+	/**
690
+	 * Returns a "facet" service instance.
691
+	 *
692
+	 * @param string|FacetInterface $facetName
693
+	 * @return FacetInterface
694
+	 */
695
+	public function facet($facetName = '')
696
+	{
697
+		$facets = $this->getFacets();
698
+		return $facets[$facetName];
699
+	}
700
+
701
+	/**
702
+	 * @return \Fab\Vidi\Resolver\FieldPathResolver
703
+	 */
704
+	protected function getFieldPathResolver()
705
+	{
706
+		return GeneralUtility::makeInstance('Fab\Vidi\Resolver\FieldPathResolver');
707
+	}
708
+
709
+	/**
710
+	 * @return ModulePreferences
711
+	 */
712
+	protected function getModulePreferences()
713
+	{
714
+		return GeneralUtility::makeInstance('Fab\Vidi\Module\ModulePreferences');
715
+	}
716 716
 
717 717
 }
Please login to merge, or discard this patch.