SignpostMarv /
Daft-Schema.org
| 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
Bug
introduced
by
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 |