Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Finding Laravel Best Practices in 2018

nunulk
September 08, 2018

Finding Laravel Best Practices in 2018

nunulk

September 08, 2018
Tweet

More Decks by nunulk

Other Decks in Technology

Transcript

  1. Routing 
 Route::get('/', function () { return view('welcome'); }); Auth::routes();

    Route::get('/home', 'HomeController@index')->name('home');
  2. Middleware public function handle($request, Closure $next, $guard = null) {

    if (Auth::guard($guard)->check()) { return redirect('/home'); } return $next($request); }
  3. Request public function authorize() { return true; } public function

    rules() { return [ 'subject' => 'required', 'priority' => ‘required|in:high,normal,low’, 'status' => ‘required|in:open,in_progress,close’, 'due_to' => ‘nullable|date', ‘assigned_to' => ‘nullable|exists:users,id’, 'description' => 'nullable|max:800', ]; }
  4. Controller public function create(CreateTaskRequest $request) { $task = new Task();

    $task->subject = $request->input('subject'); $task->assigned_to = $request->input(‘assigned_to'); $task->priority = $request->input('priority'); $task->status = $request->input('status'); $task->due_to = $request->input('due_to'); $task->description = $request->input('description'); $task->created_by = Auth::id(); $task->save();
 return new JsonResponse($task, Response::HTTP_CREATED); }
  5. Event public function create(CreateTaskRequest $request) { $task = new Task();


    // (snip)
 $task->save();
 TaskCreated::dispatch($task);
 return new JsonResponse($task, Response::HTTP_CREATED); }
  6. EventListener public function handle(TaskCreatedEvent $event) { $assignee = $event->task->assignee; if

    (is_null($assignee)) { return; } $assignee->notify(new TaskCreated($event->task)); }
  7. Request (before) public function authorize() { return true; } public

    function rules() { return [ 'subject' => 'required', 'priority' => ‘required|in:high,normal,low’, 'status' => ‘required|in:open,in_progress,close’, 'due_to' => ‘nullable|date', ‘assigned_to' => ‘nullable|exists:users,id’, 'description' => 'nullable|max:800', ]; }
  8. Request (after) // CreateTaskRequest public function authorize() { return true;

    } public function rules() { return [ ‘subject' => ‘required|max:255’, 'priority' => ['required', Rule::in(Priority::values())], 'status' => ['required', Rule::in(Status::values())], 'due_to' => ‘nullable|date’, ‘assigned_to' => ‘nullable|exists:users,id’, 'description' => ‘nullable|max:800', ]; }
  9. Controller (before) public function create(CreateTaskRequest $request) { $task = new

    Task(); $task->subject = $request->input('subject'); $task->assigned_to = $request->input(‘assigned_to'); $task->priority = $request->input('priority'); $task->status = $request->input('status'); $task->due_to = $request->input('due_to'); $task->description = $request->input('description'); $task->created_by = Auth::id(); $task->save();
 return new JsonResponse($task, Response::HTTP_CREATED); }
  10. Controller (after) public function create(CreateTaskRequest $request) { $task = $request->makeTask();

    $task->save();
 return response()->json($task, Response::HTTP_CREATED); }
  11. Controller (after) class CreateTaskRequest extends FormRequest { public function makeTask():

    Task { return new Task([
 ‘created_by' => $this->user()->id
 + $this->validated()
 ]); } }
  12. Event/Job/Notification public function create(CreateTaskRequest $request) { $task = $request->makeTask();
 $task->save();


    TaskCreated::dispatch($task);
 return response()->json($task, Response::HTTP_CREATED); }
  13. EventListener (before) public function handle(TaskCreatedEvent $event) { UpdateTaskAggregates::dispatch($task);
 $assignee =

    $event->task->assignee; if (is_null($assignee)) { return; } $assignee->notify(new TaskCreated($event->task)); }
  14. EventListener (after) class UpdateTaskAggregates implements ShouldQueue { public function handle(TaskCreatedEvent

    $event) { UpdateTaskAggregatesJob::dispatch($task);
 } }
 
 class SendTaskCreatedNotification implements ShouldQueue { public function handle(TaskCreatedEvent $event) { $assignee = $event->task->assignee; if (is_null($assignee)) { return; } $assignee->notify(new TaskCreated($event->task)); } }
  15. Model (before) 
 public function search(SearchTaskRequest $request) { $query =

    Task::latest(); $priority = $request->input('priority'); if ($priority) { $query->where('priority', $priority); } $dueToFrom = $request->input(‘due_to.from'); if ($dueToFrom) { $query->where('due_to', ‘>=‘, $dueToFrom); } $dueToTo = $request->input(‘due_to.to’); if ($dueToTo) { $query->where('due_to', ‘<=‘, $dueToTo); } return $query->get(); }
  16. Model (after) 
 class SearchTaskQueryBuilder { private $params; public function

    __construct(array $params) { $this->params = $params; } public function build(Builder $builder): Builder { // ͜͜ͰΫΤϦΛϏϧυ͢Δ
 } }

  17. Model (after) 
 // Task public function scopeSearch(
 Builder $query,

    SearchTaskQueryBuilder $builder) { return $builder->build($query); }
 
 // Task\SearchTaskController
 public function __invoke(SearchTaskRequest $request) { return Task::search($request->createQueryBuilder())->get(); }
  18. Model (before) $ php artisan tinker Psy Shell v0.9.7 (PHP

    7.1.16 — cli) by Justin Hileman >>> dump($task->priority) => "normal"
  19. Model (after) $ php artisan tinker Psy Shell v0.9.7 (PHP

    7.1.16 — cli) by Justin Hileman >>> dump($task->priority) App\Models\Task\Priority {#2878 #value: "normal" }
  20. Model (after) // Task /** * @param $value * @return

    Priority * @throws \UnexpectedValueException */ public function getPriorityAttribute(string $value): Priority { return new Priority($value); } /** * @param Priority $priority * @return void */ public function setPriorityAttribute(Priority $priority) { $this->attributes['priority'] = $priority->getValue(); }
  21. DI (before) 
 class ExternalItsController extends Controller { private $issueTracker;

    public function __construct() { $this->issueTracker = new GitHub(); } public function index() { // snip
 } }

  22. DI (after) 
 class ExternalItsController extends Controller { private $issueTracker;

    public function __construct(IssueTracker $issueTracker) { $this->issueTracker = $issueTracker; } public function index() {
 $issueTracker = app(IssueTracker::class); // snip
 } }

  23. DI (after) class AppServiceProvider extends ServiceProvider { public function register()

    { $this->app->bind(IssueTracker::class, function () { return new GitHub(); }); } }
  24. DI (after) class AppServiceProvider extends ServiceProvider { public function register()

    { $this->app ->when(ExternalItsController::class) ->needs(IssueTracker::class) ->give(function () { return new GitHub(); }); } }