Completed
Pull Request — dev (#50)
by Arnaud
02:58
created

AdminFactory::addDataProvider()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1.125

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 2
cts 4
cp 0.5
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 2
crap 1.125
1
<?php
2
3
namespace LAG\AdminBundle\Admin\Factory;
4
5
use Doctrine\ORM\EntityManager;
6
use LAG\AdminBundle\Action\ActionInterface;
7
use LAG\AdminBundle\Action\Factory\ActionFactory;
8
use LAG\AdminBundle\Admin\Admin;
9
use LAG\AdminBundle\Admin\Registry\Registry;
10
use LAG\AdminBundle\Configuration\Factory\ConfigurationFactory;
11
use LAG\AdminBundle\DataProvider\DataProvider;
12
use LAG\AdminBundle\DataProvider\DataProviderInterface;
13
use LAG\AdminBundle\Admin\Event\AdminEvent;
14
use LAG\AdminBundle\Admin\Event\AdminEvents;
15
use Exception;
16
use LAG\AdminBundle\Message\MessageHandlerInterface;
17
use LAG\AdminBundle\Repository\RepositoryInterface;
18
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
19
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
20
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
21
22
/**
23
 * AdminFactory.
24
 *
25
 * Create admin from configuration
26
 */
27
class AdminFactory
28
{
29
    /**
30
     * @var bool
31
     */
32
    protected $isInit = false;
33
34
    /**
35
     * @var EventDispatcherInterface
36
     */
37
    protected $eventDispatcher;
38
39
    /**
40
     * @var EntityManager
41
     */
42
    protected $entityManager;
43
44
    /**
45
     * @var ConfigurationFactory
46
     */
47
    protected $configurationFactory;
48
49
    /**
50
     * User custom data provider, indexed by service id
51
     *
52
     * @var ParameterBagInterface
53
     */
54
    protected $dataProviders;
55
56
    /**
57
     * @var array
58
     */
59
    protected $adminConfigurations;
60
61
    /**
62
     * @var ActionFactory
63
     */
64
    protected $actionFactory;
65
66
    /**
67
     * @var MessageHandlerInterface
68
     */
69
    protected $messageHandler;
70
71
    /**
72
     * @var Registry
73
     */
74
    protected $registry;
75
76
    /**
77
     * AdminFactory constructor.
78
     *
79
     * @param array $adminConfigurations
80
     * @param EventDispatcherInterface $eventDispatcher
81
     * @param EntityManager $entityManager
82
     * @param ConfigurationFactory $configurationFactory
83
     * @param ActionFactory $actionFactory
84
     * @param MessageHandlerInterface $messageHandler
85
     * @param Registry $registry
86
     */
87 9
    public function __construct(
88
        array $adminConfigurations,
89
        EventDispatcherInterface $eventDispatcher,
90
        EntityManager $entityManager,
91
        ConfigurationFactory $configurationFactory,
92
        ActionFactory $actionFactory,
93
        MessageHandlerInterface $messageHandler,
94
        Registry $registry
95 9
    ) {
96 9
        $this->eventDispatcher = $eventDispatcher;
97 9
        $this->entityManager = $entityManager;
98 9
        $this->configurationFactory = $configurationFactory;
99 9
        $this->adminConfigurations = $adminConfigurations;
100 9
        $this->actionFactory = $actionFactory;
101 9
        $this->messageHandler = $messageHandler;
102 9
        $this->dataProviders = new ParameterBag();
103
        $this->registry = $registry;
104
    }
105
106
    /**
107 5
     * Create admins from configuration and load them into the pool. Dispatch ADMIN_CREATE event.
108
     */
109
    public function init()
110 5
    {
111 1
        // init only once
112
        if ($this->isInit) {
113
            return;
114 5
        }
115
        // dispatch an event to allow configuration modification before resolving and creating admins
116 5
        $event = $this->dispatchEvent(
0 ignored issues
show
Bug introduced by
The call to dispatchEvent() misses a required argument $configuration.

This check looks for function calls that miss required arguments.

Loading history...
117
            AdminEvents::BEFORE_CONFIGURATION
118
        );
119 5
120
        // get back the modified configuration
121
        $this->adminConfigurations = $event->getAdminsConfiguration();
122 5
123
        // create Admins according to the given configuration
124
        foreach ($this->adminConfigurations as $name => $configuration) {
125 4
126 4
            // dispatch an event to allow modification on a specific admin
127 4
            $event = $this->dispatchEvent(
128
                AdminEvents::ADMIN_CREATE,
129 4
                $name,
0 ignored issues
show
Documentation introduced by
$name is of type integer|string, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
130
                $configuration
0 ignored issues
show
Unused Code introduced by
The call to AdminFactory::dispatchEvent() has too many arguments starting with $configuration.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
131
            );
132 4
133
            // create Admin object and add it to the registry
134
            $this
135 4
                ->registry
136
                ->add($this->create($name, $event->getConfiguration()));
0 ignored issues
show
Bug introduced by
The method getConfiguration() does not seem to exist on object<LAG\AdminBundle\Admin\Event\AdminEvent>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
137 4
138 5
            // dispatch post-create event
139 5
            $this
140 5
                ->eventDispatcher
141
                ->dispatch(AdminEvents::ADMIN_CREATED, $event);
142
        }
143
        $this->isInit = true;
144
    }
145
146
    /**
147
     * Create an Admin from configuration values. It will be added to AdminFactory admin's list.
148
     *
149
     * @param string $name
150 5
     * @param array $configuration
151
     * @return Admin
152
     * @throws Exception
153 5
     */
154
    public function create($name, array $configuration)
155 5
    {
156
        // create AdminConfiguration object
157
        $adminConfiguration = $this
158 5
            ->configurationFactory
159 5
            ->createAdminConfiguration($configuration);
160 5
161 5
        // retrieve a data provider
162
        $dataProvider = $this->getDataProvider(
163
            $adminConfiguration->getParameter('entity'),
164 5
            $adminConfiguration->getParameter('data_provider')
165 5
        );
166 5
167 5
        // create Admin object
168 5
        $admin = new Admin(
169 5
            $name,
170 5
            $dataProvider,
171
            $adminConfiguration,
172
            $this->messageHandler,
173 5
            $this->eventDispatcher
174
        );
175 5
176 5
        // adding actions
177
        foreach ($adminConfiguration->getParameter('actions') as $actionName => $actionConfiguration) {
178 5
            // create action and add it to the admin instance
179
            $this->createAction($admin, $actionName, $actionConfiguration);
0 ignored issues
show
Bug introduced by
The method createAction() does not exist on LAG\AdminBundle\Admin\Factory\AdminFactory. Did you maybe mean create()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
180
        }
181
182
        return $admin;
183
    }
184
185
    /**
186
     * Add user custom repositories (called in the repository compiler pass), to avoid injecting the service container
187
     *
188 1
     * @param string $name
189
     * @param DataProviderInterface $dataProvider
190 1
     */
191
    public function addDataProvider($name, DataProviderInterface $dataProvider)
192 1
    {
193
        $this
194
            ->dataProviders
195 1
            ->set($name, $dataProvider);
196
    }
197
198 1
    /**
199
     * Return a configured data provider or create an new instance of the default one.
200
     *
201 1
     * @param string $entityClass
202
     * @param string|null $name
203 1
     * @return DataProvider|mixed
204
     * @throws Exception
205
     */
206
    protected function getDataProvider($entityClass, $name = null)
207
    {
208
        // create or get repository according to the configuration
209
        if ($name) {
210
            // removing arobase if exists
211
            if (substr($name, 0, 1) == '@') {
212
                $name = substr($name, 1);
213 5
            }
214
215 5
            // custom data provider class must be loaded by the compiler pass
216 3
            if (!$this->dataProviders->has($name)) {
217
                throw new Exception(sprintf(
218
                    'Data provider %s not found. Did you add the @data_provider tag in your service ?',
219 3
                    $name
220
                ));
221
            }
222
            $dataProvider = $this
223
                ->dataProviders
224
                ->get($name);
225
        } else {
226
            // no data provider is configured, we create a new one
227 2
            $repository = $this
228
                ->entityManager
229 2
                ->getRepository($entityClass);
230
231
            if (!($repository instanceof RepositoryInterface)) {
232
                $repositoryClass = get_class($repository);
233
                throw new Exception("Repository {$repositoryClass} should implements ".RepositoryInterface::class);
234
            }
235
236
            $dataProvider = new DataProvider($repository);
237
        }
238 1
        return $dataProvider;
239
    }
240 1
241
    /**
242 1
     * @return boolean
243 1
     */
244
    public function isInit()
245
    {
246
        return $this->isInit;
247
    }
248
249
    /**
250
     * @return Registry
251
     */
252
    public function getRegistry()
253 5
    {
254
        return $this->registry;
255
    }
256 5
257
    /**
258
     * Dispatch an AdminEvent to allow configuration override.
259
     *
260
     * @param $name
261
     * @param array $configuration
262
     * @return AdminEvent
263
     */
264
    protected function dispatchEvent($name, array $configuration)
265
    {
266
        $event = new AdminEvent();
267
        $event
0 ignored issues
show
Bug introduced by
The method setConfiguration() does not seem to exist on object<LAG\AdminBundle\Admin\Event\AdminEvent>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
268
            ->setConfiguration($configuration)
269
            ->setAdminName($name);
270
        $this
271
            ->eventDispatcher
272
            ->dispatch(AdminEvent::ADMIN_CREATE, $event);
273
274 5
        return $event;
275
    }
276
}
277