104fd306cSNickeau<?php 204fd306cSNickeau 304fd306cSNickeau 404fd306cSNickeaunamespace ComboStrap; 504fd306cSNickeau 604fd306cSNickeau 704fd306cSNickeau/** 804fd306cSNickeau * This class represents a page layout slots 904fd306cSNickeau */ 1004fd306cSNickeauclass TemplateSlot 1104fd306cSNickeau{ 1204fd306cSNickeau public const SLOT_IDS = [ 1304fd306cSNickeau self::PAGE_SIDE_ID, 1404fd306cSNickeau self::PAGE_HEADER_ID, 1504fd306cSNickeau self::PAGE_MAIN_ID, 1604fd306cSNickeau self::PAGE_FOOTER_ID, 1704fd306cSNickeau self::MAIN_HEADER_ID, 1804fd306cSNickeau self::MAIN_CONTENT_ID, 1904fd306cSNickeau self::MAIN_SIDE_ID, 2004fd306cSNickeau self::MAIN_FOOTER_ID 2104fd306cSNickeau ]; 2204fd306cSNickeau public const PAGE_HEADER_ID = "page-header"; 2304fd306cSNickeau public const PAGE_FOOTER_ID = "page-footer"; 2404fd306cSNickeau public const MAIN_SIDE_ID = "main-side"; 2504fd306cSNickeau public const PAGE_SIDE_ID = "page-side"; 2604fd306cSNickeau public const MAIN_CONTENT_ID = "main-content"; 2704fd306cSNickeau public const MAIN_FOOTER_ID = "main-footer"; 2804fd306cSNickeau public const MAIN_HEADER_ID = "main-header"; 2904fd306cSNickeau public const PAGE_MAIN_ID = "page-main"; 3004fd306cSNickeau public const CONF_PAGE_MAIN_SIDEKICK_NAME_DEFAULT = Site::SLOT_MAIN_SIDE_NAME; 31*ad54dffdSgerardnico public const CONF_PAGE_HEADER_NAME = "combo-conf-008"; 32*ad54dffdSgerardnico public const CONF_PAGE_FOOTER_NAME = "combo-conf-009"; 3304fd306cSNickeau public const CONF_PAGE_HEADER_NAME_DEFAULT = "slot_header"; 3404fd306cSNickeau public const CONF_PAGE_FOOTER_NAME_DEFAULT = "slot_footer"; 3504fd306cSNickeau public const CONF_PAGE_MAIN_SIDEKICK_NAME = "sidekickSlotPageName"; 3604fd306cSNickeau const MAIN_TOC_ID = "main-toc"; 3704fd306cSNickeau const SLOT_MAIN_HEADER_PATH_NAME = "slot_main_header"; 3804fd306cSNickeau const SLOT_MAIN_FOOTER_PATH_NAME = "slot_main_footer"; 3904fd306cSNickeau 4004fd306cSNickeau 4104fd306cSNickeau /** 4204fd306cSNickeau * @var WikiPath - the context path of this slot 4304fd306cSNickeau */ 4404fd306cSNickeau private WikiPath $contextPath; 4504fd306cSNickeau /** 4604fd306cSNickeau * @var FetcherMarkup - the fetcher if this is a slot and has a page fragment source 4704fd306cSNickeau */ 4804fd306cSNickeau private FetcherMarkup $fetcherFragment; 4904fd306cSNickeau private string $elementId; 5004fd306cSNickeau 5104fd306cSNickeau 5204fd306cSNickeau public function __construct(string $elementId, WikiPath $contextPath) 5304fd306cSNickeau { 5404fd306cSNickeau 5504fd306cSNickeau $this->elementId = $elementId; 5604fd306cSNickeau if (!in_array($elementId, self::SLOT_IDS)) { 5704fd306cSNickeau throw new ExceptionRuntimeInternal("$elementId is not a valid slot id. Valid ids are (" . ArrayUtility::formatAsString(self::SLOT_IDS) . ")."); 5804fd306cSNickeau } 5904fd306cSNickeau $this->contextPath = $contextPath; 6004fd306cSNickeau 6104fd306cSNickeau 6204fd306cSNickeau } 6304fd306cSNickeau 6404fd306cSNickeau public static function createFromElementId(string $elementId, WikiPath $contextPath = null): TemplateSlot 6504fd306cSNickeau { 6604fd306cSNickeau 6704fd306cSNickeau if ($contextPath === null) { 6804fd306cSNickeau $contextPath = ExecutionContext::getActualOrCreateFromEnv() 6904fd306cSNickeau ->getConfig() 7004fd306cSNickeau ->getDefaultContextPath(); 7104fd306cSNickeau } 7204fd306cSNickeau return new TemplateSlot($elementId, $contextPath); 7304fd306cSNickeau 7404fd306cSNickeau } 7504fd306cSNickeau 7604fd306cSNickeau public static function createFromPathName($pathNameWithoutExtension): TemplateSlot 7704fd306cSNickeau { 7804fd306cSNickeau return self::createFromElementId(self::getElementIdFromPathName($pathNameWithoutExtension)); 7904fd306cSNickeau } 8004fd306cSNickeau 8104fd306cSNickeau private static function getElementIdFromPathName($pathNameWithoutExtension): string 8204fd306cSNickeau { 8304fd306cSNickeau if ($pathNameWithoutExtension === SlotSystem::getPageHeaderSlotName()) { 8404fd306cSNickeau return self::PAGE_HEADER_ID; 8504fd306cSNickeau } 8604fd306cSNickeau 8704fd306cSNickeau if ($pathNameWithoutExtension === SlotSystem::getPageFooterSlotName()) { 8804fd306cSNickeau return self::PAGE_FOOTER_ID; 8904fd306cSNickeau } 9004fd306cSNickeau if ($pathNameWithoutExtension === SlotSystem::getSidebarName()) { 9104fd306cSNickeau return self::PAGE_SIDE_ID; 9204fd306cSNickeau } 9304fd306cSNickeau 9404fd306cSNickeau if ($pathNameWithoutExtension === SlotSystem::getMainSideSlotName()) { 9504fd306cSNickeau return self::MAIN_SIDE_ID; 9604fd306cSNickeau } 9704fd306cSNickeau if ($pathNameWithoutExtension === self::SLOT_MAIN_HEADER_PATH_NAME) { 9804fd306cSNickeau return self::MAIN_HEADER_ID; 9904fd306cSNickeau } 10004fd306cSNickeau if ($pathNameWithoutExtension === self::SLOT_MAIN_FOOTER_PATH_NAME) { 10104fd306cSNickeau return self::MAIN_FOOTER_ID; 10204fd306cSNickeau } 10304fd306cSNickeau throw new ExceptionRuntimeInternal("Internal: The markup name ($pathNameWithoutExtension) was unexpected, it's not a slot"); 10404fd306cSNickeau 10504fd306cSNickeau } 10604fd306cSNickeau 10704fd306cSNickeau 10804fd306cSNickeau public 10904fd306cSNickeau static function getPathNameFromElementId($elementId) 11004fd306cSNickeau { 11104fd306cSNickeau switch ($elementId) { 11204fd306cSNickeau case self::PAGE_HEADER_ID: 11304fd306cSNickeau return SlotSystem::getPageHeaderSlotName(); 11404fd306cSNickeau case self::PAGE_FOOTER_ID: 11504fd306cSNickeau return SlotSystem::getPageFooterSlotName(); 11604fd306cSNickeau case self::MAIN_CONTENT_ID: 11704fd306cSNickeau throw new ExceptionRuntimeInternal("Main content area is not a slot and does not have any last slot name"); 11804fd306cSNickeau case self::PAGE_SIDE_ID: 11904fd306cSNickeau return SlotSystem::getSidebarName(); 12004fd306cSNickeau case self::MAIN_SIDE_ID: 12104fd306cSNickeau return SlotSystem::getMainSideSlotName(); 12204fd306cSNickeau case self::MAIN_HEADER_ID: 12304fd306cSNickeau return self::SLOT_MAIN_HEADER_PATH_NAME; 12404fd306cSNickeau case self::MAIN_FOOTER_ID: 12504fd306cSNickeau return self::SLOT_MAIN_FOOTER_PATH_NAME; 12604fd306cSNickeau default: 12704fd306cSNickeau throw new ExceptionRuntimeInternal("Internal: The element ($elementId) was unexpected, it's not a slot"); 12804fd306cSNickeau } 12904fd306cSNickeau 13004fd306cSNickeau } 13104fd306cSNickeau 13204fd306cSNickeau /** 13304fd306cSNickeau * 13404fd306cSNickeau * @return WikiPath 13504fd306cSNickeau */ 13604fd306cSNickeau public 13704fd306cSNickeau function getDefaultSlotContentPath(): WikiPath 13804fd306cSNickeau { 13904fd306cSNickeau return WikiPath::createComboResource(":slot:{$this->getElementId()}.md"); 14004fd306cSNickeau } 14104fd306cSNickeau 14204fd306cSNickeau 14304fd306cSNickeau /** 14404fd306cSNickeau */ 14504fd306cSNickeau public 14604fd306cSNickeau function getLastFileNameForFragment() 14704fd306cSNickeau { 14804fd306cSNickeau $elementId = $this->getElementId(); 14904fd306cSNickeau return self::getPathNameFromElementId($elementId); 15004fd306cSNickeau } 15104fd306cSNickeau 15204fd306cSNickeau 15304fd306cSNickeau public 15404fd306cSNickeau function __toString() 15504fd306cSNickeau { 15604fd306cSNickeau return "Slot {$this->getElementId()} for {$this->contextPath}"; 15704fd306cSNickeau } 15804fd306cSNickeau 15904fd306cSNickeau 16004fd306cSNickeau /** 16104fd306cSNickeau * @throws ExceptionNotFound - if the area is not a slot or there is no path found 16204fd306cSNickeau */ 16304fd306cSNickeau private 16404fd306cSNickeau function getFragmentPath() 16504fd306cSNickeau { 16604fd306cSNickeau 16704fd306cSNickeau // Main content 16804fd306cSNickeau $requestedPath = $this->contextPath; 16904fd306cSNickeau if ($this->getElementId() === self::MAIN_CONTENT_ID) { 17004fd306cSNickeau return $requestedPath; 17104fd306cSNickeau } 17204fd306cSNickeau // Slot 17304fd306cSNickeau $contextExtension = $requestedPath->getExtension(); 17404fd306cSNickeau try { 17504fd306cSNickeau return FileSystems::closest($requestedPath, $this->getLastFileNameForFragment() . '.' . $contextExtension); 17604fd306cSNickeau } catch (ExceptionNotFound $e) { 17704fd306cSNickeau foreach (WikiPath::ALL_MARKUP_EXTENSIONS as $markupExtension) { 17804fd306cSNickeau if ($markupExtension == $contextExtension) { 17904fd306cSNickeau continue; 18004fd306cSNickeau } 18104fd306cSNickeau try { 18204fd306cSNickeau return FileSystems::closest($requestedPath, $this->getLastFileNameForFragment() . '.' . $contextExtension); 18304fd306cSNickeau } catch (ExceptionNotFound $e) { 18404fd306cSNickeau // not found, we let it go to the default if needed 18504fd306cSNickeau } 18604fd306cSNickeau } 18704fd306cSNickeau } 18804fd306cSNickeau 18904fd306cSNickeau 19004fd306cSNickeau return $this->getDefaultSlotContentPath(); 19104fd306cSNickeau 19204fd306cSNickeau 19304fd306cSNickeau 19404fd306cSNickeau } 19504fd306cSNickeau 19604fd306cSNickeau 19704fd306cSNickeau /** 19804fd306cSNickeau * @throws ExceptionNotFound if the page/markup fragment was not found (a container element does not have any also) 19904fd306cSNickeau */ 20004fd306cSNickeau public 20104fd306cSNickeau function getMarkupFetcher(): FetcherMarkup 20204fd306cSNickeau { 20304fd306cSNickeau if (isset($this->fetcherFragment)) { 20404fd306cSNickeau return $this->fetcherFragment; 20504fd306cSNickeau } 20604fd306cSNickeau /** 20704fd306cSNickeau * Rebuild the fragment if any 20804fd306cSNickeau */ 20904fd306cSNickeau $fragmentPath = $this->getFragmentPath(); 21004fd306cSNickeau $contextPath = $this->contextPath; 21104fd306cSNickeau try { 21204fd306cSNickeau $this->fetcherFragment = FetcherMarkup::createXhtmlMarkupFetcherFromPath($fragmentPath, $contextPath); 21304fd306cSNickeau } catch (ExceptionNotExists $e) { 21404fd306cSNickeau throw new ExceptionNotFound("The fragment path ($fragmentPath) was no found"); 21504fd306cSNickeau } 21604fd306cSNickeau return $this->fetcherFragment; 21704fd306cSNickeau } 21804fd306cSNickeau 21904fd306cSNickeau public 22004fd306cSNickeau function getElementId(): string 22104fd306cSNickeau { 22204fd306cSNickeau return $this->elementId; 22304fd306cSNickeau } 22404fd306cSNickeau 22504fd306cSNickeau public function getPathName() 22604fd306cSNickeau { 22704fd306cSNickeau return self::getPathNameFromElementId($this->getElementId()); 22804fd306cSNickeau } 22904fd306cSNickeau 23004fd306cSNickeau 23104fd306cSNickeau} 232