Skip to content

Commit 7bf9895

Browse files
committed
feat: Implement ExportJsonsCommand to export JSONs from models using HasJsonExports trait
1 parent 7128c0e commit 7bf9895

File tree

2 files changed

+117
-9
lines changed

2 files changed

+117
-9
lines changed
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<?php
2+
3+
namespace App\Console\Commands;
4+
5+
use Illuminate\Console\Command;
6+
use Illuminate\Database\Eloquent\Model;
7+
use Illuminate\Support\Facades\File;
8+
use ReflectionClass;
9+
10+
class ExportJsonsCommand extends Command
11+
{
12+
/**
13+
* The name and signature of the console command.
14+
*
15+
* @var string
16+
*/
17+
protected $signature = 'export:jsons';
18+
19+
/**
20+
* The console command description.
21+
*
22+
* @var string
23+
*/
24+
protected $description = 'Export all JSONs defined in HasJsonExports trait';
25+
26+
/**
27+
* Execute the console command.
28+
*/
29+
public function handle(): void
30+
{
31+
$modelsPath = app_path('Models');
32+
33+
if (! File::exists($modelsPath)) {
34+
$this->error('Models directory not found.');
35+
36+
return;
37+
}
38+
39+
$modelFiles = File::allFiles($modelsPath);
40+
41+
foreach ($modelFiles as $file) {
42+
$className = 'App\\Models\\'.$file->getFilenameWithoutExtension();
43+
44+
if (! class_exists($className)) {
45+
continue;
46+
}
47+
48+
$reflection = new ReflectionClass($className);
49+
if (! $reflection->isInstantiable() || ! $reflection->isSubclassOf(Model::class)) {
50+
continue;
51+
}
52+
53+
$traits = class_uses_recursive($className);
54+
$usesHasJsonExports = false;
55+
56+
foreach ($traits as $trait) {
57+
if (str_ends_with($trait, 'HasJsonExports')) {
58+
$usesHasJsonExports = true;
59+
break;
60+
}
61+
}
62+
63+
if ($usesHasJsonExports) {
64+
$this->info("Exporting for model: $className");
65+
66+
/** @var Model */
67+
$model = new $className;
68+
$this->exportModel($model);
69+
}
70+
}
71+
}
72+
73+
protected function exportModel(Model $targetModel): void
74+
{
75+
// @phpstan-ignore method.notFound
76+
foreach ($targetModel->getJsonExportMethods() as $name => $method) {
77+
$this->line(" - Generating $name.json");
78+
79+
$data = $targetModel->$method();
80+
81+
$path = config('gemadigital.jsonExports.path', storage_path('data'))."/{$name}.json";
82+
83+
if (! file_exists(dirname($path))) {
84+
mkdir(dirname($path), 0755, true);
85+
}
86+
87+
file_put_contents(
88+
$path,
89+
$data->toJson(JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES),
90+
);
91+
}
92+
}
93+
}

src/app/Models/Traits/HasJsonExports.php

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,33 @@
1010
/** @phpstan-ignore trait.unused */
1111
trait HasJsonExports
1212
{
13-
public static function bootHasJsonExports(): void
13+
/**
14+
* @return array<string, string>
15+
*/
16+
public function getJsonExportMethods(): array
1417
{
15-
$exportHelper = function (Model $targetModel): void {
16-
foreach (get_class_methods($targetModel) as $method) {
17-
if (! str_starts_with($method, 'export') || ! str_ends_with($method, 'Json')) {
18-
continue;
19-
}
18+
$methods = [];
19+
20+
foreach (get_class_methods($this) as $method) {
21+
if (! str_starts_with($method, 'export') || ! str_ends_with($method, 'Json')) {
22+
continue;
23+
}
24+
25+
$name = Str::of($method)
26+
->substr(6, -4)
27+
->snake();
2028

21-
$name = Str::of($method)
22-
->substr(6, -4)
23-
->snake();
29+
$methods[(string) $name] = $method;
30+
}
2431

32+
return $methods;
33+
}
34+
35+
public static function bootHasJsonExports(): void
36+
{
37+
$exportHelper = function (Model $targetModel): void {
38+
// @phpstan-ignore method.notFound
39+
foreach ($targetModel->getJsonExportMethods() as $name => $method) {
2540
$data = $targetModel->$method();
2641

2742
$path = config('gemadigital.jsonExports.path', storage_path('data'))."/{$name}.json";

0 commit comments

Comments
 (0)