Techniki Pracy
8 godz. 33 min · Laravel · Full-stack i Programowanie
Piotr PalarzWeb DeveloperKurs ten rozpoczniemy od omówienia czym jest framework Laravel i co może Ci zaoferować. Następnie zobaczysz jak skonfigurować środowisko do pracy lokalnej w formie wirtualnej maszyny z preinstalowanymi narzędziami, tj. PHP, MySQL czy serwerem nginx. Zobaczysz w jaki sposób tworzyć nowe projekty wykorzystujące Laravel, zrozumiesz strukturę katalogów projektu i skonfigurujesz polaczenie z baza danych.
W kursie nie znajdziesz czysto teoretycznych lekcji. Każda z części przybliżać nas bowiem będzie do finalnej wersji projektu, którym będzie aplikacja internetowego bloga. Funkcjonalności, które od podstaw zaimplementujemy, to m.in. dodawanie i wyświetlanie wpisów, tworzenie i przypisywanie tagów, komentowanie, rejestracja i logowanie użytkowników czy wyszukiwarka. Każda z nich odkryje przez Toba możliwości frameworka Laravel i jego sposoby na rozwiazywanie konkretnych problemów.
Laravel to framework oparty o wzorzec MVC. Na konkretnych przykładach zobaczysz co to oznacza. Tworzyć będziemy wspólnie kontrolery, do których przypiszemy stosowne adresy URL, modele, które reprezentować będą dane, a także widoki, które te dane sformatują, wplatając je w kod HTML.
Choć aby w pełni zrozumieć omawiane zagadnienia, należy znać podstawowe koncepcje relacyjnych baz danych, to pisanie zapytań SQL nie jest czymś, to będziemy musieli robić. Wszystko to za sprawa migracji oraz Eloquenta. Te pierwsze pozwolą nam zaprojektować strukturę tabel bazy danych i jedna komenda je utworzyć, a Eloquent posłuży nam do tworzenia, zapisywania i odczytywania modeli reprezentujących te dane. Wszystko to uzyskamy pisząc wyłącznie prosty kod PHP.W kursie nie zabraknie również informacji na temat tworzenia relacji. Zobaczysz m. in. jak skojarzyć autora w wpisem, jak dodawać tagi czy komentarze.
Te dwa pojęcia, choć podobne, różnią się od siebie. Pierwsze pozwala określić, czy logujący się użytkownik jest tym, za kogo się podaje. Drugie mówi nam, czy dana osoba może wykonać zadana akcje. Oba te koncepty zobaczysz w akcji na praktycznym przykładzie. Do naszego bloga dodamy pełen system autentykacji, tj. rejestracje, logowanie, resetowanie hasła i potwierdzanie adresu email. Zalogowani użytkownicy otrzymają dzięki temu bonus w postaci niewidocznych dla pozostałych osób wpisów premium. Aby zarządzać wpisami na blogu, stworzymy mini sekcje administracyjna, do której dostęp będzie miał wyłącznie użytkownik oznaczony jako administrator. Dowiesz się wówczas nie tylko jak pokazywać pewne widoki wyłącznie zautoryzowanym osobom, ale także jak zabezpieczyć kontrolery przed nieuprawnionym dostępem.
Oprócz wymienionych wyżej tematów, w kursie poruszymy również uploadowanie plików na serwer, sposoby tworzenia i wysyłania maili, prace z Front-endem, debugowanie aplikacji, korzystanie z rozszerzeń tworzonych przez aktywna społeczność Laravel czy techniki wdrażania aplikacji do produkcji. Ostatni temat będzie o tyle ciekawy, ze jest on często pomijany w materiałach tego typu. Z tym kursem Twoja aplikacja nie pozostanie wyłącznie na dysku Twojego komputera. Dowiesz się bowiem jak skonfigurować serwer VPS tak, aby wykorzystać tzw. zero-downtime deployment. Dwie komendy wystarcza wówczas do tego, aby w kilkanaście sekund nowa wersja Twojej aplikacji ukazała się światu. A wszystko to bez przerywania jej działania nawet na ułamek sekundy i bez wykorzystania płatnych rozwiązań!
Kurs ten jest dla wszystkich tych, którzy znają już podstawy języka PHP i koncepcje relacyjnych baz danych SQL oraz chcieliby przyjemnie i wydajnie tworzyć ambitne aplikacje internetowe. Znajomość samego frameworka Laravel lub podobnych rozwiązań nie jest jednak wymagana. Praca z frameworkiem omawiana jest stopniowo, od podstaw do bardziej zaawansowanych tematów. Jeśli zatem masz głowę pełną pomysłów, a chcesz uniknąć frustracji związanej z pisaniem wszystkiego od podstaw - koniecznie sięgnij po Laravel i zobacz jak to narzędzie pozwoli skupić Ci się na tym, co istotne!
5.8.x
Dodajmy sobie teraz walidację danych do tego formularza. Jest
to dosyć proste, ale wcześniej widziałeś to na podstawie kontrolera
do rejestracji, więc tamto predefiniowane dla nas. Teraz zobaczysz jak możesz to zrobić
sam, kiedy będziesz tworzył własne kontrolery. Czyli tutaj powiedzieliśmy, że wszystko
chcemy przekazać do Post create, natomiast zawsze powinniśmy walidować
najpierw dane, dlatego będziemy chcieli zrobić rzecz inną. Utworzymy
zmienną data i pod tą zmianą data będziemy tutaj przekazywać, zaraz się
wszystko stanie jasne, ona będzie tablicą i wciąż tutaj będzie
brany to o czym mówiliśmy w lekcji poprzedniej, czyli fillable, a więc nic innego
nie będzie tutaj mogło być ustawione i uważam że jest to całkiem dobra praktyka żeby
zostawić w ten sposób. Natomiast co będzie w data. Odwołamy się zmiennej
request, którą tutaj mamy. Jest to obiekt, który posiada metodę validate
i ta metoda będzie przyjmowała tablice z walidacjami
takimi jak widziałeś już przypadku rejestracji, więc możemy je uzupełnić. Chciałbym żeby
tytuł był wymagany przy required
i odzwierciedla to również struktura naszej bazy danych, jeżeli w migracji ustawiliśmy coś
jako wymagane, a jeszcze ci tylko przypomnę z czego to wynika. Jeżeli
tutaj nigdzie nie powiedzieliśmy nullable, tak jak tym miejscu przy tytule, znaczy że to pole
jest wymagane, nie da się dodać pustego rekordu bazy danych, rekordów w którym nie będzie
ustawiony na przykład title, więc jeżeli tam jest to wymagane to tutaj
walidacji również powinniśmy to wziąć pod uwagę. Następnie chciałbym
żeby to było max 255 znaków bo ustawiliśmy to pole jak string i
w bazie danych właśnie tyle się zmieści. Teraz type, w naszym
przypadku type, chciałbym żeby to też było wymagane i żeby to było
text lub photo, więc możemy zastosować walidację in
i zauważ, że do tych walidacji po dwukropku przekazuje się parametry i
te parametry można rozdzielać przecinkami, czyli tutaj jeżeli podamy
sobie text oraz photo to oznacza, że type
to może być text lub photo. Jeżeli ktoś wyśle zapytanie i to z zmodyfikuje nie
zapiszemy tego w bazie danych, to jest type. Następnie mamy date i
co ważne chciałbym zrobić tak żebyśmy nie musieli przesyłać daty, czyli
żeby to było obowiązkowe, jeżeli ktoś ustawi daty to będziemy ustawiać datę aktualną. Jak
możemy zrobić, aby jakieś pole nie było wymagane, ale kiedy jest to było o danym
typie. Jest dosyć proste, dlatego że najpierw robimy walidację nullable, to
oznacza, że może tam być pusto, ale jeżeli nie jest pusto to chcemy żeby
to było date, czyli poprawna data. Następnie image, tutaj
sobie ustawimy na nullable, czyli teoretycznie nie musielibyśmy w ogóle
tego walidować, ale dzięki tym walidacjom lepiej widzisz to tutaj dokładnie będzie
przesłane i teraz content to również jest nullable, czyli nie
musi tam to podane. Natomiast co teraz jest ważne, ten
walidator, tutaj. Będzie walidował te dane i jeśli się uda je zwalidować
zwróci te, które tutaj wypisaliśmy do data i będzie to tablica, którą
spokojnie możemy przekazać już do Post create. Natomiast jeżeli mu
się nie uda to w ogóle nie dojdziemy do tej linijki. Czyli możesz spokojnie,
bezpiecznie zakładać, że tym miejscu kiedy jesteśmy to na pewno udało się zwalidować, tutaj
żaden if nie jest potrzebne, z tego powodu, że tutaj będą wyrzucane exception
i one się zajmują wszystkim. Czyli jeżeli ten walidator nie będzie w stanie wszystkich
tych danych przepuścić, będą jakieś błędy, to on zrobi taką rzecz, że przekieruje
nas z powrotem do strony z której wysłaliśmy to zapytanie, czyli do formularza
i na tej stronie będzie ta zmienna errors, o którą my już
wcześniej zadbaliśmy. Tak to dokładnie będzie wyglądać, dlatego teraz możemy bez
problemu przyjść tutaj i uzupełnić wszystkie rzeczy związane z walidacją, więc ja
to teraz szybko zrobię i również polecam ci żebyś zrobił to u ciebie, tego już tłumaczył
nie będę, bo robiliśmy to wcześniej, więc zajmiemy się zarówno wyświetlaniem odpowiedniej
klasy, tutaj CSS oraz dodaniem tutaj old do value, po
to żeby zapamiętywało przesłane dane. Zrobię to teraz szybko, okej
w ten sposób to będzie wyglądać, odświeżam. Teraz tutaj spróbujemy sobie coś
dodać. Dodałem jeszcze jedno pole Published, bo ono nam będzie potrzebne później. Nie
mnie jednak na razie go na serwerze będziemy brać pod uwagę. Robimy Add post
i jak widzisz, pojawiają nam się błędy związane z walidacją, czyli data
nie jest wymagana, a te dwa pola są wymagane, wybierzemy sobie na przykład text
i jak widzisz., teraz tylko tytuł jest wymagany. Jeżeli uzupełnimy
wszystkie te rzeczy, to będziemy mogli poprawnie dodać nasz wpis do bazy danych, aczkolwiek
jest jeden problem, powiedziałem że tata nie jest wymagana w walidacji ale tata jest wymagana
przy ustawianiu wpisu dlatego jeżeli przy ustawianiu wpisu jest wymagana
to chciałbym tutaj zastosować pewien trick. Jeżeli ktoś dodając wpis nie chce
tutaj podawać daty po prostu chce mu ustawić dzisiejszej daty, to zrobimy
dzisiejszą datę, ale musimy to zrobić tutaj ręcznie w kontrolerze, czyli zanim
przekażemy te dane będziemy musieli zrobić if'a i w
tym if'ie ustawimy sobie datę, natomiast normalnie musielibyśmy sprawdzić isset,
powiedzmy data, następnie date, to wszystko trzeba byłoby
tutaj zrobić, ale możemy skorzystać przecież Helperów laravel'owych,
więc jest taki Helper jak Arr, wcisnąłem enter, wcisnąłem enter,
zaimportowano to tutaj u góry jak widzisz czyli support
Arr i laravel nam taki Helper daje jak
Arr add i mówimy co chcemy dodać do tablicy data. Jeżeli tego
tam nie, więc chcę tam dodać date, jeżeli to się tam nie znajduje i chcę
to ustawić na wartość na Auth, to jest globalna funkcja, która zwróci nam instancję klasy Carbon
i ta instancja jak tutaj zostanie przekazana do Post create, normalnie zostanie
zapisana w bazie danych, więc zrobimy to sposób. Jeżeli data nie jest podana, powinno
to zostać ustawione na dzisiejszą datę i w zasadzie tyle wystarczy,
żeby dodać taki wpis, dlatego spróbujemy raz jeszcze i w zasadzie,
żeby wszystkiego nie uzupełniać to ja mam taki dodatek do Chrome'a zainstalowany tutaj możemy sobie
niego zerknąć, tak to wygląda fake
data i on pozwolił mi uzupełnić ten formularz. Jeżeli
wcisnę tutaj Command Shift i dwukrotnie, to on uzupełni
wszystkie rzeczy, które tutaj można uzupełnić, tag zostawimy sobie na text,
daty nie wybieramy i spróbujemy taki wpis dodać. Jak
widzimy wpis się dodał one second ago, a to oznacza data została poprawnie również
ustawione. W ten oto, wydaje mi się prosty sposób, stworzyliśmy
możliwość dodawania nowych wpisów. Teraz będziemy chcieli się zająć również edytowaniem
tych wpisów.
create.blade.php · 4 min
@extends('layouts.master')
@section('title', 'Create New Post')
@section('content')
<div class="wrapper">
<div class="wrapper">
<div class="rte">
<h1>Create new post</h1>
</div>
<form method="POST" action="{{ route('admin.post.create') }}">
@csrf
<div class="form-fieldset">
<input class="form-field{{ $errors->has('title') ? ' is-invalid' : '' }}" type="text" name="title" placeholder="Title" value="{{ old('title') }}">
</div>
<div class="form-fieldset">
<div class="form-select{{ $errors->has('type') ? ' is-invalid' : '' }}">
<select name="type">
<option value="" disabled selected>Choose Type</option>
<option value="text">Type: Text</option>
<option value="photo">Type: Photo</option>
</select>
</div>
</div>
<div class="form-fieldset">
<label class="form-label">Date:</label>
<input class="form-field{{ $errors->has('date') ? ' is-invalid' : '' }}" type="date" name="date">
</div>
<div class="form-fieldset">
<label class="form-label">Published:</label>
<input type="checkbox" name="published" value="1">
</div>
<div class="form-fieldset">
<label class="form-label">Premium:</label>
<input type="checkbox" name="premium" value="1">
</div>
<div class="form-fieldset">
<label class="form-label">Image:</label>
<input type="file" name="image">
</div>
<div class="form-fieldset is-wide">
<textarea class="form-textarea" name="content" placeholder="Content">{{ old('content') }}</textarea>
</div>
<button class="button">Add post</button>
</form>
</div>
</div>
@endsectioncreate.blade.php · 4 min
@extends('layouts.master')
@section('title', 'Create New Post')
@section('content')
<div class="wrapper">
<div class="wrapper">
<div class="rte">
<h1>Create new post</h1>
</div>
<form method="POST" action="{{ route('admin.post.create') }}">
@csrf
<div class="form-fieldset">
<input class="form-field{{ $errors->has('title') ? ' is-invalid' : '' }}" type="text" name="title" placeholder="Title" value="{{ old('title') }}">
</div>
<div class="form-fieldset">
<div class="form-select{{ $errors->has('type') ? ' is-invalid' : '' }}">
<select name="type">
<option value="" disabled selected>Choose Type</option>
<option value="text">Type: Text</option>
<option value="photo">Type: Photo</option>
</select>
</div>
</div>
<div class="form-fieldset">
<label class="form-label">Date:</label>
<input class="form-field{{ $errors->has('date') ? ' is-invalid' : '' }}" type="date" name="date">
</div>
<div class="form-fieldset">
<label class="form-label">Published:</label>
<input type="checkbox" name="published" value="1">
</div>
<div class="form-fieldset">
<label class="form-label">Premium:</label>
<input type="checkbox" name="premium" value="1">
</div>
<div class="form-fieldset">
<label class="form-label">Image:</label>
<input type="file" name="image">
</div>
<div class="form-fieldset is-wide">
<textarea class="form-textarea" name="content" placeholder="Content">{{ old('content') }}</textarea>
</div>
<button class="button">Add post</button>
</form>
</div>
</div>
@endsectioncreate.blade.php · 4 min
@extends('layouts.master')
@section('title', 'Create New Post')
@section('content')
<div class="wrapper">
<div class="wrapper">
<div class="rte">
<h1>Create new post</h1>
</div>
<form method="POST" action="{{ route('admin.post.create') }}">
@csrf
<div class="form-fieldset">
<input class="form-field{{ $errors->has('title') ? ' is-invalid' : '' }}" type="text" name="title" placeholder="Title" value="{{ old('title') }}">
</div>
<div class="form-fieldset">
<div class="form-select{{ $errors->has('type') ? ' is-invalid' : '' }}">
<select name="type">
<option value="" disabled selected>Choose Type</option>
<option value="text">Type: Text</option>
<option value="photo">Type: Photo</option>
</select>
</div>
</div>
<div class="form-fieldset">
<label class="form-label">Date:</label>
<input class="form-field{{ $errors->has('date') ? ' is-invalid' : '' }}" type="date" name="date">
</div>
<div class="form-fieldset">
<label class="form-label">Published:</label>
<input type="checkbox" name="published" value="1">
</div>
<div class="form-fieldset">
<label class="form-label">Premium:</label>
<input type="checkbox" name="premium" value="1">
</div>
<div class="form-fieldset">
<label class="form-label">Image:</label>
<input type="file" name="image">
</div>
<div class="form-fieldset is-wide">
<textarea class="form-textarea" name="content" placeholder="Content">{{ old('content') }}</textarea>
</div>
<button class="button">Add post</button>
</form>
</div>
</div>
@endsection