Passed
Branch tmp/scrutinizer-notification-d... (24bdcd)
by Romain
05:04
created

NotificationTcaService::getDefinitionIdentifier()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
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\Service;
18
19
use CuyZ\Notiz\Core\Definition\DefinitionService;
20
use CuyZ\Notiz\Core\Definition\Tree\Definition;
21
use CuyZ\Notiz\Core\Definition\Tree\EventGroup\Event\EventDefinition;
22
use CuyZ\Notiz\Core\Definition\Tree\Notification\NotificationDefinition;
23
use CuyZ\Notiz\Core\Event\Service\EventFactory;
24
use CuyZ\Notiz\Core\Exception\NotImplementedException;
25
use CuyZ\Notiz\Core\Notification\Notification;
26
use CuyZ\Notiz\Core\Support\NotizConstants;
27
use CuyZ\Notiz\Domain\Property\Marker;
28
use CuyZ\Notiz\Service\BackendUriBuilder;
29
use CuyZ\Notiz\Service\Container;
30
use CuyZ\Notiz\Service\LocalizationService;
31
use CuyZ\Notiz\Service\StringService;
32
use CuyZ\Notiz\Service\ViewService;
33
use TYPO3\CMS\Core\SingletonInterface;
34
use TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper;
35
36
/**
37
 * Utility service to ease TCA manipulation for TYPO3 notification records.
38
 */
