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

api-platform / core / 3904303394

pending completion
3904303394

Pull #5332

github

GitHub
Merge 2e0a3ceae into 965332bc8
Pull Request #5332: Revert "chore(deprecation): Only use ValueResolverInterface if it exists"

2 of 2 new or added lines in 1 file covered. (100.0%)

7939 of 12085 relevant lines covered (65.69%)

81.77 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\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\Mapping\ClassMetadata;
21

22
/**
23
 * Helper trait regarding a property in a MongoDB document using the resource metadata.
24
 *
25
 * @author Alan Poulain <contact@alanpoulain.eu>
26
 */
27
trait PropertyHelperTrait
28
{
29
    /**
30
     * Splits the given property into parts.
31
     */
32
    abstract protected function splitPropertyParts(string $property, string $resourceClass): array;
33

34
    /**
35
     * Gets class metadata for the given resource.
36
     */
37
    abstract protected function getClassMetadata(string $resourceClass): ClassMetadata;
38

39
    /**
40
     * Adds the necessary lookups for a nested property.
41
     *
42
     * @throws InvalidArgumentException If property is not nested
43
     * @throws MappingException
44
     *
45
     * @return array An array where the first element is the $alias of the lookup,
46
     *               the second element is the $field name
47
     *               the third element is the $associations array
48
     */
49
    protected function addLookupsForNestedProperty(string $property, Builder $aggregationBuilder, string $resourceClass): array
50
    {
51
        $propertyParts = $this->splitPropertyParts($property, $resourceClass);
×
52
        $alias = '';
×
53

54
        foreach ($propertyParts['associations'] as $association) {
×
55
            $classMetadata = $this->getClassMetadata($resourceClass);
×
56

57
            if (!$classMetadata instanceof MongoDbOdmClassMetadata) {
×
58
                break;
×
59
            }
60

61
            if ($classMetadata->hasReference($association)) {
×
62
                $propertyAlias = "{$association}_lkup";
×
63
                // previous_association_lkup.association
64
                $localField = "$alias$association";
×
65
                // previous_association_lkup.association_lkup
66
                $alias .= $propertyAlias;
×
67
                $referenceMapping = $classMetadata->getFieldMapping($association);
×
68

69
                if (($isOwningSide = $referenceMapping['isOwningSide']) && MongoDbOdmClassMetadata::REFERENCE_STORE_AS_ID !== $referenceMapping['storeAs']) {
×
70
                    throw MappingException::cannotLookupDbRefReference($classMetadata->getReflectionClass()->getShortName(), $association);
×
71
                }
72
                if (!$isOwningSide) {
×
73
                    if (isset($referenceMapping['repositoryMethod']) || !isset($referenceMapping['mappedBy'])) {
×
74
                        throw MappingException::repositoryMethodLookupNotAllowed($classMetadata->getReflectionClass()->getShortName(), $association);
×
75
                    }
76

77
                    $targetClassMetadata = $this->getClassMetadata($referenceMapping['targetDocument']);
×
78
                    if ($targetClassMetadata instanceof MongoDbOdmClassMetadata && MongoDbOdmClassMetadata::REFERENCE_STORE_AS_ID !== $targetClassMetadata->getFieldMapping($referenceMapping['mappedBy'])['storeAs']) {
×
79
                        throw MappingException::cannotLookupDbRefReference($classMetadata->getReflectionClass()->getShortName(), $association);
×
80
                    }
81
                }
82

83
                $aggregationBuilder->lookup($classMetadata->getAssociationTargetClass($association))
×
84
                    ->localField($isOwningSide ? $localField : '_id')
×
85
                    ->foreignField($isOwningSide ? '_id' : $referenceMapping['mappedBy'])
×
86
                    ->alias($alias);
×
87
                $aggregationBuilder->unwind("\$$alias");
×
88

89
                // association.property => association_lkup.property
90
                $property = substr_replace($property, $propertyAlias, strpos($property, (string) $association), \strlen((string) $association));
×
91
                $resourceClass = $classMetadata->getAssociationTargetClass($association);
×
92
                $alias .= '.';
×
93
            } elseif ($classMetadata->hasEmbed($association)) {
×
94
                $alias = "$association.";
×
95
                $resourceClass = $classMetadata->getAssociationTargetClass($association);
×
96
            }
97
        }
98

99
        if ('' === $alias) {
×
100
            throw new InvalidArgumentException(sprintf('Cannot add lookups for property "%s" - property is not nested.', $property));
×
101
        }
102

103
        return [$property, $propertyParts['field'], $propertyParts['associations']];
×
104
    }
105
}
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