• 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

40.63
/src/Metadata/Extractor/AbstractPropertyExtractor.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\Metadata\Extractor;
15

16
use Psr\Container\ContainerInterface;
17
use Symfony\Component\DependencyInjection\ContainerInterface as SymfonyContainerInterface;
18

19
/**
20
 * Base file extractor.
21
 *
22
 * @author Vincent Chalamon <vincentchalamon@gmail.com>
23
 */
24
abstract class AbstractPropertyExtractor implements PropertyExtractorInterface
25
{
26
    protected ?array $properties = null;
27
    private array $collectedParameters = [];
28

29
    /**
30
     * @param string[] $paths
31
     */
32
    public function __construct(protected array $paths, private readonly ?ContainerInterface $container = null)
33
    {
UNCOV
34
    }
979✔
35

36
    /**
37
     * {@inheritdoc}
38
     */
39
    public function getProperties(): array
40
    {
UNCOV
41
        if (null !== $this->properties) {
241✔
UNCOV
42
            return $this->properties;
232✔
43
        }
44

UNCOV
45
        $this->properties = [];
241✔
UNCOV
46
        foreach ($this->paths as $path) {
241✔
UNCOV
47
            $this->extractPath($path);
241✔
48
        }
49

UNCOV
50
        return $this->properties;
241✔
51
    }
52

53
    /**
54
     * Extracts metadata from a given path.
55
     */
56
    abstract protected function extractPath(string $path): void;
57

58
    /**
59
     * Recursively replaces placeholders with the service container parameters.
60
     *
61
     * @see https://github.com/symfony/symfony/blob/6fec32c/src/Symfony/Bundle/FrameworkBundle/Routing/Router.php
62
     *
63
     * @copyright (c) Fabien Potencier <fabien@symfony.com>
64
     *
65
     * @param mixed $value The source which might contain "%placeholders%"
66
     *
67
     * @throws \RuntimeException When a container value is not a string or a numeric value
68
     *
69
     * @return mixed The source with the placeholders replaced by the container
70
     *               parameters. Arrays are resolved recursively.
71
     */
72
    protected function resolve(mixed $value): mixed
73
    {
UNCOV
74
        if (null === $this->container) {
241✔
75
            return $value;
×
76
        }
77

UNCOV
78
        if (\is_array($value)) {
241✔
79
            foreach ($value as $key => $val) {
×
80
                $value[$key] = $this->resolve($val);
×
81
            }
82

83
            return $value;
×
84
        }
85

UNCOV
86
        if (!\is_string($value)) {
241✔
87
            return $value;
×
88
        }
89

UNCOV
90
        $escapedValue = preg_replace_callback('/%%|%([^%\s]++)%/', function ($match) use ($value) {
241✔
91
            $parameter = $match[1] ?? null;
×
92

93
            // skip %%
94
            if (!isset($parameter)) {
×
95
                return '%%';
×
96
            }
97

98
            if (preg_match('/^env\(\w+\)$/', $parameter)) {
×
99
                throw new \RuntimeException(\sprintf('Using "%%%s%%" is not allowed in routing configuration.', $parameter));
×
100
            }
101

102
            if (\array_key_exists($parameter, $this->collectedParameters)) {
×
103
                return $this->collectedParameters[$parameter];
×
104
            }
105

106
            if ($this->container instanceof SymfonyContainerInterface) {
×
107
                $resolved = $this->container->getParameter($parameter);
×
108
            } else {
109
                $resolved = $this->container->get($parameter);
×
110
            }
111

112
            if (\is_string($resolved) || is_numeric($resolved)) {
×
113
                $this->collectedParameters[$parameter] = $resolved;
×
114

115
                return (string) $resolved;
×
116
            }
117

118
            throw new \RuntimeException(\sprintf('The container parameter "%s", used in the resource configuration value "%s", must be a string or numeric, but it is of type %s.', $parameter, $value, \gettype($resolved)));
×
UNCOV
119
        }, $value);
241✔
120

UNCOV
121
        return str_replace('%%', '%', $escapedValue);
241✔
122
    }
123
}
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