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

api-platform / core / 15133993414

20 May 2025 09:30AM UTC coverage: 26.313% (-1.2%) from 27.493%
15133993414

Pull #7161

github

web-flow
Merge e2c03d45f into 5459ba375
Pull Request #7161: fix(metadata): infer parameter string type from schema

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

11019 existing lines in 363 files now uncovered.

12898 of 49018 relevant lines covered (26.31%)

34.33 hits per line

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

96.97
/src/Doctrine/Common/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\Common;
15

16
use Doctrine\Persistence\Mapping\ClassMetadata;
17

18
/**
19
 * Helper trait for getting information regarding a property using the resource metadata.
20
 *
21
 * @author Kévin Dunglas <dunglas@gmail.com>
22
 * @author Théo FIDRY <theo.fidry@gmail.com>
23
 * @author Alan Poulain <contact@alanpoulain.eu>
24
 */
25
trait PropertyHelperTrait
26
{
27
    /**
28
     * Gets class metadata for the given resource.
29
     */
30
    abstract protected function getClassMetadata(string $resourceClass): ClassMetadata;
31

32
    /**
33
     * Determines whether the given property is mapped.
34
     */
35
    protected function isPropertyMapped(string $property, string $resourceClass, bool $allowAssociation = false): bool
36
    {
UNCOV
37
        if ($this->isPropertyNested($property, $resourceClass)) {
341✔
UNCOV
38
            $propertyParts = $this->splitPropertyParts($property, $resourceClass);
235✔
UNCOV
39
            $metadata = $this->getNestedMetadata($resourceClass, $propertyParts['associations']);
235✔
UNCOV
40
            $property = $propertyParts['field'];
235✔
41
        } else {
UNCOV
42
            $metadata = $this->getClassMetadata($resourceClass);
337✔
43
        }
44

UNCOV
45
        return $metadata->hasField($property) || ($allowAssociation && $metadata->hasAssociation($property));
341✔
46
    }
47

48
    /**
49
     * Determines whether the given property is nested.
50
     */
51
    protected function isPropertyNested(string $property, string $resourceClass): bool
52
    {
UNCOV
53
        $pos = strpos($property, '.');
345✔
UNCOV
54
        if (false === $pos) {
345✔
UNCOV
55
            return false;
340✔
56
        }
57

UNCOV
58
        return $this->getClassMetadata($resourceClass)->hasAssociation(substr($property, 0, $pos));
237✔
59
    }
60

61
    /**
62
     * Determines whether the given property is embedded.
63
     */
64
    protected function isPropertyEmbedded(string $property, string $resourceClass): bool
65
    {
66
        return str_contains($property, '.') && $this->getClassMetadata($resourceClass)->hasField($property);
×
67
    }
68

69
    /**
70
     * Splits the given property into parts.
71
     *
72
     * Returns an array with the following keys:
73
     *   - associations: array of associations according to nesting order
74
     *   - field: string holding the actual field (leaf node)
75
     */
76
    protected function splitPropertyParts(string $property, string $resourceClass): array
77
    {
UNCOV
78
        $parts = explode('.', $property);
305✔
79

UNCOV
80
        $metadata = $this->getClassMetadata($resourceClass);
305✔
UNCOV
81
        $slice = 0;
305✔
82

UNCOV
83
        foreach ($parts as $part) {
305✔
UNCOV
84
            if ($metadata->hasAssociation($part)) {
305✔
UNCOV
85
                $metadata = $this->getClassMetadata($metadata->getAssociationTargetClass($part));
236✔
UNCOV
86
                ++$slice;
236✔
87
            }
88
        }
89

UNCOV
90
        if (\count($parts) === $slice) {
305✔
UNCOV
91
            --$slice;
222✔
92
        }
93

UNCOV
94
        return [
305✔
UNCOV
95
            'associations' => \array_slice($parts, 0, $slice),
305✔
UNCOV
96
            'field' => implode('.', \array_slice($parts, $slice)),
305✔
UNCOV
97
        ];
305✔
98
    }
99

100
    /**
101
     * Gets the Doctrine Type of a given property/resourceClass.
102
     */
103
    protected function getDoctrineFieldType(string $property, string $resourceClass): ?string
104
    {
UNCOV
105
        $propertyParts = $this->splitPropertyParts($property, $resourceClass);
291✔
UNCOV
106
        $metadata = $this->getNestedMetadata($resourceClass, $propertyParts['associations']);
291✔
107

UNCOV
108
        return $metadata->getTypeOfField($propertyParts['field']);
291✔
109
    }
110

111
    /**
112
     * Gets nested class metadata for the given resource.
113
     *
114
     * @param string[] $associations
115
     */
116
    protected function getNestedMetadata(string $resourceClass, array $associations): ClassMetadata
117
    {
UNCOV
118
        $metadata = $this->getClassMetadata($resourceClass);
304✔
119

UNCOV
120
        foreach ($associations as $association) {
304✔
UNCOV
121
            if ($metadata->hasAssociation($association)) {
235✔
UNCOV
122
                $associationClass = $metadata->getAssociationTargetClass($association);
235✔
123

UNCOV
124
                $metadata = $this->getClassMetadata($associationClass);
235✔
125
            }
126
        }
127

UNCOV
128
        return $metadata;
304✔
129
    }
130
}
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