Passed
Push — dev ( dc6ac3...67fd32 )
by Romain
06:56
created

EntityTcaWriter::addDisplayConditionToFields()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 22
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 14
nc 5
nop 0
dl 0
loc 22
rs 8.6737
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * Copyright (C) 2017
5
 * Nathan Boiron <[email protected]>
6
 * Romain Canon <[email protected]>
7
 *
8
 * This file is part of the TYPO3 NotiZ project.
9
 * It is free software; you can redistribute it and/or modify it
10
 * under the terms of the GNU General Public License, either
11
 * version 3 of the License, or any later version.
12
 *
13
 * For the full copyright and license information, see:
14
 * http://www.gnu.org/licenses/gpl-3.0.html
15
 */
16
17
namespace CuyZ\Notiz\Notification\TCA;
18
19
use CuyZ\Notiz\Notification\Service\LegacyNotificationTcaService;
20
use CuyZ\Notiz\Notification\Service\NotificationTcaService;
21
use CuyZ\Notiz\Service\Traits\SelfInstantiateTrait;
22
use TYPO3\CMS\Core\SingletonInterface;
23
use TYPO3\CMS\Core\Utility\ArrayUtility;
24
use TYPO3\CMS\Core\Utility\GeneralUtility;
25
use TYPO3\CMS\Core\Utility\VersionNumberUtility;
26
27
abstract class EntityTcaWriter implements SingletonInterface
28
{
29
    use SelfInstantiateTrait;
30
31
    const LLL_FIELDS = 'LLL:EXT:notiz/Resources/Private/Language/Notification/Entity/Fields.xlf';
32
    const LLL_TABS = 'LLL:EXT:notiz/Resources/Private/Language/Notification/Entity/Tabs.xlf';
33
34
    /**
35
     * Contains the name of the TCA table.
36
     *
37
     * @var string
38
     */
39
    protected $tableName;
40
41
    /**
42
     * @var NotificationTcaService
43
     */
44
    protected $service;
45
46
    /**
47
     * @var array
48
     */
49
    private $data = [];
50
51
    /**
52
     * Manual injection for the TCA service depending on the entity type.
53
     */
54
    public function __construct()
55
    {
56
        $this->service = GeneralUtility::makeInstance($this->getNotificationTcaServiceClass());
57
    }
58
59
    /**
60
     * This method must create the basic TCA configuration. It must fill at
61
     * least the `ctrl` and `columns` sections.
62
     *
63
     * Default TYPO3 columns are added automatically, so no need to add them.
64
     * Common notifications columns are also added automatically.
65
     *
66
     * @return array
67
     */
68
    abstract protected function buildTcaArray();
69
70
    /**
71
     * This method builds a TCA array and returns it to be used in a
72
     * configuration file.
73
     *
74
     * @param string $tableName
75
     * @return array
76
     */
77
    final public function getTcaArray($tableName)
78
    {
79
        $this->tableName = $tableName;
80
81
        // Each sub-class starts to fill the array.
82
        $this->data = $this->buildTcaArray();
83
84
        // Some columns are common for all notification types
85
        $this->addCommonColumns();
86
87
        // The default columns are always the same.
88
        $this->addDefaultTypo3Columns();
89
90
        // This hides all fields if the definition has any error.
91
        $this->addDisplayConditionToFields();
92
93
        return $this->data;
94
    }
95
96
    /**
97
     * This method returns the TCA service class for the current entity type.
98
     * You can override it to return a class extending `NotificationTcaService`.
99
     *
100
     * @return string
101
     */
102
    abstract protected function getNotificationTcaServiceClass();
103
104
    /**
105
     * This method returns the LLL string to use for the `channel` column.
106
     *
107
     * @return string
108
     */
109
    protected function getChannelLabel()
110
    {
111
        return self::LLL_FIELDS . ':field.channel';
112
    }
113
114
    /**
115
     * Returns the TCA array for the event configuration. It is a FlexForm field
116
     * with as many definitions as there are events using FlexForm.
117
     *
118
     * @return array
119
     */
120
    private function getEventConfiguration()
121
    {
122
        if ($this->service->definitionHasErrors()) {
123
            return [];
124
        }
125
126
        $configuration = [];
127
        $displayConditions = [];
128
129
        foreach ($this->service->getDefinition()->getEvents() as $event) {
130
            $provider = $event->getConfiguration()->getFlexFormProvider();
131
132
            if ($provider->hasFlexForm()) {
133
                $identifier = $event->getFullIdentifier();
134
135
                $configuration[$identifier] = $provider->getFlexFormValue();
136
                $displayConditions[] = $identifier;
137
            }
138
        }
139
140
        if (empty($configuration)) {
141
            return ['config' => ['type' => 'passthrough']];
142
        }
143
144
        $configuration['default'] = 'FILE:EXT:notiz/Configuration/FlexForm/Event/DefaultEventFlexForm.xml';
145
146
        return [
147
            'label' => self::LLL_FIELDS . ':field.event_configuration',
148
            'displayCond' => version_compare(VersionNumberUtility::getCurrentTypo3Version(), '8.0.0', '<')
149
                ? 'USER:' . LegacyNotificationTcaService::class . '->displayEventFlexForm:' . $this->tableName . ':' . implode(',', $displayConditions)
150
                : 'FIELD:event:IN:' . implode(',', $displayConditions),
151
            'config' => [
152
                'type' => 'flex',
153
                'ds_pointerField' => 'event',
154
                'ds' => $configuration,
155
                'behaviour' => [
156
                    'allowLanguageSynchronization' => true,
157
                ],
158
            ],
159
        ];
160
    }
161
162
    /**
163
     * This will add display condition to all fields in the TCA array: if there
164
     * exists at least one error in the definition tree, the fields are hidden
165
     * and an error message is shown.
166
     */
167
    private function addDisplayConditionToFields()
168
    {
169
        $condition = 'USER:' . NotificationTcaService::class . '->definitionContainsErrors';
170
171
        foreach ($this->data['columns'] as $key => $column) {
172
            if ($key === 'error_message') {
173
                continue;
174
            }
175
176
            if (isset($column['displayCond'])) {
177
                if (isset($column['displayCond']['AND'])) {
178
                    $this->data['columns'][$key]['displayCond']['AND'][] = $condition;
179
                } else {
180
                    $this->data['columns'][$key]['displayCond'] = [
181
                        'AND' => [
182
                            $condition,
183
                            $column['displayCond'],
184
                        ]
185
                    ];
186
                }
187
            } else {
188
                $this->data['columns'][$key]['displayCond'] = $condition;
189
            }
190
        }
191
    }
192
193
    /**
194
     * Returns the default TYPO3 columns to include in the final TCA array.
195
     */
196
    private function addDefaultTypo3Columns()
197
    {
198
        $defaultColumns = [
199
            'sys_language_uid' => [
200
                'exclude' => 1,
201
                'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.language',
202
                'config' => [
203
                    'type' => 'select',
204
                    'foreign_table' => 'sys_language',
205
                    'foreign_table_where' => 'ORDER BY sys_language.title',
206
                    'items' => [
207
                        ['LLL:EXT:lang/locallang_general.xlf:LGL.allLanguages', -1],
208
                        ['LLL:EXT:lang/locallang_general.xlf:LGL.default_value', 0]
209
                    ]
210
                ]
211
            ],
212
            'l10n_parent' => [
213
                'displayCond' => 'FIELD:sys_language_uid:>:0',
214
                'exclude' => 1,
215
                'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.l18n_parent',
216
                'l10n_display' => 'defaultAsReadonly',
217
                'config' => [
218
                    'type' => 'select',
219
                    'foreign_table' => $this->tableName,
220
                    'foreign_table_where' => "AND {$this->tableName}.pid=###CURRENT_PID### AND {$this->tableName}.sys_language_uid IN (-1,0)",
221
                    'items' => [
222
                        ['', 0]
223
                    ]
224
                ]
225
            ],
226
            'l10n_diffsource' => [
227
                'config' => [
228
                    'type' => 'passthrough'
229
                ]
230
            ],
231
            't3ver_label' => [
232
                'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.versionLabel',
233
                'config' => [
234
                    'type' => 'input',
235
                    'size' => 30,
236
                    'max' => 255
237
                ]
238
            ],
239
            'hidden' => [
240
                'exclude' => 1,
241
                'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.hidden',
242
                'config' => [
243
                    'type' => 'check'
244
                ]
245
            ],
246
            'starttime' => [
247
                'exclude' => 1,
248
                'l10n_mode' => 'mergeIfNotBlank',
249
                'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.starttime',
250
                'config' => [
251
                    'type' => 'input',
252
                    'size' => 13,
253
                    'max' => 20,
254
                    'eval' => 'datetime',
255
                    'checkbox' => 0,
256
                    'default' => 0,
257
                    'range' => [
258
                        'lower' => mktime(0, 0, 0, (int)date('m'), (int)date('d'), (int)date('Y'))
259
                    ]
260
                ]
261
            ],
262
            'endtime' => [
263
                'exclude' => 1,
264
                'l10n_mode' => 'mergeIfNotBlank',
265
                'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.endtime',
266
                'config' => [
267
                    'type' => 'input',
268
                    'size' => 13,
269
                    'max' => 20,
270
                    'eval' => 'datetime',
271
                    'checkbox' => 0,
272
                    'default' => 0,
273
                    'range' => [
274
                        'lower' => mktime(0, 0, 0, (int)date('m'), (int)date('d'), (int)date('Y'))
275
                    ]
276
                ]
277
            ],
278
        ];
279
280
        ArrayUtility::mergeRecursiveWithOverrule(
281
            $this->data['columns'],
282
            $defaultColumns
283
        );
284
    }
285
286
    /**
287
     * This method adds the common columns used by all Entity Notifications.
288
     */
289
    private function addCommonColumns()
290
    {
291
        $commonColumns = [
292
            'error_message' => [
293
                'displayCond' => 'USER:' . NotificationTcaService::class . '->definitionContainsErrors:inverted',
294
                'config' => [
295
                    'type' => 'user',
296
                    'userFunc' => NotificationTcaService::class . '->getErrorMessage',
297
                ],
298
            ],
299
300
            'title' => [
301
                'exclude' => 1,
302
                'label' => self::LLL_FIELDS . ":field.title",
303
                'config' => [
304
                    'type' => 'input',
305
                    'size' => 30,
306
                    'eval' => 'trim,required',
307
                ],
308
            ],
309
310
            // Event configuration
311
312
            'event' => [
313
                'exclude' => 1,
314
                'label' => self::LLL_FIELDS . ":field.event",
315
                'l10n_mode' => 'exclude',
316
                'l10n_display' => 'defaultAsReadonly',
317
                'config' => [
318
                    'type' => 'select',
319
                    'renderType' => 'selectSingle',
320
                    'size' => 8,
321
                    'itemsProcFunc' => NotificationTcaService::class . '->getEventsList',
322
                    'eval' => 'required',
323
                ],
324
            ],
325
326
            'event_configuration_flex' => $this->getEventConfiguration(),
327
328
            // Channel configuration
329
330
            'channel' => [
331
                'exclude' => 1,
332
                'label' => $this->getChannelLabel(),
333
                'l10n_mode' => 'exclude',
334
                'l10n_display' => 'defaultAsReadonly',
335
                'config' => [
336
                    'type' => 'select',
337
                    'renderType' => 'selectSingle',
338
                    'itemsProcFunc' => $this->getNotificationTcaServiceClass() . '->getChannelsList',
339
                    'eval' => 'required',
340
                ],
341
            ],
342
343
            // Markers configuration
344
345
            'markers' => [
346
                'exclude' => 1,
347
                'label' => self::LLL_FIELDS . ":field.markers",
348
                'l10n_display' => 'defaultAsReadonly',
349
                'config' => [
350
                    'type' => 'user',
351
                    'userFunc' => NotificationTcaService::class . '->getMarkersLabel',
352
                ]
353
            ],
354
        ];
355
356
        ArrayUtility::mergeRecursiveWithOverrule(
357
            $this->data['columns'],
358
            $commonColumns
359
        );
360
    }
361
}
362