Passed
Pull Request — master (#77)
by Romain
03:38
created

AbstractEvent::fillPropertyEntries()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 4
nc 3
nop 1
dl 0
loc 7
rs 9.4285
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\Event;
18
19
use CuyZ\Notiz\Core\Definition\Tree\EventGroup\Event\EventDefinition;
20
use CuyZ\Notiz\Core\Event\Exception\CancelEventDispatch;
21
use CuyZ\Notiz\Core\Event\Support\HasProperties;
22
use CuyZ\Notiz\Core\Exception\InvalidClassException;
23
use CuyZ\Notiz\Core\Notification\Notification;
24
use CuyZ\Notiz\Core\Property\Builder\PropertyBuilder;
25
use CuyZ\Notiz\Core\Property\Factory\PropertyContainer;
26
use CuyZ\Notiz\Core\Property\Factory\PropertyFactory;
27
use CuyZ\Notiz\Domain\Property\Builder\TagsPropertyBuilder;
28
use CuyZ\Notiz\Service\Container;
29
use TYPO3\CMS\Extbase\Object\ObjectManager;
30
31
/**
32
 * Default event implementation provided by this extension, you can use it for
33
 * your own events.
34
 *
35
 * It does implement all methods needed by the interface, so you wont have to do
36
 * the work yourself, unless you want to override something.
37
 *
38
 * You may still implement your own method named `run()` where you can process
39
 * the logic of the event (usually used to fill the properties of the class).
40
 *
41
 * Tag property service
42
 * --------------------
43
 *
44
 * By default, the property definitions are handled by the tag property service,
45
 * that will analyze your event class attributes and their annotations to
46
 * automatically fill the definitions.
47
 *
48
 * @see \CuyZ\Notiz\Core\Property\Service\TagsPropertyService
49
 *
50
 * The only thing you need to do is add the correct annotations on the class
51
 * attributes you want to use, and fill them with the correct values during the
52
 * dispatch process.
53
 *
54
 * Example:
55
 *
56
 * ```
57
 * /**
58
 *  * @var string
59
 *  *
60
 *  * @marker
61
 *  * /
62
 * protected $userName;
63
 *
64
 * public function run(UserObject $userObject)
65
 * {
66
 *     $this->userName = $userObject->getName();
67
 * }
68
 * ```
69
 *
70
 * Cancel dispatch
71
 * ---------------
72
 *
73
 * In the implementation of the method `run()` you can call the method
74
 * `cancelDispatch()` whenever you need to. This will cancel the dispatch of the
75
 * event and prevent any notification bound to this event from being fired.
76
 */
77
abstract class AbstractEvent implements Event, HasProperties
78
{
79
    const BUILDER_SUFFIX = 'PropertyBuilder';
80
81
    /**
82
     * @var EventDefinition
83
     */
84
    protected $eventDefinition;
85
86
    /**
87
     * @var Notification
88
     */
89
    protected $notification;
90
91
    /**
92
     * @var array
93
     */
94
    protected $configuration = [];
95
96
    /**
97
     * @var PropertyFactory
98
     */
99
    protected $propertyFactory;
100
101
    /**
102
     * @var ObjectManager
103
     */
104
    protected $objectManager;
105
106
    /**
107
     * WARNING
108
     * -------
109
     *
110
     * If you need to override the constructor, do not forget to call:
111
     * `parent::__construct`
112
     *
113
     * @param EventDefinition $eventDefinition
114
     * @param Notification $notification
115
     * @param PropertyFactory $propertyFactory
116
     * @param ObjectManager $objectManager
117
     */
118
    public function __construct(EventDefinition $eventDefinition, Notification $notification, PropertyFactory $propertyFactory, ObjectManager $objectManager)
119
    {
120
        $this->eventDefinition = $eventDefinition;
121
        $this->notification = $notification;
122
        $this->configuration = $notification->getEventConfiguration();
123
        $this->propertyFactory = $propertyFactory;
124
        $this->objectManager = $objectManager;
125
    }
126
127
    /**
128
     * This method can be called from the method `run()` to cancel the dispatch
129
     * of the event.
130
     *
131
     * You may call this under certain conditions of your own if they need the
132
     * event not to be dispatched, preventing the notifications bound to this
133
     * event to be fired.
134
     *
135
     * @throws CancelEventDispatch
136
     */
137
    protected function cancelDispatch()
138
    {
139
        throw new CancelEventDispatch;
140
    }
141
142
    /**
143
     * By default, the following builder will be used for your event:
144
     * @see \CuyZ\Notiz\Domain\Property\Builder\TagsPropertyBuilder
145
     *
146
     * To use a custom builder, you need to create a class with the same name as
147
     * your event at which you append `PropertyBuilder`. The method `build` of
148
     * your builder will then be automatically called when needed.
149
     *
150
     * Example:
151
     *
152
     * `MyVendor\MyExtension\Domain\Event\MyEvent` -> Event
153
     * `MyVendor\MyExtension\Domain\Event\MyEventPropertyBuilder` -> Builder
154
     *
155
     * @return PropertyBuilder
156
     */
157
    public static function getPropertyBuilder()
158
    {
159
        $builderClassName = static::class . static::BUILDER_SUFFIX;
160
161
        if (!class_exists($builderClassName)) {
162
            $builderClassName = TagsPropertyBuilder::class;
163
        } elseif (!in_array(PropertyBuilder::class, class_implements($builderClassName))) {
164
            throw InvalidClassException::eventPropertyBuilderMissingInterface($builderClassName);
165
        }
166
167
        /** @var PropertyBuilder $builder */
168
        $builder = Container::get($builderClassName);
169
170
        return $builder;
171
    }
172
173
    /**
174
     * Fills the property container with the values from the class attributes.
175
     *
176
     * @param PropertyContainer $container
177
     */
178
    public function fillPropertyEntries(PropertyContainer $container)
179
    {
180
        foreach ($container->getEntries() as $property) {
181
            $name = $property->getName();
182
183
            if (property_exists($this, $name)) {
184
                $property->setValue($this->$name);
185
            }
186
        }
187
    }
188
189
    /**
190
     * @return EventDefinition
191
     */
192
    public function getDefinition()
193
    {
194
        return $this->eventDefinition;
195
    }
196
197
    /**
198
     * @return Notification
199
     */
200
    public function getNotification()
201
    {
202
        return $this->notification;
203
    }
204
}
205