1. diel - Rezervačný systém v Symfony - Založenie projektu a prihlásenie
Zdravím všetky pokročilejšie programátorov v kurze tutoriálov pre PHP framework Symfony.
Budeme tu programovať rezervačný systém pre vozidlá. K dispozícii bude samozrejme základná bezpečnosť prihlásením emailom a heslom, užívateľské role (admin, bežný užívateľ), pridávanie vozidiel, ich úprava a mnoho ďalšieho.
Na väčšom projekte nás stretnú nové problémy, s ktorými sme sa ešte nestretli, a ukážeme si ich riešenie.
Ak za sebou nemáte naše minulé lekcie a alebo práve začínate sa Symfony, odporúčam sa prvýkrát pozrieť na kurz Základy frameworku Symfony.
Príprava projektu
Najprv si pripravíme celý projekt. Keďže je vydaná Symfony verzia 5, založíme si projekt nad touto verziou. Začneme s požiadavkami pre túto verziu Symfony. Nainštalujeme si PHP verziu 7.2.5 a vyšší. Ďalej budeme potrebovať composer pre inštaláciu balíkov a samotného frameworku a samozrejme databázu.
Symfony projekt
Ak máme všetko pripravené, vytvoríme si pre projekt zložku a v nej zahájime inštalácii Symfony nasledujúcim príkazom:
composer create-project symfony/website-skeleton:^5 rezervace_vozidel
Teraz sa v aktuálnom adresári vytvorila zložka s projektom, ktorá má nasledujúcu štruktúru:
Po inštalácii sa môžeme uistiť, či spĺňame požiadavky príkazom:
symfony check:requirements
Ak ste zvyknutí využívať vlastné balík pre webový server (wamp / xampp), tak ho môžete využiť. Symfony však môže urobiť svoj vlastný webový server, ktorý nie je potrebné ďalej konfigurovať, ten prípadne spustíme príkazom:
symfony server:start
V príkazovom riadku sa dozvieme adresu s portom, ktorú navštívime vo webovom prehliadači. Tým sa zobrazí uvítacia homepage Symfony.
So zakladaním nového projektu by ste nemali mať problém, prípadne opäť odporučím najskôr prejsť základný kurz, konkrétne vytvorenie projektu v lekcii Inštalácia Symfony a IDE.
Databázy
Najprv povieme Symfony kde je naša databáza a ako sa k nej pripojí.
Otvoríme si súbor .env
v root priečinku projektu a nájdeme
riadok:
DATABASE_URL=mysql://db_user:[email protected]:3306/db_name?serverVersion=5.7
Údaje na tomto riadku následne zmeníme na údaje nášho serveru.
Nezabudnite uviesť verziu vášho databázového servera. V mojom prípade to
bude užívateľ root
a heslo kokos123
, verzia MySQL
5.7
:
DATABASE_URL=mysql://root:[email protected]:3306/itnetwork_tut?serverVersion=5.7
Ak používate databázu SQLite alebo PostgreSQL, URL je iná! Dočítate sa o tom o riadok
vyššie v .env
súbore.
Teraz si môžeme nechať vytvoriť databázu projektu pomocou príkazu:
php bin/console doctrine:database:create
Prihlásenie a užívatelia
Ďalším základným kameňom aplikácie sú užívatelia.
Entita User
Najprv si vytvoríme entitu User
, ktorá bude reprezentovať
užívateľa. Urobíme to pomocou príkazu:
php bin/console make:user
Vo vygenerovanom súboru src/Entity/User.php
ešte pridáme
užívateľovi vlastnosti $canReserve
a $displayname
.
Súbor bude vyzerať takto:
<?php namespace App\Entity; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Security\Core\User\UserInterface; /** * @ORM\Entity(repositoryClass="App\Repository\UserRepository") */ class User implements UserInterface { /** * @ORM\Id() * @ORM\GeneratedValue() * @ORM\Column(type="integer") */ private $id; /** * @ORM\Column(type="string", length=180, unique=true) */ private $email; /** * @ORM\Column(type="json") */ private $roles = []; /** * @var string The hashed password * @ORM\Column(type="string") */ private $password; /** * @ORM\Column(type="string", length=255, nullable=true) */ private $displayname; /** * @ORM\Column(type="boolean") **/ private $canReserve; public function getId(): ?int { return $this->id; } public function getEmail(): ?string { return $this->email; } public function setEmail(string $email): self { $this->email = $email; return $this; } /** * A visual identifier that represents this user. * * @see UserInterface */ public function getUsername(): string { return (string) $this->email; } /** * @see UserInterface */ public function getRoles(): array { $roles = $this->roles; // guarantee every user at least has ROLE_USER $roles[] = 'ROLE_USER'; return array_unique($roles); } public function setRoles(array $roles): self { $this->roles = $roles; return $this; } /** * @see UserInterface */ public function getPassword(): string { return (string) $this->password; } public function setPassword(string $password): self { $this->password = $password; return $this; } /** * @see UserInterface */ public function getSalt() { // not needed when using the "bcrypt" algorithm in security.yaml } /** * @see UserInterface */ public function eraseCredentials() { // If you store any temporary, sensitive data on the user, clear it here // $this->plainPassword = null; } public function getDisplayname(): ?string { return $this->displayname; } public function setDisplayname(?string $displayname): self { $this->displayname = $displayname; return $this; } public function getCanReserve(): ?bool { return $this->canReserve; } public function setCanReserve(bool $canReserve): self { $this->canReserve = $canReserve; return $this; } }
Autentifikácia
Overovať užívateľa budeme pomocou emailu a hesla.
Necháme si vytvoriť tiež LoginFormAuthenticator
(/logout
, LoginForm.php
a
SecurityController.php
) cez príkaz:
php bin/console make:auth
Všetky naše nové súbory sú teda nasledujúce:
src/Entity/User.php src/Repository/UserRepository.php src/Security/LoginFormAuthenticator.php templates/security/login.html.twig
config/packages/security.yaml
Symfony si automaticky nakonfiguroval súbory
config/packages/doctrine.yaml
a
config/packages/security.yaml
, ktoré sme mu zadali do
príkazového riadku. Avšak nikto nemá zatiaľ prístup k prihláseniu na
adrese /login
. Na koniec súboru security.yaml
teda
pridáme riadok, ktorý nám zabezpečí, že budú mať všetci prístup k
prihlásenie:
access_control: - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
Migrácia
Teraz máme adresu /login
"funkčná". Nebudeme sa ale môcť
prihlásiť, pretože nemáme zatiaľ žiadne užívateľa a hlavne sme
nespravili migráciu databázy. Síce teda máme entitu, ale v databáze reálne
tabuľka s užívateľmi ešte nie je. Pre migráciu spustíme tieto dva
príkazy:
php bin/console make:migration php bin/console doctrine:migrations:migrate
Testovanie
Aby sme projekt vyvíjali trochu na úrovni, testovať užívateľa (vytvárať "umelé entity") budeme pomocou fixtures, ktoré využijeme aj v budúcnosti (napr. Pre rezervácie). Nainštalujeme si ich pomocou:
composer require --dev doctrine/doctrine-fixtures-bundle
a potom vytvoríme novú fixture:
php bin/console make:fixtures
FIXTURE nazveme UserFixture
, bude mať na starosti
používateľa. Súbor src/DataFixtures/UserFixture.php
upravíme
do nasledujúcej podoby:
<?php namespace App\DataFixtures; use App\Entity\User; use Doctrine\Bundle\FixturesBundle\Fixture; use Doctrine\Common\Persistence\ObjectManager; use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface; class UserFixture extends Fixture { public const USER_USER_REFERENCE = 'user-user'; public const USER_ADMIN_REFERENCE = 'user-admin'; private $encoder; public function __construct(UserPasswordEncoderInterface $encoder) { $this->encoder = $encoder; } public function load(ObjectManager $manager) { $user1 = new User(); $user1->setPassword($this->encoder->encodePassword($user1, "kokos1")); $user1->setCanReserve(0); // otestujeme aj to, že admin bude ignorovať túto vlastnosť $user1->setDisplayname("Admin"); $user1->setEmail("[email protected]"); $user1->setRoles(["ROLE_ADMIN"]); $user2 = new User(); $user2->setPassword($this->encoder->encodePassword($user2, "kokos1")); $user2->setCanReserve(0); $user2->setDisplayname("Test"); $user2->setEmail("[email protected]"); $user2->setRoles(["ROLE_USER"]); // vďaka tomuto sa potom dostaneme k týmto užívateľom z iných FIXTURE $this->addReference(self::USER_ADMIN_REFERENCE, $user1); $this->addReference(self::USER_USER_REFERENCE, $user2); $manager->persist($user1); $manager->persist($user2); $manager->flush(); } }
FIXTURE vytvorí v databáze 2 testovacie užívateľa. Určite ste si všimli, že jeden je administrátor a druhý len bežný užívateľ. To aby sme si mohli overiť, že funkcia aplikácie pre administrátora fungujú a zároveň nie sú dostupné pre bežného užívateľa. To je koniec koncov veľmi dôležité!
Nakoniec spustíme a potvrdíme príkaz pre nahranie používateľov do databázy:
php bin/console doctrine:fixtures:load
Záver
Teraz sa môžeme prihlásiť na adrese /login
Vyhodí nám to chybu "TODO:
provide a valid redirect inside". Zatiaľ sa nemáme kam prihlásiť, preto
budeme myslieť do budúcnosti a odkážeme na budúce route
/myBooking
v metóde onAuthenticationSuccess
v súbore
src/Security/LoginFormAuthenticator.php
nasledovne:
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey) { if ($targetPath = $this->getTargetPath($request->getSession(), $providerKey)) { return new RedirectResponse($targetPath); } // TODO: redirect after authentication For example : return new RedirectResponse($this->urlGenerator->generate('some_route')); return new RedirectResponse($this->urlGenerator->generate("myBooking")); }
Tu ukončíme dnešnú lekciu.
V ďalšej lekcii, Rezervačný systém v Symfony - Entity, repozitára, kontrolery , si vytvoríme entity rezervácie, vozidlá, kontrolér a upravíme repozitár pre rezervácie.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkamiStiahnuté 224x (13.76 MB)