Completed
Pull Request — master (#90)
by Arnaud
17:45
created

AdminFactory::injectAdmin()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 19
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 2

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 19
ccs 9
cts 9
cp 1
rs 9.4285
cc 2
eloc 10
nc 2
nop 2
crap 2
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\Configuration\Factory\ConfigurationFactory;
17
use LAG\AdminBundle\Admin\Event\AdminEvents;
18
use LAG\AdminBundle\DataProvider\Factory\DataProviderFactory;
19
use LAG\AdminBundle\DataProvider\Loader\EntityLoader;
20
use LAG\AdminBundle\LAGAdminBundle;
21
use LAG\AdminBundle\Message\MessageHandlerInterface;
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
     * AdminFactory constructor.
97
     *
98
     * @param array                         $adminConfigurations
99
     * @param EventDispatcherInterface      $eventDispatcher
100
     * @param MessageHandlerInterface       $messageHandler
101
     * @param Registry                      $adminRegistry
102
     * @param ActionRegistry                $actionRegistry
103
     * @param ActionFactory                 $actionFactory
104
     * @param ConfigurationFactory          $configurationFactory
105
     * @param DataProviderFactory           $dataProviderFactory
106
     * @param RequestHandler                $requestHandler
107
     * @param AuthorizationCheckerInterface $authorizationChecker
108
     * @param TokenStorageInterface         $tokenStorage
109
     */
110 2
    public function __construct(
111
        array $adminConfigurations,
112
        EventDispatcherInterface $eventDispatcher,
113
        MessageHandlerInterface $messageHandler,
114
        Registry $adminRegistry,
115
        ActionRegistry $actionRegistry,
116
        ActionFactory $actionFactory,
117
        ConfigurationFactory $configurationFactory,
118
        DataProviderFactory $dataProviderFactory,
119
        RequestHandler $requestHandler,
120
        AuthorizationCheckerInterface $authorizationChecker,
121
        TokenStorageInterface $tokenStorage
122
    ) {
123 2
        $this->eventDispatcher = $eventDispatcher;
124 2
        $this->configurationFactory = $configurationFactory;
125 2
        $this->adminConfigurations = $adminConfigurations;
126 2
        $this->actionFactory = $actionFactory;
127 2
        $this->messageHandler = $messageHandler;
128 2
        $this->adminRegistry = $adminRegistry;
129 2
        $this->dataProviderFactory = $dataProviderFactory;
130 2
        $this->requestHandler = $requestHandler;
131 2
        $this->authorizationChecker = $authorizationChecker;
132 2
        $this->tokenStorage = $tokenStorage;
133 2
        $this->actionRegistry = $actionRegistry;
134 2
    }
135
136
    /**
137
     * Create admins from configuration and load them into the pool. Dispatch ADMIN_CREATE event.
138
     */
139 1
    public function init()
140
    {
141
        // init only once
142 1
        if ($this->isInit) {
143 1
            return;
144
        }
145
        // dispatch an event to allow configuration modification before resolving and creating admins
146 1
        $event = new BeforeConfigurationEvent($this->adminConfigurations);
147
        $this
148 1
            ->eventDispatcher
149 1
            ->dispatch(AdminEvents::BEFORE_CONFIGURATION, $event)
150
        ;
151
152
        // get the modified configuration
153 1
        $this->adminConfigurations = $event->getAdminConfigurations();
154
        
155
        // create Admins according to the given configuration
156 1
        foreach ($this->adminConfigurations as $name => $configuration) {
157
            // dispatch an event to allow modification on a specific admin
158 1
            $event = new AdminCreateEvent($name, $configuration);
159
            $this
160 1
                ->eventDispatcher
161 1
                ->dispatch(AdminEvents::ADMIN_CREATE, $event)
162
            ;
163
164
            // create Admin object and add it to the registry
165 1
            $admin = $this->create($name, $event->getAdminConfiguration());
166
            $this
167 1
                ->adminRegistry
168 1
                ->add($admin)
169
            ;
170
171
            // dispatch post-create event
172 1
            $event = new AdminCreatedEvent($admin);
173
            $this
174 1
                ->eventDispatcher
175 1
                ->dispatch(AdminEvents::ADMIN_CREATED, $event)
176
            ;
177
        }
178 1
        $this->isInit = true;
179 1
    }
180
181
    /**
182
     * Create an Admin from configuration values. It will be added to AdminFactory admin's list.
183
     *
184
     * @param string $name
185
     * @param array $configuration
186
     *
187
     * @return AdminInterface
188
     *
189
     * @throws LogicException
190
     */
191 1
    public function create($name, array $configuration)
192
    {
193
        // create AdminConfiguration object
194
        $adminConfiguration = $this
195 1
            ->configurationFactory
196 1
            ->createAdminConfiguration($configuration)
197
        ;
198
        
199
        // retrieve a data provider and load it into the loader
200
        $dataProvider = $this
201 1
            ->dataProviderFactory
202 1
            ->get($adminConfiguration->getParameter('data_provider'), $adminConfiguration->getParameter('entity'))
203
        ;
204 1
        $entityLoader = new EntityLoader($dataProvider);
205
    
206
        // retrieve Admin dynamic class
207
        $adminClass = $this
208 1
            ->configurationFactory
209 1
            ->getApplicationConfiguration()
210 1
            ->getParameter('admin_class')
211
        ;
212
    
213
        // retrieve the actions services
214
        $actions = $this
215 1
            ->actionFactory
216 1
            ->getActions($name, $configuration)
217
        ;
218
219
        // create Admin object
220 1
        $admin = new $adminClass(
221 1
            $name,
222 1
            $entityLoader,
223 1
            $adminConfiguration,
224 1
            $this->messageHandler,
225 1
            $this->eventDispatcher,
226 1
            $this->authorizationChecker,
227 1
            $this->tokenStorage,
228 1
            $actions
229
        );
230
    
231 1
        if (!$admin instanceof AdminInterface) {
232
            throw new LogicException('Class "'.get_class($admin).'" should implements '.AdminInterface::class);
233
        }
234
235 1
        return $admin;
236
    }
237
    
238
    /**
239
     * Inject an Admin into an AdminAware controller. Add this Admin to Twig global parameters.
240
     *
241
     * @param mixed $controller
242
     * @param Request $request
243
     */
244 1
    public function injectAdmin($controller, Request $request)
245
    {
246
        // the controller should be Admin aware to have an Admin injected
247 1
        if (!$controller instanceof AdminAwareInterface) {
248 1
            return;
249
        }
250
        // get admin from the request parameters
251
        $admin = $this
252 1
            ->requestHandler
253 1
            ->handle($request)
254
        ;
255
        
256
        // inject the Admin in the controller
257 1
        $controller->setAdmin($admin);
258
        $this
259 1
            ->eventDispatcher
260 1
            ->dispatch(AdminEvents::ADMIN_INJECTED, new AdminInjectedEvent($admin, $controller))
261
        ;
262 1
    }
263
264
    /**
265
     * Return true if the AdminFactory is initialized.
266
     *
267
     * @return boolean
268
     */
269 1
    public function isInit()
270
    {
271 1
        return $this->isInit;
272
    }
273
}
274