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 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 = array(); |
||
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 = array(); |
||
115 | View Code Duplication | foreach ($types as $classname => $ids) { |
|
116 | $result = $this->em->getRepository($classname)->findBy(array('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 | /** |
||
144 | * @param Request $request |
||
145 | */ |
||
146 | public function preBindRequest(Request $request) |
||
147 | { |
||
148 | // Fetch all sub-entities that should be removed |
||
149 | $subPagePartsToDelete = array(); |
||
150 | foreach (array_keys($request->request->all()) as $key) { |
||
151 | // Example value: delete_pagepartadmin_74_tags_3 |
||
152 | if (preg_match('/^delete_pagepartadmin_(\\d+)_(\\w+)_(\\d+)$/i', $key, $matches)) { |
||
153 | $subPagePartsToDelete[$matches[1]][] = array('name' => $matches[2], 'id' => $matches[3]); |
||
154 | } |
||
155 | } |
||
156 | |||
157 | $doFlush = false; |
||
158 | foreach ($this->pagePartRefs as $pagePartRef) { |
||
159 | // Remove pageparts |
||
160 | if ('true' == $request->get($pagePartRef->getId().'_deleted')) { |
||
161 | $pagePart = $this->pageParts[$pagePartRef->getId()]; |
||
162 | $this->em->remove($pagePart); |
||
163 | $this->em->remove($pagePartRef); |
||
164 | |||
165 | unset($this->pageParts[$pagePartRef->getId()], $this->pagePartRefs[$pagePartRef->getId()]); |
||
166 | $doFlush = true; |
||
167 | } |
||
168 | |||
169 | // Remove sub-entities from pageparts |
||
170 | if (\array_key_exists($pagePartRef->getId(), $subPagePartsToDelete)) { |
||
171 | $pagePart = $this->pageParts[$pagePartRef->getId()]; |
||
172 | foreach ($subPagePartsToDelete[$pagePartRef->getId()] as $deleteInfo) { |
||
173 | /** @var EntityInterface[] $objects */ |
||
174 | $objects = \call_user_func(array($pagePart, 'get'.ucfirst($deleteInfo['name']))); |
||
175 | |||
176 | foreach ($objects as $object) { |
||
177 | if ($object->getId() == $deleteInfo['id']) { |
||
178 | $this->em->remove($object); |
||
179 | $doFlush = true; |
||
180 | } |
||
181 | } |
||
182 | } |
||
183 | } |
||
184 | } |
||
185 | |||
186 | if ($doFlush) { |
||
187 | $this->em->flush(); |
||
188 | } |
||
189 | |||
190 | // Create the objects for the new pageparts |
||
191 | $this->newPageParts = array(); |
||
192 | $newRefIds = $request->get($this->context.'_new'); |
||
193 | |||
194 | if (\is_array($newRefIds)) { |
||
195 | foreach ($newRefIds as $newId) { |
||
196 | $type = $request->get($this->context.'_type_'.$newId); |
||
197 | $this->newPageParts[$newId] = new $type(); |
||
198 | } |
||
199 | } |
||
200 | |||
201 | // Sort pageparts again |
||
202 | $sequences = $request->get($this->context.'_sequence'); |
||
203 | if (!\is_null($sequences)) { |
||
204 | $tempPageparts = $this->pageParts; |
||
205 | $this->pageParts = array(); |
||
206 | foreach ($sequences as $sequence) { |
||
207 | if (\array_key_exists($sequence, $this->newPageParts)) { |
||
208 | $this->pageParts[$sequence] = $this->newPageParts[$sequence]; |
||
209 | } elseif (\array_key_exists($sequence, $tempPageparts)) { |
||
210 | $this->pageParts[$sequence] = $tempPageparts[$sequence]; |
||
211 | } else { |
||
212 | $this->pageParts[$sequence] = $this->getPagePart($sequence, array_search($sequence, $sequences) + 1); |
||
213 | } |
||
214 | } |
||
215 | |||
216 | unset($tempPageparts); |
||
217 | } |
||
218 | } |
||
219 | |||
220 | /** |
||
221 | * @param Request $request |
||
222 | */ |
||
223 | public function bindRequest(Request $request) |
||
224 | { |
||
225 | } |
||
226 | |||
227 | /** |
||
228 | * @param FormBuilderInterface $formbuilder |
||
229 | */ |
||
230 | public function adaptForm(FormBuilderInterface $formbuilder) |
||
231 | { |
||
232 | $data = $formbuilder->getData(); |
||
233 | |||
234 | foreach ($this->pageParts as $pagePartRefId => $pagePart) { |
||
235 | $data['pagepartadmin_' . $pagePartRefId] = $pagePart; |
||
236 | $formbuilder->add('pagepartadmin_' . $pagePartRefId, $pagePart->getDefaultAdminType()); |
||
237 | } |
||
238 | |||
239 | foreach ($this->newPageParts as $newPagePartRefId => $newPagePart) { |
||
240 | $data['pagepartadmin_' . $newPagePartRefId] = $newPagePart; |
||
241 | $formbuilder->add('pagepartadmin_' . $newPagePartRefId, $newPagePart->getDefaultAdminType()); |
||
242 | } |
||
243 | |||
244 | $formbuilder->setData($data); |
||
245 | } |
||
246 | |||
247 | /** |
||
248 | * @param Request $request |
||
249 | */ |
||
250 | public function persist(Request $request) |
||
251 | { |
||
252 | /** @var PagePartRefRepository $ppRefRepo */ |
||
253 | $ppRefRepo = $this->em->getRepository(PagePartRef::class); |
||
254 | |||
255 | // Add new pageparts on the correct position + Re-order and save pageparts if needed |
||
256 | $sequences = $request->get($this->context.'_sequence', []); |
||
257 | $sequencescount = \count($sequences); |
||
258 | for ($i = 0; $i < $sequencescount; ++$i) { |
||
259 | $pagePartRefId = $sequences[$i]; |
||
260 | |||
261 | if (\array_key_exists($pagePartRefId, $this->newPageParts)) { |
||
262 | $pagePart = $this->newPageParts[$pagePartRefId]; |
||
263 | $this->em->persist($pagePart); |
||
264 | $this->em->flush($pagePart); |
||
0 ignored issues
–
show
|
|||
265 | |||
266 | $ppRefRepo->addPagePart($this->page, $pagePart, $i + 1, $this->context, false); |
||
267 | } elseif (\array_key_exists($pagePartRefId, $this->pagePartRefs)) { |
||
268 | $pagePartRef = $this->pagePartRefs[$pagePartRefId]; |
||
269 | if ($pagePartRef instanceof PagePartRef && $pagePartRef->getSequencenumber() != ($i + 1)) { |
||
270 | $pagePartRef->setSequencenumber($i + 1); |
||
271 | $pagePartRef->setContext($this->context); |
||
272 | $this->em->persist($pagePartRef); |
||
273 | } |
||
274 | $pagePart = $pagePartRef->getPagePart($this->em); |
||
0 ignored issues
–
show
It seems like
$this->em can also be of type object<Doctrine\ORM\EntityManagerInterface> ; however, Kunstmaan\PagePartBundle...ePartRef::getPagePart() does only seem to accept object<Doctrine\ORM\EntityManager> , maybe add an additional type check?
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check: /**
* @return array|string
*/
function returnsDifferentValues($x) {
if ($x) {
return 'foo';
}
return array();
}
$x = returnsDifferentValues($y);
if (is_array($x)) {
// $x is an array.
}
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.
Loading history...
|
|||
275 | } |
||
276 | |||
277 | if (isset($pagePart)) { |
||
278 | $this->container->get('event_dispatcher')->dispatch( |
||
279 | Events::POST_PERSIST, |
||
280 | new PagePartEvent($pagePart) |
||
281 | ); |
||
282 | } |
||
283 | } |
||
284 | } |
||
285 | |||
286 | /** |
||
287 | * @return string|null |
||
288 | */ |
||
289 | public function getContext() |
||
290 | { |
||
291 | return $this->context; |
||
292 | } |
||
293 | |||
294 | /** |
||
295 | * This getter returns an array holding info on page part types that can be added to the page. |
||
296 | * The types are filtererd here, based on the amount of page parts of a certain type that can be added to the page. |
||
297 | * |
||
298 | * @return array |
||
299 | */ |
||
300 | public function getPossiblePagePartTypes() |
||
301 | { |
||
302 | $possiblePPTypes = $this->configurator->getPossiblePagePartTypes(); |
||
303 | $result = array(); |
||
304 | |||
305 | // filter page part types that can only be added x times to the page context. |
||
306 | // to achieve this, provide a 'pagelimit' parameter when adding the pp type in your PagePartAdminConfiguration |
||
307 | if (!empty($possiblePPTypes)) { |
||
308 | foreach ($possiblePPTypes as $possibleTypeData) { |
||
309 | if (\array_key_exists('pagelimit', $possibleTypeData)) { |
||
310 | $pageLimit = $possibleTypeData['pagelimit']; |
||
311 | /** @var PagePartRefRepository $entityRepository */ |
||
312 | $entityRepository = $this->em->getRepository(PagePartRef::class); |
||
313 | $formPPCount = $entityRepository->countPagePartsOfType( |
||
314 | $this->page, |
||
315 | $possibleTypeData['class'], |
||
316 | $this->configurator->getContext() |
||
317 | ); |
||
318 | if ($formPPCount < $pageLimit) { |
||
319 | $result[] = $possibleTypeData; |
||
320 | } |
||
321 | } else { |
||
322 | $result[] = $possibleTypeData; |
||
323 | } |
||
324 | } |
||
325 | } |
||
326 | |||
327 | return $result; |
||
328 | } |
||
329 | |||
330 | /** |
||
331 | * @return string |
||
332 | */ |
||
333 | public function getName() |
||
334 | { |
||
335 | return $this->configurator->getName(); |
||
336 | } |
||
337 | |||
338 | /** |
||
339 | * @return array |
||
340 | */ |
||
341 | public function getPagePartMap() |
||
342 | { |
||
343 | return $this->pageParts; |
||
344 | } |
||
345 | |||
346 | /** |
||
347 | * @param PagePartInterface $pagepart |
||
348 | * |
||
349 | * @return string |
||
350 | */ |
||
351 | public function getType(PagePartInterface $pagepart) |
||
352 | { |
||
353 | $possiblePagePartTypes = $this->configurator->getPossiblePagePartTypes(); |
||
354 | foreach ($possiblePagePartTypes as &$pageparttype) { |
||
355 | if ($pageparttype['class'] == ClassLookup::getClass($pagepart)) { |
||
356 | return $pageparttype['name']; |
||
357 | } |
||
358 | } |
||
359 | |||
360 | return 'no name'; |
||
361 | } |
||
362 | |||
363 | /** |
||
364 | * @param int $id |
||
365 | * @param int $sequenceNumber |
||
366 | * |
||
367 | * @return PagePartInterface |
||
368 | */ |
||
369 | public function getPagePart($id, $sequenceNumber) |
||
370 | { |
||
371 | /** @var PagePartRefRepository $ppRefRepo */ |
||
372 | $ppRefRepo = $this->em->getRepository(PagePartRef::class); |
||
373 | |||
374 | return $ppRefRepo->getPagePart($id, $this->context, $sequenceNumber); |
||
375 | } |
||
376 | |||
377 | /** |
||
378 | * @param object $pagepart |
||
379 | * |
||
380 | * @return string |
||
381 | */ |
||
382 | public function getClassName($pagepart) |
||
383 | { |
||
384 | return \get_class($pagepart); |
||
385 | } |
||
386 | } |
||
387 |
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.