Issues (44)

src/AppIterator.php (4 issues)

1
<?php
2
3
declare(strict_types=1);
4
5
namespace BEAR\Resource;
6
7
use BEAR\Resource\Exception\ResourceDirException;
8
use Iterator;
9
use RecursiveDirectoryIterator;
10
use RecursiveIteratorIterator;
11
use ReflectionClass;
12
use SplFileInfo;
13
14
use function array_diff_key;
15
use function array_key_exists;
16
use function array_keys;
17
use function array_values;
18
use function assert;
19
use function class_exists;
20
use function file_exists;
21
use function get_declared_classes;
22
use function str_contains;
23
24
/** @implements Iterator<string, Meta> */
25
final class AppIterator implements Iterator
26
{
27
    private int $i = 0;
28
29
    /** @var array<string, Meta> */
30
    private array $metaCollection = [];
31 2
32
    /** @var list<string> */
0 ignored issues
show
The type BEAR\Resource\list 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...
33 2
    private array $keys = [];
34 1
35
    /** @throws ResourceDirException */
36 2
    public function __construct(string $resourceDir)
37 2
    {
38 2
        if (! file_exists($resourceDir)) {
39
            throw new ResourceDirException($resourceDir);
40 2
        }
41 2
42 2
        $iterator = new RecursiveIteratorIterator(
43
            new RecursiveDirectoryIterator($resourceDir),
44
            RecursiveIteratorIterator::SELF_FIRST,
45
        );
46
        $this->metaCollection = $this->getMetaCollection($iterator);
47 1
        $this->keys = array_keys($this->metaCollection);
0 ignored issues
show
Documentation Bug introduced by
It seems like array_keys($this->metaCollection) of type array is incompatible with the declared type BEAR\Resource\list of property $keys.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
48
    }
49 1
50
    /**
51
     * {@inheritDoc}
52
     */
53
    public function current(): Meta
54
    {
55 1
        return $this->metaCollection[$this->keys[$this->i]];
56
    }
57 1
58 1
    /**
59
     * {@inheritDoc}
60
     */
61
    public function next(): void
62
    {
63 1
        ++$this->i;
64
    }
65 1
66
    /**
67
     * {@inheritDoc}
68
     */
69
    public function key(): string
70
    {
71 1
        return $this->keys[$this->i];
72
    }
73 1
74
    /**
75
     * {@inheritDoc}
76
     */
77
    public function valid(): bool
78
    {
79 1
        return array_key_exists($this->i, $this->keys);
80
    }
81 1
82 1
    /**
83
     * {@inheritDoc}
84 2
     */
85
    public function rewind(): void
86 2
    {
87 2
        $this->i = 0;
88
    }
89 2
90 2
    /**
91
     * @param Iterator<SplFileInfo> $iterator
92 2
     *
93 2
     * @return array<string, Meta>
94 1
     */
95
    private function getMetaCollection(Iterator $iterator): array
96 1
    {
97 1
        $metaCollection = [];
98
        foreach ($iterator as $item) {
99
            if ($this->isNotPhp($item)) {
100 2
                continue;
101
            }
102
103 2
            $resourceClass = $this->getResourceClassName($item);
104
            if ($resourceClass === '') {
105 2
                continue;
106 2
            }
107 2
108
            assert(class_exists($resourceClass));
109 2
            $meta = new Meta($resourceClass);
110
            $metaCollection[$meta->uri] = $meta;
111
        }
112 2
113
        return $metaCollection;
114 2
    }
115 2
116
    private function isNotPhp(SplFileInfo $item): bool
117 2
    {
118 2
        $isPhp = $item->isFile()
119 2
            && $item->getExtension() === 'php'
120
            && (! str_contains($item->getBasename('.php'), '.'));
121 2
122
        return ! $isPhp;
123
    }
124 2
125
    private function getResourceClassName(SplFileInfo $file): string
126 2
    {
127 1
        $pathName = $file->getPathname();
128 1
        $declaredClasses = get_declared_classes();
129 1
        assert(file_exists($pathName));
130
        include_once $pathName;
131
        $newClasses = array_values(array_diff_key(get_declared_classes(), $declaredClasses));
132
133 1
        return $this->getName($newClasses);
134
    }
135
136
    /**
137
     * @param array<class-string> $newClasses
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<class-string> at position 2 could not be parsed: Unknown type name 'class-string' at position 2 in array<class-string>.
Loading history...
138
     *
139
     * @return class-string|string
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string|string at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string|string.
Loading history...
140
     */
141
    private function getName(array $newClasses): string
142
    {
143
        foreach ($newClasses as $newClass) {
144
            $parent = (new ReflectionClass($newClass))->getParentClass();
145
            if ($parent && $parent->name === ResourceObject::class) {
146
                return $newClass;
147
            }
148
        }
149
150
        return '';
151
    }
152
}
153