6. diel - Jednoduchý redakčný systém v Nette - Výpis článku
V minulej lekcii, Jednoduchý redakčný systém v Nette - Štruktúra projektu , sme si pripravili projektovú štruktúru pre jednoduchý redakčný systém. A ako som sľúbil, dnes sa rovno bez zbytočných rečí vrhneme na implementáciu. Takže ideme na to!
Databázy
Najprv sa pozrieme na nastavenie a obsah databázy. Vytvoríme si novú
databázu pre náš projekt (napr. nette-rs
) a v nej spustíme
nasledujúci SQL:
-- ---------------------------- -- Table structure for `article` -- ---------------------------- DROP TABLE IF EXISTS `article`; CREATE TABLE `article` ( `article_id` int(11) NOT NULL AUTO_INCREMENT, `title` varchar(255) COLLATE utf8_czech_ci DEFAULT NULL, `content` text COLLATE utf8_czech_ci, `url` varchar(255) COLLATE utf8_czech_ci DEFAULT NULL, `description` varchar(255) COLLATE utf8_czech_ci DEFAULT NULL, PRIMARY KEY (`article_id`), UNIQUE KEY `url` (`url`) ) ENGINE = InnoDB AUTO_INCREMENT = 3 DEFAULT CHARSET = utf8 COLLATE = utf8_czech_ci; -- ---------------------------- -- Records of article -- ---------------------------- INSERT INTO `article` VALUES ('1', 'Úvod', '<p>Vítejte na našem webu!</p><p>Tento web je postaven na <strong>jednoduchém redakčním systému v Nette frameworku</strong>. Toto je úvodní článek, načtený z databáze.</p>', 'uvod', 'Úvodní článek na webu v Nette v PHP'); INSERT INTO `article` VALUES ('2', 'Stránka nebyla nalezena', '<p>Litujeme, ale požadovaná stránka nebyla nalezena. Zkontrolujte prosím URL adresu.</p>', 'chyba', 'Stránka nebyla nalezena.');
To nám vytvorí a naplní tabuľku s článkami, ktorú budeme ďalej potrebovať.
SQL skript nájdete aj v archíve v priečinku sql/
pod názvom create_script.sql
.
App / config / config.neon
Nakoniec je ešte potrebné nastaviť v Nette pripojenie do našej databázy. To urobíme v hlavnom konfiguračnom súbore tak, že upravíme už prednastavené parametre, tj. Názov našej databázy aj užívateľské meno a heslo. Výsledok by mal vyzerať približne takto:
... # Konfigurace databázového připojení v rámci celé aplikace. database: dsn: 'mysql:host=127.0.0.1;dbname=nette-rs' # Typ, adresa a název databáze user: root # Uživatelské jméno password: **** # Heslo options: lazy: yes ...
Pokiaľ máte inú konfiguráciu databázy v rôznych
prostrediach (localhost verzus hosting), používa sa ešte lokálne
konfiguračný súbor config.local.neon
, ktorého nastavenie
prepíše to globálne špecificky pre dané prostredie.
Model
Rovnako ako v minulej aplikácii začneme pekne od modelu.
App / model / DatabaseManager.php
Pretože sme všetci znalí OOP a nechceme mať zbytočné duplicity v kóde, pripravíme si základné abstraktné modelovú triedu pre prácu s databázou, ktorá bude pomocou Dependency Injection (skrátene DI) získavať prístup k Nette rozhranie pre prácu s databázou a všetky ďalšie modelové triedy z nej budú následne dediť, aby automaticky tento prístup získali. Trieda je pomerne jednoduchá a vyzerá takto:
<?php namespace App\Model; use Nette\Database\Context; use Nette\SmartObject; /** * Základní model pro všechny ostatní databázové modely aplikace. * Poskytuje přístup k práci s databází. * @package App\Model */ abstract class DatabaseManager { use SmartObject; /** @var Context Služba pro práci s databází. */ protected $database; /** * Konstruktor s injektovanou službou pro práci s databází. * @param Context $database automaticky injektovaná Nette služba pro práci s databází */ public function __construct(Context $database) { $this->database = $database; } }
App / CoreModule / model / ArticleManager.php
Ďalšia na rade je model pre správu článkov, ktorý teda zdedí z triedy
DatabaseManager
. Bude už súčasťou nášho CoreModulu a jeho
cieľom je definovať metódy, ktoré pomocou Nette rozhranie pre prácu s
databázou umožní manipuláciu s tabuľkou článkov, ktorú sme si vytvorili
vyššie.
<?php namespace App\CoreModule\Model; use App\Model\DatabaseManager; use Nette\Database\Table\ActiveRow; use Nette\Database\Table\Selection; use Nette\Utils\ArrayHash; /** * Model pro správu článků v redakčním systému. * @package App\CoreModule\Model */ class ArticleManager extends DatabaseManager { /** Konstanty pro práci s databází. */ const TABLE_NAME = 'article', COLUMN_ID = 'article_id', COLUMN_URL = 'url'; /** * Vrátí seznam všech článků v databázi seřazený sestupně od naposledy přidaného. * @return Selection seznam všech článků */ public function getArticles() { return $this->database->table(self::TABLE_NAME)->order(self::COLUMN_ID . ' DESC'); } /** * Vrátí článek z databáze podle jeho URL. * @param string $url URl článku * @return false|ActiveRow první článek, který odpovídá URL nebo false pokud článek s danou URL neexistuje */ public function getArticle($url) { return $this->database->table(self::TABLE_NAME)->where(self::COLUMN_URL, $url)->fetch(); } /** * Uloží článek do systému. * Pokud není nastaveno ID vloží nový článek, jinak provede editaci článku s daným ID. * @param array|ArrayHash $article článek */ public function saveArticle($article) { if (empty($article[self::COLUMN_ID])) { unset($article[self::COLUMN_ID]); $this->database->table(self::TABLE_NAME)->insert($article); } else $this->database->table(self::TABLE_NAME)->where(self::COLUMN_ID, $article[self::COLUMN_ID])->update($article); } /** * Odstraní článek s danou URL. * @param string $url URL článku */ public function removeArticle($url) { $this->database->table(self::TABLE_NAME)->where(self::COLUMN_URL, $url)->delete(); } }
Všimnite si, že Nette rozhranie pre prácu s databázou kopíruje pokladanie klasických SQL dotazov, avšak v rámci PHP kódu v trochu zjednodušenom formáte. A tiež obsahuje napr. Ochranu proti SQL injection.
Presenter
Ďalej budeme pokračovať s Presenter. Začneme tým, že zmažeme
základné presenter app/presenters/HomepagePresenter.php
, pretože
už ho nebudeme potrebovať. Na konci tejto lekcie už totiž budeme mať
základ úplne nové aplikácie.
App / presenters / BasePresenter.php
Rovnako ako vo väčšine projektov v Nette a podobne ako v našom modeli,
začneme od základnej abstraktné triedy, z ktorej dedia všetky ostatné
Presenter a tou je BasePresenter
. V sandboxe, z ktorého
vychádzame, už je vytvorený, takže ho len trošku upravíme:
<?php namespace App\Presenters; use Nette\Application\UI\Presenter; /** * Základní presenter pro všechny ostatní presentery aplikace. * @package App\Presenters */ abstract class BasePresenter extends Presenter { }
App / CoreModule / presenters / ArticlePresenter.php
Teraz sa dostávame k Presenter, ktorá nám pomocou
ArticleManager
bude odovzdávať dáta článkov do šablóny.
Tento presenter tvorí hlavnú časť nášho CoreModule a vyzerá
nasledovne:
<?php namespace App\CoreModule\Presenters; use App\CoreModule\Model\ArticleManager; use App\Presenters\BasePresenter; use Nette\Application\BadRequestException; /** * Presenter pro vykreslování článků. * @package App\CoreModule\Presenters */ class ArticlePresenter extends BasePresenter { /** @var string URL výchozího článku. */ private $defaultArticleUrl; /** @var ArticleManager Model pro správu s článků. */ private $articleManager; /** * Konstruktor s nastavením URL výchozího článku a injektovaným modelem pro správu článků. * @param string $defaultArticleUrl URL výchozího článku * @param ArticleManager $articleManager automaticky injektovaný model pro správu článků */ public function __construct($defaultArticleUrl, ArticleManager $articleManager) { parent::__construct(); $this->defaultArticleUrl = $defaultArticleUrl; $this->articleManager = $articleManager; } /** * Načte a předá článek do šablony podle jeho URL. * @param string|null $url URL článku * @throws BadRequestException Jestliže článek s danou URL nebyl nalezen. */ public function renderDefault($url = null) { if (!$url) $url = $this->defaultArticleUrl; // Pokud není zadaná URL, vezme se URL výchozího článku. // Pokusí se načíst článek s danou URL a pokud nebude nalezen vyhodí chybu 404. if (!($article = $this->articleManager->getArticle($url))) $this->error(); // Vyhazuje výjimku BadRequestException. $this->template->article = $article; // Předá článek do šablony. } }
App / CoreModule / config / config.neon
Aby fungovalo automatické odovzdávanie závislostí pomocou DI, musíme
ešte zaregistrovať ArticleManager
ako službu v našej
aplikácii. Konkrétne to vykonáme v konfiguračnom súbore nášho modulu, kde
aj odovzdáme konfiguráciu URL predvoleného článku do nášho nového
prezentačného:
# # Konfigurační soubor pro CoreModule. # parameters: defaultArticleUrl: 'uvod' # URL výhozího článku # Nastavení služeb pro CoreModule. services: - App\CoreModule\Model\ArticleManager # Vlastní služba dále přístupná pomocí DI. - App\CoreModule\Presenters\ArticlePresenter(%defaultArticleUrl%) # Předání nastavení při vytváření služby presenteru.
Routovanie
App / router / RouterFactory.php
Aby sme sa naozaj dostali uvedených článkov podľa ich URL, je nutné
ešte upraviť routovanie našej aplikácie. To zariadime úpravou už
existujúce triedy zo sandboxe RouterFactory
, kde nastavíme
smerovanie na náš nový presenter:
<?php namespace App; use Nette\Application\IRouter; use Nette\Application\Routers\Route; use Nette\Application\Routers\RouteList; use Nette\StaticClass; /** * Továrna na routovací pravidla. * Řídí směrování a generovaní URL adres v celé aplikaci. * @package App */ class RouterFactory { use StaticClass; /** * Vytváří a vrací seznam routovacích pravidel pro aplikaci. * @return IRouter výsledný router pro aplikaci */ public static function createRouter() { $router = new RouteList; $router[] = new Route('[<url>]', 'Core:Article:default'); return $router; } }
To je zatiaľ všetko. V budúcej lekcii, Jednoduchý redakčný systém v Nette - Administrácia , sa budeme venovať šablónam a projekt sprevádzkujeme.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkamiStiahnuté 664x (3.65 MB)