Aplikacje internetowe 1 (AI1) – laboratorium nr 9
Laravel – pozostałe zagadnienia (do cz.1)
Początek laboratorium:
• w XAMPP uruchomić Apache oraz MySQL, następnie przejść do phpMyAdmin,
• pobrać na pulpit archiwum Lab009_AI1_start.zip
, w którym umieszczony jest projekt
startowy do wykonania zadań oraz rozpakować to archiwum,
• przejść do rozpakowanego folderu oraz w przypadku posiadania innych ustawień niż domyślne (np. połączenia z bazą), wykonać ich zmianę w .env.example oraz start.…,
• uruchomić skrypt start.bat
(Windows, 2x kliknięciem) lub start.sh
(inne systemy,
przez polecenie bash start.sh
).
Zadania (Laravel, problem N+1):
Zadanie 9.1: *
Wyjaśnić następujące zagadnienia:
• problem N+1
,
• Eloquent ORM, dwa tryby ładowania danych powiązanych relacjami,
• który powoduje, a który zapobiega problemowi N+1
,
• rozwiązanie problemu N+1
.
Zadanie 9.2:
Otworzyć terminal cmd (Command Prompt) w VSCode.
Uruchomić serwer deweloperski php dla przy użyciu komendy serve artisan’a
.
php artisan serve
Zadanie 9.3:
Otworzyć drugą kartę terminala cmd (Command Prompt) w VSCode. Zainstalować pakiet Laravel Debugbar oraz sprawdzić jego działanie.
composer require barryvdh/laravel-debugbar --dev
Zadanie 9.4:
Przejść na podstronę wycieczek.
Przejść do zakładki Queries
w debugbar’u.
Wyjaśnić, dlaczego wykonywane jest 8 zapytań (1 + 7).
W przeglądarce internetowej przejść pod adres:
http://localhost:8000/auth/login
Zadanie 9.5:
Zrealizować naprawę problemu N+1 poprzez zmianę ładowania „leniwego” (lazy)
na „zachłanne” (eager) kolekcji wycieczek z krajami w funkcji index w TripController
.
Przejść ponownie na podstronę wycieczek. Zaobserwować różnicę budowy zapytań.
Dodatkowo ograniczyć pobieranie tylko potrzebnych kolumn dotyczących krajów.
Ponownie zaobserwować różnicę.
Zadanie 9.6: *
Zapoznać się z innymi przykładami występowania problemu N+1
.
Zadania (Laravel, warstwa serwisów):
Zadanie 9.7:
Wyjaśnić następujące zagadnienia:
• logika biznesowa,
• warstwa serwisów (zastosowanie, zalety),
• wstrzykiwanie zależności.
(w przypadku osiągnięcia limitu artykułów z tego portalu, otworzyć linki w oknie prywatnym)
W artykule występuje także warstwa “repozytoriów”, natomiast zamiast nich, można dodać nowe funkcje w modelach (dotyczące danego modelu), które następnie używać je w serwisach.
Zadanie 9.8:
W TripController dodać konstruktor, w którym umieścić „wstrzyknięcie” serwisu „TripService” wraz z przypisaniem do zmiennej klasy (właściwości) tripService.
protected $tripService;
public function __construct(TripService $tripService)
{
$this->tripService = $tripService;
}
Zadanie 9.9:
W TripService
uzupełnić funkcję calculatePromoPrice(), w której na podstawie wartości
parametru price (obecna cena wycieczki) dokonać wyliczenia nowej ceny promocyjnej
wycieczki:
• jeśli obecna cena jest mniejsza niż 5 000 zł, to promocja nie występuje,
• jeśli obecna cena jest mniejsza niż 10 000 zł, to pomniejszyć cenę o 2 500 zł,
• w pozostałym przypadku pomniejszyć cenę o 5 000 zł.
Zwrócić nową cenę wycieczki.
Zadanie 9.10:
W TripController
w funkcji show()
wywołać funkcję calculatePromoPrice()
w celu uzyskania
nowej ceny wycieczki, którą następnie przekazać do widoku show jako zmienną
promoPrice.
Wyświetlanie nowej ceny w karcie zostało już przygotowane.
Sprawdzić wyliczenia cen dla różnych wycieczek.
Zadania (Laravel, logi, middleware):
Zadanie 9.11:
Zapoznać się z następującymi zagadnieniami:
• logi – logowanie (logs – logging),
• kanały (channels),
• poziomy logów (log levels),
• obecne ustawienia w pliku config/logging.php,
• middleware.
Wykonać poniższą własną komendę (zamieszczoną w routes/console.php
).
php artisan log:clear
[Zadanie 9.12]https://github.com/dawidolko/Web-Applications/tree/main/LAB09/task():
Dodać do funkcji show w TripController
następujące linijki.
Przejść na kilka podstron dotyczących danej wycieczki.
Następnie sprawdzić zawartość na końcu pliku storage/logs/laravel.log
, oraz ostatnie
linijki w terminalu (na którym uruchomiona jest aplikacja).
use Illuminate\Support\Facades\Log;
Log::info('Showing details for trip: '.$id);
Log::channel('stderr')->info('Showing details for trip: '.$id);
http://localhost:8000/trips/1
http://localhost:8000/trips/4
http://localhost:8000/trips/6
Zadanie 9.13:
Dodać w config/logging.php
w channels nowy kanał lab9_errors, który będzie mógł
zapisywać komunikaty o zaistniałych błędach do pliku lab9_errors.log
.
Zadanie 9.14:
Przejść do bootstrap/app.php oraz zmienić „zgłaszanie błędów/wyjątków” z std_err
na kanał utworzony w poprzednim zadaniu. Następnie:
• zalogować się na użytkownika Jan i spróbować usunąć kraj USA,
• wyłączyć bazę MySQL (w panelu XAMPP) i wykonać dowolną akcję.
Po tym sprawdzić zawartość lab9_errors.log
. Włączyć bazę MySQL.
Zadanie 9.15:
Za pomocą poniższej komendy utworzyć nowy middleware o nazwie LogActivity.
W bootstrap/app.php
zarejestrować middleware LogActivity dla grupy web.
link (brak pliku Http/Kernel.php
z Laravel’a 10)
php artisan make:middleware LogActivity
->withMiddleware(function (Middleware $middleware) {
$middleware->web(LogActivity::class);
})
Zadanie 9.16:
Przejść do app/http/Middleware/LogActivity.php
i uzupełnić funkcję handle, tak żeby była
„monitorowana aktywność użytkowników”:
• na logu w terminalu ma pojawiać się ogólna informacja, że ktoś wykonał żądanie z daną metodą HTTP na daną ścieżkę (ogólna postać),
• do logu w pliku laravel.log
ma trafiać informacja o tym który dokładnie użytkownik
wykonał żądanie z daną metodą na daną ścieżkę (konkretna postać z wartościami
parametrów),
• jeśli użytkownik nie jest zalogowany to do logu w pliku laravel.log
zamiast emaila
użytkownika ma być np. że jest on anonimowy.
public function handle(Request $request, Closure $next): Response
{
Log::channel('stderr')->notice(
"Someone did {$request->method()} on '{$request->route()->uri()}'"
);
$email = $request->user() ? $request->user()->email : 'anonymous';
Log::channel('single')->notice(
"'{$email}' did {$request->method()} on '{$request->getRequestUri()}'"
);
return $next($request);
}
Zadanie 9.17:
Sprawdzić działanie LogActivity.php
w praktyce poprzez wykonanie różnych akcji będąc
zalogowanym na różnych użytkowników.
Zadania (Laravel, locale):
Zadanie 9.18:
Zainstalować pakiet z gotowymi tłumaczeniami: laravel-lang
.
Zmienić locale w pliku config/app.php
.
composer require laravel-lang/common --dev
php artisan lang:add pl
php artisan lang:update
'locale' => 'pl',
Zadanie 9.19:
Zalogować się na Jana. Przejść do edycji dowolnej z wycieczek oraz przetestować działanie walidacji (w tym ujemny okres), zaobserwować obecne tłumaczenia komunikatów.
Zadanie 9.20:
Przejść do pliku lang/pl/validation.php
i uzupełnić go tak, aby komunikat dotyczący
okresu był już całkowicie przetłumaczony.
Zadanie 9.21:
Przejść do pliku bootstrap/app.php oraz komunikat z linijki 29 przenieść jako wartość do
pliku lang/pl.json
. Zaproponować nazwę klucza.
Następnie w jego miejscu wstawić uzyskiwanie stringu poprzez klucz.
W pliku lang/en.json
przygotować odpowiadające tłumaczenie komunikatu na j.ang
.
Sprawdzić treść komunikatu dla ustawionych locale: pl
i en
.
'locale' => 'en',
Zadanie 9.22:
Analogicznie do poprzedniego zadania przygotować tłumaczenie tytułu aplikacji: „Wycieczki górskie” na „Mountain Trips” i zastosować je w szablonach:
• head.blade.php
,
• navbar.blade.php
,
• footer.blade.php
.
Analogicznie sprawdzić dla locale: pl
i en
.
<footer class="container-fluid bg-body-tertiary ">
<div class="row text-center pt-2">
<p>© – 2024</p>
</div>
</footer>
Zadania (pozostałe zagadnienia):
Zadanie 9.23: *
Jasny/ciemny motyw – możliwy do przełączenia po kliknięciu w księżyc w navbarze, co za pomocą JS powoduje zmianę wartości atrybutu data-bs-theme. Ikona księżyca wykorzystana ze zbioru ikon Bootstrap’a.
data-bs-theme="..."
Zadanie 9.24: *
Pamiętanie ulubionych wycieczek w ramach sesji – możliwość polubienia/odlubienia wycieczki poprzez kliknięcie serca w danym wierszu. Po wygaśnięciu/skasowaniu sesji ulubione wycieczki są utracone. Ikony serc wykorzystane ze zbioru ikon Bootstrap’a.
Zadanie 9.25: *
Strony błędów – dla wybranych kodów (statusów) HTTP można utworzyć widoki, zastępujące domyślny widok.
http://localhost:8000/trips/8
Zadanie 9.26: *
Upload obrazka wycieczki – formularz przyjmujący kilka obrazków w formacie .jpg
, .jpeg
oraz zapisujący je na dysku w storage’u.
Reguły walidacji obejmują walidację dla kilku plików na raz oraz zawierają własne
komunikaty.
Po pomyślnym zapisaniu plików pokazuje się toast informacyjny.
Zadanie 9.27: *
Transakcje – …
-
– zadania/podpunkty do samodzielnego dokończenia/wykonania,
-
– zadania/podpunkty dla zainteresowanych.
Do spakowania projektu należy wykorzystać skrypt archiwizacja.bat
. Po rozpakowaniu
projektu należy użyć ponownie start.bat.
Wersja pliku: v1.0