Meta::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
ccs 4
cts 4
cp 1
crap 1
rs 10
c 0
b 0
f 0
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 4
    /** @var string */
29
    public $uri;
30 4
31 4
    /** @var Options */
32 4
    public $options;
33
34 4
    /** @var PackageMetadata */
0 ignored issues
show
Bug introduced by
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 4
37
    /** @param ResourceClassName $class */
0 ignored issues
show
Bug introduced by
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 4
    public function __construct(string $class)
39 4
    {
40 4
        $this->uri = $this->getUri($class);
41 4
        $this->options = $this->getOptions($class);
42
    }
43 4
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 4
        $this->extras[self::EXTRAS_PACKAGE] = (string) array_shift($classPath);
50
        array_shift($classPath); // "/Resource/"
51 4
        $scheme = array_shift($classPath);
52 4
53 4
        return strtolower("{$scheme}://self/" . implode('/', $classPath));
54 4
    }
55 4
56
    /**
57
     * Return available resource request method
58 4
     *
59
     * @param ResourceClassName $class
60
     */
61
    private function getOptions(string $class): Options
62
    {
63
        if (! class_exists($class)) {
64 4
            throw new LogicException(); // @codeCoverageIgnore
65
        }
66 4
67 4
        $ref = new ReflectionClass($class);
68 4
        $allows = $this->getAllows($ref->getMethods());
69 4
        $params = [];
70 4
        foreach ($allows as $method) {
71
            $params[] = $this->getParams($class, $method);
72
        }
73
74 4
        return new Options($allows, $params);
75
    }
76
77 4
    /**
78
     * @param ReflectionMethod[] $methods
79 4
     *
80 4
     * @return string[]
81 4
     * @psalm-return list<string>
82 4
     */
83 4
    private function getAllows(array $methods): array
84 4
    {
85 3
        $allows = [];
86
        foreach ($methods as $method) {
87 3
            $isRequestMethod = str_starts_with($method->name, 'on') && ! str_starts_with($method->name, 'onLink');
88
            if (! $isRequestMethod) {
89 4
                continue;
90
            }
91
92 4
            $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