Completed
Push — master ( 95cc7b...2fc2b4 )
by Fabien
02:25
created

TableService::isHidden()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 0
1
<?php
2
3
namespace Fab\Vidi\Tca;
4
5
/*
6
 * This file is part of the Fab/Vidi project under GPLv2 or later.
7
 *
8
 * For the full copyright and license information, please read the
9
 * LICENSE.md file that was distributed with this source code.
10
 */
11
12
use TYPO3\CMS\Core\Utility\GeneralUtility;
13
use TYPO3\CMS\Extbase\Persistence\QueryInterface;
14
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
15
use Fab\Vidi\Exception\InvalidKeyInArrayException;
16
17
/**
18
 * A class to handle TCA ctrl.
19
 */
20
class TableService extends AbstractTca
21
{
22
23
    /**
24
     * @var array
25
     */
26
    protected $tca;
27
28
    /**
29
     * @var array
30
     */
31
    protected $columnTca;
32
33
    /**
34
     * @var string
35
     */
36
    protected $tableName;
37
38
    /**
39
     * @var array
40
     */
41
    protected $instances;
42
43
    /**
44
     * @throws InvalidKeyInArrayException
45
     * @param string $tableName
46
     * @return \Fab\Vidi\Tca\TableService
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
47
     */
48
    public function __construct($tableName)
49
    {
50
        $this->tableName = $tableName;
51 View Code Duplication
        if (empty($GLOBALS['TCA'][$this->tableName])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
52
            throw new InvalidKeyInArrayException(sprintf('No TCA existence for table "%s"', $this->tableName), 1356945106);
53
        }
54
        $this->tca = $GLOBALS['TCA'][$this->tableName]['ctrl'];
55
        $this->columnTca = $GLOBALS['TCA'][$this->tableName]['columns'];
56
    }
57
58
    /**
59
     * Tell whether the table has a label field.
60
     *
61
     * @throws \Fab\Vidi\Exception\InvalidKeyInArrayException
62
     * @return string
63
     */
64
    public function hasLabelField()
65
    {
66
        return $this->has('label');
67
    }
68
69
    /**
70
     * Get the label name of table name.
71
     *
72
     * @throws \Fab\Vidi\Exception\InvalidKeyInArrayException
73
     * @return string
74
     */
75
    public function getLabelField()
76
    {
77
        $labelField = $this->get('label');
78
        if (empty($labelField)) {
79
            throw new InvalidKeyInArrayException(sprintf('No label configured for table "%s"', $this->tableName), 1385586726);
80
        }
81
        return $labelField;
82
    }
83
84
    /**
85
     * Returns the translated label of the table name.
86
     *
87
     * @return string
88
     */
89 View Code Duplication
    public function getLabel()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
90
    {
91
        $label = '';
92
        try {
93
            $label = LocalizationUtility::translate($this->getLabelField(), '');
94
        } catch (\InvalidArgumentException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
95
        }
96
        if (empty($label)) {
97
            $label = $this->getLabelField();
98
        }
99
        return $label;
100
    }
101
102
    /**
103
     * Returns the title of the table.
104
     *
105
     * @return string
106
     */
107 View Code Duplication
    public function getTitle()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
108
    {
109
        $title = '';
110
        try {
111
            $title = LocalizationUtility::translate($this->get('title'), '');
112
        } catch (\InvalidArgumentException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
113
        }
114
        if (empty($title)) {
115
            $title = $this->get('title');
116
        }
117
        return $title;
118
    }
119
120
    /**
121
     * Return the "disabled" field.
122
     *
123
     * @throws \Fab\Vidi\Exception\InvalidKeyInArrayException
124
     * @return string|null
125
     */
126 View Code Duplication
    public function getHiddenField()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
127
    {
128
        $hiddenField = null;
129
        $enableColumns = $this->get('enablecolumns');
130
        if (is_array($enableColumns) && !empty($enableColumns['disabled'])) {
131
            $hiddenField = $enableColumns['disabled'];
132
        }
133
        return $hiddenField;
134
    }
135
136
    /**
137
     * Return the "starttime" field.
138
     *
139
     * @throws \Fab\Vidi\Exception\InvalidKeyInArrayException
140
     * @return string|null
141
     */
142 View Code Duplication
    public function getStartTimeField()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
143
    {
144
        $startTimeField = null;
145
        $enableColumns = $this->get('enablecolumns');
146
        if (is_array($enableColumns) && !empty($enableColumns['starttime'])) {
147
            $startTimeField = $enableColumns['starttime'];
148
        }
149
        return $startTimeField;
150
    }
151
152
    /**
153
     * Return the "endtime" field.
154
     *
155
     * @throws \Fab\Vidi\Exception\InvalidKeyInArrayException
156
     * @return string|null
157
     */
158 View Code Duplication
    public function getEndTimeField()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
159
    {
160
        $endTimeField = null;
161
        $enableColumns = $this->get('enablecolumns');
162
        if (is_array($enableColumns) && !empty($enableColumns['endtime'])) {
163
            $endTimeField = $enableColumns['endtime'];
164
        }
165
        return $endTimeField;
166
    }
167
168
    /**
169
     * Tells whether the table is hidden.
170
     *
171
     * @return bool
172
     */
173
    public function isHidden()
174
    {
175
        return isset($this->tca['hideTable']) ? $this->tca['hideTable'] : false;
176
    }
177
178
    /**
179
     * Tells whether the table is not hidden.
180
     *
181
     * @return bool
182
     */
183
    public function isNotHidden()
184
    {
185
        return !$this->isHidden();
186
    }
187
188
    /**
189
     * Get the "deleted" field for the table.
190
     *
191
     * @return string|null
192
     */
193
    public function getDeletedField()
194
    {
195
        return $this->get('delete');
196
    }
197
198
    /**
199
     * Get the modification time stamp field.
200
     *
201
     * @return string|null
202
     */
203
    public function getTimeModificationField()
204
    {
205
        return $this->get('tstamp');
206
    }
207
208
    /**
209
     * Get the creation time stamp field.
210
     *
211
     * @return string|null
212
     */
213
    public function getTimeCreationField()
214
    {
215
        return $this->get('crdate');
216
    }
217
218
    /**
219
     * Get the language field for the table.
220
     *
221
     * @return string|null
222
     */
223
    public function getLanguageField()
224
    {
225
        return $this->get('languageField');
226
    }
227
228
    /**
229
     * Get the field which points to the parent.
230
     *
231
     * @return string|null
232
     */
233
    public function getLanguageParentField()
234
    {
235
        return $this->get('transOrigPointerField');
236
    }
237
238
    /**
239
     * Returns the default order in the form of a SQL segment.
240
     *
241
     * @return string|null
242
     */
243
    public function getDefaultOrderSql()
244
    {
245
        // "sortby" typically has "sorting" as value.
246
        $order = $this->get('sortby') ? $this->get('sortby') . ' ASC' : $this->get('default_sortby');
247
        return $order;
248
    }
249
250
    /**
251
     * Returns the parsed default orderings.
252
     * Returns array looks like array('title' => 'ASC');
253
     *
254
     * @return array
255
     */
256
    public function getDefaultOrderings()
257
    {
258
259
        // first clean up the sql segment
260
        $defaultOrder = str_replace('ORDER BY', '', $this->getDefaultOrderSql());
261
        $defaultOrderParts = GeneralUtility::trimExplode(',', $defaultOrder, true);
262
263
        $orderings = [];
264
        foreach ($defaultOrderParts as $defaultOrderPart) {
265
            $parts = GeneralUtility::trimExplode(' ', $defaultOrderPart);
266
            if (empty($parts[1])) {
267
                $parts[1] = QueryInterface::ORDER_DESCENDING;
268
            }
269
            $orderings[$parts[0]] = $parts[1];
270
        }
271
272
        return $orderings;
273
    }
274
275
    /**
276
     * Returns the searchable fields.
277
     *
278
     * @return string|null
279
     */
280
    public function getSearchFields()
281
    {
282
        return $this->get('searchFields');
283
    }
284
285
    /**
286
     * Returns an array containing the field names.
287
     *
288
     * @return array
289
     */
290
    public function getFields()
291
    {
292
        return array_keys($this->columnTca);
293
    }
294
295
    /**
296
     * Returns an array containing the fields and their configuration.
297
     *
298
     * @return array
299
     */
300
    public function getFieldsAndConfiguration()
301
    {
302
        return $this->columnTca;
303
    }
304
305
    /**
306
     * Tell whether we have a field "sorting".
307
     *
308
     * @return bool
309
     */
310
    public function hasSortableField()
311
    {
312
        return $this->has('sortby');
313
    }
314
315
    /**
316
     * Tell whether the field exists or not.
317
     *
318
     * @param string $fieldName
319
     * @return bool
320
     */
321
    public function hasField($fieldName)
322
    {
323
        if ($this->isComposite($fieldName)) {
324
            $parts = explode('.', $fieldName);
325
            list ($strippedFieldPath, $possibleTableName) = $parts;
326
            $hasField = isset($this->columnTca[$strippedFieldPath], $GLOBALS['TCA'][$possibleTableName]);
327
328
            // Continue checking that the $strippedFieldName is of type "group"
329
            if (isset($GLOBALS['TCA'][$this->tableName]['columns'][$strippedFieldPath]) && count($parts) > 2) {
330
                $hasField = Tca::table($this->tableName)->field($strippedFieldPath)->isGroup(); // Group
331
            } elseif (isset($this->columnTca[$strippedFieldPath]['config']['readOnly']) && (bool)$this->columnTca[$strippedFieldPath]['config']['readOnly']) {
332
                $hasField = false; // handle case metadata.fe_groups where "fe_groups" is a tableName.
333
            }
334
        } else {
335
            $hasField = isset($this->columnTca[$fieldName]) || in_array($fieldName, Tca::getSystemFields(), true);
336
        }
337
        return $hasField;
338
    }
339
340
    /**
341
     * Tell whether the field name contains a path, e.g. metadata.title
342
     *
343
     * @param string $fieldName
344
     * @return boolean
345
     */
346
    public function isComposite($fieldName)
347
    {
348
        return strpos($fieldName, '.') > 0;
349
    }
350
351
    /**
352
     * Tells whether the $key exists.
353
     *
354
     * @param string $key
355
     * @return string
356
     */
357
    public function has($key)
358
    {
359
        return isset($this->tca[$key]);
360
    }
361
362
    /**
363
     * Tells whether the table name has "workspace" support.
364
     *
365
     * @return string
366
     */
367
    public function hasWorkspaceSupport()
368
    {
369
        return isset($this->tca['versioningWS']);
370
    }
371
372
    /**
373
     * Tells whether the table name has "language" support.
374
     *
375
     * @return string
376
     */
377
    public function hasLanguageSupport()
378
    {
379
        return isset($this->tca['languageField']);
380
    }
381
382
    /**
383
     * Return configuration value given a key.
384
     *
385
     * @param string $key
386
     * @return string|null
387
     */
388
    public function get($key)
389
    {
390
        return $this->has($key) ? $this->tca[$key] : null;
391
    }
392
393
    /**
394
     * @return array
395
     */
396
    public function getTca()
397
    {
398
        return $this->tca;
399
    }
400
401
    /**
402
     * Tell whether the current BE User has access to this field.
403
     *
404
     * @return bool
405
     */
406
    public function hasAccess()
407
    {
408
        $hasAccess = true;
409
        if ($this->isBackendMode()) {
410
            $hasAccess = $this->getBackendUser()->check('tables_modify', $this->tableName);
411
        }
412
        return $hasAccess;
413
    }
414
415
    /**
416
     * @param string $fieldName
417
     * @throws \Exception
418
     * @return \Fab\Vidi\Tca\FieldService
419
     */
420
    public function field($fieldName)
421
    {
422
423
        // In case field contains items.tx_table for field type "group"
424
        $compositeField = '';
425
        if (strpos($fieldName, '.') !== false) {
426
            $compositeField = $fieldName;
427
            $fieldParts = explode('.', $compositeField, 2);
428
            $fieldName = $fieldParts[0];
429
430
            // Special when field has been instantiated without the field name and path.
431
            if (!empty($this->instances[$fieldName])) {
432
                /** @var FieldService $field */
433
                $field = $this->instances[$fieldName];
434
                $field->setCompositeField($compositeField);
435
            }
436
        }
437
438
        // True for system fields such as uid, pid that don't necessarily have a TCA.
439
        if (empty($this->columnTca[$fieldName]) && in_array($fieldName, Tca::getSystemFields())) {
440
            $this->columnTca[$fieldName] = [];
441
        } elseif (empty($this->columnTca[$fieldName])) {
442
            $message = sprintf(
443
                'Does the field really exist? No TCA entry found for field "%s" for table "%s"',
444
                $fieldName,
445
                $this->tableName
446
            );
447
            throw new \Exception($message, 1385554481);
448
        }
449
450
451
        if (empty($this->instances[$fieldName])) {
452
453
            $instance = GeneralUtility::makeInstance(
454
                'Fab\Vidi\Tca\FieldService',
455
                $fieldName,
456
                $this->columnTca[$fieldName],
457
                $this->tableName,
458
                $compositeField
459
            );
460
461
            $this->instances[$fieldName] = $instance;
462
        }
463
        return $this->instances[$fieldName];
464
    }
465
466
}
467