Válí se ti projekty v šuplíku? Dostaň je mezi lidi a získej cool tričko a body na profi IT kurzy v soutěži ITnetwork summer 2017!
Přidej si svou IT školu do profilu a najdi spolužáky zde na síti :)

8. díl - Jednoduchý redakční systém v Symfony - Administrace

PHP Symfony Základy Jednoduchý redakční systém v Symfony - Administrace

Unicorn College ONEbit hosting Tento obsah je dostupný zdarma v rámci projektu IT lidem. Vydávání, hosting a aktualizace umožňují jeho sponzoři.

V minulé lekci, Jednoduchý redakční systém v Symfony - Výpis článku, jsme již vytvořili základní strukturu pro výpis článků. Dnes budeme pokračovat s tvorbou jejich administrace v redakčním systému postaveném na PHP frameworku Symfony.

Kontroler

Jelikož modelovou vrstvu v podobě entity a repositáře máme již nachystanou z minula, začneme rovnou od kontroleru.

src/AppBundle/Con­troller/Article­Controller.php

Protože v Symfony můžeme mít více akcí v jednom kontroleru, budeme pokračovat v rozšiřování naší třídy ArticleController a přidáme do ní následující metody dalších akcí:

<?php

namespace AppBundle\Controller;

use AppBundle\Entity\Article;
use AppBundle\Repository\ArticleRepository;
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Form;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

/**
 * Zpracovává vykreslování článků.
 * @package AppBundle\Controller
 */
class ArticleController extends Controller
{
        /** @var ArticleRepository $articleRepository Repositář pro práci s články. */
        private $articleRepository = null;

        /**
         * Getter třídy ArticleRepository s počáteční inicializací.
         * @return ArticleRepository repositář pro práci s články
         */
        private function getArticleRepository()
        {
                if (is_null($this->articleRepository))
                        $this->articleRepository = $this->container->get('article_repository');
                return $this->articleRepository;
        }

        /**
         * Vykreslí seznam článků do šablony.
         * @return Response HTTP odpověď
         * @Route("/seznam-clanku", name="article_list")
         */
        public function listAction()
        {
                return $this->render('AppBundle:Article:list.html.twig', [
                        'articles' => $this->getArticleRepository()->getArticles()
                ]);
        }

        /**
         * Odstraní článek.
         * @param null|string $url URL článku
         * @return Response HTTP odpověď
         * @Route("/odstranit/{url}", name="remove_article")
         */
        public function removeAction($url = null)
        {
                $this->getArticleRepository()->removeArticle($url);
                $this->addFlash('notice', 'Článek byl úspěšně odstraněn.');
                return $this->redirectToRoute('article_list');
        }

        /**
         * Vykresluje editaci článku podle jeho URL.
         * @param null|string $url     URL článku
         * @param Request     $request HTTP požadavek
         * @return Response HTTP odpověď
         * @Route("/editor/{url}", name="article_editor")
         */
        public function editorAction($url = null, Request $request)
        {
                // Pokud byla zadána URL, pokusí se článek načíst, jinak vypíše chybovou hlášku.
                if ($url && !($article = $this->getArticleRepository()->getArticle($url)))
                        $this->addFlash('warning', 'Článek nebyl nalezen.');

                // Pokud se nejedná o editaci článku, vytváří se nový článek.
                if (empty($article)) $article = new Article();

                /** @var Form $form Formulář pro editaci článku. */
                $form = $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í formuláře.
                $form->handleRequest($request);
                if ($form->isSubmitted() && $form->isValid()) {
                        try {
                                $this->getArticleRepository()->saveArticle($article);
                                $this->addFlash('notice', 'Článek byl úspěšně uložen.');
                                return $this->redirectToRoute('homepage', ['url' => $article->getUrl()]);
                        } catch (UniqueConstraintViolationException $exception) {
                                $this->addFlash('warning', 'Článek s touto URL adresou již existuje.');
                        }
                }

                // Předání formuláře do šablony.
                return $this->render('AppBundle:Article:editor.html.twig', [
                        'form' => $form->createView()
                ]);
        }

