Completed
Push — master ( 1de9b7...830752 )
by Kristof
38:46 queued 24:09
created

PagePartBundle/PagePartAdmin/PagePartAdmin.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Kunstmaan\PagePartBundle\PagePartAdmin;
4
5
use Doctrine\ORM\EntityManager;
6
use Doctrine\ORM\EntityManagerInterface;
7
use Kunstmaan\AdminBundle\Entity\EntityInterface;
8
use Kunstmaan\PagePartBundle\Entity\PagePartRef;
9
use Kunstmaan\PagePartBundle\Event\Events;
10
use Kunstmaan\PagePartBundle\Event\PagePartEvent;
11
use Kunstmaan\PagePartBundle\Helper\HasPagePartsInterface;
12
use Kunstmaan\PagePartBundle\Helper\PagePartInterface;
13
use Kunstmaan\PagePartBundle\Repository\PagePartRefRepository;
14
use Kunstmaan\UtilitiesBundle\Helper\ClassLookup;
15
use Symfony\Component\DependencyInjection\ContainerInterface;
16
use Symfony\Component\Form\FormBuilderInterface;
17
use Symfony\Component\HttpFoundation\Request;
18
19
/**
20
 * PagePartAdmin
21
 */
22
class PagePartAdmin
23
{
24
    /**
25
     * @var PagePartAdminConfiguratorInterface
26
     */
27
    protected $configurator;
28
29
    /**
30
     * @var EntityManager|EntityManagerInterface
31
     */
32
    protected $em;
33
34
    /**
35
     * @var HasPagePartsInterface
36
     */
37
    protected $page;
38
39
    /**
40
     * @var string
41
     */
42
    protected $context;
43
44
    /**
45
     * @var ContainerInterface
46
     */
47
    protected $container;
48
49
    /**
50
     * @var PagePartInterface[]
51
     */
52
    protected $pageParts = array();
53
54
    /**
55
     * @var PagePartRef[]
56
     */
57
    protected $pagePartRefs = array();
58
59
    /**
60
     * @var PagePartInterface[]
61
     */
62
    protected $newPageParts = array();
63
64
    /**
65
     * @param PagePartAdminConfiguratorInterface $configurator The configurator
66
     * @param EntityManagerInterface             $em           The entity manager
67
     * @param HasPagePartsInterface              $page         The page
68
     * @param null|string                        $context      The context
69
     * @param null|ContainerInterface            $container    The container
70
     *
71
     * @throws \InvalidArgumentException
72
     */
73
    public function __construct(PagePartAdminConfiguratorInterface $configurator, EntityManagerInterface $em, HasPagePartsInterface $page, $context = null, ContainerInterface $container = null)
74
    {
75
        if (!($page instanceof EntityInterface)) {
76
            throw new \InvalidArgumentException('Page must be an instance of EntityInterface.');
77
        }
78
79
        $this->configurator = $configurator;
80
        $this->em = $em;
81
        $this->page = $page;
82
        $this->container = $container;
83
84
        if ($context) {
85
            $this->context = $context;
86
        } else {
87
            if ($this->configurator->getContext()) {
88
                $this->context = $this->configurator->getContext();
89
            } else {
90
                $this->context = 'main';
91
            }
92
        }
93
94
        $this->initializePageParts();
95
    }
96
97
    /**
98
     * Get all pageparts from the database, and store them.
99
     */
100
    private function initializePageParts()
101
    {
102
        // Get all the pagepartrefs
103
        /** @var PagePartRefRepository $ppRefRepo */
104
        $ppRefRepo = $this->em->getRepository('KunstmaanPagePartBundle:PagePartRef');
105
        $ppRefs = $ppRefRepo->getPagePartRefs($this->page, $this->context);
106
107
        // Group pagepartrefs per type
108
        $types = array();
109
        foreach ($ppRefs as $pagePartRef) {
110
            $types[$pagePartRef->getPagePartEntityname()][] = $pagePartRef->getPagePartId();
111
            $this->pagePartRefs[$pagePartRef->getId()] = $pagePartRef;
112
        }
113
114
        // Fetch all the pageparts (only one query per pagepart type)
115
        /** @var EntityInterface[] $pageParts */
116
        $pageParts = array();
117 View Code Duplication
        foreach ($types as $classname => $ids) {
118
            $result = $this->em->getRepository($classname)->findBy(array('id' => $ids));
119
            $pageParts = array_merge($pageParts, $result);
120
        }
121
122
        // Link the pagepartref to the pagepart
123
        foreach ($this->pagePartRefs as $pagePartRef) {
124
            foreach ($pageParts as $key => $pagePart) {
125
                if (ClassLookup::getClass($pagePart) == $pagePartRef->getPagePartEntityname()
126
                    && $pagePart->getId() == $pagePartRef->getPagePartId()
127
                ) {
128
                    $this->pageParts[$pagePartRef->getId()] = $pagePart;
129
                    unset($pageParts[$key]);
130
131
                    break;
132
                }
133
            }
134
        }
135
    }
136
137
    /**
138
     * @return EntityInterface
139
     */
140
    public function getPage()
141
    {
142
        return $this->page;
143
    }
144
145
    /**
146
     * @param Request $request
147
     */
148
    public function preBindRequest(Request $request)
149
    {
150
        // Fetch all sub-entities that should be removed
151
        $subPagePartsToDelete = array();
152
        foreach (array_keys($request->request->all()) as $key) {
153
            // Example value: delete_pagepartadmin_74_tags_3
154
            if (preg_match('/^delete_pagepartadmin_(\\d+)_(\\w+)_(\\d+)$/i', $key, $matches)) {
155
                $subPagePartsToDelete[$matches[1]][] = array('name' => $matches[2], 'id' => $matches[3]);
156
            }
157
        }
158
159
        $doFlush = false;
160
        foreach ($this->pagePartRefs as $pagePartRef) {
161
            // Remove pageparts
162
            if ('true' == $request->get($pagePartRef->getId().'_deleted')) {
163
                $pagePart = $this->pageParts[$pagePartRef->getId()];
164
                $this->em->remove($pagePart);
165
                $this->em->remove($pagePartRef);
166
167
                unset($this->pageParts[$pagePartRef->getId()]);
168
                unset($this->pagePartRefs[$pagePartRef->getId()]);
169
                $doFlush = true;
170
            }
171
172
            // Remove sub-entities from pageparts
173
            if (array_key_exists($pagePartRef->getId(), $subPagePartsToDelete)) {
174
                $pagePart = $this->pageParts[$pagePartRef->getId()];
175
                foreach ($subPagePartsToDelete[$pagePartRef->getId()] as $deleteInfo) {
176
                    /** @var EntityInterface[] $objects */
177
                    $objects = call_user_func(array($pagePart, 'get'.ucfirst($deleteInfo['name'])));
178
179
                    foreach ($objects as $object) {
180
                        if ($object->getId() == $deleteInfo['id']) {
181
                            $this->em->remove($object);
182
                            $doFlush = true;
183
                        }
184
                    }
185
                }
186
            }
187
        }
188
189
        if ($doFlush) {
190
            $this->em->flush();
191
        }
192
193
        // Create the objects for the new pageparts
194
        $this->newPageParts = array();
195
        $newRefIds = $request->get($this->context.'_new');
196
197
        if (is_array($newRefIds)) {
198
            foreach ($newRefIds as $newId) {
199
                $type = $request->get($this->context.'_type_'.$newId);
200
                $this->newPageParts[$newId] = new $type();
201
            }
202
        }
203
204
        // Sort pageparts again
205
        $sequences = $request->get($this->context.'_sequence');
206
        if (!is_null($sequences)) {
207
            $tempPageparts = $this->pageParts;
208
            $this->pageParts = array();
209
            foreach ($sequences as $sequence) {
210
                if (array_key_exists($sequence, $this->newPageParts)) {
211
                    $this->pageParts[$sequence] = $this->newPageParts[$sequence];
212
                } elseif (array_key_exists($sequence, $tempPageparts)) {
213
                    $this->pageParts[$sequence] = $tempPageparts[$sequence];
214
                } else {
215
                    $this->pageParts[$sequence] = $this->getPagePart($sequence, array_search($sequence, $sequences) + 1);
216
                }
217
            }
218
219
            unset($tempPageparts);
220
        }
221
    }
222
223
    /**
224
     * @param Request $request
225
     */
226
    public function bindRequest(Request $request)
227
    {
228
    }
229
230
    /**
231
     * @param FormBuilderInterface $formbuilder
232
     */
233
    public function adaptForm(FormBuilderInterface $formbuilder)
234
    {
235
        $data = $formbuilder->getData();
236
237
        foreach ($this->pageParts as $pagePartRefId => $pagePart) {
238
            $data['pagepartadmin_' . $pagePartRefId] = $pagePart;
239
            $formbuilder->add('pagepartadmin_' . $pagePartRefId, $pagePart->getDefaultAdminType());
240
        }
241
242
        foreach ($this->newPageParts as $newPagePartRefId => $newPagePart) {
243
            $data['pagepartadmin_' . $newPagePartRefId] = $newPagePart;
244
            $formbuilder->add('pagepartadmin_' . $newPagePartRefId, $newPagePart->getDefaultAdminType());
245
        }
246
247
        $formbuilder->setData($data);
248
    }
249
250
    /**
251
     * @param Request $request
252
     */
253
    public function persist(Request $request)
254
    {
255
        /** @var PagePartRefRepository $ppRefRepo */
256
        $ppRefRepo = $this->em->getRepository('KunstmaanPagePartBundle:PagePartRef');
257
258
        // Add new pageparts on the correct position + Re-order and save pageparts if needed
259
        $sequences = $request->get($this->context.'_sequence', []);
260
        $sequencescount = count($sequences);
261
        for ($i = 0; $i < $sequencescount; ++$i) {
262
            $pagePartRefId = $sequences[$i];
263
264
            if (array_key_exists($pagePartRefId, $this->newPageParts)) {
265
                $pagePart = $this->newPageParts[$pagePartRefId];
266
                $this->em->persist($pagePart);
267
                $this->em->flush($pagePart);
0 ignored issues
show
The call to EntityManagerInterface::flush() has too many arguments starting with $pagePart.

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...
268
269
                $ppRefRepo->addPagePart($this->page, $pagePart, ($i + 1), $this->context, false);
270
            } elseif (array_key_exists($pagePartRefId, $this->pagePartRefs)) {
271
                $pagePartRef = $this->pagePartRefs[$pagePartRefId];
272
                if ($pagePartRef instanceof PagePartRef && $pagePartRef->getSequencenumber() != ($i + 1)) {
273
                    $pagePartRef->setSequencenumber($i + 1);
274
                    $pagePartRef->setContext($this->context);
275
                    $this->em->persist($pagePartRef);
276
                }
277
                $pagePart = $pagePartRef->getPagePart($this->em);
278
            }
279
280
            if (isset($pagePart)) {
281
                $this->container->get('event_dispatcher')->dispatch(
282
                    Events::POST_PERSIST,
283
                    new PagePartEvent($pagePart)
284
                );
285
            }
286
        }
287
    }
288
289
    /**
290
     * @return null|string
291
     */
292
    public function getContext()
293
    {
294
        return $this->context;
295
    }
296
297
    /**
298
     * This getter returns an array holding info on page part types that can be added to the page.
299
     * The types are filtererd here, based on the amount of page parts of a certain type that can be added to the page.
300
     *
301
     * @return array
302
     */
303
    public function getPossiblePagePartTypes()
304
    {
305
        $possiblePPTypes = $this->configurator->getPossiblePagePartTypes();
306
        $result = array();
307
308
        // filter page part types that can only be added x times to the page context.
309
        // to achieve this, provide a 'pagelimit' parameter when adding the pp type in your PagePartAdminConfiguration
310
        if (!empty($possiblePPTypes)) {
311
            foreach ($possiblePPTypes as $possibleTypeData) {
312
                if (array_key_exists('pagelimit', $possibleTypeData)) {
313
                    $pageLimit = $possibleTypeData['pagelimit'];
314
                    /** @var PagePartRefRepository $entityRepository */
315
                    $entityRepository = $this->em->getRepository('KunstmaanPagePartBundle:PagePartRef');
316
                    $formPPCount = $entityRepository->countPagePartsOfType(
317
                        $this->page,
318
                        $possibleTypeData['class'],
319
                        $this->configurator->getContext()
320
                    );
321
                    if ($formPPCount < $pageLimit) {
322
                        $result[] = $possibleTypeData;
323
                    }
324
                } else {
325
                    $result[] = $possibleTypeData;
326
                }
327
            }
328
        }
329
330
        return $result;
331
    }
332
333
    /**
334
     * @return string
335
     */
336
    public function getName()
337
    {
338
        return $this->configurator->getName();
339
    }
340
341
    /**
342
     * @return array
343
     */
344
    public function getPagePartMap()
345
    {
346
        return $this->pageParts;
347
    }
348
349
    /**
350
     * @param PagePartInterface $pagepart
351
     *
352
     * @return string
353
     */
354
    public function getType(PagePartInterface $pagepart)
355
    {
356
        $possiblePagePartTypes = $this->configurator->getPossiblePagePartTypes();
357
        foreach ($possiblePagePartTypes as &$pageparttype) {
358
            if ($pageparttype['class'] == ClassLookup::getClass($pagepart)) {
359
                return $pageparttype['name'];
360
            }
361
        }
362
363
        return 'no name';
364
    }
365
366
    /**
367
     * @param int $id
368
     * @param int $sequenceNumber
369
     *
370
     * @return PagePartInterface
371
     */
372
    public function getPagePart($id, $sequenceNumber)
373
    {
374
        /** @var PagePartRefRepository $ppRefRepo */
375
        $ppRefRepo = $this->em->getRepository('KunstmaanPagePartBundle:PagePartRef');
376
377
        return $ppRefRepo->getPagePart($id, $this->context, $sequenceNumber);
378
    }
379
380
    /**
381
     * @param object $pagepart
382
     *
383
     * @return string
384
     */
385
    public function getClassName($pagepart)
386
    {
387
        return get_class($pagepart);
388
    }
389
}
390