Passed
Pull Request — master (#144)
by Romain
06:13 queued 02:55
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
            // Each sub-class starts to fill the array.
86
            $this->data = $this->buildTcaArray();
87
88
            // Some columns are common for all notification types
89
            $this->addCommonColumns();
90
91
            // The default columns are always the same.
92
            $this->addDefaultTypo3Columns();
93
        }
94
95
        return $this->data;
96
    }
97
98
    /**
99
     * This method returns the TCA service class for the current entity type.
100
     * You can override it to return a class extending `NotificationTcaService`.
101
     *
102
     * @return string
103
     */
104
    abstract protected function getNotificationTcaServiceClass();
105
106
    /**
107
     * Returns the title of the entity, can be a LLL reference.
108
     *
109
     * @return string
110
     */
111
    abstract protected function getEntityTitle();
112
113
    /**
114
     * This method returns the LLL string to use for the `channel` column.
115
     *
116
     * @return string
117
     */
118
    protected function getChannelLabel()
119
    {
120
        return self::LLL_FIELDS . ':field.channel';
121
    }
122
123
    /**
124
     * Returns the TCA array for the event configuration. It is a FlexForm field
125
     * with as many definitions as there are events using FlexForm.
126
     *
127
     * @return array
128
     */
129
    private function getEventConfiguration()
130
    {
131
        if ($this->service->definitionHasErrors()) {
132
            return [];
133
        }
134
135
        $configuration = [];
136
        $displayConditions = [];
137
138
        foreach ($this->service->getDefinition()->getEvents() as $event) {
139
            $provider = $event->getConfiguration()->getFlexFormProvider();
140
141
            if ($provider->hasFlexForm()) {
142
                $identifier = $event->getFullIdentifier();
143
144
                $configuration[$identifier] = $provider->getFlexFormValue();
145
                $displayConditions[] = $identifier;
146
            }
147
        }
148
149
        if (empty($configuration)) {
150
            return ['config' => ['type' => 'passthrough']];
151
        }
152
153
        $configuration['default'] = 'FILE:EXT:notiz/Configuration/FlexForm/Event/DefaultEventFlexForm.xml';
154
155
        return [
156
            'label' => self::LLL_FIELDS . ':field.event_configuration',
157
            'displayCond' => version_compare(VersionNumberUtility::getCurrentTypo3Version(), '8.0.0', '<')
158
                ? 'USER:' . LegacyNotificationTcaService::class . '->displayEventFlexForm:' . $this->tableName . ':' . implode(',', $displayConditions)
159
                : 'FIELD:event:IN:' . implode(',', $displayConditions),
160
            'config' => [
161
                'type' => 'flex',
162
                'ds_pointerField' => 'event',
163
                'ds' => $configuration,
164
                'behaviour' => [
165
                    'allowLanguageSynchronization' => true,
166
                ],
167
            ],
168
        ];
169
    }
170
171
    /**
172
     * @return array
173
     */
174
    protected function getDefaultCtrl()
175
    {
176
        return [
177
            'title' => $this->getEntityTitle(),
178
179
            'label' => 'title',
180
            'descriptionColumn' => 'description',
181
            'tstamp' => 'tstamp',
182
            'crdate' => 'crdate',
183
            'cruser_id' => 'cruser_id',
184
            'dividers2tabs' => true,
185
186
            'rootLevel' => -1,
187
            'security' => [
188
                'ignoreWebMountRestriction' => true,
189
                'ignoreRootLevelRestriction' => true,
190
            ],
191
192
            'requestUpdate' => 'event',
193
194
            'languageField' => 'sys_language_uid',
195
            'transOrigPointerField' => 'l10n_parent',
196
            'transOrigDiffSourceField' => 'l10n_diffsource',
197
            'delete' => 'deleted',
198
            'enablecolumns' => [
199
                'disabled' => 'hidden',
200
                'starttime' => 'starttime',
201
                'endtime' => 'endtime',
202
            ],
203
            'searchFields' => 'title,event',
204
            'iconfile' => $this->service->getNotificationIconPath(),
205
206
            self::ENTITY_NOTIFICATION => true,
207
208
            DefaultEventFromGet::ENABLE_DEFAULT_VALUE => true,
209
        ];
210
    }
211
212
    /**
213
     * Returns the default TYPO3 columns to include in the final TCA array.
214
     */
215
    private function addDefaultTypo3Columns()
