Issues (72)

src/Enums.php (3 issues)

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Cerbero\Enum;
6
7
use Closure;
8
use Generator;
9
use GlobIterator;
10
use UnitEnum;
0 ignored issues
show
The type UnitEnum 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...
11
12
/**
13
 * The enums manager.
14
 */
15
class Enums
16
{
17
    /**
18
     * The application base path.
19
     *
20
     * @var string
21
     */
22
    protected static ?string $basePath = null;
23
24
    /**
25
     * The glob paths to find enums in.
26
     *
27
     * @var string[]
28
     */
29
    protected static array $paths = [];
30
31
    /**
32
     * The TypeScript path to sync enums in.
33
     *
34
     * @var Closure(class-string<UnitEnum>|string $enum): string|string
35
     */
36
    protected static Closure|string $typeScript = 'resources/js/enums/index.ts';
37
38
    /**
39
     * The logic to run when an inaccessible enum method is called.
40
     *
41
     * @var ?Closure(class-string<UnitEnum> $enum, string $name, array<array-key, mixed> $arguments): mixed
42
     */
43
    protected static ?Closure $onStaticCall = null;
44
45
    /**
46
     * The logic to run when an inaccessible case method is called.
47
     *
48
     * @var ?Closure(UnitEnum $case, string $name, array<array-key, mixed> $arguments): mixed
49
     */
50
    protected static ?Closure $onCall = null;
51
52
    /**
53
     * The logic to run when a case is invoked.
54
     *
55
     * @var ?Closure(UnitEnum $case, mixed ...$arguments): mixed
56
     */
57
    protected static ?Closure $onInvoke = null;
58
59
    /**
60
     * Set the application base path.
61
     */
62 11
    public static function setBasePath(string $path): void
63
    {
64 11
        static::$basePath = path($path);
65
    }
66
67
    /**
68
     * Retrieve the application base path, optionally appending the given path.
69
     */
70 21
    public static function basePath(?string $path = null): string
71
    {
72 21
        $basePath = static::$basePath ?: dirname(__DIR__, 4);
73
74 21
        return $path === null ? $basePath : $basePath . DIRECTORY_SEPARATOR . ltrim(path($path), '\/');
75
    }
76
77
    /**
78
     * Set the glob paths to find all the application enums.
79
     */
80 5
    public static function setPaths(string ...$paths): void
81
    {
82 5
        static::$paths = array_map(path(...), $paths);
0 ignored issues
show
The type Cerbero\Enum\path 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...
83
    }
84
85
    /**
86
     * Retrieve the paths to find all the application enums.
87
     *
88
     * @return string[]
89
     */
90 11
    public static function paths(): array
91
    {
92 11
        return static::$paths;
93
    }
94
95
    /**
96
     * Set the TypeScript path to sync enums in.
97
     *
98
     * @param callable(class-string<UnitEnum>|string $enum): string|string $path
99
     */
100 4
    public static function setTypeScript(callable|string $path): void
101
    {
102
        /** @phpstan-ignore assign.propertyType */
103 4
        static::$typeScript = is_callable($path) ? $path(...) : $path;
104
    }
105
106
    /**
107
     * Retrieve the TypeScript path, optionally for the given enum.
108
     *
109
     * @param class-string<UnitEnum>|string $enum
110
     * @return string
111
     */
112 7
    public static function typeScript(string $enum = ''): string
113
    {
114 7
        return static::$typeScript instanceof Closure ? (static::$typeScript)($enum) : static::$typeScript;
115
    }
116
117
    /**
118
     * Yield the namespaces of all the application enums.
119
     *
120
     * @return Generator<int, class-string<UnitEnum>>
121
     */
122 2
    public static function namespaces(): Generator
123
    {
124 2
        $psr4 = psr4();
125
126 2
        foreach (static::paths() as $path) {
127 2
            $pattern = static::basePath($path) . DIRECTORY_SEPARATOR . '*.php';
128
129 2
            foreach (new GlobIterator($pattern) as $fileInfo) {
130
                /** @var \SplFileInfo $fileInfo */
131 2
                $enumPath = (string) $fileInfo->getRealPath();
132
133 2
                foreach ($psr4 as $root => $relative) {
134 2
                    $absolute = static::basePath($relative) . DIRECTORY_SEPARATOR;
135
136 2
                    if (str_starts_with($enumPath, $absolute)) {
137 2
                        $enum = strtr($enumPath, [$absolute => $root, '/' => '\\', '.php' => '']);
138
139 2
                        if (enum_exists($enum)) {
0 ignored issues
show
The function enum_exists was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

139
                        if (/** @scrutinizer ignore-call */ enum_exists($enum)) {
Loading history...
140 2
                            yield $enum;
141
                        }
142
                    }
143
                }
144
            }
145
        }
146
    }
147
148
    /**
149
     * Set the logic to run when an inaccessible enum method is called.
150
     *
151
     * @param callable(class-string<UnitEnum> $enum, string $name, array<array-key, mixed> $arguments): mixed $callback
152
     */
153 2
    public static function onStaticCall(callable $callback): void
154
    {
155 2
        static::$onStaticCall = $callback(...);
156
    }
157
158
    /**
159
     * Handle the call to an inaccessible enum method.
160
     *
161
     * @param class-string<UnitEnum> $enum
162
     * @param array<array-key, mixed> $arguments
163
     */
164 4
    public static function handleStaticCall(string $enum, string $name, array $arguments): mixed
165
    {
166 4
        return static::$onStaticCall
167 2
            ? (static::$onStaticCall)($enum, $name, $arguments)
168 4
            : $enum::fromName($name)->value(); /** @phpstan-ignore method.nonObject */
169
    }
170
171
    /**
172
     * Set the logic to run when an inaccessible case method is called.
173
     *
174
     * @param callable(UnitEnum $case, string $name, array<array-key, mixed> $arguments): mixed $callback
175
     */
176 2
    public static function onCall(callable $callback): void
177
    {
178 2
        static::$onCall = $callback(...);
179
    }
180
181
    /**
182
     * Handle the call to an inaccessible case method.
183
     *
184
     * @param array<array-key, mixed> $arguments
185
     */
186 14
    public static function handleCall(UnitEnum $case, string $name, array $arguments): mixed
187
    {
188 14
        return static::$onCall ? (static::$onCall)($case, $name, $arguments) : $case->resolveMetaAttribute($name);
189
    }
190
191
    /**
192
     * Set the logic to run when a case is invoked.
193
     *
194
     * @param callable(UnitEnum $case, mixed ...$arguments): mixed $callback
195
     */
196 2
    public static function onInvoke(callable $callback): void
197
    {
198 2
        static::$onInvoke = $callback(...);
199
    }
200
201
    /**
202
     * Handle the invocation of a case.
203
     */
204 2
    public static function handleInvoke(UnitEnum $case, mixed ...$arguments): mixed
205
    {
206 2
        return static::$onInvoke ? (static::$onInvoke)($case, ...$arguments) : $case->value();
207
    }
208
}
209