Passed
Pull Request — master (#144)
by Romain
03:27
created

EntityTcaWriter::addDisplayConditionToFields()   A

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