216
    {
217
        $defaultColumns = [
218
            'sys_language_uid' => [
219
                'exclude' => 1,
220
                'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.language',
221
                'config' => [
222
                    'type' => 'select',
223
                    'foreign_table' => 'sys_language',
224
                    'foreign_table_where' => 'ORDER BY sys_language.title',
225
                    'items' => [
226
                        ['LLL:EXT:lang/locallang_general.xlf:LGL.allLanguages', -1],
227
                        ['LLL:EXT:lang/locallang_general.xlf:LGL.default_value', 0],
228
                    ],
229
                ],
230
            ],
231
            'l10n_parent' => [
232
                'displayCond' => 'FIELD:sys_language_uid:>:0',
233
                'exclude' => 1,
234
                'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.l18n_parent',
235
                'l10n_display' => 'defaultAsReadonly',
236
                'config' => [
237
                    'type' => 'select',
238
                    'foreign_table' => $this->tableName,
239
                    'foreign_table_where' => "AND {$this->tableName}.pid=###CURRENT_PID### AND {$this->tableName}.sys_language_uid IN (-1,0)",
240
                    'items' => [
241
                        ['', 0],
242
                    ],
243
                ],
244
            ],
245
            'l10n_diffsource' => [
246
                'config' => [
247
                    'type' => 'passthrough',
248
                ],
249
            ],
250
            't3ver_label' => [
251
                'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.versionLabel',
252
                'config' => [
253
                    'type' => 'input',
254
                    'size' => 30,
255
                    'max' => 255,
256
                ],
257
            ],
258
            'hidden' => [
259
                'exclude' => 1,
260
                'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.hidden',
261
                'config' => [
262
                    'type' => 'check',
263
                ],
264
            ],
265
            'starttime' => [
266
                'exclude' => 1,
267
                'l10n_mode' => 'mergeIfNotBlank',
268
                'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.starttime',
269
                'config' => [
270
                    'type' => 'input',
271
                    'size' => 13,
272
                    'max' => 20,
273
                    'eval' => 'datetime',
274
                    'checkbox' => 0,
275
                    'default' => 0,
276
                    'range' => [
277
                        'lower' => mktime(0, 0, 0, (int)date('m'), (int)date('d'), (int)date('Y')),
278
                    ],
279
                ],
280
            ],
281
            'endtime' => [
282
                'exclude' => 1,
283
                'l10n_mode' => 'mergeIfNotBlank',
284
                'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.endtime',
285
                'config' => [
286
                    'type' => 'input',
287
                    'size' => 13,
288
                    'max' => 20,
289
                    'eval' => 'datetime',
290
                    'checkbox' => 0,
291
                    'default' => 0,
292
                    'range' => [
293
                        'lower' => mktime(0, 0, 0, (int)date('m'), (int)date('d'), (int)date('Y')),
294
                    ],
295
                ],
296
            ],
297
        ];
298
299
        ArrayUtility::mergeRecursiveWithOverrule(
300
            $this->data['columns'],
301
            $defaultColumns
302
        );
303
    }
304
305
    /**
306
     * This method adds the common columns used by all Entity Notifications.
307
     */
308
    private function addCommonColumns()
309
    {
310
        $commonColumns = [
311
            'title' => [
312
                'exclude' => 1,
313
                'label' => self::LLL_FIELDS . ":field.title",
314
                'config' => [
315
                    'type' => 'input',
316
                    'size' => 30,
317
                    'eval' => 'trim,required',
318
                ],
319
            ],
320
321
            'description' => [
322
                'exclude' => 1,
323
                'label' => self::LLL_FIELDS . ":field.description",
324
                'config' => [
325
                    'type' => 'text',
326
                    'cols' => 40,
327
                    'rows' => 5,
328
                ],
329
            ],
330
331
            // Event configuration
332
333
            'event' => [
334
                'exclude' => 1,
335
                'label' => self::LLL_FIELDS . ":field.event",
336
                'l10n_mode' => 'exclude',
337
                'l10n_display' => 'defaultAsReadonly',
338
                'config' => [
339
                    'type' => 'select',
340
                    'size' => 8,
341
                    'itemsProcFunc' => $this->getNotificationTcaServiceClass() . '->getEventsList',
342
                    'eval' => 'required',
343
                ],
344
            ],
345
346
            'event_configuration_flex' => $this->getEventConfiguration(),
347
348
            // Channel configuration
349
350
            'channel' => [
351
                'exclude' => 1,
352
                'label' => $this->getChannelLabel(),
353
                'l10n_mode' => 'exclude',
354
                'l10n_display' => 'defaultAsReadonly',
355
                'config' => [
356
                    'type' => 'select',
357
                    'renderType' => 'selectSingle',
358
                    'itemsProcFunc' => $this->getNotificationTcaServiceClass() . '->getChannelsList',
359
                    'eval' => 'required',
360
                ],
361
            ],
362
363
            // Markers configuration
364
365
            'markers' => [
366
                'exclude' => 1,
367
                'label' => self::LLL_FIELDS . ":field.markers",
368
                'l10n_display' => 'defaultAsReadonly',
369
                'config' => [
370
                    'type' => 'user',
371
                    'userFunc' => $this->getNotificationTcaServiceClass() . '->getMarkersLabel',
372
                ],
373
            ],
374
        ];
375
376
        ArrayUtility::mergeRecursiveWithOverrule(
377
            $this->data['columns'],
378
            $commonColumns
379
        );
380
    }
381
}
382