9. diel - Jednoduchý redakčný systém v Laravel - Správa článkov
V minulej lekcii, Jednoduchý redakčný systém v Laravel - Tvorba článkov , sme začali s tvorbou administrácie pre jednoduchý redakčný systém v Laravel frameworku. Vytvorili sme si zoznam článkov a editor pre ich tvorbu. V dnešnej tutoriále dokončíme administráciu pridaním editácia článkov spolu s ich odstraňovaním a povieme si niečo o triedach HTTP požiadaviek.
HTTP požiadavky
Predtým než sa vrhneme na vytváranie nových častí aplikácie, sa
spätne pozrieme na našej metódu store()
v kontroleru
ArticleController.php
, ktorú sme definovali v minulej lekcii. Ako
už názov napovedá, táto metóda by mala slúžiť pre vkladanie nového
záznamu (v našom prípade článku) do databázy. Okrem iného ale obsahuje
tiež validáciu prijatých dát, čo v prípade väčších formulárov nemusí
byť práve praktické. Preto si predstavíme tzv. Request
triedy.
Request triedy
Request
triedy kontrolujú, či je používateľ oprávnený pre
odoslanie danej požiadavky, a zvalidujú odoslané dáta. Môžeme tak
presunúť sadu pravidiel daného HTTP požiadavky práve do nich a metóda
kontroleru bude potom obsahovať len logiku akcie. Poďme si teraz takú triedu
vytvoriť.
Pre akciu store()
si vygenerujeme triedu
StoreRequest
pomocou Artisan príkazu make:request
,
ktorý nepotrebuje žiadne špeciálne možnosti:
php artisan make:request Article/StoreRequest
Keďže tried požiadaviek môžeme mať pre jeden kontrolér viac, je dobrým zvykom vytvárať pre každý kontrolér vlastné zložku.
Vytvorila sa nám automaticky nový priečinok
app/Http/Requests/
následne s nami definovanou podpriečinok
Article/
. V nej nájdeme vygenerovaný súbor
StoreRequest.php
, ktorého obsah je nasledovné:
<?php namespace App\Http\Requests\Article; use Illuminate\Foundation\Http\FormRequest; class StoreRequest extends FormRequest { /** * Determine if the user is authorized to make this request. * * @return bool */ public function authorize() { return false; } /** * Get the validation rules that apply to the request. * * @return array */ public function rules() { return [ // ]; } }
Novo vygenerovaná trieda StoreRequest
dedič triedu frameworku
FormRequest
obsahuje iba tieto dve metódy:
authorize()
- Určuje, či je používateľ oprávnený pre odoslania požiadavky. Ide o jedno z miest, kam môžeme toto overenie umiestniť. Ďalším z nich môže byť napríklad middleware, to si však ukážeme až v ďalších lekciách.rules()
- Vracia pole s nastavenými overovacími pravidlami.
Keďže sa oprávneniami (a užívateľmi) zatiaľ nezaoberáme, môžeme
metódu authorize()
kompletne odstrániť. Ak totiž nie je
definovaná, automaticky sa overenie považuje za úspešné. Čo už nás ale
zaujíma viac, je práve metóda rules()
, ktorú naplníme
pravidlami z metódy store()
nášho kontroleru. Bude teda vyzerať
takto:
/** * Vrať validační pravidla pro formulář, který má na starosti tvorbu článků. * * @return array */ public function rules() { return [ 'title' => ['required', 'min:3', 'max:80'], 'url' => ['required', 'min:3', 'max:80', 'unique:articles,url'], 'description' => ['required', 'min:25', 'max:255'], 'content' => ['required', 'min:50'], ]; }
Následne môžeme validáciu z metódy store()
kompletne
odstrániť. Upravíme však typ objektu premennej $request
na
našej Request
triedu miesto tej obyčajnej, aby sa následne
aplikovala aj definované pravidlá:
/** * Zvaliduj odeslaná data přes formulář a vytvoř nový článek. * * @param StoreRequest $request * @return Response */ public function store(StoreRequest $request) { Article::create($request->all()); return redirect()->route('article.index'); }
Nezabudneme samozrejme importovať našej novú triedu:
use App\Http\Requests\Article\StoreRequest;
Z metódy, ktorá na začiatku mala 25 riadkov vrátane dokumentácie, sme následne vytvorili metódu s iba 12 riadkami a to sme zachovali úplne rovnakú funkčnosť! Len si teraz skúste vytvoriť nejaký článok a ignorovať niektoré z validačných pravidiel. Trieda HTTP požiadavky vás nepustí ďalej
Editácia článkov
Poďme sa teraz presunúť k editácii článku.
Akcie edit () a update ()
Pohľad s formulárom pre jeho úpravu budeme vracať v metóde
edit()
:
/** * Zobraz formulář pro editaci článku a předej danému pohledu načtený článek. * * @param Article $article * @return Response */ public function edit(Article $article) { return view('article.edit', ['article' => $article]); }
Samotná úprava záznamu bude prebiehať v metóde
update()
:
/** * Zvaliduj odeslaná data přes formulář a uprav načtený článek. * * @param UpdateRequest $request * @param Article $article * @return Response */ public function update(UpdateRequest $request, Article $article) { $article->update($request->all()); return redirect()->route('article.index'); }
Rovnako ako u akcie store()
, aj tu odovzdáme Eloquent metóde
iba polia dát z formulára, v tomto prípade metóde update()
.
UpdateRequest
Pre validáciu dát opäť používame vlastné Request
triedu s
názvom UpdateRequest
, ktorú si teraz vygenerujeme v priečinku
app/Http/Requests/Article/
pomocou už spomínaného Artisan
príkazu:
php artisan make:request Article/UpdateRequest
Túto vygenerovanú triedu si ihneď upravíme. Odstránime metódu
authorize()
a definujeme si validačné pravidlá v metóde
rules()
:
<?php namespace App\Http\Requests\Article; use Illuminate\Foundation\Http\FormRequest; use Illuminate\Validation\Rule; class UpdateRequest extends FormRequest { /** * Vrať validační pravidla pro formulář, který má na starosti editaci článků. * * @return array */ public function rules() { return [ 'title' => ['required', 'min:3', 'max:80'], 'url' => [ 'required', 'min:3', 'max:80', Rule::unique('articles', 'url')->ignore($this->route('article')->id), ], 'description' => ['required', 'min:25', 'max:255'], 'content' => ['required', 'min:50'], ]; } }
Pre editáciu článku sa validačné pravidlá stala trochu zložitejšími.
Pre validačný pravidlo unique
musíme definovať výnimku
aktuálneho záznamu. Keby sme ju totiž nedefinovali a chceli pozmeniť
článok bez modifikácie jeho URL, validácia by nám následne vyhodila chybu,
že v databáze už existuje článok s danou URL adresou, aj keď sa jedná o
práve editovaný článok.
Túto výnimku nastavujeme skrz metódu ignore()
Builderu
Unique
, ktorá prijíma ID záznamu. Tiež si všimnite ďalšie
výhody parametrov fungujúcich cez dependency injection (tzv. Route model
binding). Inštanciu modelu článku môžeme ľahko získať pomocou
metódy route()
triedy frameworku FormRequest
, kedy
odovzdáme názov parametra definovaného v routovacím súbore a nemusíme
tento záznam zložito vyberať z databázy iba cez odovzdaný identifikátor (v
našom prípade URL článku).
Nakoniec pridáme do nášho kontroleru ArticleController
import
tejto novej triedy:
use App\Http\Requests\Article\UpdateRequest;
Pohľad
Teraz si vytvoríme pohľad s názvom edit.blade.php
v
priečinku resources/views/article/
, ktorý je takmer totožný s
pohľadom create.blade.php
:
@extends('base') @section('title', 'Editace článku ' . $article->title) @section('description', 'Editor pro editaci článků.') @section('content') <h1>Editace článku {{ $article->title }}</h1> <form action="{{ route('article.update', ['article' => $article]) }}" method="POST"> @csrf @method('PUT') <div class="form-group"> <label for="title">Nadpis</label> <input type="text" name="title" id="title" class="form-control" value="{{ old('title') ?: $article->title }}" required minlength="3" maxlength="80" /> </div> <div class="form-group"> <label for="url">URL</label> <input type="text" name="url" id="url" class="form-control" value="{{ old('url') ?: $article->url }}" required minlength="3" maxlength="80" /> </div> <div class="form-group"> <label for="description">Popisek článku</label> <textarea name="description" id="description" rows="4" class="form-control" required minlength="25" maxlength="255">{{ old('description') ?: $article->description }}</textarea> </div> <div class="form-group"> <label for="content">Obsah článku</label> <textarea name="content" id="content" class="form-control" rows="8">{{ old('content') ?: $article->content }}</textarea> </div> <button type="submit" class="btn btn-primary">Uložit článek</button> </form> @endsection @push('scripts') <script type="text/javascript" src="{{ asset('//cdn.tinymce.com/4/tinymce.min.js') }}"></script> <script type="text/javascript"> tinymce.init({ selector: '#content', plugins: [ 'advlist autolink lists link image charmap print preview anchor', 'searchreplace visualblocks code fullscreen', 'insertdatetime media table contextmenu paste' ], toolbar: 'insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image', entities: '160,nbsp', entity_encoding: 'raw' }); </script> @endpush
Keďže HTTP akcie store()
je typu
PUT
, musíme vo formulári opäť použiť Blade direktívu
@method
.
Ak teraz vyskúšame upraviť niektorý z existujúcich článkov, všetko prebehne úplne v poriadku. Za pozornosť ešte stojí dátum poslednej zmeny v zozname článkov, ktorý sa automaticky aktualizuje pri akejkoľvek zmene daného záznamu. Len si to sami vyskúšajte
Odstraňovanie článkov
Posledná časť administrácie, ktorá nám chýba, je odstraňovanie
článkov. Keďže formulár pre túto akciu už máme vytvorený v zozname
článkov a venovali sme sa mu minulú lekciu, stačí nám teraz iba upraviť
akciu destroy()
v našom kontroleru:
/** * Odstraň článek z databáze. * * @param Article $article * @return Response */ public function destroy(Article $article) { try { $article->delete(); } catch (\Exception $exception) { return redirect()->back()->withErrors(['Při procesu odstranění článku došlo k chybě.']); } return redirect()->route('article.index'); }
Na odstránenie záznamu používame Eloquent metódu delete()
,
v ktorej však môže dôjsť k výnimke. Tú musíme ošetriť, aby sa
užívateľovi nezobrazila stránka s chybou 500. presmeruje ho teda späť (na
to používame metódu back()
builder funkcia
redirect()
) a dáme mu vedieť, že proces odstránenia sa
nepodaril.
Týmto sme dokončili vzhľadnú a plne fungujúce administráciu. Ak sa vám niečo nepodarilo, môžete si stiahnuť projekt z priloženého archívu nižšie. V opačnom prípade výsledok nášho snaženia môžeme zhrnúť takto obrázkom:
V budúcej lekcii, Kvíz - Štruktúra projektu, migrácia a šablóny v Laravel , sa zameriame viac na front-end časť našej aplikácie. Pozrieme sa totiž na možnosti kompilácie súborov, ako sú JavaScript, SCSS, LESS a ďalšie.
V nasledujúcom kvíze, Kvíz - Štruktúra projektu, migrácia a šablóny v Laravel, si vyskúšame nadobudnuté skúsenosti z predchádzajúcich lekcií.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 177x (46.79 MB)
Aplikácia je vrátane zdrojových kódov v jazyku PHP