Completed
Pull Request — master (#71)
by Arnaud
03:02
created

AdminFactory::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 20
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 20
ccs 11
cts 11
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 18
nc 1
nop 8
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 Doctrine\ORM\EntityManager;
6
use LAG\AdminBundle\Action\Factory\ActionFactory;
7
use LAG\AdminBundle\Admin\Admin;
8
use LAG\AdminBundle\Admin\AdminInterface;
9
use LAG\AdminBundle\Admin\Event\AdminCreatedEvent;
10
use LAG\AdminBundle\Admin\Event\AdminCreateEvent;
11
use LAG\AdminBundle\Admin\Event\BeforeConfigurationEvent;
12
use LAG\AdminBundle\Admin\Registry\Registry;
13
use LAG\AdminBundle\Configuration\Factory\ConfigurationFactory;
14
use LAG\AdminBundle\DataProvider\DataProvider;
15
use LAG\AdminBundle\DataProvider\DataProviderInterface;
16
use LAG\AdminBundle\Admin\Event\AdminEvents;
17
use Exception;
18
use LAG\AdminBundle\Filter\Factory\RequestFilterFactory;
19
use LAG\AdminBundle\Message\MessageHandlerInterface;
20
use LAG\AdminBundle\Repository\RepositoryInterface;
21
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
22
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
23
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
24
25
/**
26
 * AdminFactory.
27
 *
28
 * Create admin from configuration
29
 */
30
class AdminFactory
31
{
32
    /**
33
     * @var bool
34
     */
35
    protected $isInit = false;
36
37
    /**
38
     * @var EventDispatcherInterface
39
     */
40
    protected $eventDispatcher;
41
42
    /**
43
     * @var EntityManager
44
     */
45
    protected $entityManager;
46
47
    /**
48
     * @var ConfigurationFactory
49
     */
50
    protected $configurationFactory;
51
52
    /**
53
     * User custom data provider, indexed by service id
54
     *
55
     * @var ParameterBagInterface
56
     */
57
    protected $dataProviders;
58
59
    /**
60
     * @var array
61
     */
62
    protected $adminConfigurations;
63
64
    /**
65
     * @var ActionFactory
66
     */
67
    protected $actionFactory;
68
69
    /**
70
     * @var MessageHandlerInterface
71
     */
72
    protected $messageHandler;
73
74
    /**
75
     * @var Registry
76
     */
77
    protected $registry;
78
79
    /**
80
     * @var RequestFilterFactory
81
     */
82
    protected $requestFilterFactory;
83
84
    /**
85
     * AdminFactory constructor.
86
     *
87
     * @param array $adminConfigurations
88
     * @param EventDispatcherInterface $eventDispatcher
89
     * @param EntityManager $entityManager
90
     * @param ConfigurationFactory $configurationFactory
91
     * @param ActionFactory $actionFactory
92
     * @param MessageHandlerInterface $messageHandler
93
     * @param Registry $registry
94
     * @param RequestFilterFactory $requestFilterFactory
95
     */
96 4
    public function __construct(
97
        array $adminConfigurations,
98
        EventDispatcherInterface $eventDispatcher,
99
        EntityManager $entityManager,
100
        ConfigurationFactory $configurationFactory,
101
        ActionFactory $actionFactory,
102
        MessageHandlerInterface $messageHandler,
103
        Registry $registry,
104
        RequestFilterFactory $requestFilterFactory
105
    ) {
106 4
        $this->eventDispatcher = $eventDispatcher;
107 4
        $this->entityManager = $entityManager;
108 4
        $this->configurationFactory = $configurationFactory;
109 4
        $this->adminConfigurations = $adminConfigurations;
110 4
        $this->actionFactory = $actionFactory;
111 4
        $this->messageHandler = $messageHandler;
112 4
        $this->dataProviders = new ParameterBag();
113 4
        $this->registry = $registry;
114 4
        $this->requestFilterFactory = $requestFilterFactory;
115 4
    }
116
117
    /**
118
     * Create admins from configuration and load them into the pool. Dispatch ADMIN_CREATE event.
119
     */
120 2
    public function init()
121
    {
122
        // init only once
123 2
        if ($this->isInit) {
124 1
            return;
125
        }
126
        // dispatch an event to allow configuration modification before resolving and creating admins
127 2
        $event = new BeforeConfigurationEvent($this->adminConfigurations);
128 2
        $this
129
            ->eventDispatcher
130 2
            ->dispatch(AdminEvents::BEFORE_CONFIGURATION, $event);
131
132
        // get the modified configuration
133 2
        $this->adminConfigurations = $event->getAdminConfigurations();
134
135
        // create Admins according to the given configuration
136 2
        foreach ($this->adminConfigurations as $name => $configuration) {
137
138
            // dispatch an event to allow modification on a specific admin
139 1
            $event = new AdminCreateEvent($name, $configuration);
140 1
            $this
141
                ->eventDispatcher
142 1
                ->dispatch(AdminEvents::ADMIN_CREATE, $event);
143
144
            // create Admin object and add it to the registry
145 1
            $admin = $this->create($name, $event->getAdminConfiguration());
146 1
            $this
147
                ->registry
148 1
                ->add($admin);
149
150
            // dispatch post-create event
151 1
            $event = new AdminCreatedEvent($admin);
152 1
            $this
153
                ->eventDispatcher
154 1
                ->dispatch(AdminEvents::ADMIN_CREATED, $event);
155 2
        }
156 2
        $this->isInit = true;
157 2
    }
158
159
    /**
160
     * Create an Admin from configuration values. It will be added to AdminFactory admin's list.
161
     *
162
     * @param string $name
163
     * @param array $configuration
164
     * @return Admin
165
     * @throws Exception
166
     */
167 2
    public function create($name, array $configuration)
168
    {
169
        // create AdminConfiguration object
170 2
        $adminConfiguration = $this
171
            ->configurationFactory
172 2
            ->createAdminConfiguration($configuration);
173
174
        // retrieve a data provider
175 2
        $dataProvider = $this->getDataProvider(
176 2
            $adminConfiguration->getParameter('entity'),
177 2
            $adminConfiguration->getParameter('data_provider')
178 2
        );
179
180
        // retrieve a request filter
181 2
        $requestFilter = $this
182
            ->requestFilterFactory
183 2
            ->create($adminConfiguration);
184
185
        // create Admin object
186 2
        $admin = new Admin(
187 2
            $name,
188 2
            $dataProvider,
189 2
            $adminConfiguration,
190 2
            $this->messageHandler,
191 2
            $this->eventDispatcher,
192
            $requestFilter
193 2
        );
194
195
        // adding actions
196 2
        foreach ($adminConfiguration->getParameter('actions') as $actionName => $actionConfiguration) {
197
            // create action and add it to the admin instance
198 2
            $this->createAction($admin, $actionName, $actionConfiguration);
199 2
        }
200
201 2
        return $admin;
202
    }
203
204
    /**
205
     * Add user custom repositories (called in the repository compiler pass), to avoid injecting the service container
206
     *
207
     * @param string $name
208
     * @param DataProviderInterface $dataProvider
209
     */
210 1
    public function addDataProvider($name, DataProviderInterface $dataProvider)
211
    {
212 1
        $this
213
            ->dataProviders
214 1
            ->set($name, $dataProvider);
215 1
    }
216
217
    /**
218
     * @return boolean
219
     */
220
    public function isInit()
221
    {
222
        return $this->isInit;
223
    }
224
225
    /**
226
     * @return Registry
227
     */
228 3
    public function getRegistry()
229
    {
230 3
        return $this->registry;
231
    }
232
233
    /**
234
     * Create an Action from the configuration, and add it to the Admin.
235
     *
236
     * @param AdminInterface $admin
237
     * @param $actionName
238
     * @param array $actionConfiguration
239
     */
240 2
    protected function createAction(AdminInterface $admin, $actionName, array $actionConfiguration)
241
    {
242
        // creating action from configuration
243 2
        $action = $this
244
            ->actionFactory
245 2
            ->create($actionName, $actionConfiguration, $admin);
246
247
        // adding action to admin
248 2
        $admin->addAction($action);
249 2
    }
250
251
    /**
252
     * Return a configured data provider or create an new instance of the default one.
253
     *
254
     * @param string $entityClass
255
     * @param string|null $name
256
     * @return DataProvider|mixed
257
     * @throws Exception
258
     */
259 2
    protected function getDataProvider($entityClass, $name = null)
260
    {
261
        // create or get repository according to the configuration
262 2
        if ($name) {
263
            // removing arobase if exists
264
            if (substr($name, 0, 1) == '@') {
265
                $name = substr($name, 1);
266
            }
267
268
            // custom data provider class must be loaded by the compiler pass
269
            if (!$this->dataProviders->has($name)) {
270
                throw new Exception(sprintf(
271
                    'Data provider %s not found. Did you add the @data_provider tag in your service ?',
272
                    $name
273
                ));
274
            }
275
            $dataProvider = $this
276
                ->dataProviders
277
                ->get($name);
278
        } else {
279
            // no data provider is configured, we create a new one
280 2
            $repository = $this
281
                ->entityManager
282 2
                ->getRepository($entityClass);
283
284 2
            if (!($repository instanceof RepositoryInterface)) {
285
                $repositoryClass = get_class($repository);
286
                throw new Exception("Repository {$repositoryClass} should implements ".RepositoryInterface::class);
287
            }
288 2
            $dataProvider = new DataProvider($repository);
289
        }
290 2
        return $dataProvider;
291
    }
292
293
}
294