PHP code example of artisansdk / cqrs

1. Go to this page and download the library: Download artisansdk/cqrs library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

artisansdk / cqrs example snippets


namespace App\Commands;

use App\User;
use ArtisanSdk\CQRS\Command;

class SaveUser extends Command
{
    protected $model;

    public function __construct(User $model)
    {
        $this->model = $model;
    }

    public function run()
    {
        $user = $this->model;
        $user->email = $this->argument('email');
        $user->save();

        return $user;
    }
}

$user = ArtisanSdk\CQRS\Dispatcher::make()
    ->command(App\Commands\SaveUser::class)
    ->email('[email protected]')
    ->run();

$user = App\Commands\SaveUser::make()
    ->email('[email protected]')
    ->run();

namespace App\Http\Controllers;

use App\Commands\SaveUser;
use App\Http\Controllers\Controller;
use ArtisanSdk\CQRS\Concerns\CQRS;
use Illuminate\Http\Request;

class UserController extends Controller
{
    use CQRS;

    public function post(Request $request)
    {
        return $this->command(SaveUser::class)
            ->email($request->input('email'))
            ->run();
    }
}

$user = (new App\Commands\SaveUser(new App\User))
    ->arguments([
        'email' => '[email protected]',
    ])
    ->run();

namespace App\Commands;

use App\User;
use ArtisanSdk\Contract\Eventable;
use ArtisanSdk\CQRS\Command;

class SaveUser extends Command implements Eventable
{
    protected $model;

    public function __construct(User $model)
    {
        $this->model = $model;
    }

    public function run()
    {
        $user = $this->model;
        $user->email = $this->argument('email');
        $user->save();

        return $user;
    }
}

$user = App\Commands\SaveUser::make()
    ->email('[email protected]')
    ->silently();

namespace App\Commands;

use ArtisanSdk\Contract\Buses\Transactional;
use ArtisanSdk\CQRS\Command;

class SaveUser extends Command implements Transactional
{
    protected $model;

    public function __construct(User $model)
    {
        $this->model = $model;
    }

    public function run()
    {
        $user = $this->model;
        $user->email = $this->argument('email');
        $user->save();

        return $user;
    }
}

namespace App\Commands;

use App\User;
use ArtisanSdk\Contract\Buses\Transactional;
use ArtisanSdk\CQRS\Command;

class ChangePassword extends Command implements Transactional
{
    protected $model;

    public function __construct(User $model)
    {
        $this->model = $model;
    }

    public function run()
    {
        if( ! $user = $this->user($email) ) {
            $this->abort();

            return false;
        }

        $user->password = $this->argument('password');
        $user->save();

        return $user;
    }

    protected function user() : User
    {
        return $this->model
            ->where('email', $this->argument('email'))
            ->first();
    }
}

namespace App\Events;

use App\User;
use ArtisanSdk\CQRS\Events\Event;

class UserSaved extends Event
{
    protected $user;

    public function __construct(User $user)
    {
        $this->user = $user;
    }
}

namespace App\Commands;

use App\Events\UserSaved;
use ArtisanSdk\Contract\Eventable;
use ArtisanSdk\CQRS\Command;

class SaveUser extends Command implements Eventable
{
    protected $model;

    public function __construct(User $model)
    {
        $this->model = $model;
    }

    public function run()
    {
        $user = $this->model;
        $user->email = $this->argument('email');
        $user->save();

        return $user;
    }

    public function afterEvent()
    {
        return UserSaved::class;
    }
}

$command = (new App\Commands\SaveUser(new App\User()));
$builder = new ArtisanSdk\CQRS\Builder($command);
$user = $builder->email('[email protected]')->run();
$event = new App\Events\UserSaved($user);

namespace App\Commands;

use ArtisanSdk\CQRS\Command;

class SendUserWelcomeEmail extends Command
{
    public function run()
    {
        $user = $this->argument('user');

        // ... the $user is an instance of `App\User` and can be used in a Mailable
    }
}

event()->listen(App\Events\UserSaved::class, App\Commands\SendUserWelcomeEmail::class);

$command = (new App\Commands\SaveUser(new App\User()));
$builder = new ArtisanSdk\CQRS\Builder($command);
$user = $builder->email('[email protected]')->run();
$event = new App\Events\UserSaved($user);
$handler = (new App\Commands\SendUserWelcomeEmail());
$result = $handler->handle($event);

namespace App\Commands;

use ArtisanSdk\CQRS\Command;
use ArtisanSdk\CQRS\Triats\Queue;
use ArtisanSdk\Contract\CQRS\Queuable;

class SendUserWelcomeEmail extends Command implements Queueable
{
    use Queues;

    // ... same as before but it'll now be queued
}

$job = App\Commands\SendUserWelcomeEmail::make()
    ->email('[email protected]')
    ->queue();

$job = (new App\Commands\SendUserWelcomeEmail())
    ->queue(new ArtisanSdk\CQRS\Events\Event([
        'email' => '[email protected]',
    ]));

namespace App\Queries;

use ArtisanSdk\CQRS\Query;

class GetStates extends Query
{
    public function builder()
    {
        // 

$states = App\Queries\GetStates::make()->get();

namespace App\Queries;

use ArtisanSdk\CQRS\Query;
use GuzzleHttp\Client as Guzzle;

class GeocodeIP extends Query
{
    protected $http;

    public function __construct(Guzzle $http)
    {
        $this->http = $http;
    }

    public function builder()
    {
        //        // Use Guzzle to get the geocoded response
        $response = $this->http->get($url);

        // Parse the JSON body of the response
        return json_decode($response->getBody()->getContent());
    }
}

$result = App\Queries\GeocodeIP::make()
    ->ip('104.131.182.33')
    ->get();

echo $result->zip_code; // 07014

namespace App\Queries;

use App\User;
use ArtisanSdk\CQRS\Query;

class ListUsers extends Query
{
    protected $model;

    public function __construct(User $model)
    {
        $this->model = $model;
    }

    public function builder()
    {
        $query = $this->model->query();

        $order = $this->option('order', 'id', ['in:id,name,email,created_at,updated_at']);
        $sort = $this->option('sort', 'desc', ['in:asc,desc']);

        $query->orderBy($order, $sort);

        if( $keyword = $this->option('keyword', null, ['string', 'max:64']) ) {
            $this->scopeKeyword($query, $keyword);
        }

        return $query;
    }

    // This method could be called anything, but naming it similar to Eloquent
    // helps clarify the intent of such builder abstractions to protected methods.
    protected scopeKeyword($query, string $keyword)
    {
        $wildcard = sprintf('%%s%', $keyword);

        return $query->where(function($query) use ($wildcard) {
            return $query
                ->orWhere('name', 'LIKE', $wildcard)
                ->orWhere('email', 'LIKE', $wildcard);
        });
    }
}

// Get the users with default arguments: sort desc by name
$users = App\Queries\ListUsers::make()->get();

// Get the users using custom arguments which are validated in the builder
$users = App\Queries\ListUsers::make()
    ->order('name')
    ->sort('asc')
    ->keyword('john')
    ->get();

// Get the ?page=# results of users with only the name and email columns
$paginator = App\Queries\ListUsers::make()->paginate(10, ['name', 'email']);

// select * from `users` order by `name` desc
$sql = App\Queries\ListUsers::make()
    ->order('name')
    ->toSql();

// Bypass the run() method and execute against the builder directly
$users = App\Queries\ListUsers::make()
    ->order('name')
    ->builder()
    ->limit(10)
    ->get();

// Customize the builder outside of the query
$query = App\Queries\ListUsers::make();
$query->order('name');
$builder = $query->builder(); // get the builder outside of the query
$builder->whereIn('id', [1, 2, 3]); // a customization to the query
$users = $query->get(); // since $builder is referenced, query executes against customized builder

namespace App\Queries;

use App\User;
use ArtisanSdk\CQRS\Query;

class FindUserByEmail extends Query
{
    protected $model;

    public function __construct(User $model)
    {
        $this->model = $model;
    }

    public function builder()
    {
        return $this->model->query()
            ->where('email', $this->argument('email', ['email']));
    }

    public function run()
    {
        return $this->builder()->first();
    }

    public function firstOrFail()
    {
        return $this->builder()->firstOrFail();
    }

    public static function find(string $email)
    {
        return static::make()->email($email)->run();
    }

    public static function findOrFail(string $email)
    {
        return static::make()->email($email)->firstOrFail();
    }
}

$user = ArtisanSdk\CQRS\Dispatcher::make()
    ->query(App\Queries\FindUserByEmail::class)
    ->email('[email protected]')
    ->run(); // or get()

$user = App\Queries\FindUserByEmail::make()
    ->email('[email protected]')
    ->get();

// Throw Illuminate\Database\Eloquent\ModelNotFoundException if not found
$user = App\Queries\FindUserByEmail::make()
    ->email('[email protected]')
    ->firstOrFail();

// Returns null if not found
$user = App\Queries\FindUserByEmail::find('[email protected]');

// Throw Illuminate\Database\Eloquent\ModelNotFoundException if not found
$user = App\Queries\FindUserByEmail::findOrFail('[email protected]');

namespace App\Http\Controllers;

use App\Commands\FindUserByEmail;
use App\Http\Controllers\Controller;
use ArtisanSdk\CQRS\Concerns\CQRS;
use Illuminate\Http\Request;

class UserController extends Controller
{
    use CQRS;

    public function show(Request $request, string $email)
    {
        return $this->query(FindUserByEmail::class)
            ->email($email)
            ->firstOrFail();
    }
}

namespace App\Queries;

use App\Post;
use ArtisanSdk\Contract\Eventable;
use ArtisanSdk\CQRS\Query;

class MostPopularPosts extends Query implements Eventable
{
    protected $model;

    public function __construct(Post $model)
    {
        $this->model = $model;
    }

    public function builder()
    {
        return $this->query()
            ->orderBy('views', 'desc')
            ->take($this->option('limit', 10, 'is_integer'));
    }
}

namespace App\Queries;

use App\Post;
use ArtisanSdk\Contract\Cacheable;
use ArtisanSdk\CQRS\Query;

class MostPopularPosts extends Query implements Cacheable
{
    public $ttl = 60 * 60 * 24 * 7; // 1 week cache

    // ... same logic as above
}

// Get the results and cache them for future query execution
$posts = MostPopularPosts::make()->get();

// Secondary calls return the cached results
$cached = MostPopularPosts::make()->get();

// Bust the cache then get the results
$busted = MostPopularPosts::make()->busted()->get();

// This is shorthand for cache busted results
$busted = MostPopularPosts::make()->fresh();

namespace App\Commands;

use App\Events\NewPasswordSet;
use App\Events\ChangingPassword;
use ArtisanSdk\Contract\Eventable;
use ArtisanSdk\CQRS\Command;

class ChangePassword extends Command implements Eventable
{
    public function beforeEvent(array $arguments)
    {
        return ChangingPassword::class;
    }

    public function run()
    {
        $user = $this->argument('user');
        $user->password = $this->argument('password');

        return $this->save($user);
    }

    public function afterEvent($result)
    {
        return NewPasswordSet::class;
    }
}

namespace App\Commands;

use App\Invoice;
use App\Coupon;
use ArtisanSdk\CQRS\Command;
use Illuminate\Validation\Factory as Validator;

class CalculateInvoice extends Command
{
    public function run()
    {
        // Validate the argument is simply set with a non empty value
        $number = $this->argument('number');

        // Validate the argument matches the Invoice class
        $invoice = $this->argument('invoice', Invoice::class);

        // Validate the argument against a rule of validation rules...
        $subtotal = $this->argument('subtotal', ['integer', 'min:0'])

        // ...or construct it manually yourself for something more complicated
        $subtotal = $this->argument('subtotal', Validator::make($this->arguments(), [
            'subtotal' => ['integer', 'min:0', 'lte:total'],
        ]));

        // Validate the argument against a custom callable...
        $coupon = $this->argument('coupon', function(string $code, string $argument) {
            return $this->couponExists($code, $argument);
        });

        // ... or just reference a method on a callable class
        $coupon = $this->argument('coupon', [$this, 'couponExists']);
    }

    public function couponExists(string $code, string $argument)
    {
        return Coupon::where('code', $code)->exists();
    }
}

namespace App\Commands;

use App\Invoice;
use ArtisanSdk\CQRS\Command;

class CalculateInvoice extends Command
{
    public function run()
    {
        $invoice = $this->argument('invoice', Invoice::class);

        if( $this->hasOption('save') && true === $this->option('save')) {
            $invoice->save();
        }

        return $invoice;
    }
}

namespace App\Commands;

use App\Invoice;
use ArtisanSdk\CQRS\Command;

class CalculateInvoice extends Command
{
    public function run()
    {
        $invoice = $this->argument('invoice', Invoice::class);

        if( $this->option('save', true) ) {
            $invoice->save();
        }

        return $invoice;
    }
}

namespace App\Commands;

use App\Invoice;
use App\User;
use ArtisanSdk\CQRS\Command;

class CalculateInvoice extends Command
{
    public function run()
    {
        $invoice = $this->argument('invoice', Invoice::class);

        // This is wasteful since you have to resolve the user even when not used
        // $editor = $this->option('editor', auth()->user());

        // Resolve the authenticated user as the default using a closure...
        $editor = $this->option('editor', function(string $option) {
            return auth()->user();
        });

        // ... or just reference a method on a callable class
        $editor = $this->option('editor', [$this, 'resolveUser']);

        $invoice->editor()->associate($user);

        $invoice->save();

        return $invoice;
    }

    public function resolveUser(string $option) : User
    {
        return auth()->user();
    }
}

namespace App\Commands;

use ArtisanSdk\CQRS\Command;

class CalculateInvoice extends Command
{
    public function run()
    {
        $invoice = $this->argument('invoice');
        $invoice->total = 100;

        return $this->save($invoice);
    }
}

namespace App\Commands;

use App\User;
use App\Commands\ResetUserPassword;
use App\Events\UserPasswordReset;
use App\Events\UserRegistered;
use ArtisanSdk\CQRS\Command;
use ArtisanSdk\Contract\Eventable;

class RegisterUser extends Command implements Eventable
{
    protected $user;

    public function __construct(User $user)
    {
        $this->user = $user;
    }

    public function run()
    {
        $user = new User();
        $user->email = $this->argument('email');
        $this->save($user);

        return $this->command(ResetUserPassword::class)
            ->user($user)
            ->silently();
    }

    public function afterEvent()
    {
        return UserRegistered::class;
    }
}

class ResetUserPassword extends Command implements Eventable
{
    public function run()
    {
        $user = $this->argument('user');
        $user->password = null;

        return $this->save($user);
    }

    public function afterEvent()
    {
        return ResetUserPassword::class;
    }
}

ArtisanSdk\CQRS\Builder::macro('attempt');

ArtisanSdk\CQRS\Builder::macro('attempt', function(...$arguments) {
    try {
        return $this->run();
    } catch (Exception $error) {
        throw new App\Exceptions\Error(sprintf($arguments[0], $error->getMessage()));
    }
});

$user = App\Commands\SaveUser::make()
    ->email('[email protected]')
    ->attempt('User could not be saved: %s');