This package is aimed to be a suite of artisan commands and tools to help make the work easier.
jfheinrich-eu/laravel-make-commands is a Laravel package for this package is aimed to be a suite of artisan commands and tools to help make the work easier..
It currently has 0 GitHub stars and 852 downloads on Packagist (latest version 3.3.0-rc.13).
Install it with composer require jfheinrich-eu/laravel-make-commands.
Discover more Laravel packages by jfheinrich-eu
or browse all Laravel packages to compare alternatives.
Last updated
This package is aimed to be a suite of artisan commands and tools to help make the work easier.
$ composer require jfheinrich-eu/laravel-make-commands
To publish the assets and config file, run following command:
$ php artisan make-commands:install
This install the config file to [Project root]/app/config/make-commands.php and the stubs to [Project root]/stubs/make-commands.
To install only the config file, use this command:
$ php artisan vendor:publish --tag make-commands-config
To install only the stubs, use this command:
$ php artisan vendor:publish --tag make-commands-assets
Creates a new interface in app\Contracts
php artisan make-commands:interface Interface
$ php artisan make-commands:interface TestInterface
$ cat app/Contracts/TestInterface.php
<?php declare(strict_types=1);
namespace App\Contracts;
interface TestInterface
{
}
Creates a new repository.
Optionally you can give the model on which the repository should based on. In this case, the command creates a repository with
all() : returns all records as a Eloquent collection
create(): creates a new record and returns then new record as Eloquent Model. The data for the record will be given by the generic RepositoryDto class as attribute collection.
update(): updates a existing record and returns boolean. The data to update will be given by the generic RepositoryDto class as attribute collection.
delete(): deletes a existing record and returns boolean. The deletion runs over the primary key.
find(): returns a Eloquent model, found by primary key. Is there no record with given primary key, a ModelNotFoundException will be thrown.
The generic class RepositoryDto:
<?php
declare(strict_types=1);
namespace JfheinrichEu\LaravelMakeCommands\Dto;
use Illuminate\Support\Collection;
/**
* @property int $id
* @property Collection<int,array<string,mixed>> $attributes
*/
final class RepositoryDto extends DataTransferObject
{
/**
* @param null|int $id
* @param null|Collection<int,array<string,mixed>> $attributes
*/
public function __construct(
protected ?int $id = null,
protected ?Collection $attributes = null
) {
}
}
The attributes property of RepositoryDto gets the required columns from the model as illuminate\Support\Collection.
This collection can be constructed like this:
$dto->setAttributes(collect(['id' => 42, 'email' => '[email protected]']);
$ php artisan make-commands:repository <Repository name> --model=<Modelname>
$ php artisan make-commands:repository UserRepository --model=User
app/Repositories/UserRepository.php
<?php declare(strict_types=1);
namespace App\Repositories
use Illuminate\Database\Eloquent\Collection;
use App\Models\User;
use Illuminate\Database\Eloquent\Model;
use JfheinrichEu\LaravelMakeCommands\Dto\RepositoryDto;
use Illuminate\Database\Eloquent\ModelNotFoundException;
class TestRepository
{
public function __construct(protected User $user) {}
public function all(): Collection
{
return $this->user::all();
}
/**
* @inheritdoc
*/
public function create(RepositoryDto $dto): Model|User
{
return $this->user::create($dto->attributes->toArray());
}
/**
* @inheritdoc
*/
public function update(RepositoryDto $dto): bool
{
return $this->user->whereId($dto->id)
->update($dto->attributes->toArray());
}
/**
* @inheritdoc
*/
public function delete(int $id): bool
{
return $this->user->whereId($id)->delete($id);
}
/**
* @inheritdoc
*/
public function find(int $id): Model| User
{
$model = $this->user->find($id)
if (null == $model)
{
throw new ModelNotFoundException("Resource not found");
}
return $model;
}
}
Creates a new service class, which can optionally implement a existing interface and can based on a existing repository.
php artisan make-commands:service name [--interface=Interface] [--repository=Repository]
Use existing interface App\Contracts\UserPostInterface
<?php declare(strict_types=1);
namespace App\Contracts;
interface UserPostInterface
{
public function get( string|array|null $title, ?int $userId = 0): array|string;
}
$ php artisan make-commands:service UserPostService --interface=UserPostInterface --repository=UserRepository
app/Services/UserPostService.php
<?php
declare(strict_types=1);
namespace App\Services;
use App\Contracts\UserPostInterface;
use App\Repositories\UserRepository;
class UserPostService implements UserPostInterface
{
public function __construct(protected UserRepository $userRepository)
{
}
public function get(array|string|null $title,?int $userId = 0): array|string
{
// Implementation
}
}
Based on the great work of Steve McDougall with his package laraval-data-object-tools.
I extend this package with implementation of „JsonSerializable“.
To generate a new DTO all you need to do is run the following artisan command:
php artisan make-commands:dto MyDto
This will generate the following class: app/Dto/MyDto.php. By default this class
will be a final class that implements a DtoContract, which extends JsonSerializable, which enforces two methods
toArray so that you can easily cast your DTOs to arraysJsonSerialize so that you can easily serialize your DTOsIf you are using PHP 8.2 however, you will by default get a readonly class generated, so that you do not have
to declare each property as readonly.
$ php artisan make-commands:dto MyDto
app/Dto/MyDto.php
<?php
declare(strict_types=1);
namespace App\Dto;
use JfheinrichEu\LaravelMakeCommands\Dto\DataTransferObject;
final class MyDto extends DataTransferObject
{
public function __construct(
//
) {}
}
To work with the hydration functionality you can either use Laravels DI container, or the ready made facade.
Using the container:
class StoreController
{
public function __construct(
private readonly HydratorContract $hydrator,
) {}
public function __invoke(StoreRequest $request)
{
$model = Model::query()->create(
attributes: $this->hydrator->fill(
class: ModelObject::class,
parameters: $request->validated(),
)->toArray(),
);
}
}
To work with the facade, you can do something very similar:
class StoreController
{
public function __invoke(StoreRequest $request)
{
$model = Model::query()->create(
attributes: Hydrator::fill(
class: ModelObject::class,
parameters: $request->validated(),
)->toArray(),
);
}
}
Under the hood this package uses an EventSauce package, created by Frank de Jonge. It is possibly the best package I have found to hydrate objects nicely in PHP. You can find the documentation here if you would like to see what else you are able to do with the package to suit your needs.
The database seeder in this package
are designed to seed a table from a json data file.
All what you have to do is to
integrate DatabaseJsonSeeder in Database\Seeder\DatabaseSeeder
<?php declare(strict_types=1);
namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use JfheinrichEu\LaravelMakeCommands\Support\Database\Seeder\DatabaseJsonSeeder;
class DatabaseSeeder extends DatabaseJsonSeeder
{
use WithoutModelEvents;
protected array $nonJsonSeeders = [
// Database\Seeders\MyNonJsonSeeder::class,
];
/**
* Seed the application's database.
*
* @return void
*/
public function run(): void
{
parent::setCommand($this->command)->setContainer($this->container);
parent::run();
// run the non JSON seeders
$this->call($this->nonJsonSeeders);
}
}
After that, enter the models to be considered by the JsonSeeder into config/make-commands.php
and configure the paths to the seeder classes and the seeder data files,
below the key seeders.
The order of the models must be specified according to the dependencies.
The JsonSeeder classes will be created automatically if they do not exist yet.
<?php
declare(strict_types=1);
return [
/*
* List of all commands to be registered.
*/
'commands' => [
JfheinrichEu\LaravelMakeCommands\Console\Commands\DtoMakeCommand::class,
JfheinrichEu\LaravelMakeCommands\Console\Commands\InterfaceMakeCommand::class,
JfheinrichEu\LaravelMakeCommands\Console\Commands\RepositoryMakeCommand::class,
JfheinrichEu\LaravelMakeCommands\Console\Commands\ServiceMakeCommand::class,
],
'seeders' => [
// Path to the seeder classes, must match the namespace Database\Seeders.
'path-seeder' => database_path('seeders'),
// The directory where the data files goes in.
'path-datafiles' => database_path('seeders/data'),
// The models which will be used by the JsonSeeder.
'models' => [
App\Models\User::class,
App\Models\Right::class,
],
],
];
Now you need to create the data files in JSON format. The file name must match the table name of the model.
Here is an example for the User Model.
database/seeders/data/users.json
[
{
"id": 1,
"name": "Bastard Operator from hell",
"email": "[email protected]",
"email_verified_at": "2023-01-01 12:00:00",
"password": "$2y$10$9wMEaiSx1KpwmHnbpH33pecbGd/FrRaY5SJXoqhdZ4mZnRVZmv0Ke",
"two_factor_secret": null,
"two_factor_recovery_codes": null,
"remember_token": null
},
{
"id": 2,
"name": "backend",
"email": "[email protected]",
"email_verified_at": "2023-01-01 13:00:00",
"password": "$2y$10$VvIem6s7FgZIvdSiGqwG4.i0nEYYC.quHyb6SQkeALxa8lZXQnf6K",
"two_factor_secret": null,
"two_factor_recovery_codes": null,
"remember_token": null
}
]
After that, you can run the seeders with
php artisan db:seed
You can create the seeder JSON datafile directly from the database.
Use therefor the command
php artisan make-commands:seeder-data [Model…]
$ php artisan make-commands:seeder-data \App\Models\User \App\Models\UserPost
App\Models\User(users.json) .............................................................................................................. RUNNING
App\Models\User(users.json) ........................................................................................................ 74.14 ms DONE
App\Models\Right(rights.json) ............................................................................................................ RUNNING
App\Models\Right(rights.json) ....................................................................................................... 2.43 ms DONE
This creates the files users.json and user_posts.json into the configured seeder data directory.
The UseView Trait allows to create eloquent models based on Views, which are
are.
Eloquent models must exist for the underlying tables of the View.
The Model must extend ViewModel and must define at least the three attributes:
The ViewModel adds the following properties and methods to the Model.
<?php
declare(strict_types=1);
namespace App\Models;
use JfheinrichEu\LaravelMakeCommands\Models\ViewModel;
class MyView extends ViewModel
{
/**
* @var string
*/
protected $table = 'my_view';
/** @var string */
protected string $mainTable = 'data_table1';
/** @var string[] */
protected array $baseTables = [
'data_table1',
'data_table2',
'data_table3',
];
...
}
Because Eloquent and Doctrine did not run back the columns of a view, two problems arise:
For the second point there is the artisan command make-commands:view-model-hook in this package which creates a hook class in the directory app/Support/IdeHelper. This must then only be entered in the IDE-Helper config file under hooks.