Zarábaj až 6 000 € mesačne! Akreditované rekvalifikačné kurzy od 0 €. Viac informácií.

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.

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.


 

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é 73x (55.8 kB)
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
Preskočiť článok
(neodporúčame)
Jednoduchý redakčný systém v Symfony - Kontaktný formulár
Článok pre vás napísal Jindřich Máca
Avatar
Užívateľské hodnotenie:
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