        /**
         * Načte a vykreslí článek do šablony podle jeho URL.
         * @param null|string $url URL článku
         * @return Response HTTP odpověď
         * @Route("/", name="homepage")
         * @Route("/{url}", name="article_detail")
         */
        public function indexAction($url = null)
        {
                // Pokud není zadaná URL, nastaví se jí hodnota pro výchozí článek.
                if (!$url) $url = $this->getParameter('default_article_url');

                // Pokusí se načíst článek s danou URL a pokud nebude nalezen, vyhodí chybu 404.
                if (!($article = $this->getArticleRepository()->getArticle($url)))
                        throw $this->createNotFoundException('Článek s danou URL neexistuje!');

                // Předá článek do šablony.
                return $this->render('AppBundle:Article:index.html.twig', [
                        'article' => $article
                ]);
        }
}

Nyní by asi bylo dobré si uvedený kód trochu popsat. V první řadě jsme přidali následující akce i s pravidly pro routování, které využívají našeho repositáře článků:

  • listAction() - Vypisuje seznam všech článků.
  • removeAction() - Odstraní vybraný článek.
  • editorAction() - Umožňuje vytvářet nové i editovat stávající články.

Dále jsme sjednotili získání onoho repositáře článků pomocí DI napříč všemi těmito metodami i původní metodou indexAction() a to pomocí principů OOP, konkrétně privátního atributu a metody getArticleRepository().

Nakonec stojí asi za povšimnutí formulář pro vytváření a editaci článků, který jsme postavili na naší entitě Article, takže využívá jejích validačních pravidel a dovolí nám tak uložit pouze článek s validními daty.

Šablony

Nyní se podíváme na šablony k jednotlivým akcím.

src/Resources/vi­ews/Form/row.html­.twig

Začneme trochu neobvykle a to tím, že si definujeme vlastní šablonu pro vykreslení jednoho formulářové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 %}

Tu dále využijeme při vykreslování našich formulářů pro hezčí a přehlednější vzhled. ;)

src/Resources/vi­ews/Article/e­ditor.html.twig

Nyní šablona pro editor článků. Zde si povšimněte jak jednoduše jsme zařídili vykreslení formuláře i s naší vlastní šablonou a dále způsobu přidávání dalších JavaScript knihoven:

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

{% block title %}Editor{% endblock %}
{% block description %}Editor článků.{% endblock %}
{% block body %}
    {# Formulář pro editaci. #}
    {% form_theme form 'AppBundle:Form:row.html.twig' %}
    {{ form(form) }}
{% endblock %}

{% block javascripts %}
    {{ parent() }}
    <script type="text/javascript" src="//tinymce.cachefly.net/4.0/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: "named",
            entity_encoding: "raw"
        });
    </script>
{% endblock %}

src/Resources/vi­ews/Article/lis­t.html.twig

Dále přidáme šablonu pro výpis článků:

{% extends 'AppBundle::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_detail', {'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 %}

src/Resources/vi­ews/base.html­.twig

Na závěr přidáme ještě odkaz do výchozí šablony. Nebudu sem už vypisovat znovu celou šablonu, pouze změnu:

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

Nyní se již můžete podívat na výsledek, zkusit si vypsat seznam článků a klidně je i nějak editovat. :)

Příště si přidáme ještě ContactControler a příslušné šablony, čímž administraci článků v našem redakčním systému v Symfony dokončíme.


 

Stáhnout

Staženo 7x (11.62 MB)
Aplikace je včetně zdrojových kódů v jazyce PHP

 

 

Článek pro vás napsal Jindřich Máca
Avatar
Jak se ti líbí článek?
2 hlasů
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 (6)

 

 

Komentáře

Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zatím nikdo nevložil komentář - buď první!