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 = []; |
||
53 | |||
54 | /** |
||
55 | * @var PagePartRef[] |
||
56 | */ |
||
57 | protected $pagePartRefs = []; |
||
58 | |||
59 | /** |
||
60 | * @var PagePartInterface[] |
||
61 | */ |
||
62 | protected $newPageParts = []; |
||
63 | |||
64 | /** |
||
65 | * @param PagePartAdminConfiguratorInterface $configurator The configurator |
||
66 | * @param EntityManagerInterface $em The entity manager |
||
67 | * @param HasPagePartsInterface $page The page |
||
68 | * @param string|null $context The context |
||
69 | * @param ContainerInterface|null $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 | } elseif ($this->configurator->getContext()) { |
||
87 | $this->context = $this->configurator->getContext(); |
||
88 | } else { |
||
89 | $this->context = 'main'; |
||
90 | } |
||
91 | |||
92 | $this->initializePageParts(); |
||
93 | } |
||
94 | |||
95 | /** |
||
96 | * Get all pageparts from the database, and store them. |
||
97 | */ |
||
98 | private function initializePageParts() |
||
99 | { |
||
100 | // Get all the pagepartrefs |
||
101 | /** @var PagePartRefRepository $ppRefRepo */ |
||
102 | $ppRefRepo = $this->em->getRepository(PagePartRef::class); |
||
103 | $ppRefs = $ppRefRepo->getPagePartRefs($this->page, $this->context); |
||
104 | |||
105 | // Group pagepartrefs per type |
||
106 | $types = []; |
||
107 | foreach ($ppRefs as $pagePartRef) { |
||
108 | $types[$pagePartRef->getPagePartEntityname()][] = $pagePartRef->getPagePartId(); |
||
109 | $this->pagePartRefs[$pagePartRef->getId()] = $pagePartRef; |
||
110 | } |
||
111 | |||
112 | // Fetch all the pageparts (only one query per pagepart type) |
||
113 | /** @var EntityInterface[] $pageParts */ |
||
114 | $pageParts = []; |
||
115 | View Code Duplication | foreach ($types as $classname => $ids) { |
|
0 ignored issues
–
show
|
|||
116 | $result = $this->em->getRepository($classname)->findBy(['id' => $ids]); |
||
117 | $pageParts = array_merge($pageParts, $result); |
||
118 | } |
||
119 | |||
120 | // Link the pagepartref to the pagepart |
||
121 | foreach ($this->pagePartRefs as $pagePartRef) { |
||
122 | foreach ($pageParts as $key => $pagePart) { |
||
123 | if (ClassLookup::getClass($pagePart) == $pagePartRef->getPagePartEntityname() |
||
124 | && $pagePart->getId() == $pagePartRef->getPagePartId() |
||
125 | ) { |
||
126 | $this->pageParts[$pagePartRef->getId()] = $pagePart; |
||
127 | unset($pageParts[$key]); |
||
128 | |||
129 | break; |
||
130 | } |
||
131 | } |
||
132 | } |
||
133 | } |
||
134 | |||
135 | /** |
||
136 | * @return EntityInterface |
||
137 | */ |
||
138 | public function getPage() |
||
139 | { |
||
140 | return $this->page; |
||
141 | } |
||
142 | |||
143 | public function preBindRequest(Request $request) |
||
144 | { |
||
145 | // Fetch all sub-entities that should be removed |
||
146 | $subPagePartsToDelete = []; |
||
147 | foreach (array_keys($request->request->all()) as $key) { |
||
148 | // Example value: delete_pagepartadmin_74_tags_3 |
||
149 | if (preg_match('/^delete_pagepartadmin_(\\d+)_(\\w+)_(\\d+)$/i', $key, $matches)) { |
||
150 | $subPagePartsToDelete[$matches[1]][] = ['name' => $matches[2], 'id' => $matches[3]]; |
||
151 | } |
||
152 | } |
||
153 | |||
154 | $doFlush = false; |
||
155 | foreach ($this->pagePartRefs as $pagePartRef) { |
||
156 | // Remove pageparts |
||
157 | if ('true' == $request->get($pagePartRef->getId() . '_deleted')) { |
||
158 | $pagePart = $this->pageParts[$pagePartRef->getId()]; |
||
159 | $this->em->remove($pagePart); |
||
160 | $this->em->remove($pagePartRef); |
||
161 | |||
162 | unset($this->pageParts[$pagePartRef->getId()], $this->pagePartRefs[$pagePartRef->getId()]); |
||
163 | $doFlush = true; |
||
164 | } |
||
165 | |||
166 | // Remove sub-entities from pageparts |
||
167 | if (\array_key_exists($pagePartRef->getId(), $subPagePartsToDelete)) { |
||
168 | $pagePart = $this->pageParts[$pagePartRef->getId()]; |
||
169 | foreach ($subPagePartsToDelete[$pagePartRef->getId()] as $deleteInfo) { |
||
170 | /** @var EntityInterface[] $objects */ |
||
171 | $objects = \call_user_func([$pagePart, 'get' . ucfirst($deleteInfo['name'])]); |
||
172 | |||
173 | foreach ($objects as $object) { |
||
174 | if ($object->getId() == $deleteInfo['id']) { |
||
175 | $this->em->remove($object); |
||
176 | $doFlush = true; |
||
177 | } |
||
178 | } |
||
179 | } |
||
180 | } |
||
181 | } |
||
182 | |||
183 | if ($doFlush) { |
||
184 | $this->em->flush(); |
||
185 | } |
||
186 | |||
187 | // Create the objects for the new pageparts |
||
188 | $this->newPageParts = []; |
||
189 | $newRefIds = $request->get($this->context . '_new'); |
||
190 | |||
191 | if (\is_array($newRefIds)) { |
||
192 | foreach ($newRefIds as $newId) { |
||
193 | $type = $request->get($this->context . '_type_' . $newId); |
||
194 | $this->newPageParts[$newId] = new $type(); |
||
195 | } |
||
196 | } |
||
197 | |||
198 | // Sort pageparts again |
||
199 | $sequences = $request->get($this->context . '_sequence'); |
||
200 | if (!\is_null($sequences)) { |
||
201 | $tempPageparts = $this->pageParts; |
||
202 | $this->pageParts = []; |
||
203 | foreach ($sequences as $sequence) { |
||
204 | if (\array_key_exists($sequence, $this->newPageParts)) { |
||
205 | $this->pageParts[$sequence] = $this->newPageParts[$sequence]; |
||
206 | } elseif (\array_key_exists($sequence, $tempPageparts)) { |
||
207 | $this->pageParts[$sequence] = $tempPageparts[$sequence]; |
||
208 | } else { |
||
209 | $this->pageParts[$sequence] = $this->getPagePart($sequence, array_search($sequence, $sequences) + 1); |
||
210 | } |
||
211 | } |
||
212 | |||
213 | unset($tempPageparts); |
||
214 | } |
||
215 | } |
||
216 | |||
217 | public function bindRequest(Request $request) |
||
218 | { |
||
219 | } |
||
220 | |||
221 | public function adaptForm(FormBuilderInterface $formbuilder) |
||
222 | { |
||
223 | $data = $formbuilder->getData(); |
||
224 | |||
225 | foreach ($this->pageParts as $pagePartRefId => $pagePart) { |
||
226 | $data['pagepartadmin_' . $pagePartRefId] = $pagePart; |
||
227 | $formbuilder->add('pagepartadmin_' . $pagePartRefId, $pagePart->getDefaultAdminType()); |
||
228 | } |
||
229 | |||
230 | foreach ($this->newPageParts as $newPagePartRefId => $newPagePart) { |
||
231 | $data['pagepartadmin_' . $newPagePartRefId] = $newPagePart; |
||
232 | $formbuilder->add('pagepartadmin_' . $newPagePartRefId, $newPagePart->getDefaultAdminType()); |
||
233 | } |
||
234 | |||
235 | $formbuilder->setData($data); |
||
236 | } |
||
237 | |||
238 | public function persist(Request $request) |
||
239 | { |
||
240 | /** @var PagePartRefRepository $ppRefRepo */ |
||
241 | $ppRefRepo = $this->em->getRepository(PagePartRef::class); |
||
242 | |||
243 | // Add new pageparts on the correct position + Re-order and save pageparts if needed |
||
244 | $sequences = $request->get($this->context . '_sequence', []); |
||
245 | $sequencescount = \count($sequences); |
||
246 | for ($i = 0; $i < $sequencescount; ++$i) { |
||
247 | $pagePartRefId = $sequences[$i]; |
||
248 | |||
249 | if (\array_key_exists($pagePartRefId, $this->newPageParts)) { |
||
250 | $pagePart = $this->newPageParts[$pagePartRefId]; |
||
251 | $this->em->persist($pagePart); |
||
252 | $this->em->flush($pagePart); |
||
253 | |||
254 | $ppRefRepo->addPagePart($this->page, $pagePart, $i + 1, $this->context, false); |
||
255 | } elseif (\array_key_exists($pagePartRefId, $this->pagePartRefs)) { |
||
256 | $pagePartRef = $this->pagePartRefs[$pagePartRefId]; |
||
257 | if ($pagePartRef instanceof PagePartRef && $pagePartRef->getSequencenumber() != ($i + 1)) { |
||
258 | $pagePartRef->setSequencenumber($i + 1); |
||
259 | $pagePartRef->setContext($this->context); |
||
260 | $this->em->persist($pagePartRef); |
||
261 | } |
||
262 | $pagePart = $pagePartRef->getPagePart($this->em); |
||
263 | } |
||
264 | |||
265 | if (isset($pagePart)) { |
||
266 | $this->container->get('event_dispatcher')->dispatch( |
||
267 | Events::POST_PERSIST, |
||
268 | new PagePartEvent($pagePart) |
||
269 | ); |
||
270 | } |
||
271 | } |
||
272 | } |
||
273 | |||
274 | /** |
||
275 | * @return string|null |
||
276 | */ |
||
277 | public function getContext() |
||
278 | { |
||
279 | return $this->context; |
||
280 | } |
||
281 | |||
282 | /** |
||
283 | * This getter returns an array holding info on page part types that can be added to the page. |
||
284 | * The types are filtererd here, based on the amount of page parts of a certain type that can be added to the page. |
||
285 | * |
||
286 | * @return array |
||
287 | */ |
||
288 | public function getPossiblePagePartTypes() |
||
289 | { |
||
290 | $possiblePPTypes = $this->configurator->getPossiblePagePartTypes(); |
||
291 | $result = []; |
||
292 | |||
293 | // filter page part types that can only be added x times to the page context. |
||
294 | // to achieve this, provide a 'pagelimit' parameter when adding the pp type in your PagePartAdminConfiguration |
||
295 | if (!empty($possiblePPTypes)) { |
||
296 | foreach ($possiblePPTypes as $possibleTypeData) { |
||
297 | if (\array_key_exists('pagelimit', $possibleTypeData)) { |
||
298 | $pageLimit = $possibleTypeData['pagelimit']; |
||
299 | /** @var PagePartRefRepository $entityRepository */ |
||
300 | $entityRepository = $this->em->getRepository(PagePartRef::class); |
||
301 | $formPPCount = $entityRepository->countPagePartsOfType( |
||
302 | $this->page, |
||
303 | $possibleTypeData['class'], |
||
304 | $this->configurator->getContext() |
||
305 | ); |
||
306 | if ($formPPCount < $pageLimit) { |
||
307 | $result[] = $possibleTypeData; |
||
308 | } |
||
309 | } else { |
||
310 | $result[] = $possibleTypeData; |
||
311 | } |
||
312 | } |
||
313 | } |
||
314 | |||
315 | return $result; |
||
316 | } |
||
317 | |||
318 | /** |
||
319 | * @return string |
||
320 | */ |
||
321 | public function getName() |
||
322 | { |
||
323 | return $this->configurator->getName(); |
||
324 | } |
||
325 | |||
326 | /** |
||
327 | * @return array |
||
328 | */ |
||
329 | public function getPagePartMap() |
||
330 | { |
||
331 | return $this->pageParts; |
||
332 | } |
||
333 | |||
334 | /** |
||
335 | * @return string |
||
336 | */ |
||
337 | public function getType(PagePartInterface $pagepart) |
||
338 | { |
||
339 | $possiblePagePartTypes = $this->configurator->getPossiblePagePartTypes(); |
||
340 | foreach ($possiblePagePartTypes as &$pageparttype) { |
||
341 | if ($pageparttype['class'] == ClassLookup::getClass($pagepart)) { |
||
342 | return $pageparttype['name']; |
||
343 | } |
||
344 | } |
||
345 | |||
346 | return 'no name'; |
||
347 | } |
||
348 | |||
349 | /** |
||
350 | * @param int $id |
||
351 | * @param int $sequenceNumber |
||
352 | * |
||
353 | * @return PagePartInterface |
||
354 | */ |
||
355 | public function getPagePart($id, $sequenceNumber) |
||
356 | { |
||
357 | /** @var PagePartRefRepository $ppRefRepo */ |
||
358 | $ppRefRepo = $this->em->getRepository(PagePartRef::class); |
||
359 | |||
360 | return $ppRefRepo->getPagePart($id, $this->context, $sequenceNumber); |
||
361 | } |
||
362 | |||
363 | /** |
||
364 | * @param object $pagepart |
||
365 | * |
||
366 | * @return string |
||
367 | */ |
||
368 | public function getClassName($pagepart) |
||
369 | { |
||
370 | return \get_class($pagepart); |
||
371 | } |
||
372 | } |
||
373 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.