39
abstract class NotificationTcaService implements SingletonInterface
40
{
41
    /**
42
     * @var EventFactory
43
     */
44
    protected $eventFactory;
45
46
    /**
47
     * @var DefinitionService
48
     */
49
    protected $definitionService;
50
51
    /**
52
     * @var ViewService
53
     */
54
    protected $viewService;
55
56
    /**
57
     * @var BackendUriBuilder
58
     */
59
    protected $backendUriBuilder;
60
61
    /**
62
     * @var DataMapper
63
     */
64
    protected $dataMapper;
65
66
    /**
67
     * @var Notification[]
68
     */
69
    private $notification;
70
71
    /**
72
     * Manual dependency injection.
73
     */
74
    public function __construct()
75
    {
76
        $this->eventFactory = Container::get(EventFactory::class);
77
        $this->definitionService = Container::get(DefinitionService::class);
78
        $this->viewService = Container::get(ViewService::class);
79
        $this->backendUriBuilder = Container::get(BackendUriBuilder::class);
80
        $this->dataMapper = Container::get(DataMapper::class);
81
    }
82
83
    /**
84
     * @param array $parameters
85
     * @return bool
86
     */
87
    public function definitionContainsErrors(array $parameters)
88
    {
89
        $result = !$this->definitionHasErrors();
90
91
        if (in_array('inverted', $parameters['conditionParameters'])) {
92
            $result = !$result;
93
        }
94
95
        return $result;
96
    }
97
98
    /**
99
     * @return string
100
     */
101
    public function getErrorMessage()
102
    {
103
        $view = $this->viewService->getStandaloneView('Backend/TCA/DefinitionErrorMessage');
104
105
        $view->assign('showDefinitionUri', $this->backendUriBuilder->uriFor('showDefinition'));
106
        $view->assign('result', $this->definitionService->getValidationResult());
107
108
        return $view->render();
109
    }
110
111
    /**
112
     * Loads all available events and stores them as an array to be used in the
113
     * TCA.
114
     *
115
     * @param array $parameters
116
     */
117
    public function getEventsList(array &$parameters)
118
    {
119
        if ($this->definitionHasErrors()) {
120
            return;
121
        }
122
123
        $eventGroups = $this->getDefinition()->getEventGroups();
124
125
        foreach ($eventGroups as $eventGroup) {
126
            $parameters['items'][] = [
127
                $eventGroup->getLabel(),
128
                '--div--',
129
            ];
130
131
            foreach ($eventGroup->getEvents() as $event) {
132
                $parameters['items'][] = [
133
                    $event->getLabel(),
134
                    $event->getFullIdentifier(),
135
                ];
136
            }
137
        }
138
    }
139
140
    /**
141
     * This function will fetch the event selected in the given notification.
142
     *
143
     * If the notification is new or if the event identifier is not found, the
144
     * first event from the first event group is returned.
145
     *
146
     * @param array $row
147
     * @return EventDefinition
148
     */
149
    protected function getSelectedEvent(array $row)
150
    {
151
        $definition = $this->getDefinition();
152
153
        // The first configured event is selected by default.
154
        $event = $definition->getFirstEventGroup()->getFirstEvent();
155
156
        if (isset($row['event'])) {
157
            // @PHP7
158
            $eventValue = is_array($row['event'])
159
                ? $row['event'][0]
160
                : $row['event'];
161
162
            if ($definition->hasEventFromFullIdentifier($eventValue)) {
163
                $event = $definition->getEventFromFullIdentifier($eventValue);
164
            }
165
        }
166
167
        return $event;
168
    }
169
170
    /**
171
     * Loads all markers for the current selected event and formats them as a
172
     * list to be displayed on the edit form.
173
     *
174
     * @param array $parameters
175
     * @return string
176
     */
177
    public function getMarkersLabel(array &$parameters)
178
    {
179
        if ($this->definitionHasErrors()) {
180
            return '';
181
        }
182
183
        $row = $parameters['row'];
184
        $eventDefinition = $this->getSelectedEvent($row);
185
        $notification = $this->getNotification($row);
186
187
        /** @var Marker[] $markers */
188
        $markers = $eventDefinition->getPropertyDefinition(Marker::class, $notification)->getEntries();
189
190
        $output = '';
191
192
        foreach ($markers as $marker) {
193
            $label = StringService::mark($marker->getLabel());
194
            $output .= "<tr><td><strong>{$marker->getFormattedName()}</strong></td><td>$label</td></tr>";
195
        }
196
197
        $description = LocalizationService::localize('Notification/Entity/Fields:field.markers.description', [$eventDefinition->getLabel()]);
198
199
        return <<<HTML
200
<p>$description</p>
201
202
<table class="table table-striped table-hover">
203
    <tbody>
204
        $output
205
    </tbody>
206
</table>
207
HTML;
208
    }
209
210
    /**
211
     * Loads all available channels and stores them as an array to be used in
212
     * the TCA.
213
     *
214
     * @param array $parameters
215
     */
216
    public function getChannelsList(array &$parameters)
217
    {
218
        if ($this->definitionHasErrors()) {
219
            return;
220
        }
221
222
        foreach ($this->getNotificationDefinition()->getChannels() as $channelDefinition) {
223
            $label = $channelDefinition->getLabel();
224
225
            if (empty($label)) {
226
                $label = $channelDefinition->getIdentifier();
227
            }
228
229
            $parameters['items'][] = [$label, $channelDefinition->getClassName()];
230
        }
231
    }
232
233
    /**
234
     * If a RTE is using a missing CKEditor preset, a message is shown to the
235
     * user to help him fix it.
236
     *
237
     * @param array $parent
238
     * @return string
239
     */
240
    public function showCKEditorPresetMissing(array $parent)
241
    {
242
        $preset = $parent['parameters']['preset'];
243
244
        $message = LocalizationService::localize('Notification/Entity/Fields:field.rte.ck_editor_preset_missing', [$preset]);
245
        $message = StringService::mark($message, '<code>$1</code>');
246
247
        return '<span class="bg-danger">' . $message . '</span>';
248
    }
249
250
    /**
251
     * Returns a notification object based on an array containing the
252
     * notification properties.
253
     *
254
     * @param array $row
255
     * @return Notification
256
     */
257
    protected function getNotification(array $row)
258
    {
259
        $hash = json_encode($row);
260
261
        if (!isset($this->notification[$hash])) {
262
            $this->notification[$hash] = isset($row['uid']) && is_integer($row['uid'])
263
                ? $this->getNotificationDefinition()->getProcessor()->getNotificationFromIdentifier($row['uid'])
264
                : reset($this->dataMapper->map($this->getNotificationDefinition()->getClassName(), [$row]));
265
        }
266
267
        return $this->notification[$hash];
268
    }
269
270
    /**
271
     * @param array $array
272
     * @param $label
273
     */
274
    protected function appendOptionGroup(array &$array, $label)
275
    {
276
        array_unshift($array, ['label' => "––– $label –––", 'value' => '--div--']);
277
    }
278
279
    /**
280
     * @return string
281
     */
282
    public function getNotificationIconPath()
283
    {
284
        if ($this->definitionService->getValidationResult()->hasErrors()) {
285
            return NotizConstants::EXTENSION_ICON_DEFAULT;
286
        }
287
288
        return $this->getNotificationDefinition()->getIconPath();
289
    }
290
291
    /**
292
     * @return Definition
293
     */
294
    public function getDefinition()
295
    {
296
        return $this->definitionService->getDefinition();
297
    }
298
299
    /**
300
     * @return NotificationDefinition
301
     */
302
    protected function getNotificationDefinition()
303
    {
304
        return $this->getDefinition()->getNotification($this->getDefinitionIdentifier());
305
    }
306
307
    /**
308
     * This method must return the current notification identifier to be used to
309
     * retrieve the current notification definition.
310
     *
311
     * @return string
312
     * @throws NotImplementedException
313
     */
314
    protected function getDefinitionIdentifier()
315
    {
316
        throw NotImplementedException::tcaServiceNotificationIdentifierMissing(__METHOD__);
317
    }
318
319
    /**
320
     * @return bool
321
     */
322
    public function definitionHasErrors()
323
    {
324
        return $this->definitionService->getValidationResult()->hasErrors();
325
    }
326
}
327