80 % bodů zdarma na online výuku díky naší Letní akci!
Pouze tento týden sleva až 80 % na e-learning týkající se PHP

8. diel - Jednoduchý redakčný systém v Symfony - Administrácia

V minulej lekcii, Jednoduchý redakčný systém v Symfony - Výpis článku , sme už vytvorili základnú štruktúru pre výpis článkov. Dnes budeme pokračovať s tvorbou ich administrácie v redakčnom systéme postavenom na PHP frameworku Symfony.

Kontrolér

Keďže modelovú vrstvu v podobe entity a repozitára máme už nachystanú z minula, začneme rovno od kontroleru.

Src / Controller / ArticleContro­ller.php

Pretože v Symfony môžeme mať viac podujatí v jednom kontroleru, budeme pokračovať v rozširovaní našej triedy ArticleController a pridáme do nej nasledujúce metódy ďalších akcií:

<?php

namespace App\Controller;

use App\Entity\Article;
use App\Repository\ArticleRepository;
use Doctrine\ORM\ORMException;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Entity;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Annotation\Route;

/**
 * Kontroler pro práci s články.
 * @package App\Controller
 */
class ArticleController extends AbstractController
{
    /** @var ArticleRepository Repositář pro správu článků. */
    private $articleRepository;

    /**
     * Konstruktor kontroleru pro práci s články.
     * @param ArticleRepository $articleRepository automaticky injektovaný repositář pro správu článků
     */
    public function __construct(ArticleRepository $articleRepository)
    {
        $this->articleRepository = $articleRepository;
    }

    /**
     * Načte a předá seznam všech článků do šablony.
     * @return Response HTTP odpověď
     * @Route("/seznam-clanku", name="article_list")
     */
    public function list(): Response
    {
        return $this->render('article/list.html.twig', ['articles' => $this->articleRepository->findAll()]);
    }

    /**
     * Odstraní článek podle jeho URL.
     * @param string|null $url URL článku
     * @return Response HTTP odpověď
     * @Route("/odstranit/{url}", name="remove_article")
     * @throws ORMException Jestliže nastane chyba při mazání článku.
     */
    public function remove(string $url = null): Response
    {
        $this->articleRepository->removeByUrl($url);
        $this->addFlash('notice', 'Článek byl úspěšně odstraněn.');
        return $this->redirectToRoute('article_list');
    }

    /**
     * Vytváří a zpracovává formulář pro editaci článku podle jeho URL.
     * @param string|null $url     URL článku
     * @param Request     $request HTTP požadavek
     * @return Response HTTP odpověď
     * @Route("/editor/{url}", name="article_editor")
     * @throws ORMException Jestliže nastane chyba při ukládání článku.
     */
    public function editor(string $url = null, Request $request): Response
    {
        if ($url) { // Pokud byla zadána URL, pokusí se načíst článek podle ní.
            if (!($article = $this->articleRepository->findOneByUrl($url))) {
                // Pokud se článek s danou URL nepodaří najít, vypíše chybovou hlášku a vytvoří nový s danou URL.
                $this->addFlash('warning', 'Článek se zadanou URL nebyl nalezen!');
                $article = (new Article())->setUrl($url);
            }
        } else $article = new Article(); // Jinak se nejedná o editaci článku a vytváří se nový článek.

        // Vytváření editačního formuláře podle entity článku.
        $editorForm = $this->createFormBuilder($article)
            ->add('title', null, ['label' => 'Titulek'])
            ->add('url', null, ['label' => 'URL'])
            ->add('description', null, ['label' => 'Popisek'])
            ->add('content', null, ['label' => 'Obsah', 'required' => false])
            ->add('submit', SubmitType::class, ['label' => 'Uložit článek'])
            ->getForm();

        // Zpracování editačního formuláře.
        $editorForm->handleRequest($request);
        if ($editorForm->isSubmitted() && $editorForm->isValid()) {
            $this->articleRepository->save($article);
            $this->addFlash('notice', 'Článek byl úspěšně uložen.');
            return $this->redirectToRoute('article', ['url' => $article->getUrl()]);
        }

        // Předání editačního formuláře do šablony.
        return $this->render('article/editor.html.twig', ['editorForm' => $editorForm->createView()]);
    }

