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