• Stars
    star
    129
  • Rank 278,249 (Top 6 %)
  • Language
    PHP
  • License
    MIT License
  • Created over 5 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Easily decorate your method calls with laravel-decorator package

🎄 Laravel Decorator

Decorator pattern in laravel apps

Build Status Quality Score StyleCI Software License Latest Stable Version Code Coverage Total Downloads

Made with ❤️ for smart clean coders

A try to port "decorator" feature from python language to laravel framework.

python-and-prey

🚚 Installation:

composer require imanghafoori/laravel-decorator

What is a "Decorator"

A decorator is callable which wraps around the original decorated callable, in order to form a new callable composed of the previous two.

Like a python snake swallowing a deer whole and wraps around it's body !

After that the snake becomes capable to eat and digest grasses 🌿 because it has a deer inside it.

Technically, A "Decorator":

1- Is a "callable"

2- which takes an other "callable" (as it's only argument, like a snake swallows an other snake)

3- and returns a new "callable" (which internally calls the original callable, putting some code before and after it.)

What?!??! ???! (0_o)

What can be considered as a "callable" within laravel ?!

Long story short, anything that can be called (invoked) with App::call(); or call_user_func() like: 'MyClass@myMethod' or a closure, [UserRepo::class, 'find']

Cache Like a Pro:

Caching DB queries is always a need, but it is always annoying to add more code to the existing code. It will become more messy, we may break the current code, after all it adds a layer of fog. Yeah?

Imagine that you have a UserControllerwhich calls a UserRepo@find to get a $user .

Then after a while you decide to put a cache layer between those two classes for obvious reasons.

According to SOLID principles, you shouldn't put the caching code logic neither in your controller nor your UserRepo. But somewhere in between.

In other words, you want to add a new feature (caching in this case) without modifing the existing code.

It smells like Open-closed Principle Yeah?! 👃

You want to keep the responsibilities seperate. In this case caching should not be in a repository or controller but in it's own class.

It smells like Single Responsibility Principle yeah?! 👃

class UserRepository
{
    function find($uid)
    {
        return User::find($uid);
    }
}

class MadUsersController extends Controller
{
    function show ($madUserId)
    {
        $madUser = app()->call('UserRepository@find', ['id' => $madUserId]);
    }
}

ok now there is no cache, going on. it is a direct call.

With the help of laravel-decorator built-in cache decorator, you can go to AppServiceProvider.php or any other service provider

<?php

use Imanghafoori\Decorator\Decorators\DecoratorFactory;

class AppServiceProvider extends ServiceProvider
{

    public function boot()
    {
        $keyMaker = function ($madId) {
            return 'mad_user_key_' . $madId;
        };
        $time = 10;
        $decorator = DecoratorFactory::cache($keyMaker, $time);
        
        \Decorator::decorate('UserRepository@find', $decorator);
    }
}

You will get cached results from your calls, in your UserController without touching it! but rememnber to change:

 app()->call('UserRepository@find', ...
 // to :
  app('decorator')->call('UserRepository@find', ...

Define Your Own Decorators:

public function boot ()
{
    \Decorator::define('myDecoratorName1', 'SomeClass@someMethod');
    
    // or

    \Decorator::define('myDecoratorName2', function ($callable) {
        return function (...) use ($callable){ ... } 
    });
}

Then you can use this name (myDecoratorName) to decorate methods.

How to decorate a method?

// You may set multiple decorators on a single method... 
\Decorator::decorate('class@method, 'someClass@someOtherDecorator'); // (first)

// or reference the decorator by it's name :
\Decorator::decorate('class@method, 'myDecoratorName'); // (second)

How to call a method with it's decorators?

image

Decorate Facades:

Decorating Facade Methods

First you should extend the Imanghafoori\Decorator\DecoratableFacade class (instead of the laravel base Facade).

image

Now You Can Apply Decorators in your ServiceProvider's boot method:

image

Then if you call your facade as normal you get decorated results.

image

⚠️ Warning:

With great power, comes great responsibilities.

Remember not to violate the Liskoves Substitution Principle when you decorate something.

For example a method call which returns int|null should not unexpectedly return a string after being decorated.

$result = app('decorate')->call(...

Since the users of the method should be ready for type of value they get back.

But if you return only int and your decorator causes the null value to be filtered out. that's ok.

Your Stars Make Us Do More

As always if you found this package useful and you want to encourage us to maintain and work on it, Please press the star button to declare your willingness.

More packages from the author:

💎 A minimal yet powerful package to give you opportunity to refactor your controllers.


💎 A minimal yet powerful package to give a better structure and caching opportunity for your laravel apps.


💎 It allows you login with any password in local environment only.


💎 Authorization and ACL is now very easy with hey-man package!


More Repositories

1

laravel-microscope

Fearless refactoring, it does a lot of smart checks to find certain errors.
PHP
1,307
star
2

laravel-widgetize

A minimal package to help you make your laravel application cleaner and faster.
PHP
902
star
3

laravel-heyman

Declarative style of authorization and validation in laravel.
PHP
880
star
4

laravel-MasterPass

Helps you securely setup a master password and login into user accounts with it.
PHP
354
star
5

laravel-terminator

A package to help you clean up your controllers in laravel
PHP
246
star
6

laravel-video

A laravel package to stream video content.
PHP
232
star
7

laravel-anypass

A minimal package that helps you login with any password on local environments
PHP
211
star
8

eloquent-relativity

Allows you to decouple your eloquent models from one another.
PHP
147
star
9

eloquent-mockery

Mock your eloquent queries without the repository pattern
PHP
123
star
10

laravel-middlewarize

Use middleware to decorate method calls within your application code.
PHP
105
star
11

laravel-nullable

Functional programming paradigms in laravel to avoid run-time errors.
PHP
102
star
12

laravel-temp-tag

Temporarily and Transparently, tag your eloquent models
PHP
100
star
13

laravel-smart-facades

Strategy design pattern in laravel, the easiest way.
PHP
87
star
14

laravel-password-history

Keep a password history of your users to prevent them from reusing the same password.
PHP
64
star
15

iranian-laravel-contributors

The list of people from Iran who have contributed to the laravel framework
40
star
16

laravel-tokenized-login

Two factor authentication in Laravel
PHP
36
star
17

eloquent-history

PHP
31
star
18

smart-realtime-facades

PHP
30
star
19

php-smart-search-replace

Smart search/replace functionality for PHP code
PHP
27
star
20

gilded_rose

Based on a tutorial for code refactoring
PHP
25
star
21

why_github_is_not_open_source

Why github.com is NOT open-source???
25
star
22

laravel-makesure

Readable syntax to write tests in laravel
PHP
21
star
23

eloquent-rating

5 star rating for eloquent models
PHP
18
star
24

laravel-file-cache-cleaner

Delete the obsolete cache files in the storage directory
PHP
15
star
25

php_token_analyzer

PHP
11
star
26

laravel-db-freeze

A package that allows you to bypass any insert, edit, delete into your database in demo mode through .env variables
10
star
27

laravel-anytoken

A minimal development package that helps you fake any api token as a valid one during development
10
star
28

composer-json

A utility class for read composer.json data and use it in PHP
PHP
9
star
29

crudbooster-statistics

Statistics module for Crudbooster CMS
HTML
8
star
30

imanghafoori1

8
star
31

laravel-microscope-ui

8
star
32

laravel-tik8

Simple modular ticketing system by laravel
8
star
33

crudbooster-logs

A plug-in for CrudBooster CMS to add log functionality
PHP
8
star
34

chat

node chat application
HTML
7
star
35

crudbooster-notifications

Adds notification functionality to crudbooster
PHP
7
star
36

laravel-nice-middlewares

This is a plug-in for laravel-middlewarize package.
PHP
6
star
37

questionist

Advanced event/listener system
PHP
6
star
38

abstract_php_filesystem

PHP
3
star
39

example_query

PHP
2
star
40

test-bin

1
star
41

laravel-endpoints

Define your endpoints as classes
1
star
42

git_toturial

1
star