    /**
     * Načte článek podle jeho URL a předá jej do šablony.
     * Pokud není zadaná URL, nastaví se jí hodnota pro výchozí článek.
     * @param Article $article článek
     * @return Response HTTP odpověď
     * @throws NotFoundHttpException Jestliže článek s danou URL nebyl nalezen.
     * @Route("/{url?%default_article_url%}", name="article")
     * @Entity("article", expr="repository.findOneByUrl(url)")
     */
    public function index(Article $article): Response
    {
        return $this->render('article/index.html.twig', ['article' => $article]);
    }
}

Teraz by asi bolo dobré si kód trochu popísať. V prvom rade sme pridali nasledujúce akcie is pravidlami pre routovanie, ktoré využívajú nášho repozitára článkov:

  • listAction() - Vypisuje zoznam všetkých článkov.
  • removeAction() - Odstráni vybraný článok.
  • editorAction() - Umožňuje vytvárať nové aj editovať existujúce články.

Ďalej sme zjednotili získanie repozitára pre správu článkov pomocou DI naprieč všetkými týmito metódami a to pomocou princípov OOP, konkrétne privátneho atribútu a konstruktoru.

Tento výukový obsah pomáhajú rozvíjať nasledujúce firmy, ktoré možno hľadajú práve teba!

Nakoniec stojí asi za povšimnutie formulár pre vytváranie a editáciu článkov, ktorý sme postavili na našej entite Article, takže využíva jej validačných pravidiel a automaticky nám tak dovolí uložiť iba článok s validnými dátami.

Konfigurácia

Ešte než sa presunieme k samotným šablónam, pridáme jednu drobnú vychytávku do konfigurácie.

Config / packages / twig.yaml

Naučíme totiž všetky formuláre v našej aplikácii používať predvolenú Twig šablónu pre ich vykresľovanie:

twig:
    paths: ['%kernel.project_dir%/templates']
    debug: '%kernel.debug%'
    strict_variables: '%kernel.debug%'

    # Nastaví všem formulářům v aplikaci tuto šablonu pro vykreslování.
    form_themes:
        - 'form/fields.html.twig'

Šablóny

Teraz sa pozrieme na šablóny k jednotlivým akciám.

Templates / form / fields.html.twig

Začneme definíciou onej šablóny pre vykreslenie jedného všeobecného formulárového elementu:

