1: <?php
2:
3: declare(strict_types=1);
4:
5: namespace LaravelUi5\OData\Console;
6:
7: use Illuminate\Console\Command;
8: use Illuminate\Filesystem\Filesystem;
9: use LaravelUi5\OData\Service\Cache\EdmxWriter;
10: use LaravelUi5\OData\Service\Cache\ResolverMapWriter;
11: use LaravelUi5\OData\Service\Contracts\ODataServiceRegistryInterface;
12: use ReflectionClass;
13:
14: class CacheCommand extends Command
15: {
16: protected $signature = 'odata:cache';
17:
18: protected $description = 'Generate cached Edm PHP classes for all registered OData services (dev only)';
19:
20: public function handle(ODataServiceRegistryInterface $registry): int
21: {
22: if (app()->environment('production', 'staging')) {
23: $this->error('odata:cache must not be run in production or staging.');
24: $this->error('The generated Edm/ cache is committed to version control and deployed as-is.');
25: $this->error('Run odata:cache on your development machine, commit the result, then deploy.');
26:
27: return self::FAILURE;
28: }
29:
30: $fs = new Filesystem();
31:
32: foreach ($registry->services() as $service) {
33: $reflected = new ReflectionClass($service);
34: $outputDir = dirname($reflected->getFileName()) . '/Edm';
35: $namespace = $reflected->getNamespaceName() . '\\Edm';
36:
37: // Remove stale cache so schema() takes the cold path.
38: if ($fs->isDirectory($outputDir)) {
39: $fs->deleteDirectory($outputDir);
40: $this->info("Cleared {$outputDir}");
41: }
42:
43: $edmx = $service->schema()->getEdmx();
44:
45: $writer = new EdmxWriter(
46: edmx: $edmx,
47: outputDir: $outputDir,
48: namespace: $namespace,
49: output: fn(string $line) => $this->info($line),
50: );
51:
52: $writer->write();
53:
54: $resolverMap = $service->resolverMap();
55: ResolverMapWriter::write($service, $resolverMap);
56:
57: $this->info("Cached: {$reflected->getName()}");
58: }
59:
60: // Refresh autoloader so the newly generated Edm classes are discoverable.
61: $this->info('Refreshing autoloader...');
62: passthru('composer dump-autoload 2>&1');
63:
64: $this->info('OData schema cached successfully.');
65:
66: return self::SUCCESS;
67: }
68: }
69: