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;
}
}
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();
}
}
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
}
}
$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
}
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());
}
}
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;
}
}