{# Vlastní definice vzhledu jednoho řádku formuláře. #}
{% block form_row %}
    <div>
        {{ form_errors(form) }}<br>
        {{ form_label(form) }}<br>
        {{ form_widget(form) }}
    </div>
{% endblock form_row %}

Šablónu si samozrejme môžete upraviť podľa ľubovôle na dosiahnutie vášho obľúbeného vzhľadu.

Templates / article / editor.html.twig

Teraz nasleduje šablóna pre editor článkov. Tu si všimnite ako jednoducho sme zariadili vykreslenie formulára aj s našou vlastnou šablónou a ďalej spôsobu pridávanie ďalších JavaScript knižníc:

{% extends 'base.html.twig' %}

{% block title %}Editor{% endblock %}
{% block description %}Editor článků.{% endblock %}
{% block body %}
    {# Formulář pro editaci článku. #}
    {{ form(editorForm) }}
{% endblock %}

{% block javascripts %}
    {{ parent() }}
    <script type="text/javascript" src="//cdn.tinymce.com/4/tinymce.min.js"></script>
    <script type="text/javascript">
        tinymce.init({
            selector: '#form_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>
{% endblock %}

Templates / article / list.html.twig

Ďalej pridáme šablónu pre výpis článkov:

{% extends 'base.html.twig' %}

{% block title %}Výpis článků{% endblock %}
{% block description %}Výpis všech článků.{% endblock %}
{% block body %}
    <table>
        {% for article in articles %}
            <tr>
                <td>
                    <h2><a href="{{ path('article', {'url': article.url}) }}">{{ article.title }}</a></h2>
                    {{ article.description }}
                    <br/>
                    <a href="{{ path('article_editor', {'url': article.url}) }}">Editovat</a>
                    <a href="{{ path('remove_article', {'url': article.url}) }}">Odstranit</a>
                </td>
            </tr>
        {% endfor %}
    </table>
{% endblock %}

Templates / base.html.twig

Na záver pridáme ešte odkazy do východiskovej šablóny. Nebudem ju sem už vypisovať znovu celú, iba zmeny:

...
<nav>
    <ul>
        <li><a href="{{ path('article') }}">Úvod</a></li>
        <li><a href="{{ path('article_list') }}">Seznam článků</a></li>
        <li><a href="#">Kontakt</a></li>
    </ul>
</nav>
...

Teraz sa už môžete pozrieť na výsledok, skúsiť si vypísať zoznam článkov a pokojne ich aj nejako editovať. :)

Nabudúce si v lekcii Jednoduchý redakčný systém v Symfony - Kontaktný formulár pridáme ešte ContactControler a príslušné šablóny, čím administráciu článkov v našom redakčnom systéme v Symfony dokončíme.


 

Stiahnuť

Stiahnuté 45x (13.36 MB)
Aplikácia je vrátane zdrojových kódov v jazyku PHP

 

Predchádzajúci článok
Jednoduchý redakčný systém v Symfony - Výpis článku
Všetky články v sekcii
Základy frameworku Symfony pre PHP
Článok pre vás napísal Jindřich Máca
Avatar
Ako sa ti páči článok?
Ešte nikto nehodnotil, buď prvý!
Autor se věnuje převážně webovým technologiím, ale má velkou zálibu ve všem vědeckém, nejen ze světa IT. :-)
Aktivity (1)

 

 

Komentáre

Avatar
Tomáš Daněk:26.9.2018 8:39

Výpis článků nebude fungovat dokud do adreaáře public/ nenakopírujete soubor .htaccess z přiloženého archivu. Bez tohoto .htaccess souboru se už při zobrazení úvodní stránky korektně nenačte Symfony Toolbar. Bylo by dobré doplnit do textu. Děkuji

 
Odpovedať
26.9.2018 8:39
Avatar
Jindřich Máca
Tým ITnetwork
Avatar
Odpovedá na Tomáš Daněk
Jindřich Máca:26.9.2018 19:02

Ahoj, tohle je popsané už v článku s instalací projektu Lekce 2 - Instalace Symfony a IDE v sekci Směrování. Pokud chceš, aby Ti projekt správně fungoval na Apache serveru, měl by jsi nainstalovat apache-pack a to pomocí příkazu composer require symfony/apache-pack. Ten právě mimo jiné automaticky přidá onen soubor .htaccess do složky public/. Je to přesně popsáno i v oficiální dokumentaci. Ale tohle není nijak povinné, protože např. pokud by jsi chtěl rozjet projekt na Nginx serveru, budeš postupovat jinak. :)

 
Odpovedať
26.9.2018 19:02
Tento výukový obsah pomáhajú rozvíjať nasledujúce firmy, ktoré možno hľadajú práve teba!
Avatar
Odpovedá na Jindřich Máca
Tomáš Daněk:26.9.2018 21:13

Pardon, instalaci apache-pack jsem "přehlédl"...

 
Odpovedať
26.9.2018 21:13
Robíme čo je v našich silách, aby bola tunajšia diskusia čo najkvalitnejšia. Preto do nej tiež môžu prispievať len registrovaní členovia. Pre zapojenie sa do diskusie sa zaloguj. Ak ešte nemáš účet, zaregistruj sa, je to zadarmo.

Zobrazené 3 správy z 3.