Passed
Push — master ( cf28ed...fb61c9 )
by Romain
07:26 queued 04:29
created

NotificationTcaService   A

Complexity

Total Complexity 27

Size/Duplication

Total Lines 235
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 66
dl 0
loc 235
rs 10
c 0
b 0
f 0
wmc 27

12 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A getChannelsList() 0 14 4
A getMarkersLabel() 0 28 3
A getEventsList() 0 18 4
A getSelectedEvent() 0 19 4
A appendOptionGroup() 0 3 1
A definitionHasErrors() 0 3 1
A getNotificationIconPath() 0 7 2
A getDefinition() 0 3 1
A getNotification() 0 11 4
A getNotificationDefinition() 0 3 1
A getDefinitionIdentifier() 0 3 1
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\Container;
29
use CuyZ\Notiz\Service\LocalizationService;
30
use CuyZ\Notiz\Service\StringService;
31
use CuyZ\Notiz\Service\ViewService;
32
use TYPO3\CMS\Core\SingletonInterface;
33
use TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper;
34
35
/**
36
 * Utility service to ease TCA manipulation for TYPO3 notification records.
37
 */
38
abstract class NotificationTcaService implements SingletonInterface
39
{
40
    /**
41
     * @var EventFactory
42
     */
43
    protected $eventFactory;
44
45
    /**
46
     * @var DefinitionService
47
     */
48
    protected $definitionService;
49
50
    /**
51
     * @var ViewService
52
     */
53
    protected $viewService;
54
55
    /**
56
     * @var DataMapper
57
     */
58
    protected $dataMapper;
59
60
    /**
61
     * @var Notification[]
62
     */
63
    private $notification;
64
65
    /**
66
     * Manual dependency injection.
67
     */
68
    public function __construct()
69
    {
70
        $this->eventFactory = Container::get(EventFactory::class);
71
        $this->definitionService = Container::get(DefinitionService::class);
72
        $this->viewService = Container::get(ViewService::class);
73
        $this->dataMapper = Container::get(DataMapper::class);
74
    }
75
76
    /**
77
     * Loads all available events and stores them as an array to be used in the
78
     * TCA.
79
     *
80
     * @param array $parameters
81
     */
82
    public function getEventsList(array &$parameters)
83
    {
84
        if ($this->definitionHasErrors()) {
85
            return;
86
        }
87
88
        $eventGroups = $this->getDefinition()->getEventGroups();
89
90
        foreach ($eventGroups as $eventGroup) {
91
            $parameters['items'][] = [
92
                $eventGroup->getLabel(),
93
                '--div--',
94
            ];
95
96
            foreach ($eventGroup->getEvents() as $event) {
97
                $parameters['items'][] = [
98
                    $event->getLabel(),
99
                    $event->getFullIdentifier(),
100
                ];
101
            }
102
        }
103
    }
104
105
    /**
106
     * This function will fetch the event selected in the given notification.
107
     *
108
     * If the notification is new or if the event identifier is not found, the
109
     * first event from the first event group is returned.
110
     *
111
     * @param array $row
112
     * @return EventDefinition
113
     */
114
    protected function getSelectedEvent(array $row)
115
    {
116
        $definition = $this->getDefinition();
117
118
        // The first configured event is selected by default.
119
        $event = $definition->getFirstEventGroup()->getFirstEvent();
120
121
        if (isset($row['event'])) {
122
            // @PHP7
123
            $eventValue = is_array($row['event'])
124
                ? $row['event'][0]
125
                : $row['event'];
126
127
            if ($definition->hasEventFromFullIdentifier($eventValue)) {
128
                $event = $definition->getEventFromFullIdentifier($eventValue);
129
            }
130
        }
131
132
        return $event;
133
    }
134
135
    /**
136
     * Loads all markers for the current selected event and formats them as a
137
     * list to be displayed on the edit form.
138
     *
139
     * @param array $parameters
140
     * @return string
141
     */
142
    public function getMarkersLabel(array &$parameters)
143
    {
144
        if ($this->definitionHasErrors()) {
145
            return '';
146
        }
147
148
        $row = $parameters['row'];
149
        $eventDefinition = $this->getSelectedEvent($row);
150
        $notification = $this->getNotification($row);
151
152
        /** @var Marker[] $markers */
153
        $markers = $eventDefinition->getPropertyDefinition(Marker::class, $notification)->getEntries();
154
155
        $output = '';
156
157
        foreach ($markers as $marker) {
158
            $label = StringService::mark($marker->getLabel());
159
            $output .= "<tr><td><strong>{$marker->getFormattedName()}</strong></td><td>$label</td></tr>";
160
        }
161
162
        $description = LocalizationService::localize('Notification/Entity:field.markers.description', [$eventDefinition->getLabel()]);
163
164
        return <<<HTML
165
<p>$description</p>
166
167
<table class="table table-striped table-hover">
168
    <tbody>
169
        $output
170
    </tbody>
171
</table>
172
HTML;
173
    }
174
175
    /**
176
     * Loads all available channels and stores them as an array to be used in
177
     * the TCA.
178
     *
179
     * @param array $parameters
180
     */
181
    public function getChannelsList(array &$parameters)
182
    {
183
        if ($this->definitionHasErrors()) {
184
            return;
185
        }
186
187
        foreach ($this->getNotificationDefinition()->getChannels() as $channelDefinition) {
188
            $label = $channelDefinition->getLabel();
189
190
            if (empty($label)) {
191
                $label = $channelDefinition->getIdentifier();
192
            }
193
194
            $parameters['items'][] = [$label, $channelDefinition->getClassName()];
195
        }
196
    }
197
198
    /**
199
     * Returns a notification object based on an array containing the
200
     * notification properties.
201
     *
202
     * @param array $row
203
     * @return Notification
204
     */
205
    protected function getNotification(array $row)
206
    {
207
        $hash = json_encode($row);
208
209
        if (!isset($this->notification[$hash])) {
210
            $this->notification[$hash] = isset($row['uid']) && is_integer($row['uid'])
211
                ? $this->getNotificationDefinition()->getProcessor()->getNotificationFromIdentifier($row['uid'])
212
                : reset($this->dataMapper->map($this->getNotificationDefinition()->getClassName(), [$row]));
213
        }
214
215
        return $this->notification[$hash];
216
    }
217
218
    /**
219
     * @param array $array
220
     * @param $label
221
     */
222
    protected function appendOptionGroup(array &$array, $label)
223
    {
224
        array_unshift($array, ['label' => "––– $label –––", 'value' => '--div--']);
225
    }
226
227
    /**
228
     * @return string
229
     */
230
    public function getNotificationIconPath()
231
    {
232
        if ($this->definitionService->getValidationResult()->hasErrors()) {
233
            return NotizConstants::EXTENSION_ICON_DEFAULT;
234
        }
235
236
        return $this->getNotificationDefinition()->getIconPath();
237
    }
238
239
    /**
240
     * @return Definition
241
     */
242
    public function getDefinition()
243
    {
244
        return $this->definitionService->getDefinition();
245
    }
246
247
    /**
248
     * @return NotificationDefinition
249
     */
250
    protected function getNotificationDefinition()
251
    {
252
        return $this->getDefinition()->getNotification($this->getDefinitionIdentifier());
253
    }
254
255
    /**
256
     * This method must return the current notification identifier to be used to
257
     * retrieve the current notification definition.
258
     *
259
     * @return string
260
     * @throws NotImplementedException
261
     */
262
    protected function getDefinitionIdentifier()
263
    {
264
        throw NotImplementedException::tcaServiceNotificationIdentifierMissing(__METHOD__);
265
    }
266
267
    /**
268
     * @return bool
269
     */
270
    public function definitionHasErrors()
271
    {
272
        return $this->definitionService->getValidationResult()->hasErrors();
273
    }
274
}
275