Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- declare(strict_types=1);
- interface PagesRepositoryInterface
- {
- public function loadOne(string $pagesId): ?Pages;
- }
- interface PageRepositoryInterface
- {
- public function loadOne(string $pageId): ?Page;
- public function save(Page $page): void;
- }
- interface PageRenamingInterface
- {
- /**
- * @param Page $toBeRenamed
- * @param string $newName
- *
- * @return Page
- *
- * @throws \RuntimeException Thrown when renaming could not be completed for any reason. This exception should be
- * specialized so that it covers a specific error.
- */
- public function execute(Page $toBeRenamed, string $newName): Page;
- }
- abstract class Entity
- {
- private $id;
- public function __construct(string $id)
- {
- $this->id = $id;
- }
- final public function id(): string
- {
- return $this->id;
- }
- }
- class Page extends Entity
- {
- private $name;
- private $pagesParentId;
- public function __construct(string $id, string $name, ?string $pagesParentId)
- {
- parent::__construct($id);
- self::validateName($name);
- $this->name = $name;
- $this->pagesParentId = $pagesParentId;
- }
- /**
- * @param string $name
- */
- private static function validateName(string $name): void
- {
- // throw on error
- }
- public function name(): string
- {
- return $this->name;
- }
- public function belongsToPagesCollection(): bool
- {
- return $this->pagesParentId() !== null;
- }
- public function pagesParentId(): ?string
- {
- return $this->pagesParentId;
- }
- public function changeName(string $newName)
- {
- self::validateName($newName);
- $this->name = $newName;
- }
- }
- class Pages extends Entity
- {
- /**
- * Indexed by page name
- *
- * @var Page[]
- */
- private $linkedPages = [];
- public function __construct(string $id, array $linkedPages)
- {
- parent::__construct($id);
- foreach (self::validatePages(...$linkedPages) as $page) {
- $this->linkPage($page);
- }
- }
- /**
- * @param Page[] ...$pages
- *
- * @return Page[]
- */
- private static function validatePages(Page ...$pages): array
- {
- return $pages;
- }
- public function linkPage(Page $page): void
- {
- $name = $page->name();
- if (array_key_exists($name, $this->linkedPages)) {
- throw new \RuntimeException(sprintf(
- 'The pages collection "%s" already contains a page with the name "%s".',
- $this->id(),
- $name
- ));
- }
- $this->linkedPages[$name] = $page;
- }
- public function updatePageWithNewName(Page $pageWithNewName)
- {
- $linkedPage = $this->findLinkedPage($pageWithNewName);
- if ($linkedPage === null) {
- throw new \RuntimeException(sprintf(
- 'The Pages collections "%s" does not contain a page with the id "%s".',
- $this->id(),
- $pageWithNewName->id()
- ));
- }
- if ($linkedPage->name() === $pageWithNewName->name()) {
- throw new \RuntimeException('Original page and a new page cannot have the same name during renaming.');
- }
- $this->linkPage($pageWithNewName);
- unset($this->linkedPages[$linkedPage->name()]);
- }
- private function findLinkedPage(Page $toBeFound): ?Page
- {
- foreach ($this->linkedPages as $page) {
- if ($page->id() === $toBeFound->id()) {
- return $page;
- }
- }
- return null;
- }
- }
- class RenamePage
- {
- public $pageId;
- public $newName;
- public function __construct(string $pageId, string $newName)
- {
- $this->pageId = $pageId;
- $this->newName = $newName;
- }
- }
- class RenameStandalonePage implements PageRenamingInterface
- {
- public function execute(Page $toBeRenamed, string $newName): Page
- {
- $toBeRenamed->changeName($newName);
- return $toBeRenamed;
- }
- }
- class RenamePageIncludedInPages implements PageRenamingInterface
- {
- private $pagesRepository;
- public function __construct(PagesRepositoryInterface $pagesRepository)
- {
- $this->pagesRepository = $pagesRepository;
- }
- public function execute(Page $toBeRenamed, string $newName): Page
- {
- $pagesParentId = $toBeRenamed->pagesParentId();
- $pagesCollection = $this->pagesRepository->loadOne($pagesParentId);
- if ($pagesCollection === null) {
- throw new RuntimeException(sprintf(
- 'The page "%s" could not be renamed because the parent pages "%s" could not be found.',
- $toBeRenamed->id(),
- $pagesParentId
- ));
- }
- $toBeRenamed->changeName($newName);
- $pagesCollection->updatePageWithNewName($toBeRenamed);
- return $toBeRenamed;
- }
- }
- class PageRenamingStrategy
- {
- private $renameStandalonePage;
- private $renamePageIncludedInPages;
- public function __construct(
- RenameStandalonePage $renameStandalonePage,
- RenamePageIncludedInPages $renamePageIncludedInPages
- )
- {
- $this->renameStandalonePage = $renameStandalonePage;
- $this->renamePageIncludedInPages = $renamePageIncludedInPages;
- }
- public function getForPage(Page $pageToBeRenamed): PageRenamingInterface
- {
- if (!$pageToBeRenamed->belongsToPagesCollection()) {
- return $this->renameStandalonePage;
- }
- return $this->renamePageIncludedInPages;
- }
- }
- class RenamePageHandler
- {
- private $pageRepository;
- private $renamingStrategy;
- public function __construct(PageRepositoryInterface $pageRepository, PageRenamingStrategy $renamingStrategy)
- {
- $this->pageRepository = $pageRepository;
- $this->renamingStrategy = $renamingStrategy;
- }
- public function handle(RenamePage $command): void
- {
- $pageId = $command->pageId;
- $page = $this->pageRepository->loadOne($pageId);
- if ($page === null) {
- throw new RuntimeException(sprintf(
- 'The page with the id "%s" could not be found, thus renamed.',
- $pageId
- ));
- }
- $updatedPage = $this->renamingStrategy->getForPage($page)->execute($page, $command->newName);
- $this->pageRepository->save($updatedPage);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement