Advertisement
Guest User

Untitled

a guest
Jan 7th, 2018
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 6.61 KB | None | 0 0
  1. <?php
  2. declare(strict_types=1);
  3.  
  4. interface PagesRepositoryInterface
  5. {
  6.     public function loadOne(string $pagesId): ?Pages;
  7. }
  8.  
  9. interface PageRepositoryInterface
  10. {
  11.     public function loadOne(string $pageId): ?Page;
  12.  
  13.     public function save(Page $page): void;
  14. }
  15.  
  16. interface PageRenamingInterface
  17. {
  18.     /**
  19.      * @param Page   $toBeRenamed
  20.      * @param string $newName
  21.      *
  22.      * @return Page
  23.      *
  24.      * @throws \RuntimeException Thrown when renaming could not be completed for any reason. This exception should be
  25.      *                           specialized so that it covers a specific error.
  26.      */
  27.     public function execute(Page $toBeRenamed, string $newName): Page;
  28. }
  29.  
  30. abstract class Entity
  31. {
  32.     private $id;
  33.  
  34.     public function __construct(string $id)
  35.     {
  36.         $this->id = $id;
  37.     }
  38.  
  39.     final public function id(): string
  40.     {
  41.         return $this->id;
  42.     }
  43. }
  44.  
  45. class Page extends Entity
  46. {
  47.     private $name;
  48.  
  49.     private $pagesParentId;
  50.  
  51.     public function __construct(string $id, string $name, ?string $pagesParentId)
  52.     {
  53.         parent::__construct($id);
  54.  
  55.         self::validateName($name);
  56.  
  57.         $this->name          = $name;
  58.         $this->pagesParentId = $pagesParentId;
  59.     }
  60.  
  61.     /**
  62.      * @param string $name
  63.      */
  64.     private static function validateName(string $name): void
  65.     {
  66.         // throw on error
  67.     }
  68.  
  69.     public function name(): string
  70.     {
  71.         return $this->name;
  72.     }
  73.  
  74.     public function belongsToPagesCollection(): bool
  75.     {
  76.         return $this->pagesParentId() !== null;
  77.     }
  78.  
  79.     public function pagesParentId(): ?string
  80.     {
  81.         return $this->pagesParentId;
  82.     }
  83.  
  84.     public function changeName(string $newName)
  85.     {
  86.         self::validateName($newName);
  87.  
  88.         $this->name = $newName;
  89.     }
  90. }
  91.  
  92. class Pages extends Entity
  93. {
  94.     /**
  95.      * Indexed by page name
  96.      *
  97.      * @var Page[]
  98.      */
  99.     private $linkedPages = [];
  100.  
  101.     public function __construct(string $id, array $linkedPages)
  102.     {
  103.         parent::__construct($id);
  104.  
  105.         foreach (self::validatePages(...$linkedPages) as $page) {
  106.             $this->linkPage($page);
  107.         }
  108.     }
  109.  
  110.     /**
  111.      * @param Page[] ...$pages
  112.      *
  113.      * @return Page[]
  114.      */
  115.     private static function validatePages(Page ...$pages): array
  116.     {
  117.         return $pages;
  118.     }
  119.  
  120.     public function linkPage(Page $page): void
  121.     {
  122.         $name = $page->name();
  123.         if (array_key_exists($name, $this->linkedPages)) {
  124.             throw new \RuntimeException(sprintf(
  125.                 'The pages collection "%s" already contains a page with the name "%s".',
  126.                 $this->id(),
  127.                 $name
  128.             ));
  129.         }
  130.  
  131.         $this->linkedPages[$name] = $page;
  132.     }
  133.  
  134.     public function updatePageWithNewName(Page $pageWithNewName)
  135.     {
  136.         $linkedPage = $this->findLinkedPage($pageWithNewName);
  137.         if ($linkedPage === null) {
  138.             throw new \RuntimeException(sprintf(
  139.                 'The Pages collections "%s" does not contain a page with the id "%s".',
  140.                 $this->id(),
  141.                 $pageWithNewName->id()
  142.             ));
  143.         }
  144.  
  145.         if ($linkedPage->name() === $pageWithNewName->name()) {
  146.             throw new \RuntimeException('Original page and a new page cannot have the same name during renaming.');
  147.         }
  148.  
  149.         $this->linkPage($pageWithNewName);
  150.  
  151.         unset($this->linkedPages[$linkedPage->name()]);
  152.     }
  153.  
  154.     private function findLinkedPage(Page $toBeFound): ?Page
  155.     {
  156.         foreach ($this->linkedPages as $page) {
  157.             if ($page->id() === $toBeFound->id()) {
  158.                 return $page;
  159.             }
  160.         }
  161.  
  162.         return null;
  163.     }
  164. }
  165.  
  166. class RenamePage
  167. {
  168.     public $pageId;
  169.  
  170.     public $newName;
  171.  
  172.     public function __construct(string $pageId, string $newName)
  173.     {
  174.         $this->pageId  = $pageId;
  175.         $this->newName = $newName;
  176.     }
  177. }
  178.  
  179. class RenameStandalonePage implements PageRenamingInterface
  180. {
  181.     public function execute(Page $toBeRenamed, string $newName): Page
  182.     {
  183.         $toBeRenamed->changeName($newName);
  184.  
  185.         return $toBeRenamed;
  186.     }
  187. }
  188.  
  189. class RenamePageIncludedInPages implements PageRenamingInterface
  190. {
  191.  
  192.     private $pagesRepository;
  193.  
  194.     public function __construct(PagesRepositoryInterface $pagesRepository)
  195.     {
  196.         $this->pagesRepository = $pagesRepository;
  197.     }
  198.  
  199.     public function execute(Page $toBeRenamed, string $newName): Page
  200.     {
  201.         $pagesParentId   = $toBeRenamed->pagesParentId();
  202.         $pagesCollection = $this->pagesRepository->loadOne($pagesParentId);
  203.         if ($pagesCollection === null) {
  204.             throw new RuntimeException(sprintf(
  205.                 'The page "%s" could not be renamed because the parent pages "%s" could not be found.',
  206.                 $toBeRenamed->id(),
  207.                 $pagesParentId
  208.             ));
  209.         }
  210.  
  211.         $toBeRenamed->changeName($newName);
  212.         $pagesCollection->updatePageWithNewName($toBeRenamed);
  213.  
  214.         return $toBeRenamed;
  215.     }
  216. }
  217.  
  218. class PageRenamingStrategy
  219. {
  220.     private $renameStandalonePage;
  221.  
  222.     private $renamePageIncludedInPages;
  223.  
  224.     public function __construct(
  225.         RenameStandalonePage $renameStandalonePage,
  226.         RenamePageIncludedInPages $renamePageIncludedInPages
  227.     )
  228.     {
  229.         $this->renameStandalonePage      = $renameStandalonePage;
  230.         $this->renamePageIncludedInPages = $renamePageIncludedInPages;
  231.     }
  232.  
  233.     public function getForPage(Page $pageToBeRenamed): PageRenamingInterface
  234.     {
  235.         if (!$pageToBeRenamed->belongsToPagesCollection()) {
  236.             return $this->renameStandalonePage;
  237.         }
  238.  
  239.         return $this->renamePageIncludedInPages;
  240.     }
  241. }
  242.  
  243. class RenamePageHandler
  244. {
  245.     private $pageRepository;
  246.  
  247.     private $renamingStrategy;
  248.  
  249.     public function __construct(PageRepositoryInterface $pageRepository, PageRenamingStrategy $renamingStrategy)
  250.     {
  251.         $this->pageRepository   = $pageRepository;
  252.         $this->renamingStrategy = $renamingStrategy;
  253.     }
  254.  
  255.     public function handle(RenamePage $command): void
  256.     {
  257.         $pageId = $command->pageId;
  258.         $page   = $this->pageRepository->loadOne($pageId);
  259.         if ($page === null) {
  260.             throw new RuntimeException(sprintf(
  261.                 'The page with the id "%s" could not be found, thus renamed.',
  262.                 $pageId
  263.             ));
  264.         }
  265.  
  266.         $updatedPage = $this->renamingStrategy->getForPage($page)->execute($page, $command->newName);
  267.  
  268.         $this->pageRepository->save($updatedPage);
  269.     }
  270. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement