Skip to content

Commit

Permalink
Reworked generators
Browse files Browse the repository at this point in the history
  • Loading branch information
andrey-helldar committed Jun 19, 2024
1 parent 4f5c2fb commit ff33e87
Show file tree
Hide file tree
Showing 19 changed files with 464 additions and 349 deletions.
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"laravel/prompts": "^0.1.24"
},
"require-dev": {
"mockery/mockery": "^1.6",
"orchestra/testbench": "^8.23 || ^9.1",
"pestphp/pest": "^2.34",
"pestphp/pest-plugin-laravel": "^2.4",
Expand Down
7 changes: 5 additions & 2 deletions src/Casts/ColumnCast.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@

class ColumnCast implements CastsAttributes
{
public function get(Model $model, string $key, mixed $value, array $attributes): ?array
public function get(Model $model, string $key, mixed $value, array $attributes): ?array {}

public function set(Model $model, string $key, mixed $value, array $attributes): ?string
{
}

public function set(Model $model, string $key, mixed $value, array $attributes): ?string
protected function locale(): string
{
return app()->getLocale();
}
}
93 changes: 20 additions & 73 deletions src/Console/ModelMakeCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@

namespace LaravelLang\Models\Console;

use DragonCode\Support\Facades\Filesystem\File;
use Illuminate\Console\Command;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Console\ModelMakeCommand as BaseMakeCommand;
use Illuminate\Support\Str;
use LaravelLang\Config\Facades\Config;
use LaravelLang\Models\Eloquent\Translation;
use LaravelLang\Models\Generators\MigrationGenerator;
use LaravelLang\Models\Generators\ModelGenerator;
use LaravelLang\Models\Services\ClassMap;

use function Laravel\Prompts\confirm;
Expand All @@ -28,81 +26,27 @@ class ModelMakeCommand extends Command

public function handle(): void
{
if (!$model = $this->model()) {
if (! $model = $this->model()) {
info('You haven\'t selected a model.');

return;
}

$columns = $this->columns();

$this->generateModel($model, $columns, Config::shared()->models->suffix);
$this->generateMigration($model, $columns, Config::shared()->models->suffix);
$this->generateModel($model, $columns);
$this->generateMigration($model, $columns);
$this->generateHelper($model);
}

protected function generateModel(string $model, array $columns, string $suffix): void
protected function generateModel(string $model, array $columns): void
{
$fillable = array_map(
fn (string $column) => sprintf(" '$column',"),
$columns
);

$casts = array_map(
fn (string $column) => sprintf(" '%s' => ColumnCast::class,", $column),
array_filter($columns, fn (string $column) => $column !== 'locale')
);

$content = \DragonCode\Support\Facades\Helpers\Str::of(
file_get_contents(__DIR__ . '/../../stubs/model.stub')
)->replaceFormat([
'namespace' => Str::of($model)->ltrim('\\')->beforeLast('\\'),
'model' => Str::afterLast($model, '\\'),
'suffix' => $suffix,
'fillable' => implode(PHP_EOL, $fillable),
'casts' => implode(PHP_EOL, $casts),
], '{{%s}}')
->toString();

$path = ClassMap::path($model);
$extension = pathinfo($path, PATHINFO_EXTENSION);

File::store(
Str::beforeLast($path, '.' . $extension) . $suffix . '.' . $extension,
$content
);
ModelGenerator::of($model, $columns)->generate();
}

protected function generateMigration(string $model, array $columns, string $suffix): void
protected function generateMigration(string $model, array $columns): void
{
/** @var Model $base */
$base = new $model;

/** @var Translation $translated */
$translated = new ($model . $suffix);

$columns = array_map(
fn (string $column) => sprintf(" \$table->string('$column')->nullable();"),
array_filter($columns, fn (string $column) => $column !== 'locale')
);

$columnType = $base->getKeyType() === 'uuid' ? 'uuid' : 'bigInteger';

$content = \DragonCode\Support\Facades\Helpers\Str::of(
file_get_contents(__DIR__ . '/../../stubs/migration.stub')
)->replaceFormat([
'modelNamespace' => $model,
'model' => class_basename($model),
'table' => $translated->getTable(),
'primaryType' => $columnType,
'columns' => implode(PHP_EOL, $columns),
], '{{%s}}')
->toString();

File::store(
database_path(sprintf("migrations/%s_create_%s_table.php", date('Y_m_d_His'), $translated->getTable())),
$content
);
MigrationGenerator::of($model, $columns)->generate();
}

protected function generateHelper(string $model): void
Expand All @@ -116,8 +60,8 @@ protected function model(): ?string
$this->askTranslationModel()
);

if (!$model) {
if (!$this->ascToCreate()) {
if (! $model) {
if (! $this->ascToCreate()) {
return null;
}

Expand All @@ -130,11 +74,11 @@ protected function model(): ?string
protected function columns(): array
{
if ($columns = $this->option('columns')) {
return collect($columns)->prepend('locale')->all();
return $columns;
}

if ($columns = $this->askColumns()) {
return collect($columns)->prepend('locale')->all();
return $columns;
}

return $this->columns;
Expand Down Expand Up @@ -174,7 +118,10 @@ protected function ascToCreate(): bool

protected function resolveModelClass(string $model): ?string
{
$model = Str::of($model)->replace('/', '\\')->start('\\')->toString();
$model = Str::of($model)
->replace('/', '\\')
->start('\\')
->toString();

$values = [
$model,
Expand All @@ -194,10 +141,10 @@ protected function resolveModelClass(string $model): ?string
protected function createBaseModel(string $model): void
{
$this->call(BaseMakeCommand::class, [
'name' => Str::after($model, 'App\\Models\\'),
'name' => Str::after($model, 'App\\Models\\'),
'--migration' => true,
'--factory' => true,
'--seed' => true,
'--factory' => true,
'--seed' => true,
]);
}
}
2 changes: 1 addition & 1 deletion src/Console/ModelsHelperCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
use DragonCode\Support\Facades\Filesystem\Directory;
use Illuminate\Console\Command;
use LaravelLang\Config\Facades\Config;
use LaravelLang\Models\Generators\HelperGenerator;
use LaravelLang\Models\Services\ClassMap;
use LaravelLang\Models\Services\HelperGenerator;

class ModelsHelperCommand extends Command
{
Expand Down
7 changes: 7 additions & 0 deletions src/Eloquent/Translation.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ abstract class Translation extends Model
{
public $timestamps = false;

public function translatable(): array
{
return array_filter($this->getFillable(), function (string $column) {
return $column !== 'locale';
});
}

protected function casts(): array
{
return $this->casts;
Expand Down
112 changes: 112 additions & 0 deletions src/Generators/Generator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
<?php

declare(strict_types=1);

namespace LaravelLang\Models\Generators;

use DragonCode\Support\Facades\Filesystem\File;
use DragonCode\Support\Facades\Helpers\Str;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str as IS;
use LaravelLang\Config\Facades\Config;
use LaravelLang\Models\Eloquent\Translation;

abstract class Generator
{
protected string $stub;

protected array $registry = [];

abstract protected function data(): array;

abstract protected function filename(): string;

public function __construct(
protected string $model,
protected array $columns
) {}

public static function of(string $model, array $columns = []): static
{
return new static($model, $columns);
}

public function generate(): void
{
$this->store($this->filename(), $this->make());
}

protected function make(): string
{
return Str::of($this->template())
->replaceFormat($this->resolveData(), '{{%s}}')
->toString();
}

protected function baseData(): array
{
return [
'fqn' => $this->getFqn(),
'namespace' => $this->getNamespace(),
'model' => $this->getModel(),
];
}

protected function resolveData(): array
{
return collect($this->data())
->map(fn (mixed $value) => is_array($value) ? implode(PHP_EOL, $value) : $value)
->merge($this->baseData())
->all();
}

protected function store(string $path, string $content): void
{
File::store($path, $content);
}

protected function getFqn(): string
{
return ltrim($this->model, '\\');
}

protected function getNamespace(): string
{
return IS::of($this->model)
->ltrim('\\')
->beforeLast('\\')
->toString();
}

protected function getModel(): string
{
return IS::afterLast($this->model, '\\');
}

protected function baseModel(): Model
{
return $this->registry[$this->model] ??= new $this->model();
}

protected function translationModel(): Translation
{
$model = $this->translationModelNamespace();

return $this->registry[$model] ??= new $model();
}

protected function translationModelNamespace(): string
{
return $this->model . $this->modelSuffix();
}

protected function modelSuffix(): string
{
return Config::shared()->models->suffix;
}

protected function template(): string
{
return file_get_contents($this->stub);
}
}
51 changes: 51 additions & 0 deletions src/Generators/HelperGenerator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

declare(strict_types=1);

namespace LaravelLang\Models\Generators;

use Illuminate\Support\Str;
use LaravelLang\Config\Facades\Config;

class HelperGenerator extends Generator
{
protected string $stub = __DIR__ . '/../../stubs/helper.stub';

protected string $properties = ' * @property string|null $%s';

protected function data(): array
{
return [
'hash' => $this->getHash(),
'properties' => $this->getProperties(),

'translationNamespace' => $this->translationModelNamespace(),
'translationModel' => $this->getTranslationModel(),
];
}

protected function filename(): string
{
return Config::shared()->models->helpers . '/_ide_helper_models_' . $this->getHash() . '.php';
}

protected function getProperties(): array
{
return array_map(fn (string $attribute) => sprintf($this->properties, $attribute), $this->getTranslatable());
}

protected function getHash(): string
{
return md5($this->model);
}

protected function getTranslatable(): array
{
return $this->translationModel()->translatable();
}

protected function getTranslationModel(): string
{
return Str::afterLast($this->translationModelNamespace(), '\\');
}
}
Loading

0 comments on commit ff33e87

Please sign in to comment.