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

AdminFactory::__construct()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 29
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 29
ccs 15
cts 15
cp 1
rs 8.8571
c 0
b 0
f 0
cc 1
eloc 27
nc 1
nop 13
crap 1

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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