Completed
Pull Request — master (#90)
by Arnaud
16:42
created

AdminFactory   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 261
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 15

Test Coverage

Coverage 98.57%

Importance

Changes 0
Metric Value
wmc 9
lcom 1
cbo 15
dl 0
loc 261
ccs 69
cts 70
cp 0.9857
rs 9.1666
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 0 29 1
B init() 0 41 3
A create() 0 48 2
A injectAdmin() 0 21 2
A isInit() 0 4 1
1
<?php
2
3
namespace LAG\AdminBundle\Admin\Factory;
4
5
use LAG\AdminBundle\Action\Factory\ActionFactory;
6
use LAG\AdminBundle\Action\Registry\Registry as ActionRegistry;
7
use LAG\AdminBundle\Admin\AdminAwareInterface;
8
use LAG\AdminBundle\Admin\AdminInterface;
9
use LAG\AdminBundle\Admin\Configuration\AdminConfiguration;
10
use LAG\AdminBundle\Admin\Event\AdminCreatedEvent;
11
use LAG\AdminBundle\Admin\Event\AdminCreateEvent;
12
use LAG\AdminBundle\Admin\Event\AdminInjectedEvent;
13
use LAG\AdminBundle\Admin\Event\BeforeConfigurationEvent;
14
use LAG\AdminBundle\Admin\Registry\Registry;
15
use LAG\AdminBundle\Admin\Request\RequestHandler;
16
use LAG\AdminBundle\Admin\Event\AdminEvents;
17
use LAG\AdminBundle\Application\Configuration\ApplicationConfigurationStorage;
18
use LAG\AdminBundle\DataProvider\Factory\DataProviderFactory;
19
use LAG\AdminBundle\DataProvider\Loader\EntityLoader;
20
use LAG\AdminBundle\Message\MessageHandlerInterface;
21
use LAG\AdminBundle\View\Factory\ViewFactory;
22
use LogicException;
23
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
24
use Symfony\Component\HttpFoundation\Request;
25
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
26
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
27
28
/**
29
 * AdminFactory.
30
 *
31
 * This class is responsible for the creation of Admins from configuration array.
32
 */
33
class AdminFactory
34
{
35
    /**
36
     * @var bool
37
     */
38
    private $isInit = false;
39
40
    /**
41
     * @var EventDispatcherInterface
42
     */
43
    private $eventDispatcher;
44
45
    /**
46
     * @var ConfigurationFactory
47
     */
48
    private $configurationFactory;
49
50
    /**
51
     * @var AdminConfiguration[]
52
     */
53
    private $adminConfigurations;
54
55
    /**
56
     * @var ActionFactory
57
     */
58
    private $actionFactory;
59
60
    /**
61
     * @var MessageHandlerInterface
62
     */
63
    private $messageHandler;
64
65
    /**
66
     * @var Registry
67
     */
68
    private $adminRegistry;
69
70
    /**
71
     * @var DataProviderFactory
72
     */
73
    private $dataProviderFactory;
74
    
75
    /**
76
     * @var RequestHandler
77
     */
78
    private $requestHandler;
79
    
80
    /**
81
     * @var AuthorizationCheckerInterface
82
     */
83
    private $authorizationChecker;
84
    
85
    /**
86
     * @var TokenStorageInterface
87
     */
88
    private $tokenStorage;
89
    
90
    /**
91
     * @var ActionRegistry
92
     */
93
    private $actionRegistry;
94
    
95
    /**
96
     * @var ViewFactory
97
     */
98
    private $viewFactory;
99
    
100
    /**
101
     * @var ApplicationConfigurationStorage
102
     */
103
    private $applicationConfigurationStorage;
104
    
105
    /**
106
     * AdminFactory constructor.
107
     *
108
     * @param array                           $adminConfigurations
109
     * @param EventDispatcherInterface        $eventDispatcher
110
     * @param MessageHandlerInterface         $messageHandler
111
     * @param Registry                        $adminRegistry
112
     * @param ActionRegistry                  $actionRegistry
113
     * @param ActionFactory                   $actionFactory
114
     * @param ConfigurationFactory            $configurationFactory
115
     * @param DataProviderFactory             $dataProviderFactory
116
     * @param ViewFactory                     $viewFactory
117
     * @param RequestHandler                  $requestHandler
118
     * @param AuthorizationCheckerInterface   $authorizationChecker
119
     * @param TokenStorageInterface           $tokenStorage
120
     * @param ApplicationConfigurationStorage $applicationConfigurationStorage
121
     */
122 2
    public function __construct(
123
        array $adminConfigurations,
124
        EventDispatcherInterface $eventDispatcher,
125
        MessageHandlerInterface $messageHandler,
126
        Registry $adminRegistry,
127
        ActionRegistry $actionRegistry,
128
        ActionFactory $actionFactory,
129
        ConfigurationFactory $configurationFactory,
130
        DataProviderFactory $dataProviderFactory,
131
        ViewFactory $viewFactory,
132
        RequestHandler $requestHandler,
133
        AuthorizationCheckerInterface $authorizationChecker,
134
        TokenStorageInterface $tokenStorage,
135
        ApplicationConfigurationStorage $applicationConfigurationStorage
136
    ) {
137 2
        $this->eventDispatcher = $eventDispatcher;
138 2
        $this->configurationFactory = $configurationFactory;
139 2
        $this->adminConfigurations = $adminConfigurations;
140 2
        $this->actionFactory = $actionFactory;
141 2
        $this->messageHandler = $messageHandler;
142 2
        $this->adminRegistry = $adminRegistry;
143 2
        $this->dataProviderFactory = $dataProviderFactory;
144 2
        $this->requestHandler = $requestHandler;
145 2
        $this->authorizationChecker = $authorizationChecker;
146 2
        $this->tokenStorage = $tokenStorage;
147 2
        $this->actionRegistry = $actionRegistry;
148 2
        $this->viewFactory = $viewFactory;
149 2
        $this->applicationConfigurationStorage = $applicationConfigurationStorage;
150 2
    }
151
152
    /**
153
     * Create admins from configuration and load them into the pool. Dispatch ADMIN_CREATE event.
154
     */
155 1
    public function init()
156
    {
157
        // init only once
158 1
        if ($this->isInit) {
159 1
            return;
160
        }
161
        // dispatch an event to allow configuration modification before resolving and creating admins
162 1
        $event = new BeforeConfigurationEvent($this->adminConfigurations);
163
        $this
164 1
            ->eventDispatcher
165 1
            ->dispatch(AdminEvents::BEFORE_CONFIGURATION, $event)
166
        ;
167
168
        // get the modified configuration
169 1
        $this->adminConfigurations = $event->getAdminConfigurations();
170
        
171
        // create Admins according to the given configuration
172 1
        foreach ($this->adminConfigurations as $name => $configuration) {
173
            // dispatch an event to allow modification on a specific admin
174 1
            $event = new AdminCreateEvent($name, $configuration);
175
            $this
176 1
                ->eventDispatcher
177 1
                ->dispatch(AdminEvents::ADMIN_CREATE, $event)
178
            ;
179
180
            // create Admin object and add it to the registry
181 1
            $admin = $this->create($name, $event->getAdminConfiguration());
182
            $this
183 1
                ->adminRegistry
184 1
                ->add($admin)
185
            ;
186
187
            // dispatch post-create event
188 1
            $event = new AdminCreatedEvent($admin);
189
            $this
190 1
                ->eventDispatcher
191 1
                ->dispatch(AdminEvents::ADMIN_CREATED, $event)
192
            ;
193
        }
194 1
        $this->isInit = true;
195 1
    }
196
197
    /**
198
     * Create an Admin from configuration values. It will be added to AdminFactory admin's list.
199
     *
200
     * @param string $name
201
     * @param array  $configuration
202
     *
203
     * @return AdminInterface
204
     *
205
     * @throws LogicException
206
     */
207 1
    public function create($name, array $configuration)
208
    {
209
        // create AdminConfiguration object
210
        $adminConfiguration = $this
211 1
            ->configurationFactory
212 1
            ->create($configuration)
213
        ;
214
        
215
        // retrieve a data provider and load it into the loader
216
        $dataProvider = $this
217 1
            ->dataProviderFactory
218 1
            ->get($adminConfiguration->getParameter('data_provider'), $adminConfiguration->getParameter('entity'))
219
        ;
220 1
        $entityLoader = new EntityLoader($dataProvider);
221
    
222
        // retrieve Admin dynamic class
223
        $adminClass = $this
224 1
            ->applicationConfigurationStorage
225 1
            ->getApplicationConfiguration()
226 1
            ->getParameter('admin_class')
227
        ;
228
    
229
        // retrieve the actions services
230
        $actions = $this
231 1
            ->actionFactory
232 1
            ->getActions($name, $configuration)
233
        ;
234
235
        // create Admin object
236 1
        $admin = new $adminClass(
237 1
            $name,
238 1
            $entityLoader,
239 1
            $adminConfiguration,
240 1
            $this->messageHandler,
241 1
            $this->eventDispatcher,
242 1
            $this->authorizationChecker,
243 1
            $this->tokenStorage,
244 1
            $this->requestHandler,
245 1
            $this->viewFactory,
246 1
            $actions
247
        );
248
    
249 1
        if (!$admin instanceof AdminInterface) {
250
            throw new LogicException('Class "'.get_class($admin).'" should implements '.AdminInterface::class);
251
        }
252
253 1
        return $admin;
254
    }
255
    
256
    /**
257
     * Inject an Admin into an AdminAware controller. Add this Admin to Twig global parameters.
258
     *
259
     * @param mixed $controller
260
     * @param Request $request
261
     */
262 1
    public function injectAdmin($controller, Request $request)
263
    {
264
        // the controller should be Admin aware to have an Admin injected
265 1
        if (!$controller instanceof AdminAwareInterface) {
266 1
            return;
267
        }
268
        // get admin from the request parameters
269
        $admin = $this
270 1
            ->requestHandler
271 1
            ->handle($request)
272
        ;
273
        
274
        // inject the Admin in the controller
275 1
        $controller->setAdmin($admin);
276
        
277
        // dispatch an even to allow some custom logic
278
        $this
279 1
            ->eventDispatcher
280 1
            ->dispatch(AdminEvents::ADMIN_INJECTED, new AdminInjectedEvent($admin, $controller))
281
        ;
282 1
    }
283
284
    /**
285
     * Return true if the AdminFactory is initialized.
286
     *
287
     * @return boolean
288
     */
289 1
    public function isInit()
290
    {
291 1
        return $this->isInit;
292
    }
293
}
294