This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
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\NodeBundle\Repository; |
||
4 | |||
5 | use Gedmo\Tree\Entity\Repository\NestedTreeRepository; |
||
6 | use Kunstmaan\AdminBundle\Entity\BaseUser; |
||
7 | use Kunstmaan\AdminBundle\Helper\Security\Acl\AclHelper; |
||
8 | use Kunstmaan\AdminBundle\Helper\Security\Acl\AclNativeHelper; |
||
9 | use Kunstmaan\AdminBundle\Helper\Security\Acl\Permission\PermissionDefinition; |
||
10 | use Kunstmaan\NodeBundle\Entity\HasNodeInterface; |
||
11 | use Kunstmaan\NodeBundle\Entity\Node; |
||
12 | use Kunstmaan\NodeBundle\Entity\NodeTranslation; |
||
13 | use Kunstmaan\NodeBundle\Entity\NodeVersion; |
||
14 | use Kunstmaan\NodeBundle\Helper\HiddenFromNavInterface; |
||
15 | use Kunstmaan\UtilitiesBundle\Helper\ClassLookup; |
||
16 | |||
17 | /** |
||
18 | * NodeRepository |
||
19 | */ |
||
20 | class NodeRepository extends NestedTreeRepository |
||
21 | { |
||
22 | /** |
||
23 | * @param string $lang The locale |
||
24 | * @param string $permission The permission (read, write, ...) |
||
25 | * @param AclHelper $aclHelper The acl helper |
||
26 | * @param bool $includeHiddenFromNav include the hiddenfromnav nodes |
||
27 | * or not |
||
28 | * |
||
29 | * @return Node[] |
||
30 | */ |
||
31 | public function getTopNodes( |
||
32 | $lang, |
||
33 | $permission, |
||
34 | AclHelper $aclHelper, |
||
35 | $includeHiddenFromNav = false |
||
36 | ) { |
||
37 | $result = $this->getChildNodes( |
||
38 | null, |
||
39 | $lang, |
||
40 | $permission, |
||
41 | $aclHelper, |
||
42 | $includeHiddenFromNav |
||
43 | ); |
||
44 | |||
45 | return $result; |
||
46 | } |
||
47 | |||
48 | /** |
||
49 | * @param int|null $parentId The parent node id |
||
50 | * @param string $lang The locale |
||
51 | * @param string $permission The permission (read, write, ...) |
||
52 | * @param AclHelper $aclHelper The acl helper |
||
53 | * @param bool $includeHiddenFromNav Include nodes hidden from |
||
54 | * navigation or not |
||
55 | * @param Node $rootNode Root node of the current tree |
||
56 | * |
||
57 | * @return Node[] |
||
58 | */ |
||
59 | public function getChildNodes( |
||
60 | $parentId, |
||
61 | $lang, |
||
62 | $permission, |
||
63 | AclHelper $aclHelper, |
||
64 | $includeHiddenFromNav = false, |
||
65 | $includeHiddenWithInternalName = false, |
||
66 | $rootNode = null |
||
67 | ) { |
||
68 | $qb = $this->createQueryBuilder('b') |
||
69 | ->select('b', 't', 'v') |
||
70 | ->leftJoin('b.nodeTranslations', 't', 'WITH', 't.lang = :lang') |
||
71 | ->leftJoin( |
||
72 | 't.publicNodeVersion', |
||
73 | 'v', |
||
74 | 'WITH', |
||
75 | 't.publicNodeVersion = v.id' |
||
76 | ) |
||
77 | ->where('b.deleted = 0') |
||
78 | ->setParameter('lang', $lang) |
||
79 | ->addOrderBy('t.weight', 'ASC') |
||
80 | ->addOrderBy('t.title', 'ASC'); |
||
81 | |||
82 | if (!$includeHiddenFromNav) { |
||
83 | if ($includeHiddenWithInternalName) { |
||
84 | $qb->andWhere( |
||
85 | '(b.hiddenFromNav != true OR b.internalName IS NOT NULL)' |
||
86 | ); |
||
87 | } else { |
||
88 | $qb->andWhere('b.hiddenFromNav != true'); |
||
89 | } |
||
90 | } |
||
91 | |||
92 | View Code Duplication | if (\is_null($parentId)) { |
|
93 | $qb->andWhere('b.parent is NULL'); |
||
94 | } elseif ($parentId !== false) { |
||
95 | $qb->andWhere('b.parent = :parent') |
||
96 | ->setParameter('parent', $parentId); |
||
97 | } |
||
98 | if ($rootNode) { |
||
99 | $qb->andWhere('b.lft >= :left') |
||
100 | ->andWhere('b.rgt <= :right') |
||
101 | ->setParameter('left', $rootNode->getLeft()) |
||
102 | ->setParameter('right', $rootNode->getRight()); |
||
103 | } |
||
104 | |||
105 | $query = $aclHelper->apply( |
||
106 | $qb, |
||
107 | new PermissionDefinition(array($permission)) |
||
108 | ); |
||
109 | |||
110 | return $query->getResult(); |
||
111 | } |
||
112 | |||
113 | /** |
||
114 | * @param HasNodeInterface $hasNode |
||
115 | * |
||
116 | * @return Node|null |
||
117 | */ |
||
118 | public function getNodeFor(HasNodeInterface $hasNode) |
||
119 | { |
||
120 | /* @var NodeVersion $nodeVersion */ |
||
121 | $nodeVersion = $this->getEntityManager()->getRepository( |
||
122 | NodeVersion::class |
||
123 | )->getNodeVersionFor( |
||
124 | $hasNode |
||
125 | ); |
||
126 | if (!\is_null($nodeVersion)) { |
||
127 | /* @var NodeTranslation $nodeTranslation */ |
||
128 | $nodeTranslation = $nodeVersion->getNodeTranslation(); |
||
129 | if (!\is_null($nodeTranslation)) { |
||
130 | return $nodeTranslation->getNode(); |
||
131 | } |
||
132 | } |
||
133 | |||
134 | return null; |
||
135 | } |
||
136 | |||
137 | /** |
||
138 | * @param int $id The id |
||
139 | * @param string $entityName The class name |
||
140 | * |
||
141 | * @return Node|null |
||
142 | */ |
||
143 | public function getNodeForIdAndEntityname($id, $entityName) |
||
144 | { |
||
145 | /* @var NodeVersion $nodeVersion */ |
||
146 | $nodeVersion = $this->getEntityManager()->getRepository( |
||
147 | NodeVersion::class |
||
148 | )->findOneBy( |
||
149 | array('refId' => $id, 'refEntityName' => $entityName) |
||
150 | ); |
||
151 | if ($nodeVersion) { |
||
152 | return $nodeVersion->getNodeTranslation()->getNode(); |
||
153 | } |
||
154 | |||
155 | return null; |
||
156 | } |
||
157 | |||
158 | /** |
||
159 | * @param Node $parentNode The parent node (may be null) |
||
160 | * @param string $slug The slug |
||
161 | * |
||
162 | * @return Node|null |
||
163 | */ |
||
164 | public function getNodeForSlug(Node $parentNode, $slug) |
||
165 | { |
||
166 | $slugParts = explode('/', $slug); |
||
167 | $result = null; |
||
168 | foreach ($slugParts as $slugPart) { |
||
169 | if ($parentNode) { |
||
170 | if ($r = $this->findOneBy( |
||
171 | array( |
||
172 | 'slug' => $slugPart, |
||
173 | 'parent.parent' => $parentNode->getId(), |
||
174 | ) |
||
175 | ) |
||
176 | ) { |
||
177 | $result = $r; |
||
178 | } |
||
179 | } elseif ($r = $this->findOneBy(['slug' => $slugPart])) { |
||
180 | $result = $r; |
||
181 | } |
||
182 | } |
||
183 | |||
184 | return $result; |
||
185 | } |
||
186 | |||
187 | /** |
||
188 | * @param HasNodeInterface $hasNode The object to link to |
||
189 | * @param string $lang The locale |
||
190 | * @param BaseUser $owner The user |
||
191 | * @param string $internalName The internal name (may be null) |
||
192 | * |
||
193 | * @throws \InvalidArgumentException |
||
194 | * |
||
195 | * @return Node |
||
196 | */ |
||
197 | public function createNodeFor( |
||
198 | HasNodeInterface $hasNode, |
||
199 | $lang, |
||
200 | BaseUser $owner, |
||
201 | $internalName = null |
||
202 | ) { |
||
203 | $em = $this->getEntityManager(); |
||
204 | $node = new Node(); |
||
205 | $node->setRef($hasNode); |
||
206 | if (!$hasNode->getId() > 0) { |
||
207 | throw new \InvalidArgumentException('the entity of class '. $node->getRefEntityName().' has no id, maybe you forgot to flush first'); |
||
208 | } |
||
209 | $node->setDeleted(false); |
||
210 | $node->setInternalName($internalName); |
||
211 | $parent = $hasNode->getParent(); |
||
212 | if ($parent) { |
||
213 | /* @var NodeVersion $parentNodeVersion */ |
||
214 | $parentNodeVersion = $em->getRepository( |
||
215 | NodeVersion::class |
||
216 | )->findOneBy( |
||
217 | array( |
||
218 | 'refId' => $parent->getId(), |
||
219 | 'refEntityName' => ClassLookup::getClass($parent), |
||
220 | ) |
||
221 | ); |
||
222 | if ($parentNodeVersion) { |
||
223 | $node->setParent( |
||
224 | $parentNodeVersion->getNodeTranslation()->getNode() |
||
225 | ); |
||
226 | } |
||
227 | } |
||
228 | if ($hasNode instanceof HiddenFromNavInterface) { |
||
229 | $node->setHiddenFromNav($hasNode->isHiddenFromNav()); |
||
230 | } |
||
231 | $em->persist($node); |
||
232 | $em->flush(); |
||
233 | $em->refresh($node); |
||
234 | $em->getRepository(NodeTranslation::class) |
||
235 | ->createNodeTranslationFor( |
||
236 | $hasNode, |
||
237 | $lang, |
||
238 | $node, |
||
239 | $owner |
||
240 | ); |
||
241 | |||
242 | return $node; |
||
243 | } |
||
244 | |||
245 | /** |
||
246 | * Get all the information needed to build a menu tree with one query. |
||
247 | * We only fetch the fields we need, instead of fetching full objects to |
||
248 | * limit the memory usage. |
||
249 | * |
||
250 | * @param string $lang The locale |
||
251 | * @param string $permission The permission (read, |
||
252 | * write, ...) |
||
253 | * @param AclNativeHelper $aclNativeHelper The acl helper |
||
254 | * @param bool $includeHiddenFromNav Include nodes hidden from |
||
255 | * navigation or not |
||
256 | * @param Node $rootNode The root node of the |
||
257 | * current site |
||
258 | * |
||
259 | * @return array |
||
260 | */ |
||
261 | public function getAllMenuNodes( |
||
262 | $lang, |
||
263 | $permission, |
||
264 | AclNativeHelper $aclNativeHelper, |
||
265 | $includeHiddenFromNav = false, |
||
266 | Node $rootNode = null |
||
267 | ) { |
||
268 | $connection = $this->_em->getConnection(); |
||
269 | $qb = $connection->createQueryBuilder(); |
||
270 | $databasePlatformName = $connection->getDatabasePlatform()->getName(); |
||
271 | $createIfStatement = function ( |
||
272 | $expression, |
||
273 | $trueValue, |
||
274 | $falseValue |
||
275 | ) use ($databasePlatformName) { |
||
276 | switch ($databasePlatformName) { |
||
277 | case 'sqlite': |
||
278 | $statement = 'CASE WHEN %s THEN %s ELSE %s END'; |
||
279 | |||
280 | break; |
||
281 | |||
282 | default: |
||
283 | $statement = 'IF(%s, %s, %s)'; |
||
284 | } |
||
285 | |||
286 | return sprintf($statement, $expression, $trueValue, $falseValue); |
||
287 | }; |
||
288 | |||
289 | $sql = <<<SQL |
||
290 | n.id, n.parent_id AS parent, t.url, t.id AS nt_id, |
||
291 | {$createIfStatement('t.weight IS NULL', 'v.weight', 't.weight')} AS weight, |
||
292 | {$createIfStatement('t.title IS NULL', 'v.title', 't.title')} AS title, |
||
293 | {$createIfStatement('t.online IS NULL', '0', 't.online')} AS online, |
||
294 | n.hidden_from_nav AS hidden, |
||
295 | n.ref_entity_name AS ref_entity_name |
||
296 | SQL; |
||
297 | |||
298 | $qb->select($sql) |
||
299 | ->from('kuma_nodes', 'n') |
||
300 | ->leftJoin( |
||
301 | 'n', |
||
302 | 'kuma_node_translations', |
||
303 | 't', |
||
304 | '(t.node_id = n.id AND t.lang = :lang)' |
||
305 | ) |
||
306 | ->leftJoin( |
||
307 | 'n', |
||
308 | 'kuma_node_translations', |
||
309 | 'v', |
||
310 | '(v.node_id = n.id AND v.lang <> :lang)' |
||
311 | ) |
||
312 | ->where('n.deleted = 0') |
||
313 | ->addGroupBy('n.id') |
||
314 | ->addOrderBy('t.weight', 'ASC') |
||
315 | ->addOrderBy('t.title', 'ASC'); |
||
316 | |||
317 | if (!$includeHiddenFromNav) { |
||
318 | $qb->andWhere('n.hidden_from_nav <> 0'); |
||
319 | } |
||
320 | |||
321 | if (!\is_null($rootNode)) { |
||
322 | $qb->andWhere('n.lft >= :left') |
||
323 | ->andWhere('n.rgt <= :right'); |
||
324 | } |
||
325 | |||
326 | $permissionDef = new PermissionDefinition(array($permission)); |
||
327 | $permissionDef->setEntity('Kunstmaan\NodeBundle\Entity\Node'); |
||
328 | $permissionDef->setAlias('n'); |
||
329 | $qb = $aclNativeHelper->apply($qb, $permissionDef); |
||
330 | |||
331 | $stmt = $this->_em->getConnection()->prepare($qb->getSQL()); |
||
332 | $stmt->bindValue(':lang', $lang); |
||
333 | if (!\is_null($rootNode)) { |
||
334 | $stmt->bindValue(':left', $rootNode->getLeft()); |
||
335 | $stmt->bindValue(':right', $rootNode->getRight()); |
||
336 | } |
||
337 | $stmt->execute(); |
||
338 | |||
339 | return $stmt->fetchAll(); |
||
0 ignored issues
–
show
|
|||
340 | } |
||
341 | |||
342 | /** |
||
343 | * Get all parents of a given node. We can go multiple levels up. |
||
344 | * |
||
345 | * @param Node $node |
||
346 | * @param string $lang |
||
347 | * |
||
348 | * @return Node[] |
||
349 | */ |
||
350 | View Code Duplication | public function getAllParents(Node $node = null, $lang = null) |
|
351 | { |
||
352 | if (\is_null($node)) { |
||
353 | return array(); |
||
354 | } |
||
355 | |||
356 | $qb = $this->createQueryBuilder('node'); |
||
357 | |||
358 | // Directly hydrate the nodeTranslation and nodeVersion |
||
359 | $qb->select('node', 't', 'v') |
||
360 | ->innerJoin('node.nodeTranslations', 't') |
||
361 | ->leftJoin( |
||
362 | 't.publicNodeVersion', |
||
363 | 'v', |
||
364 | 'WITH', |
||
365 | 't.publicNodeVersion = v.id' |
||
366 | ) |
||
367 | ->where('node.deleted = 0'); |
||
368 | |||
369 | if ($lang) { |
||
370 | $qb->andWhere('t.lang = :lang') |
||
371 | ->setParameter('lang', $lang); |
||
372 | } |
||
373 | |||
374 | $qb->andWhere( |
||
375 | $qb->expr()->andX( |
||
376 | $qb->expr()->lte('node.lft', $node->getLeft()), |
||
377 | $qb->expr()->gte('node.rgt', $node->getRight()) |
||
378 | ) |
||
379 | ); |
||
380 | |||
381 | $qb->addOrderBy('node.lft', 'ASC'); |
||
382 | |||
383 | return $qb->getQuery()->getResult(); |
||
384 | } |
||
385 | |||
386 | /** |
||
387 | * Get the root node of a given node. |
||
388 | * |
||
389 | * @param Node $node |
||
390 | * @param string $lang |
||
391 | * |
||
392 | * @return Node |
||
393 | */ |
||
394 | View Code Duplication | public function getRootNodeFor(Node $node = null, $lang = null) |
|
395 | { |
||
396 | if (\is_null($node)) { |
||
397 | return null; |
||
398 | } |
||
399 | |||
400 | $qb = $this->createQueryBuilder('node'); |
||
401 | |||
402 | // Directly hydrate the nodeTranslation and nodeVersion |
||
403 | $qb->select('node', 't', 'v') |
||
404 | ->innerJoin('node.nodeTranslations', 't') |
||
405 | ->leftJoin( |
||
406 | 't.publicNodeVersion', |
||
407 | 'v', |
||
408 | 'WITH', |
||
409 | 't.publicNodeVersion = v.id' |
||
410 | ) |
||
411 | ->where('node.deleted = 0') |
||
412 | ->andWhere('node.parent IS NULL'); |
||
413 | |||
414 | if ($lang) { |
||
415 | $qb->andWhere('t.lang = :lang') |
||
416 | ->setParameter('lang', $lang); |
||
417 | } |
||
418 | |||
419 | $qb->andWhere( |
||
420 | $qb->expr()->andX( |
||
421 | $qb->expr()->lte('node.lft', $node->getLeft()), |
||
422 | $qb->expr()->gte('node.rgt', $node->getRight()) |
||
423 | ) |
||
424 | ); |
||
425 | |||
426 | return $qb->getQuery()->getOneOrNullResult(); |
||
427 | } |
||
428 | |||
429 | /** |
||
430 | * @return Node[] |
||
431 | */ |
||
432 | public function getAllTopNodes() |
||
433 | { |
||
434 | $qb = $this->createQueryBuilder('b') |
||
435 | ->select('b', 't', 'v') |
||
436 | ->leftJoin('b.nodeTranslations', 't') |
||
437 | ->leftJoin( |
||
438 | 't.publicNodeVersion', |
||
439 | 'v', |
||
440 | 'WITH', |
||
441 | 't.publicNodeVersion = v.id' |
||
442 | ) |
||
443 | ->where('b.deleted = 0') |
||
444 | ->andWhere('b.parent IS NULL'); |
||
445 | |||
446 | return $qb->getQuery()->getResult(); |
||
447 | } |
||
448 | |||
449 | /** |
||
450 | * Get an array of Nodes based on the internal name. |
||
451 | * |
||
452 | * @param string $internalName The internal name of the node |
||
453 | * @param string $lang The locale |
||
454 | * @param int|bool|null $parentId The parent id |
||
455 | * @param bool $includeOffline Include offline nodes |
||
456 | * |
||
457 | * @return Node[] |
||
458 | */ |
||
459 | public function getNodesByInternalName( |
||
460 | $internalName, |
||
461 | $lang, |
||
462 | $parentId = false, |
||
463 | $includeOffline = false |
||
464 | ) { |
||
465 | $qb = $this->createQueryBuilder('n') |
||
466 | ->select('n', 't', 'v') |
||
467 | ->innerJoin('n.nodeTranslations', 't') |
||
468 | ->leftJoin( |
||
469 | 't.publicNodeVersion', |
||
470 | 'v', |
||
471 | 'WITH', |
||
472 | 't.publicNodeVersion = v.id' |
||
473 | ) |
||
474 | ->where('n.deleted = 0') |
||
475 | ->andWhere('n.internalName = :internalName') |
||
476 | ->setParameter('internalName', $internalName) |
||
477 | ->andWhere('t.lang = :lang') |
||
478 | ->setParameter('lang', $lang) |
||
479 | ->addOrderBy('t.weight', 'ASC') |
||
480 | ->addOrderBy('t.title', 'ASC'); |
||
481 | |||
482 | if (!$includeOffline) { |
||
483 | $qb->andWhere('t.online = true'); |
||
484 | } |
||
485 | |||
486 | View Code Duplication | if (\is_null($parentId)) { |
|
487 | $qb->andWhere('n.parent is NULL'); |
||
488 | } elseif ($parentId === false) { |
||
489 | // Do nothing |
||
490 | } else { |
||
491 | $qb->andWhere('n.parent = :parent') |
||
492 | ->setParameter('parent', $parentId); |
||
493 | } |
||
494 | |||
495 | $query = $qb->getQuery(); |
||
496 | |||
497 | return $query->getResult(); |
||
498 | } |
||
499 | |||
500 | /** |
||
501 | * Get a single node by internal name. |
||
502 | * |
||
503 | * @param string $internalName The internal name of the node |
||
504 | * |
||
505 | * @return Node|null |
||
506 | */ |
||
507 | public function getNodeByInternalName($internalName) |
||
508 | { |
||
509 | $qb = $this->createQueryBuilder('n') |
||
510 | ->select('n') |
||
511 | ->where('n.deleted = 0') |
||
512 | ->andWhere('n.internalName = :internalName') |
||
513 | ->setParameter('internalName', $internalName); |
||
514 | |||
515 | return $qb->getQuery()->getOneOrNullResult(); |
||
516 | } |
||
517 | |||
518 | /** |
||
519 | * Finds all different page classes currently registered as nodes |
||
520 | * |
||
521 | * @return string[] |
||
522 | */ |
||
523 | public function findAllDistinctPageClasses() |
||
524 | { |
||
525 | $qb = $this->createQueryBuilder('n') |
||
526 | ->select('n.refEntityName') |
||
527 | ->where('n.deleted = 0') |
||
528 | ->distinct(true); |
||
529 | |||
530 | return $qb->getQuery()->getArrayResult(); |
||
531 | } |
||
532 | |||
533 | public function getChildCount(Node $node, bool $direct = false, bool $includeDeleted = false): int |
||
534 | { |
||
535 | $qb = $this->getChildrenQueryBuilder($node, $direct); |
||
536 | $qb->resetDQLPart('orderBy'); |
||
537 | |||
538 | $aliases = $qb->getRootAliases(); |
||
539 | $alias = $aliases[0]; |
||
540 | |||
541 | $qb->select('COUNT('.$alias.')'); |
||
542 | |||
543 | if (false === $includeDeleted) { |
||
544 | $qb->andWhere($alias.'.deleted = 0'); |
||
545 | } |
||
546 | |||
547 | return (int) $qb->getQuery()->getSingleScalarResult(); |
||
548 | } |
||
549 | } |
||
550 |
This method has been deprecated. The supplier of the class has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.