Issues (108)

src/Meta.php (2 issues)

Labels
Severity
1
<?php
2
3
declare(strict_types=1);
4
5
namespace BEAR\Resource;
6
7
use LogicException;
8
use ReflectionClass;
9
use ReflectionMethod;
10
11
use function array_shift;
12
use function class_exists;
13
use function explode;
14
use function implode;
15
use function str_starts_with;
16
use function strtolower;
17
use function substr;
18
19
/**
20
 * @psalm-import-type PackageMetadata from Types
21
 * @psalm-import-type ResourceClassName from Types
22
 */
23
final class Meta
24
{
25
    private const EXTRAS_VENDOR = 'vendor';
26
    private const EXTRAS_PACKAGE = 'package';
27
28
    /** @var string */
29
    public $uri;
30
31
    /** @var Options */
32
    public $options;
33
34
    /** @var PackageMetadata */
0 ignored issues
show
The type BEAR\Resource\PackageMetadata was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
35
    public $extras = [];
36
37
    /** @param ResourceClassName $class */
0 ignored issues
show
The type BEAR\Resource\ResourceClassName was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
38
    public function __construct(string $class)
39
    {
40
        $this->uri = $this->getUri($class);
41
        $this->options = $this->getOptions($class);
42
    }
43
44
    private function getUri(string $class): string
45
    {
46
        $classPath = explode('\\', $class);
47
        // $class
48
        $this->extras[self::EXTRAS_VENDOR] = array_shift($classPath); // @phpstan-ignore-line
49
        $this->extras[self::EXTRAS_PACKAGE] = (string) array_shift($classPath);
50
        array_shift($classPath); // "/Resource/"
51
        $scheme = array_shift($classPath);
52
53
        return strtolower("{$scheme}://self/" . implode('/', $classPath));
54
    }
55
56
    /**
57
     * Return available resource request method
58
     *
59
     * @param ResourceClassName $class
60
     */
61
    private function getOptions(string $class): Options
62
    {
63
        if (! class_exists($class)) {
64
            throw new LogicException(); // @codeCoverageIgnore
65
        }
66
67
        $ref = new ReflectionClass($class);
68
        $allows = $this->getAllows($ref->getMethods());
69
        $params = [];
70
        foreach ($allows as $method) {
71
            $params[] = $this->getParams($class, $method);
72
        }
73
74
        return new Options($allows, $params);
75
    }
76
77
    /**
78
     * @param ReflectionMethod[] $methods
79
     *
80
     * @return string[]
81
     * @psalm-return list<string>
82
     */
83
    private function getAllows(array $methods): array
84
    {
85
        $allows = [];
86
        foreach ($methods as $method) {
87
            $isRequestMethod = str_starts_with($method->name, 'on') && ! str_starts_with($method->name, 'onLink');
88
            if (! $isRequestMethod) {
89
                continue;
90
            }
91
92
            $allows[] = strtolower(substr($method->name, 2));
93
        }
94
95
        return $allows;
96
    }
97
98
    /** @param ResourceClassName $class */
99
    private function getParams(string $class, string $method): Params
100
    {
101
        $refMethod = new ReflectionMethod($class, 'on' . $method);
102
        $parameters = $refMethod->getParameters();
103
        $optionalParams = $requiredParams = [];
104
        foreach ($parameters as $parameter) {
105
            $name = $parameter->name;
106
            if ($parameter->isOptional()) {
107
                $optionalParams[] = $name;
108
109
                continue;
110
            }
111
112
            $requiredParams[] = $name;
113
        }
114
115
        return new Params($method, $requiredParams, $optionalParams);
116
    }
117
}
118