@@ -331,19 +331,175 @@ final readonly class PageRepository
331331 );
332332 }
333333
334- public function delete (string $id ): void
334+ public function deleteBySlug (string $slug ): void
335335 {
336- $this->connection->createCommand()->delete('{{%page}}', ['id ' => $id ])->execute();
336+ $this->connection->createCommand()->delete('{{%page}}', ['slug ' => $slug ])->execute();
337337 }
338338}
339339` ` `
340340
341341# # Actions and routes
342342
343- You need actions to :
343+ You need to be able to :
344344
3453451. List all pages.
3463462. View a page.
3473473. Delete a page.
3483484. Create a page.
3493495. Edit a page.
350+
351+ Let's tackle these one by one.
352+
353+
354+ # ## List all pages
355+
356+ Create `src/Web/Page/ListAction.php` :
357+
358+ ` ` ` php
359+ <?php
360+
361+ declare(strict_types=1);
362+
363+ namespace App\W eb\P age;
364+
365+ use Psr\H ttp\M essage\R esponseInterface;
366+ use Yiisoft\Y ii\V iew\R enderer\V iewRenderer;
367+
368+ final readonly class ListAction
369+ {
370+ public function __construct(
371+ private ViewRenderer $viewRenderer,
372+ private PageRepository $pageRepository,
373+ )
374+ {
375+ }
376+
377+ public function __invoke(): ResponseInterface
378+ {
379+ return $this->viewRenderer->render(__DIR__ . '/list', [
380+ 'pages' => $this->pageRepository->findAll(),
381+ ]);
382+ }
383+ }
384+ ` ` `
385+
386+ Define list view in `src/Web/Page/list.php` :
387+
388+ ` ` ` php
389+ <?php
390+ use App\W eb\P age\P age;
391+ use Yiisoft\H tml\H tml;
392+
393+ /** @var iterable<Page> $pages */
394+ ?>
395+
396+ <ul>
397+ <?php foreach ($pages as $page): ?>
398+ <li>
399+ <?= Html::a($page->title, $this->urlGenerator->generate('page/view', ['slug' => $page->slug])) ?>
400+ </li>
401+ <?php endforeach ?>
402+ </ul>
403+ ` ` `
404+
405+ # ## View a page
406+
407+ Create `src/Web/Page/ViewAction.php` :
408+
409+ ` ` ` php
410+ <?php
411+
412+ declare(strict_types=1);
413+
414+ namespace App\W eb\P age;
415+
416+ use Psr\H ttp\M essage\R esponseFactoryInterface;
417+ use Psr\H ttp\M essage\R esponseInterface;
418+ use Yiisoft\H ttp\S tatus;
419+ use Yiisoft\R outer\H ydratorAttribute\R outeArgument;
420+ use Yiisoft\Y ii\V iew\R enderer\V iewRenderer;
421+
422+ final readonly class ViewAction
423+ {
424+ public function __construct(
425+ private ViewRenderer $viewRenderer,
426+ private PageRepository $pageRepository,
427+ private ResponseFactoryInterface $responseFactory
428+ )
429+ {
430+ }
431+
432+ public function __invoke(
433+ #[RouteArgument('slug')]
434+ string $slug
435+ ): ResponseInterface
436+ {
437+ $page = $this->pageRepository->findOneBySlug($slug);
438+ if ($page === null || $page->isDeleted()) {
439+ return $this->responseFactory->createResponse(Status::NOT_FOUND);
440+ }
441+
442+ return $this->viewRenderer->render(__DIR__ . '/view', [
443+ 'page' => $page,
444+ ]);
445+ }
446+ }
447+ ` ` `
448+
449+ Now, a template in `src/Web/Page/view.php` :
450+
451+ ` ` ` php
452+ <?php
453+ use App\W eb\P age\P age;
454+ use Yiisoft\H tml\H tml;
455+
456+ /** @var Page $page */
457+ ?>
458+
459+ <h1><?= Html::encode($page->title) ?></h1>
460+
461+ <p>
462+ <?= Html::encode($page->text) ?>
463+ </p>
464+ ` ` `
465+
466+ # ## Delete a page
467+
468+ Create `src/Web/Page/DeleteAction.php` :
469+
470+ ` ` ` php
471+ <?php
472+
473+ declare(strict_types=1);
474+
475+ namespace App\W eb\P age;
476+
477+ use Psr\H ttp\M essage\R esponseFactoryInterface;
478+ use Psr\H ttp\M essage\R esponseInterface;
479+ use Yiisoft\H ttp\S tatus;
480+ use Yiisoft\R outer\UrlGenera torInterface;
481+
482+ final readonly class DeleteAction
483+ {
484+ public function __construct(
485+ private PageRepository $pageRepository,
486+ private ResponseFactoryInterface $responseFactory,
487+ private UrlGeneratorInterface $urlGenerator,
488+ )
489+ {}
490+
491+ public function __invoke(string $slug): ResponseInterface
492+ {
493+ $this->pageRepository->deleteBySlug($slug);
494+
495+ return $this->responseFactory
496+ ->createResponse()
497+ ->withStatus(Status::PERMANENT_REDIRECT)
498+ ->withHeader('Location', $this->urlGenerator->generate('page/list'));
499+ }
500+ }
501+ ` ` `
502+
503+ # ## Create a page
504+
505+
0 commit comments