dwikipeddos/peddos-laravel-tools

peddos' tool for laravel development

v1.0.16 2023-10-31 08:49 UTC

This package is auto-updated.

Last update: 2024-05-03 08:10:24 UTC


README

A package for laravel that a compilation of tools for easy laravel development, this package contains external packages from Spatie (the best laravel package developer!)

This package provide helpers and classes to simplify the usage of the packages above, or simply the way i like to use the package. Not only that, i also compiled classes that I myself often use in most of my projects.

This package can help you with

  • Filtering queries using spatie's laravel-query-builder
  • Simple use of spatie's media-library to attach a single media (which is usually the case, yes i am talking about profile picture)
  • Generating and validating OTP
  • Syncing all roles with their own permissions
  • Generating CRUD files complete with its function!
  • and many more!

Contents

Installation

Use composer dependency manager to install peddos-laravel-tools

composer require dwikipeddos/peddos-laravel-tools

don't forget to publish the config file by running

php artisan vendor:publish --tag=peddos-laravel-tools-config

also publish spatie permissions config and migration

php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"

Usage Example

Below are example usage of the packages

⚠️Warning!⚠️

the command might be changed in the future, because this package is compiled from many project hence the inconsistentcy of the command names, and stuff. so... please do read the Usage example, because I wil try to update the documentation here ASAP

Filtering Queries

Usually when using laravel-query-builder from spatie you use it like

use Spatie\QueryBuilder\QueryBuilder;

QueryBuilder::for(Model::class)
    ->allowedFilters('name')
    ->get();

This is fine and good... until you need a lot more filtering possibilities, then adding sorting and includes to the equation, this can quickly clutter your controller, so we can move the querying part to seperate class on their own, you can do this by creating a new class that extends Dwikipeddos\PeddosLaravelTools\Queries\PaginatedQuery , I usually create a folder called Queries and put all my query class there.

Now all you need to do is fill the filtering and which Model will it query from like

use Dwikipeddos\PeddosLaravelTools\Queries\PaginatedQuery;

class UserQuery extends PaginatedQuery
{
    //you have to override the __construct method
    public function __construct()
    {
        parent::__construct(User::query()); //which model to be queried for
    }

    //set filters that are allowed like you usually do when using spatie query builder
    protected function getAllowedFilters(): array
    {
        return [
            AllowedFilter::partial('name'),
            AllowedFilter::partial('email'),
        ];
    }

    //set sorts that are allowed like you usually do when using spatie query builder
    protected function getAllowedSorts(): array
    {
        return [
            AllowedSort::field('created_at'),
            AllowedSort::field('name'),
        ];
    }

    //set includes that are allowed like you usually do when using spatie query builder
    protected function getAllowedIncludes(): array
    {
        return [
            AllowedInclude::relationship('socialAccounts'),
            AllowedInclude::relationship('fcm_token'),
        ];
    }
}

we also added append so the API consumer can append some attributes that are hidden. all you need to do just add

//specify the attributes that can be appended
protected array $append = [
    'phone',
    'employer',
];

and now in your controller you can do

function index(UserQuery $query){
    return $query->includes() //to apply includes
    ->sort() //to apply sorts
    ->filter() //to apply filter
}

//or you could simplify it even more with
function index(UserQuery $query){
    return $query->filterSortPaginateWithAppend();
}

paginate? did the function say paginate? yes, it did, we also has added page limit into our query class which you can use by adding limit query. finally now you can do the filtering like what you usually do in laravel-query-builder

/user?filter[name]=peddos&sort=name&append[]=phone&limit=10

this will filter the user where the name is peddos and sorted by name and appending phone and the a single page will only contains 10 users

It Works!

Generate and Verify OTP

To generate an OTP the package using Action class which basically just a class that handles a single function, to generate OTP is as simple as to read more about action you might want to read Generating Actions

use Dwikipeddos\PeddosLaravelTools\Actions\GenerateOTPAction;

(new GenerateOTPAction)->execute(
    4, //number of seed
    1, //user_id
);

Or you can inject the action into the controller

function login(LoginRequest $request, GenerateOTPAction $action){
    //login stuff
    $action->execute(4,1);
}

⚠️Limitation⚠️

This action only works with laravel's default User model, while you can publish the migration as of now, but you can only add some column without changing the existsing one, because it could broke the action.

SingleMedia

Single media is a tool to associate your model with only single media using Spatie\laravel-medialibrary Normally to load single media from model you would need to do :

$article->getFirstMedia()->getUrl();

and to store something to the media collection you would do something like

$article->addMediaFromRequest("image")->toMediaCollection("image");

now with this package this is way simpler and easier. first of you need to prepare your model like so :

use Dwikipeddos\PeddosLaravel\Tools\HasSingleImage;
use Spatie\MediaLibrary\HasMedia;

class Article implements HasMedia{
    use HasSingleImage;
}

by default, the package should generate both the image and thumbnail with the collection name of "image" and "thumb" respectively, however you can change this by overrideng $defaultSingleImageName and the $defaultThumbnailName like

class Article implements HasMedia{
    use HasSingleImage;

    $defaultThumnailName = "thumbnail";
    $defaultSingleImageName = "Banner";
}

also by default the package has image placeholder in case the model has no image at all, you can change the default by doing

