Issues (5)

bin/SyncLookup.php (1 issue)

Labels
Severity
1
<?php
2
/**
3
* @author SignpostMarv
4
*/
5
declare(strict_types=1);
6
7
namespace SignpostMarv\DaftObject\SchemaOrgLookup;
8
9
use CallbackFilterIterator;
10
use PhpParser\BuilderFactory;
11
use PhpParser\Node\Expr\Array_;
12
use PhpParser\Node\Expr\ArrayItem;
13
use PhpParser\Node\Scalar\String_;
14
use PhpParser\Node\Stmt\Return_;
15
use PhpParser\PrettyPrinter\Standard;
16
use RecursiveCallbackFilterIterator;
17
use RecursiveDirectoryIterator;
18
use RecursiveIteratorIterator;
19
use ReflectionClassConstant;
20
use SignpostMarv\DaftObject\SchemaOrg\Thing;
21
22
require_once(__DIR__ . '/../vendor/autoload.php');
23
24
/**
25
* @var iterable<string>
26
*/
27
$iterator = new CallbackFilterIterator(
28
    new RecursiveIteratorIterator(
29
        new RecursiveCallbackFilterIterator(
30
            new RecursiveDirectoryIterator(
31
                (__DIR__ . '/../src/'),
32
                (
33
                    RecursiveDirectoryIterator::CURRENT_AS_PATHNAME |
34
                    RecursiveDirectoryIterator::SKIP_DOTS |
35
                    RecursiveDirectoryIterator::UNIX_PATHS
36
                )
37
            ),
38
            function (string $path_name) : bool {
0 ignored issues
show
function(...) { /* ... */ } of type callable is incompatible with the type string expected by parameter $callback of RecursiveCallbackFilterIterator::__construct(). ( Ignorable by Annotation )

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

38
            /** @scrutinizer ignore-type */ function (string $path_name) : bool {
Loading history...
39
                return
40
                    is_dir($path_name) ||
41
                    (
42
                        is_file($path_name) &&
43
                        '.php' === mb_substr($path_name, -4)
44
                    );
45
            }
46
        )
47
    ),
48
    function (string $path_name) : bool {
49
        return is_file($path_name);
50
    }
51
);
52
53
$root_length = mb_strlen(__DIR__ . '/../src/');
54
55
/**
56
* @var array<string, array<int, string>>
57
*
58
* @psalm-var array<class-string<Thing>, array<int, class-string<Thing>>>
59
*/
60
$cache = [];
61
62
/**
63
* @var array<string, array<string, int>>
64
*/
65
$distances = [];
66
67
/**
68
* @var array<int, string>
69
*
70
* @psalm-var array<int, class-string<Thing>>
71
*/
72
$classes = [];
73
74
foreach ($iterator as $pathname) {
75
    $class_name =
76
        'SignpostMarv\\DaftObject\\SchemaOrg\\' .
77
        str_replace('/', '\\', mb_substr($pathname, $root_length, -4));
78
79
    if (is_a($class_name, Thing::class, true)) {
80
        $reflector_type = new ReflectionClassConstant($class_name, 'SCHEMA_ORG_TYPE');
81
82
        $classes[] = $class_name;
83
        $cache[$class_name] = [];
84
        $distances[$class_name] = [];
85
    }
86
}
87
88
foreach ($classes as $class_name) {
89
    $checking = $class_name;
90
91
    $append = [];
92
93
    $int_distance = 0;
94
95
    while (is_a($checking, Thing::class, true)) {
96
        $append[] = $checking;
97
        $distances[$checking][$class_name] = $int_distance;
98
99
        foreach ($append as $append_class_name) {
100
            if ( ! in_array($append_class_name, $cache[$checking], true)) {
101
                $cache[$checking][] = $append_class_name;
102
            }
103
        }
104
105
        ++$int_distance;
106
107
        /**
108
        * @var string
109
        *
110
        * @psalm-var class-string
111
        */
112
        $checking = get_parent_class($checking);
113
    }
114
}
115
116
foreach ($cache as $class_name => $cache_classes) {
117
    usort($cache_classes, function (string $a, string $b) use ($class_name, $distances) : int {
118
        return $distances[$class_name][$b] <=> $distances[$class_name][$a];
119
    });
120
121
    $cache[$class_name] = $cache_classes;
122
}
123
124
uksort($cache, function (string $a, string $b) use ($distances) : int {
125
    return $distances[Thing::class][$a] <=> $distances[Thing::class][$b];
126
});
127
128
$out = new Standard();
129
$factory = new BuilderFactory();
130
131
/**
132
* @var array<string, array<int, string>>
133
*
134
* @psalm-var array<class-string<Thing>, array<int, class-string<Thing>>>
135
*/
136
$cache = $cache;
137
138
foreach ($cache as $parent_class => $cache_classes) {
139
    $class_name = 'Lookup_' . hash('sha512', $parent_class);
140
141
    $builder = $factory->namespace(
142
        'SignpostMarv\\DaftObject\\SchemaOrgLookup'
143
    )->addStmt(
144
        $factory->class(
145
            $class_name
146
        )->implement(
147
            'LookupInterface'
148
        )->addStmt(
149
            $factory->method('ObtainClasses')->makePublic()->makeStatic()->addStmt(
150
                (
151
                    new Return_(
152
                        new Array_(
153
                            array_map(
154
                                function (string $str) : ArrayItem {
155
                                    return new ArrayItem(new String_($str));
156
                                },
157
                                $cache_classes
158
                            )
159
                        )
160
                    )
161
                )
162
            )->setReturnType('array')
163
        )
164
    );
165
166
    file_put_contents(
167
        (
168
            __DIR__ .
169
            '/../SchemaOrgLookup/' .
170
            $class_name .
171
            '.php'
172
        ),
173
        $out->prettyPrintFile([$builder->getNode()])
174
    );
175
}
176