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

api-platform / core / 16705318661

03 Aug 2025 01:05PM UTC coverage: 0.0% (-21.9%) from 21.944%
16705318661

Pull #7317

github

web-flow
Merge 1ca8642ff into d06b1a0a0
Pull Request #7317: Fix/4372 skip null values in hal

0 of 14 new or added lines in 3 files covered. (0.0%)

11680 existing lines in 376 files now uncovered.

0 of 51817 relevant lines covered (0.0%)

0.0 hits per line

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

0.0
/src/Doctrine/Odm/PropertyHelperTrait.php
1
<?php
2

3
/*
4
 * This file is part of the API Platform project.
5
 *
6
 * (c) Kévin Dunglas <dunglas@gmail.com>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11

12
declare(strict_types=1);
13

14
namespace ApiPlatform\Doctrine\Odm;
15

16
use ApiPlatform\Metadata\Exception\InvalidArgumentException;
17
use Doctrine\ODM\MongoDB\Aggregation\Builder;
18
use Doctrine\ODM\MongoDB\Mapping\ClassMetadata as MongoDbOdmClassMetadata;
19
use Doctrine\ODM\MongoDB\Mapping\MappingException;
20
use Doctrine\Persistence\ManagerRegistry;
21
use Doctrine\Persistence\Mapping\ClassMetadata;
22

23
/**
24
 * Helper trait regarding a property in a MongoDB document using the resource metadata.
25
 *
26
 * @author Alan Poulain <contact@alanpoulain.eu>
27
 */
28
trait PropertyHelperTrait
29
{
30
    abstract protected function getManagerRegistry(): ?ManagerRegistry;
31

32
    /**
33
     * Splits the given property into parts.
34
     */
35
    abstract protected function splitPropertyParts(string $property, string $resourceClass): array;
36

37
    /**
38
     * Gets class metadata for the given resource.
39
     */
40
    protected function getClassMetadata(string $resourceClass): ClassMetadata
41
    {
42
        /**
43
         * @var ?ManagerRegistry $managerRegistry
44
         *
45
         * @phpstan-ignore varTag.nativeType (https://github.com/phpstan/phpstan/issues/9515)
46
         */
UNCOV
47
        $managerRegistry = $this->getManagerRegistry();
×
UNCOV
48
        $manager = $managerRegistry?->getManagerForClass($resourceClass);
×
49

UNCOV
50
        if ($manager) {
×
51
            return $manager->getClassMetadata($resourceClass);
×
52
        }
53

UNCOV
54
        return new MongoDbOdmClassMetadata($resourceClass);
×
55
    }
56

57
    /**
58
     * Adds the necessary lookups for a nested property.
59
     *
60
     * @throws InvalidArgumentException If property is not nested
61
     * @throws MappingException
62
     *
63
     * @return array An array where the first element is the $alias of the lookup,
64
     *               the second element is the $field name
65
     *               the third element is the $associations array
66
     */
67
    protected function addLookupsForNestedProperty(string $property, Builder $aggregationBuilder, string $resourceClass, bool $preserveNullAndEmptyArrays = false): array
68
    {
69
        $propertyParts = $this->splitPropertyParts($property, $resourceClass);
×
70
        $alias = '';
×
71

72
        foreach ($propertyParts['associations'] as $association) {
×
73
            $classMetadata = $this->getClassMetadata($resourceClass);
×
74

75
            if (!$classMetadata instanceof MongoDbOdmClassMetadata) {
×
76
                break;
×
77
            }
78

79
            if ($classMetadata->hasReference($association)) {
×
80
                $propertyAlias = "{$association}_lkup";
×
81
                // previous_association_lkup.association
82
                $localField = "$alias$association";
×
83
                // previous_association_lkup.association_lkup
84
                $alias .= $propertyAlias;
×
85
                $referenceMapping = $classMetadata->getFieldMapping($association);
×
86

87
                if (($isOwningSide = $referenceMapping['isOwningSide']) && MongoDbOdmClassMetadata::REFERENCE_STORE_AS_ID !== $referenceMapping['storeAs']) {
×
88
                    throw MappingException::cannotLookupDbRefReference($classMetadata->getReflectionClass()->getShortName(), $association);
×
89
                }
90
                if (!$isOwningSide) {
×
91
                    if (isset($referenceMapping['repositoryMethod']) || !isset($referenceMapping['mappedBy'])) {
×
92
                        throw MappingException::repositoryMethodLookupNotAllowed($classMetadata->getReflectionClass()->getShortName(), $association);
×
93
                    }
94

95
                    $targetClassMetadata = $this->getClassMetadata($referenceMapping['targetDocument']);
×
96
                    if ($targetClassMetadata instanceof MongoDbOdmClassMetadata && MongoDbOdmClassMetadata::REFERENCE_STORE_AS_ID !== $targetClassMetadata->getFieldMapping($referenceMapping['mappedBy'])['storeAs']) {
×
97
                        throw MappingException::cannotLookupDbRefReference($classMetadata->getReflectionClass()->getShortName(), $association);
×
98
                    }
99
                }
100

101
                $aggregationBuilder->lookup($classMetadata->getAssociationTargetClass($association))
×
102
                    ->localField($isOwningSide ? $localField : '_id')
×
103
                    ->foreignField($isOwningSide ? '_id' : $referenceMapping['mappedBy'])
×
104
                    ->alias($alias);
×
105
                $aggregationBuilder->unwind("\$$alias")
×
106
                    ->preserveNullAndEmptyArrays($preserveNullAndEmptyArrays);
×
107

108
                // association.property => association_lkup.property
109
                $property = substr_replace($property, $propertyAlias, strpos($property, (string) $association), \strlen((string) $association));
×
110
                $resourceClass = $classMetadata->getAssociationTargetClass($association);
×
111
                $alias .= '.';
×
112
            } elseif ($classMetadata->hasEmbed($association)) {
×
113
                $alias = "$association.";
×
114
                $resourceClass = $classMetadata->getAssociationTargetClass($association);
×
115
            }
116
        }
117

118
        if ('' === $alias) {
×
119
            throw new InvalidArgumentException(\sprintf('Cannot add lookups for property "%s" - property is not nested.', $property));
×
120
        }
121

122
        return [$property, $propertyParts['field'], $propertyParts['associations']];
×
123
    }
124
}
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

© 2025 Coveralls, Inc