public string $defaultSingleImage = "https://image.com/pepega.png";
public string $defaultThumbnail = "https://image.com/pepega-sm.png";

and, how do you insert image to using Single image? simply by

class ArticleController extends Controller{
    function store(ArticleStoreRequest $request){
        $article = Article::create($request->validated());
        $article->addSingleImageFromRequest(); //THIS!
    }
}

by default addSingleImageFromRequest() will use the $defaultSingleImageName in the model as the request key that contains the image but you can do

    $article->addSingleImageFromRequest("my_image_key"); 
    //this will make the package to use "my_image_key" to find the image

and to get the image you can simply do

$article->getSingleImage();
//or to get the thumbnail
$article->getSingleImageThumbnail();

IT WORKS!

Sync Role and Permission

This package can help you sync role and permission and its quite easy, first of all you need to publish the config file if you haven't by running the command :

php artisan vendor:publish --tag=peddos-laravel-tools-config

Oh right, don't forget to run the migration

php artisan migrate

Now there's should be a file called peddoslaraveltools.php in your config directory. all you have to do now is write the permission and the role that are allowed to access it inside the available_permissions array, the config file should looks like this :

'available_permissions' => [
    [
        'name' => 'post.create', //permission name
        'roles' => ['super-admin', 'user'] // role that are allowed to access said permission
    ],
    [
        'name' => 'post.view',
        'roles' => ['user','guest','super-admin']
    ]
],

Once you've done that now you can sync the permission and the role with the command

php artisan peddos-permission-role:sync

This command will create the permission and the role if its not yet in the database so you don't need to worry about it!

Generating CRUD Files

You know that boring feelings of creating that basic CRUD files? from model, migration, factories, controller, routes, requests and policies? almost everything is the same except for the model it process right, so you do you actually need to type them out every time you creating a simple CRUD? well now you can skip that altogether with this package's CRUD generator! Simply run the command

php artisan generate:all {Name}

Replace {Name} with the model name you want to create and boom! Everything is generated! the basic CRUD is already working even filtering is already applied!

⚠️Limitation⚠️

Currently this command only able to generate basic CRUD and cannot generate more complex function, also you still need to fill the migration, factory, query, and rule for the validation in the FormRequest.

Generating Actions

Actions, Actions are well a simple class that can be injected and holds only a single simple function, this is useful to offload some simple function off the controller. to generate this Action all you need to do is

php artisan make:action {name}

Replace {name} with the action name, usually it should be verb like "VerifyUserOTP". If you take a look at the generated file at App\Actions\{Name}, you should see something like

namespace App\Actions;

class VerifyOtpAction
{
    public function execute(string $otp): bool
    {
       //some code
    }
}

As you can see Actions only has 1 function which is execute, and this function may or may not take parameters, because this is just like service class but simpler. You can use Action class in controller like

class AuthController{
    function verifyOtp(Request $request, VerifyOtpAction $action){
        //you can use it like this
        $isOtpValid = $action->execute($request->otp);
    }
}

or you can manually create it and use it like

$isOtpValid = (new VerifyOtpAction)->execute($otp);

so in summary Actions are just service class that are so simple it just need 1 function (execute) but you kinda need it in multiple place so you need to make a new class for it.

Generating Enum

With php 8 supporting for Enum, I love it very much to the point i am abusing it 🙂, what is enum? basically enums are welp a class that define a custom type that is limited to one of a discrete number of possible values. for example, you want to store sex in DB some most likely you will store it as a single Char and use M and F for Male and Female. but what if you want to do something like that but with different kind of list? for example you want to make list of "how an employee get to work" you dont want to store it as a string, because it will take a lot of storage as your app scales up, what you can do is make the possible answers into Numbers and convert it later to string again for example :

  • Walking = 1
  • Driving = 2
  • PublicTransportation = 3

and then on the DB you can store it an an int column voila, save more space, moreover if you want to add new possible answer all you need to do just assign number to that new answer and boom easy peasy.

a typical php enum should look like this :

namespace App\Enums;

enum EmployeeAccomodation: int
{
    case WALKING = 1;
    case DRIVING = 2;
    case PUBLIC_TRANSPORTATION = 3;
}

to create one using this package you can use this command :

php artisan make:enum {name}

replace the {name} with the name of your enum, this should create a new file in App\Enums. I know this is also a simple class that well probably don't need to make command for it but hey, i am lazy so here you go. to convert number to its own enum in laravel you can do :

EmployeeAccomodation::from(1); //WALKING

and you can also do something like this with the enum

namespace App\Enums;

enum EmployeeAccomodation: int
{
    case WALKING = 1;
    case DRIVING = 2;
    case PUBLIC_TRANSPORTATION = 3;

    function toString(){
        return Str::title(Str::replace('_', ' ', Str::snake($this->name)));
    }

    //
    EmployeeAccomodation::from(3)->toString(); //Public Transportation
}

IT WORKS!

Generating Query

Query classes are one of the most powerful card i have in this package. Usually a query is automatically generated by php artisan generate:all {name} but if for some reason you don't use it and want to make a query you can use this command to generate query

php artisan make:query {name}

Replace {name} with the name of your query, and it should be created in App\Queries\ as for how to use the query you might want to read Filtering Queries

IT WORKS!

License

MIT