• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

FreezyBee / DoctrineFormMapper / 7776375984

04 Feb 2024 07:49PM UTC coverage: 95.726% (-0.4%) from 96.121%
7776375984

push

github

janatjak
doctrine 3

224 of 234 relevant lines covered (95.73%)

0.96 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.0
/src/Utils/RelationsHelper.php
1
<?php
2

3
declare(strict_types=1);
4

5
/*
6
 * This file is part of the some package.
7
 * (c) Jakub Janata <jakubjanata@gmail.com>
8
 * For the full copyright and license information, please view the LICENSE file.
9
 */
10

11
namespace FreezyBee\DoctrineFormMapper\Utils;
12

13
use Doctrine\ORM\EntityManagerInterface;
14
use Doctrine\ORM\Mapping\ClassMetadata;
15
use FreezyBee\DoctrineFormMapper\DoctrineFormMapper;
16
use FreezyBee\DoctrineFormMapper\Exceptions\InvalidStateException;
17
use FreezyBee\DoctrineFormMapper\IComponentMapper;
18
use LogicException;
19
use Nette\Forms\Controls\ChoiceControl;
20
use Nette\Forms\Controls\MultiChoiceControl;
21
use Stringable;
22
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
23

24
/**
25
 * @author Jakub Janata <jakubjanata@gmail.com>
26
 */
27
trait RelationsHelper
28
{
29
    protected EntityManagerInterface $em;
30

31
    protected PropertyAccessorInterface $accessor;
32

33
    public function __construct(DoctrineFormMapper $mapper)
34
    {
35
        $this->em = $mapper->getEntityManager();
1✔
36
        $this->accessor = $mapper->getAccessor();
1✔
37
    }
1✔
38

39
    /**
40
     * @param MultiChoiceControl|ChoiceControl $component
41
     * @param mixed $entity
42
     */
43
    public function setDefaultItems($component, $entity): void
44
    {
45
        if (count($component->getItems()) === 0) {
1✔
46
            $associationKeyOrCallback = $component->getOption(IComponentMapper::ITEMS_TITLE);
1✔
47

48
            if ($associationKeyOrCallback === null) {
1✔
49
                throw new InvalidStateException('Use IComponentMapper::ITEMS_TITLE to specify items title or callback');
1✔
50
            }
51

52
            $criteria = $component->getOption(IComponentMapper::ITEMS_FILTER) ?? [];
1✔
53
            $orderBy = $component->getOption(IComponentMapper::ITEMS_ORDER) ?? [];
1✔
54

55
            $name = $component->getName();
1✔
56
            if (!$name) {
1✔
57
                throw new InvalidStateException('Component name is null or blank');
×
58
            }
59

60
            $related = $this->relatedMetadata($entity, $name);
1✔
61
            $items = $this->findPairs($related, $associationKeyOrCallback, $criteria, $orderBy);
1✔
62
            $component->setItems($items);
1✔
63
        }
64
    }
1✔
65

66
    /**
67
     * @param mixed $entity
68
     * @return ClassMetadata<object>
69
     */
70
    protected function relatedMetadata($entity, string $relationName): ClassMetadata
71
    {
72
        $className = get_class($entity);
1✔
73
        assert(is_string($className));
74

75
        $meta = $this->em->getClassMetadata($className);
1✔
76
        /** @var class-string $targetClass */
77
        $targetClass = $meta->getAssociationTargetClass($relationName);
1✔
78
        return $this->em->getClassMetadata($targetClass);
1✔
79
    }
80

81
    /**
82
     * @param ClassMetadata<object> $meta
83
     * @param callable|string $associationKeyOrCallback
84
     * @param array<string, mixed>|callable $criteria
85
     * @param array<string, 'ASC'|'asc'|'DESC'|'desc'> $orderBy
86
     * @return mixed[]
87
     */
88
    protected function findPairs(ClassMetadata $meta, $associationKeyOrCallback, $criteria, array $orderBy): array
89
    {
90
        $classname = $meta->getName();
1✔
91
        if (!class_exists($classname)) {
1✔
92
            throw new LogicException();
×
93
        }
94

95
        $items = [];
1✔
96
        $idKey = $meta->getSingleIdentifierFieldName();
1✔
97

98
        if (is_callable($criteria)) {
1✔
99
            $qb = $this->em->createQueryBuilder()
1✔
100
                ->select('entity')
1✔
101
                ->from($classname, 'entity');
1✔
102

103
            // call user func
104
            $criteria($qb);
1✔
105

106
            $entities = $qb->getQuery()->getResult();
1✔
107
        } else {
108
            $entities = $this->em->getRepository($classname)->findBy($criteria, $orderBy);
1✔
109
        }
110

111
        foreach ($entities as $entity) {
1✔
112
            $identifier = $this->accessor->getValue($entity, $idKey);
1✔
113
            if (is_object($identifier) && $identifier instanceof Stringable) {
1✔
114
                // support for UuidInterface
115
                $identifier = (string) $identifier;
1✔
116
            }
117

118
            $items[$identifier] = is_callable($associationKeyOrCallback) ?
1✔
119
                $associationKeyOrCallback($entity) :
1✔
120
                $this->accessor->getValue($entity, $associationKeyOrCallback);
1✔
121
        }
122

123
        return $items;
1✔
124
    }
125
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc