104fd306cSNickeau<?php 204fd306cSNickeau 304fd306cSNickeaunamespace ComboStrap; 404fd306cSNickeau 504fd306cSNickeau 604fd306cSNickeauuse ComboStrap\Api\QualityMessageHandler; 704fd306cSNickeauuse ComboStrap\Meta\Api\Metadata; 804fd306cSNickeauuse ComboStrap\Meta\Api\MetadataBoolean; 904fd306cSNickeauuse ComboStrap\Meta\Api\MetadataStore; 1004fd306cSNickeauuse ComboStrap\Meta\Api\MetadataStoreAbs; 1104fd306cSNickeauuse ComboStrap\Meta\Field\Alias; 1204fd306cSNickeauuse ComboStrap\Meta\Field\Aliases; 1304fd306cSNickeauuse ComboStrap\Meta\Field\AliasType; 1404fd306cSNickeauuse ComboStrap\Meta\Field\PageH1; 1504fd306cSNickeauuse ComboStrap\Meta\Field\PageImage; 1604fd306cSNickeauuse ComboStrap\Meta\Field\PageImages; 1704fd306cSNickeauuse ComboStrap\Meta\Field\PageTemplateName; 1804fd306cSNickeauuse ComboStrap\Meta\Field\Region; 1904fd306cSNickeauuse ComboStrap\Meta\Store\MetadataDokuWikiStore; 2004fd306cSNickeauuse ComboStrap\Web\Url; 2104fd306cSNickeauuse ComboStrap\Web\UrlEndpoint; 2204fd306cSNickeauuse DateTime; 2304fd306cSNickeauuse dokuwiki\ChangeLog\ChangeLog; 2404fd306cSNickeauuse Exception; 2504fd306cSNickeauuse renderer_plugin_combo_analytics; 2604fd306cSNickeau 2704fd306cSNickeau 2804fd306cSNickeau/** 2904fd306cSNickeau * 3004fd306cSNickeau * A markup is a logical unit that represents a markup file. 3104fd306cSNickeau * 3204fd306cSNickeau * It has its own file system {@link MarkupFileSystem} explained in the 3304fd306cSNickeau * https://combostrap.com/page/system (or system.txt file). 3404fd306cSNickeau * ie the {@link Path::getParent()} is not the same than on an normal file system. 3504fd306cSNickeau * 3604fd306cSNickeau * This should be an extension of {@link WikiPath} but for now, we are not extending {@link WikiPath} 3704fd306cSNickeau * for the following old reasons: 3804fd306cSNickeau * * we want to be able to return a {@link MarkupPath} in the {@link MarkupPath::getParent()} function 3904fd306cSNickeau * otherwise if we do, we get a hierarchical error. 4004fd306cSNickeau * * we can then accepts also {@link LocalPath} 4104fd306cSNickeau * 4204fd306cSNickeau * But because this is a {@link ResourceCombo}, we see tht this is part of the {@link WikiPath} 4304fd306cSNickeau * system with an {@link ResourceCombo::getUid()} unique uid. 4404fd306cSNickeau * 4504fd306cSNickeau * We should find a way to be able to create a wiki path with a {@link LocalPath} 4604fd306cSNickeau * via the {@link WikiPath::getDrive()} ? 4704fd306cSNickeau * 4804fd306cSNickeau */ 4904fd306cSNickeauclass MarkupPath extends PathAbs implements ResourceCombo, Path 5004fd306cSNickeau{ 5104fd306cSNickeau 5204fd306cSNickeau const CANONICAL_PAGE = "markup"; 5304fd306cSNickeau 5404fd306cSNickeau 5504fd306cSNickeau const TYPE = "page"; 5604fd306cSNickeau 5704fd306cSNickeau /** 5804fd306cSNickeau * @var Canonical 5904fd306cSNickeau */ 6004fd306cSNickeau private $canonical; 6104fd306cSNickeau /** 6204fd306cSNickeau * @var PageH1 6304fd306cSNickeau */ 6404fd306cSNickeau private $h1; 6504fd306cSNickeau /** 6604fd306cSNickeau * @var ResourceName 6704fd306cSNickeau */ 6804fd306cSNickeau private $pageName; 6904fd306cSNickeau /** 7004fd306cSNickeau * @var PageType 7104fd306cSNickeau */ 7204fd306cSNickeau private $type; 7304fd306cSNickeau /** 7404fd306cSNickeau * @var PageTitle $title 7504fd306cSNickeau */ 7604fd306cSNickeau private $title; 7704fd306cSNickeau 7804fd306cSNickeau private $uidObject; 7904fd306cSNickeau 8004fd306cSNickeau private LowQualityPageOverwrite $canBeOfLowQuality; 8104fd306cSNickeau /** 8204fd306cSNickeau * @var Region 8304fd306cSNickeau */ 8404fd306cSNickeau private $region; 8504fd306cSNickeau /** 8604fd306cSNickeau * @var Lang 8704fd306cSNickeau */ 8804fd306cSNickeau private $lang; 8904fd306cSNickeau /** 9004fd306cSNickeau * @var PageId 9104fd306cSNickeau */ 9204fd306cSNickeau private $pageId; 9304fd306cSNickeau 9404fd306cSNickeau /** 9504fd306cSNickeau * @var LowQualityCalculatedIndicator 9604fd306cSNickeau */ 9704fd306cSNickeau private $lowQualityIndicatorCalculated; 9804fd306cSNickeau 9904fd306cSNickeau /** 10004fd306cSNickeau * @var PageTemplateName 10104fd306cSNickeau */ 10204fd306cSNickeau private $layout; 10304fd306cSNickeau /** 10404fd306cSNickeau * @var Aliases 10504fd306cSNickeau */ 10604fd306cSNickeau private $aliases; 10704fd306cSNickeau /** 10804fd306cSNickeau * @var Slug a slug path 10904fd306cSNickeau */ 11004fd306cSNickeau private $slug; 11104fd306cSNickeau 11204fd306cSNickeau 11304fd306cSNickeau /** 11404fd306cSNickeau * @var QualityDynamicMonitoringOverwrite 11504fd306cSNickeau */ 11604fd306cSNickeau private $qualityMonitoringIndicator; 11704fd306cSNickeau 11804fd306cSNickeau /** 11904fd306cSNickeau * @var string the alias used to build this page 12004fd306cSNickeau */ 12104fd306cSNickeau private $buildAliasPath; 12204fd306cSNickeau /** 12304fd306cSNickeau * @var PagePublicationDate 12404fd306cSNickeau */ 12504fd306cSNickeau private $publishedDate; 12604fd306cSNickeau /** 12704fd306cSNickeau * @var StartDate 12804fd306cSNickeau */ 12904fd306cSNickeau private $startDate; 13004fd306cSNickeau /** 13104fd306cSNickeau * @var EndDate 13204fd306cSNickeau */ 13304fd306cSNickeau private $endDate; 13404fd306cSNickeau /** 13504fd306cSNickeau * @var PageImages 13604fd306cSNickeau */ 13704fd306cSNickeau private $pageImages; 13804fd306cSNickeau 13904fd306cSNickeau private PageKeywords $keywords; 14004fd306cSNickeau /** 14104fd306cSNickeau * @var CacheExpirationFrequency 14204fd306cSNickeau */ 14304fd306cSNickeau private $cacheExpirationFrequency; 14404fd306cSNickeau /** 14504fd306cSNickeau * @var CacheExpirationDate 14604fd306cSNickeau */ 14704fd306cSNickeau private $cacheExpirationDate; 14804fd306cSNickeau /** 14904fd306cSNickeau * 15004fd306cSNickeau * @var LdJson 15104fd306cSNickeau */ 15204fd306cSNickeau private $ldJson; 15304fd306cSNickeau 15404fd306cSNickeau 15504fd306cSNickeau /** 15604fd306cSNickeau * @var PageDescription $description 15704fd306cSNickeau */ 15804fd306cSNickeau private $description; 15904fd306cSNickeau /** 16004fd306cSNickeau * @var CreationDate 16104fd306cSNickeau */ 16204fd306cSNickeau private $creationTime; 16304fd306cSNickeau /** 16404fd306cSNickeau * @var Locale 16504fd306cSNickeau */ 16604fd306cSNickeau private $locale; 16704fd306cSNickeau /** 16804fd306cSNickeau * @var ModificationDate 16904fd306cSNickeau */ 17004fd306cSNickeau private $modifiedTime; 17104fd306cSNickeau /** 17204fd306cSNickeau * @var PageUrlPath 17304fd306cSNickeau */ 17404fd306cSNickeau private $pageUrlPath; 17504fd306cSNickeau /** 17604fd306cSNickeau * @var MetadataStore|string 17704fd306cSNickeau */ 17804fd306cSNickeau private $readStore; 17904fd306cSNickeau 18004fd306cSNickeau /** 18104fd306cSNickeau * @var Path - {@link MarkupPath} has other hierachy system in regards with parent 18204fd306cSNickeau * May be we just should extends {@link WikiPath} but it was a way to be able to locate 18304fd306cSNickeau * default markup path file that were not in any drive 18404fd306cSNickeau * TODO: Just extends WikiPath and add private drive when data should be accessed locally ? 18504fd306cSNickeau */ 18604fd306cSNickeau private Path $path; 18704fd306cSNickeau 18804fd306cSNickeau /** 18904fd306cSNickeau * Page constructor. 19004fd306cSNickeau * 19104fd306cSNickeau */ 19204fd306cSNickeau public function __construct(Path $path) 19304fd306cSNickeau { 19404fd306cSNickeau 19504fd306cSNickeau $this->path = $path; 19604fd306cSNickeau if (FileSystems::isDirectory($path)) { 19704fd306cSNickeau $this->setCorrectPathForDirectoryToIndexPage(); 19804fd306cSNickeau } 19904fd306cSNickeau $this->buildPropertiesFromFileSystem(); 20004fd306cSNickeau 20104fd306cSNickeau } 20204fd306cSNickeau 20304fd306cSNickeau /** 20404fd306cSNickeau * The current running rendering markup 20504fd306cSNickeau * @throws ExceptionNotFound 20604fd306cSNickeau */ 20704fd306cSNickeau public static function createPageFromExecutingId(): MarkupPath 20804fd306cSNickeau { 20904fd306cSNickeau $wikiPath = WikiPath::createExecutingMarkupWikiPath(); 21004fd306cSNickeau return self::createPageFromPathObject($wikiPath); 21104fd306cSNickeau } 21204fd306cSNickeau 21304fd306cSNickeau 21404fd306cSNickeau public static function createMarkupFromId($id): MarkupPath 21504fd306cSNickeau { 21604fd306cSNickeau return new MarkupPath(WikiPath::createMarkupPathFromId($id)); 21704fd306cSNickeau } 21804fd306cSNickeau 21904fd306cSNickeau /** 22004fd306cSNickeau * @param string $path - relative or absolute 22104fd306cSNickeau * @return MarkupPath 22204fd306cSNickeau */ 22304fd306cSNickeau public static function createMarkupFromStringPath(string $path): MarkupPath 22404fd306cSNickeau { 22504fd306cSNickeau $wikiPath = WikiPath::createMarkupPathFromPath($path); 22604fd306cSNickeau return new MarkupPath($wikiPath); 22704fd306cSNickeau 22804fd306cSNickeau } 22904fd306cSNickeau 23004fd306cSNickeau /** 23104fd306cSNickeau * @return MarkupPath - the requested page 23204fd306cSNickeau * @throws ExceptionNotFound 23304fd306cSNickeau */ 23404fd306cSNickeau public static function createFromRequestedPage(): MarkupPath 23504fd306cSNickeau { 23604fd306cSNickeau $path = WikiPath::createRequestedPagePathFromRequest(); 23704fd306cSNickeau return MarkupPath::createPageFromPathObject($path); 23804fd306cSNickeau } 23904fd306cSNickeau 24004fd306cSNickeau 24104fd306cSNickeau public static function createPageFromPathObject(Path $path): MarkupPath 24204fd306cSNickeau { 24304fd306cSNickeau if ($path instanceof MarkupPath) { 24404fd306cSNickeau return $path; 24504fd306cSNickeau } 24604fd306cSNickeau return new MarkupPath($path); 24704fd306cSNickeau } 24804fd306cSNickeau 24904fd306cSNickeau 25004fd306cSNickeau /** 25104fd306cSNickeau * 25204fd306cSNickeau * @throws ExceptionBadSyntax - if this is not a 25304fd306cSNickeau * @deprecated just pass a namespace path to the page creation and you will get the index page in return 25404fd306cSNickeau */ 25504fd306cSNickeau public static function getIndexPageFromNamespace(string $namespacePath): MarkupPath 25604fd306cSNickeau { 25704fd306cSNickeau WikiPath::checkNamespacePath($namespacePath); 25804fd306cSNickeau 25904fd306cSNickeau return MarkupPath::createMarkupFromId($namespacePath); 26004fd306cSNickeau } 26104fd306cSNickeau 26204fd306cSNickeau 26304fd306cSNickeau static function createPageFromAbsoluteId($qualifiedPath): MarkupPath 26404fd306cSNickeau { 26504fd306cSNickeau $path = WikiPath::createMarkupPathFromId($qualifiedPath); 26604fd306cSNickeau return new MarkupPath($path); 26704fd306cSNickeau } 26804fd306cSNickeau 26904fd306cSNickeau 27004fd306cSNickeau /** 27104fd306cSNickeau * 27204fd306cSNickeau * @throws ExceptionCompile 27304fd306cSNickeau */ 27404fd306cSNickeau public 27504fd306cSNickeau function setCanonical($canonical): MarkupPath 27604fd306cSNickeau { 27704fd306cSNickeau $this->canonical 27804fd306cSNickeau ->setValue($canonical) 27904fd306cSNickeau ->sendToWriteStore(); 28004fd306cSNickeau return $this; 28104fd306cSNickeau } 28204fd306cSNickeau 28304fd306cSNickeau 28404fd306cSNickeau /** 28504fd306cSNickeau * @return bool true if this is a fragment markup 28604fd306cSNickeau */ 28704fd306cSNickeau public function isSlot(): bool 28804fd306cSNickeau { 28904fd306cSNickeau $slotNames = SlotSystem::getSlotNames(); 29004fd306cSNickeau try { 29104fd306cSNickeau $name = $this->getPathObject()->getLastNameWithoutExtension(); 29204fd306cSNickeau } catch (ExceptionNotFound $e) { 29304fd306cSNickeau // root case 29404fd306cSNickeau return false; 29504fd306cSNickeau } 29604fd306cSNickeau return in_array($name, $slotNames, true); 29704fd306cSNickeau } 29804fd306cSNickeau 29904fd306cSNickeau /** 30004fd306cSNickeau * @return bool true if this is the side slot 30104fd306cSNickeau */ 30204fd306cSNickeau public function isSideSlot(): bool 30304fd306cSNickeau { 30404fd306cSNickeau $slotNames = SlotSystem::getSidebarName(); 30504fd306cSNickeau try { 30604fd306cSNickeau $name = $this->getPathObject()->getLastNameWithoutExtension(); 30704fd306cSNickeau } catch (ExceptionNotFound $e) { 30804fd306cSNickeau // root case 30904fd306cSNickeau return false; 31004fd306cSNickeau } 31104fd306cSNickeau return $name === $slotNames; 31204fd306cSNickeau } 31304fd306cSNickeau 31404fd306cSNickeau /** 31504fd306cSNickeau * @return bool true if this is the main 31604fd306cSNickeau */ 31704fd306cSNickeau public function isMainHeaderFooterSlot(): bool 31804fd306cSNickeau { 31904fd306cSNickeau 32004fd306cSNickeau $slotNames = [SlotSystem::getMainHeaderSlotName(), SlotSystem::getMainFooterSlotName()]; 32104fd306cSNickeau try { 32204fd306cSNickeau $name = $this->getPathObject()->getLastNameWithoutExtension(); 32304fd306cSNickeau } catch (ExceptionNotFound $e) { 32404fd306cSNickeau // root case 32504fd306cSNickeau return false; 32604fd306cSNickeau } 32704fd306cSNickeau 32804fd306cSNickeau return in_array($name, $slotNames, true); 32904fd306cSNickeau } 33004fd306cSNickeau 33104fd306cSNickeau 33204fd306cSNickeau /** 33304fd306cSNickeau * Return a canonical if set 33404fd306cSNickeau * otherwise derive it from the id 33504fd306cSNickeau * by taking the last two parts 33604fd306cSNickeau * 33704fd306cSNickeau * @return WikiPath 33804fd306cSNickeau * @throws ExceptionNotFound 33904fd306cSNickeau * @deprecated for {@link Canonical::getValueOrDefault()} 34004fd306cSNickeau */ 34104fd306cSNickeau public 34204fd306cSNickeau function getCanonicalOrDefault(): WikiPath 34304fd306cSNickeau { 34404fd306cSNickeau return $this->canonical->getValueFromStoreOrDefault(); 34504fd306cSNickeau 34604fd306cSNickeau } 34704fd306cSNickeau 34804fd306cSNickeau 34904fd306cSNickeau /** 35004fd306cSNickeau * Rebuild the page 35104fd306cSNickeau * (refresh from disk, reset object to null) 35204fd306cSNickeau * @return $this 35304fd306cSNickeau */ 35404fd306cSNickeau public 35504fd306cSNickeau function rebuild(): MarkupPath 35604fd306cSNickeau { 35704fd306cSNickeau $this->readStore = null; 35804fd306cSNickeau $this->buildPropertiesFromFileSystem(); 35904fd306cSNickeau return $this; 36004fd306cSNickeau } 36104fd306cSNickeau 36204fd306cSNickeau /** 36304fd306cSNickeau * 36404fd306cSNickeau * @return MarkupPath[]|null the internal links or null 36504fd306cSNickeau */ 36604fd306cSNickeau public 36704fd306cSNickeau function getLinkReferences(): ?array 36804fd306cSNickeau { 36904fd306cSNickeau $store = $this->getReadStoreOrDefault(); 37004fd306cSNickeau if (!($store instanceof MetadataDokuWikiStore)) { 37104fd306cSNickeau return null; 37204fd306cSNickeau } 37304fd306cSNickeau $metadata = $store->getCurrentFromName('relation'); 37404fd306cSNickeau if ($metadata === null) { 37504fd306cSNickeau /** 37604fd306cSNickeau * Happens when no rendering has been made 37704fd306cSNickeau */ 37804fd306cSNickeau return null; 37904fd306cSNickeau } 38004fd306cSNickeau if (!key_exists('references', $metadata)) { 38104fd306cSNickeau return null; 38204fd306cSNickeau } 38304fd306cSNickeau 38404fd306cSNickeau $pages = []; 38504fd306cSNickeau foreach (array_keys($metadata['references']) as $referencePageId) { 38604fd306cSNickeau $pages[$referencePageId] = MarkupPath::createMarkupFromId($referencePageId); 38704fd306cSNickeau } 38804fd306cSNickeau return $pages; 38904fd306cSNickeau 39004fd306cSNickeau } 39104fd306cSNickeau 39204fd306cSNickeau 39304fd306cSNickeau /** 39404fd306cSNickeau * 39504fd306cSNickeau * @throws ExceptionNotExists - if the path does not exists 39604fd306cSNickeau * @throws ExceptionCast - if the path is not a wiki path which is mandatory for the context 39704fd306cSNickeau */ 39804fd306cSNickeau public function createHtmlFetcherWithItselfAsContextPath(): FetcherMarkup 39904fd306cSNickeau { 40004fd306cSNickeau $path = $this->getPathObject(); 40104fd306cSNickeau return FetcherMarkup::createXhtmlMarkupFetcherFromPath($path, $path->toWikiPath()); 40204fd306cSNickeau } 40304fd306cSNickeau 40404fd306cSNickeau /** 40504fd306cSNickeau * @throws ExceptionCompile 40604fd306cSNickeau */ 40704fd306cSNickeau public function getHtmlPath(): LocalPath 40804fd306cSNickeau { 40904fd306cSNickeau 41004fd306cSNickeau $fetcher = $this->createHtmlFetcherWithItselfAsContextPath(); 41104fd306cSNickeau return $fetcher->processIfNeededAndGetFetchPath(); 41204fd306cSNickeau 41304fd306cSNickeau } 41404fd306cSNickeau 41504fd306cSNickeau /** 41604fd306cSNickeau * Set the page quality 41704fd306cSNickeau * @param boolean $value true if this is a low quality page rank false otherwise 41804fd306cSNickeau * @throws ExceptionCompile 41904fd306cSNickeau */ 42004fd306cSNickeau public 42104fd306cSNickeau function setCanBeOfLowQuality(bool $value): MarkupPath 42204fd306cSNickeau { 42304fd306cSNickeau return $this->setQualityIndicatorAndDeleteCacheIfNeeded($this->canBeOfLowQuality, $value); 42404fd306cSNickeau } 42504fd306cSNickeau 42604fd306cSNickeau /** 42704fd306cSNickeau * @return MarkupPath[] the backlinks 42804fd306cSNickeau * Duplicate of related 42904fd306cSNickeau * 43004fd306cSNickeau * Same as {@link WikiPath::getReferencedBy()} ? 43104fd306cSNickeau */ 43204fd306cSNickeau public 43304fd306cSNickeau function getBacklinks(): array 43404fd306cSNickeau { 43504fd306cSNickeau $backlinks = array(); 43604fd306cSNickeau /** 43704fd306cSNickeau * Same as 43804fd306cSNickeau * idx_get_indexer()->lookupKey('relation_references', $ID); 43904fd306cSNickeau */ 44004fd306cSNickeau $ft_backlinks = ft_backlinks($this->getWikiId()); 44104fd306cSNickeau foreach ($ft_backlinks as $backlinkId) { 44204fd306cSNickeau $backlinks[$backlinkId] = MarkupPath::createMarkupFromId($backlinkId); 44304fd306cSNickeau } 44404fd306cSNickeau return $backlinks; 44504fd306cSNickeau } 44604fd306cSNickeau 44704fd306cSNickeau 44804fd306cSNickeau /** 44904fd306cSNickeau * Low page quality 45004fd306cSNickeau * @return bool true if this is a low quality page 45104fd306cSNickeau */ 45204fd306cSNickeau function isLowQualityPage(): bool 45304fd306cSNickeau { 45404fd306cSNickeau 45504fd306cSNickeau 45604fd306cSNickeau if (!$this->getCanBeOfLowQuality()) { 45704fd306cSNickeau return false; 45804fd306cSNickeau } 45904fd306cSNickeau 46004fd306cSNickeau if (!Site::isLowQualityProtectionEnable()) { 46104fd306cSNickeau return false; 46204fd306cSNickeau } 46304fd306cSNickeau try { 46404fd306cSNickeau return $this->getLowQualityIndicatorCalculated(); 46504fd306cSNickeau } catch (ExceptionNotFound $e) { 46604fd306cSNickeau // We were returning null but null used in a condition is falsy 46704fd306cSNickeau // we return false 46804fd306cSNickeau return false; 46904fd306cSNickeau } 47004fd306cSNickeau 47104fd306cSNickeau } 47204fd306cSNickeau 47304fd306cSNickeau 47404fd306cSNickeau /** 47504fd306cSNickeau * 47604fd306cSNickeau */ 47704fd306cSNickeau public function getCanBeOfLowQuality(): bool 47804fd306cSNickeau { 47904fd306cSNickeau 48004fd306cSNickeau return $this->canBeOfLowQuality->getValueOrDefault(); 48104fd306cSNickeau 48204fd306cSNickeau } 48304fd306cSNickeau 48404fd306cSNickeau 48504fd306cSNickeau /** 48604fd306cSNickeau * Return the Title 48704fd306cSNickeau * @deprecated for {@link PageTitle::getValue()} 48804fd306cSNickeau */ 48904fd306cSNickeau public 49004fd306cSNickeau function getTitle(): ?string 49104fd306cSNickeau { 49204fd306cSNickeau return $this->title->getValueFromStore(); 49304fd306cSNickeau } 49404fd306cSNickeau 49504fd306cSNickeau /** 49604fd306cSNickeau * If true, the page is quality monitored (a note is shown to the writer) 49704fd306cSNickeau * @return null|bool 49804fd306cSNickeau */ 49904fd306cSNickeau public 50004fd306cSNickeau function getQualityMonitoringIndicator(): ?bool 50104fd306cSNickeau { 50204fd306cSNickeau return $this->qualityMonitoringIndicator->getValueFromStore(); 50304fd306cSNickeau } 50404fd306cSNickeau 50504fd306cSNickeau /** 50604fd306cSNickeau * @return string the title, or h1 if empty or the id if empty 50704fd306cSNickeau * Shortcut to {@link PageTitle::getValueOrDefault()} 50804fd306cSNickeau * 50904fd306cSNickeau */ 51004fd306cSNickeau public 51104fd306cSNickeau function getTitleOrDefault(): string 51204fd306cSNickeau { 51304fd306cSNickeau try { 51404fd306cSNickeau return $this->title->getValueOrDefault(); 51504fd306cSNickeau } catch (ExceptionNotFound $e) { 51604fd306cSNickeau LogUtility::internalError("Internal Error: The page ($this) does not have any default title"); 51704fd306cSNickeau return $this->getPathObject()->getLastNameWithoutExtension(); 51804fd306cSNickeau } 51904fd306cSNickeau 52004fd306cSNickeau } 52104fd306cSNickeau 52204fd306cSNickeau 52304fd306cSNickeau public function getH1OrDefault(): string 52404fd306cSNickeau { 52504fd306cSNickeau 52604fd306cSNickeau return $this->h1->getValueOrDefault(); 52704fd306cSNickeau 52804fd306cSNickeau } 52904fd306cSNickeau 53004fd306cSNickeau /** 53104fd306cSNickeau * @return string 53204fd306cSNickeau * @throws ExceptionNotFound 53304fd306cSNickeau */ 53404fd306cSNickeau public 53504fd306cSNickeau function getDescription(): string 53604fd306cSNickeau { 53704fd306cSNickeau return $this->description->getValue(); 53804fd306cSNickeau } 53904fd306cSNickeau 54004fd306cSNickeau 54104fd306cSNickeau /** 54204fd306cSNickeau * @return string - the description or the dokuwiki generated description 54304fd306cSNickeau */ 54404fd306cSNickeau public 54504fd306cSNickeau function getDescriptionOrElseDokuWiki(): string 54604fd306cSNickeau { 54704fd306cSNickeau return $this->description->getValueOrDefault(); 54804fd306cSNickeau } 54904fd306cSNickeau 55004fd306cSNickeau 55104fd306cSNickeau /** 55204fd306cSNickeau * @return string 55304fd306cSNickeau * The content / markup that should be parsed by the parser 55404fd306cSNickeau */ 55504fd306cSNickeau public 55604fd306cSNickeau function getMarkup(): string 55704fd306cSNickeau { 55804fd306cSNickeau 55904fd306cSNickeau try { 56004fd306cSNickeau return FileSystems::getContent($this->getPathObject()); 56104fd306cSNickeau } catch (ExceptionNotFound $e) { 56204fd306cSNickeau LogUtility::msg("The page ($this) was not found"); 56304fd306cSNickeau return ""; 56404fd306cSNickeau } 56504fd306cSNickeau 56604fd306cSNickeau } 56704fd306cSNickeau 56804fd306cSNickeau 56904fd306cSNickeau public 57004fd306cSNickeau function isInIndex(): bool 57104fd306cSNickeau { 57204fd306cSNickeau $Indexer = idx_get_indexer(); 57304fd306cSNickeau $pages = $Indexer->getPages(); 57404fd306cSNickeau $return = array_search($this->getPathObject()->getWikiId(), $pages, true); 57504fd306cSNickeau return $return !== false; 57604fd306cSNickeau } 57704fd306cSNickeau 57804fd306cSNickeau 57904fd306cSNickeau /** 58004fd306cSNickeau * Save the content with the {@link ChangeLog} 58104fd306cSNickeau * @param string $content 58204fd306cSNickeau * @param string $summary 58304fd306cSNickeau * @return $this 58404fd306cSNickeau * Use {@link FileSystems::setContent()} if you don't want any log 58504fd306cSNickeau * This function wraps {@link saveWikiText()} it implements the events system and may have side-effects 58604fd306cSNickeau */ 58704fd306cSNickeau public 58804fd306cSNickeau function setContentWithLog(string $content, string $summary = "Default"): MarkupPath 58904fd306cSNickeau { 59004fd306cSNickeau $path = $this->getPathObject(); 59104fd306cSNickeau if (!($path instanceof WikiPath)) { 59204fd306cSNickeau throw new ExceptionRuntime("The path of this markup is not a wiki path"); 59304fd306cSNickeau } 59404fd306cSNickeau saveWikiText($path->getWikiId(), $content, $summary); 59504fd306cSNickeau return $this; 59604fd306cSNickeau } 59704fd306cSNickeau 59804fd306cSNickeau public 59904fd306cSNickeau function addToIndex() 60004fd306cSNickeau { 60104fd306cSNickeau /** 60204fd306cSNickeau * Add to index check the metadata cache 60304fd306cSNickeau * Because we log the cache at the requested page level, we need to 60404fd306cSNickeau * set the global ID 60504fd306cSNickeau */ 60604fd306cSNickeau global $ID; 60704fd306cSNickeau $keep = $ID; 60804fd306cSNickeau global $ACT; 60904fd306cSNickeau $keepACT = $ACT; 61004fd306cSNickeau try { 61104fd306cSNickeau $ACT = "show"; 61204fd306cSNickeau $ID = $this->getPathObject()->toWikiPath()->getWikiId(); 61304fd306cSNickeau idx_addPage($ID); 61404fd306cSNickeau } finally { 61504fd306cSNickeau $ID = $keep; 61604fd306cSNickeau $ACT = $keepACT; 61704fd306cSNickeau } 61804fd306cSNickeau return $this; 61904fd306cSNickeau 62004fd306cSNickeau } 62104fd306cSNickeau 62204fd306cSNickeau /** 62304fd306cSNickeau * @return mixed 62404fd306cSNickeau */ 62504fd306cSNickeau public 62604fd306cSNickeau function getTypeOrDefault() 62704fd306cSNickeau { 62804fd306cSNickeau return $this->type->getValueFromStoreOrDefault(); 62904fd306cSNickeau } 63004fd306cSNickeau 63104fd306cSNickeau 63204fd306cSNickeau /** 63304fd306cSNickeau * @throws ExceptionNotFound 63404fd306cSNickeau */ 63504fd306cSNickeau public 63604fd306cSNickeau function getFirstImage(): IFetcherLocalImage 63704fd306cSNickeau { 63804fd306cSNickeau try { 63904fd306cSNickeau return IFetcherLocalImage::createImageFetchFromPath(FirstRasterImage::createForPage($this)->getValue()); 64004fd306cSNickeau } catch (ExceptionBadSyntax|ExceptionBadArgument $e) { 64104fd306cSNickeau LogUtility::error("First Raster Image error. Error: " . $e->getMessage(), self::CANONICAL_PAGE, $e); 64204fd306cSNickeau throw new ExceptionNotFound(); 64304fd306cSNickeau } catch (ExceptionNotExists $e) { 64404fd306cSNickeau throw new ExceptionNotFound(); 64504fd306cSNickeau } 64604fd306cSNickeau 64704fd306cSNickeau } 64804fd306cSNickeau 64904fd306cSNickeau /** 65004fd306cSNickeau * Return the media stored during parsing 65104fd306cSNickeau * 65204fd306cSNickeau * They are saved via the function {@link \Doku_Renderer_metadata::_recordMediaUsage()} 65304fd306cSNickeau * called by the {@link \Doku_Renderer_metadata::internalmedia()} 65404fd306cSNickeau * 65504fd306cSNickeau * 65604fd306cSNickeau * {@link \Doku_Renderer_metadata::externalmedia()} does not save them 65704fd306cSNickeau */ 65804fd306cSNickeau public 65904fd306cSNickeau function getMediasMetadata(): ?array 66004fd306cSNickeau { 66104fd306cSNickeau 66204fd306cSNickeau $store = $this->getReadStoreOrDefault(); 66304fd306cSNickeau if (!($store instanceof MetadataDokuWikiStore)) { 66404fd306cSNickeau return null; 66504fd306cSNickeau } 66604fd306cSNickeau $medias = []; 66704fd306cSNickeau 66804fd306cSNickeau $relation = $store->getCurrentFromName('relation'); 66904fd306cSNickeau if (isset($relation['media'])) { 67004fd306cSNickeau /** 67104fd306cSNickeau * The relation is 67204fd306cSNickeau * $this->meta['relation']['media'][$src] = $exists; 67304fd306cSNickeau * 67404fd306cSNickeau */ 67504fd306cSNickeau foreach ($relation['media'] as $src => $exists) { 67604fd306cSNickeau if ($exists) { 67704fd306cSNickeau $medias[] = $src; 67804fd306cSNickeau } 67904fd306cSNickeau } 68004fd306cSNickeau } 68104fd306cSNickeau return $medias; 68204fd306cSNickeau } 68304fd306cSNickeau 68404fd306cSNickeau 68504fd306cSNickeau /** 68604fd306cSNickeau * Get author name 68704fd306cSNickeau * 68804fd306cSNickeau * @return string 68904fd306cSNickeau */ 69004fd306cSNickeau public 69104fd306cSNickeau function getAuthor(): ?string 69204fd306cSNickeau { 69304fd306cSNickeau $store = $this->getReadStoreOrDefault(); 69404fd306cSNickeau if (!($store instanceof MetadataDokuWikiStore)) { 69504fd306cSNickeau return null; 69604fd306cSNickeau } 69704fd306cSNickeau 69804fd306cSNickeau return $store->getFromName('creator'); 69904fd306cSNickeau } 70004fd306cSNickeau 70104fd306cSNickeau /** 70204fd306cSNickeau * Get author ID 70304fd306cSNickeau * 70404fd306cSNickeau * @return string 70504fd306cSNickeau */ 70604fd306cSNickeau public 70704fd306cSNickeau function getAuthorID(): ?string 70804fd306cSNickeau { 70904fd306cSNickeau 71004fd306cSNickeau $store = $this->getReadStoreOrDefault(); 71104fd306cSNickeau if (!($store instanceof MetadataDokuWikiStore)) { 71204fd306cSNickeau return null; 71304fd306cSNickeau } 71404fd306cSNickeau 71504fd306cSNickeau return $store->getFromName('user'); 71604fd306cSNickeau 71704fd306cSNickeau } 71804fd306cSNickeau 71904fd306cSNickeau 72004fd306cSNickeau /** 72104fd306cSNickeau * Get the create date of page 72204fd306cSNickeau * 72304fd306cSNickeau * @return DateTime 72404fd306cSNickeau * @throws ExceptionNotFound 72504fd306cSNickeau */ 72604fd306cSNickeau public 72704fd306cSNickeau function getCreatedTime(): ?DateTime 72804fd306cSNickeau { 72904fd306cSNickeau return $this->creationTime->getValue(); 73004fd306cSNickeau } 73104fd306cSNickeau 73204fd306cSNickeau 73304fd306cSNickeau /** 73404fd306cSNickeau * 73504fd306cSNickeau * @return DateTime 73604fd306cSNickeau */ 73704fd306cSNickeau public 73804fd306cSNickeau function getModifiedTime(): DateTime 73904fd306cSNickeau { 74004fd306cSNickeau return $this->modifiedTime->getValueFromStore(); 74104fd306cSNickeau } 74204fd306cSNickeau 74304fd306cSNickeau /** 74404fd306cSNickeau * @throws ExceptionNotFound 74504fd306cSNickeau */ 74604fd306cSNickeau public 74704fd306cSNickeau function getModifiedTimeOrDefault(): DateTime 74804fd306cSNickeau { 74904fd306cSNickeau return $this->modifiedTime->getValueFromStoreOrDefault(); 75004fd306cSNickeau } 75104fd306cSNickeau 75204fd306cSNickeau 75304fd306cSNickeau /** 75404fd306cSNickeau * Utility class, refresh the metadata (used only in test) 75504fd306cSNickeau * @deprecated if possible used {@link FetcherMarkup} instead 75604fd306cSNickeau */ 75704fd306cSNickeau public function renderMetadataAndFlush(): MarkupPath 75804fd306cSNickeau { 75904fd306cSNickeau 76004fd306cSNickeau if (!FileSystems::exists($this)) { 76104fd306cSNickeau if (PluginUtility::isDevOrTest()) { 76204fd306cSNickeau LogUtility::msg("You can't render the metadata of a markup path that does not exist ($this)"); 76304fd306cSNickeau } 76404fd306cSNickeau return $this; 76504fd306cSNickeau } 76604fd306cSNickeau 76704fd306cSNickeau try { 76804fd306cSNickeau $wikiPath = $this->getPathObject()->toWikiPath(); 76904fd306cSNickeau FetcherMarkup::confRoot() 77004fd306cSNickeau ->setRequestedContextPath($wikiPath) 77104fd306cSNickeau ->setRequestedExecutingPath($wikiPath) 77204fd306cSNickeau ->setRequestedMimeToMetadata() 77304fd306cSNickeau ->build() 77404fd306cSNickeau ->processMetadataIfNotYetDone(); 77504fd306cSNickeau } catch (ExceptionCast|ExceptionNotExists $e) { 77604fd306cSNickeau // not a wiki path, no meta 77704fd306cSNickeau } 77804fd306cSNickeau 77904fd306cSNickeau 78004fd306cSNickeau return $this; 78104fd306cSNickeau 78204fd306cSNickeau } 78304fd306cSNickeau 78404fd306cSNickeau /** 78504fd306cSNickeau * @return string|null 78604fd306cSNickeau * @deprecated for {@link Region} 78704fd306cSNickeau */ 78804fd306cSNickeau public 78904fd306cSNickeau function getLocaleRegion(): ?string 79004fd306cSNickeau { 79104fd306cSNickeau return $this->region->getValueFromStore(); 79204fd306cSNickeau } 79304fd306cSNickeau 79404fd306cSNickeau public 79504fd306cSNickeau function getRegionOrDefault() 79604fd306cSNickeau { 79704fd306cSNickeau 79804fd306cSNickeau return $this->region->getValueFromStoreOrDefault(); 79904fd306cSNickeau 80004fd306cSNickeau } 80104fd306cSNickeau 80204fd306cSNickeau public 80304fd306cSNickeau function getLang(): ?string 80404fd306cSNickeau { 80504fd306cSNickeau return $this->lang->getValueFromStore(); 80604fd306cSNickeau } 80704fd306cSNickeau 80804fd306cSNickeau public function getLangOrDefault(): string 80904fd306cSNickeau { 81004fd306cSNickeau return $this->lang->getValueOrDefault(); 81104fd306cSNickeau } 81204fd306cSNickeau 81304fd306cSNickeau /** 81404fd306cSNickeau * The home page is an index page 81504fd306cSNickeau * Adapted from {@link FsWikiUtility::getHomePagePath()} 81604fd306cSNickeau * @return bool 81704fd306cSNickeau */ 81804fd306cSNickeau public function isIndexPage(): bool 81904fd306cSNickeau { 82004fd306cSNickeau 82104fd306cSNickeau $startPageName = Site::getIndexPageName(); 82204fd306cSNickeau try { 82304fd306cSNickeau if ($this->getPathObject()->getLastNameWithoutExtension() === $startPageName) { 82404fd306cSNickeau return true; 82504fd306cSNickeau } 82604fd306cSNickeau } catch (ExceptionNotFound $e) { 82704fd306cSNickeau // ok 82804fd306cSNickeau } 82904fd306cSNickeau 83004fd306cSNickeau try { 83104fd306cSNickeau /** 83204fd306cSNickeau * page named like the NS inside the NS 83304fd306cSNickeau * ie ns:ns 83404fd306cSNickeau */ 83504fd306cSNickeau $objectPath = $this->path; 83604fd306cSNickeau $parentPath = $this->path->getParent(); 83704fd306cSNickeau if (!($parentPath instanceof WikiPath)) { 83804fd306cSNickeau return false; 83904fd306cSNickeau } 84004fd306cSNickeau if ($parentPath->getLastNameWithoutExtension() === $objectPath->getLastNameWithoutExtension()) { 84104fd306cSNickeau /** 84204fd306cSNickeau * If the start page does not exists, this is the index page 84304fd306cSNickeau */ 84404fd306cSNickeau $startPage = $parentPath->resolveId($startPageName); 84504fd306cSNickeau if (!FileSystems::exists($startPage)) { 84604fd306cSNickeau return true; 84704fd306cSNickeau } 84804fd306cSNickeau } 84904fd306cSNickeau } catch (ExceptionNotFound $e) { 85004fd306cSNickeau // no parent, no last name, etc 85104fd306cSNickeau } 85204fd306cSNickeau 85304fd306cSNickeau return false; 85404fd306cSNickeau } 85504fd306cSNickeau 85604fd306cSNickeau 85704fd306cSNickeau /** 85804fd306cSNickeau * @throws ExceptionNotFound 85904fd306cSNickeau */ 86004fd306cSNickeau public 86104fd306cSNickeau function getPublishedTime(): DateTime 86204fd306cSNickeau { 86304fd306cSNickeau return $this->publishedDate->getValueFromStore(); 86404fd306cSNickeau } 86504fd306cSNickeau 86604fd306cSNickeau /** 86704fd306cSNickeau * @return bool 86804fd306cSNickeau * @deprecated for {@link FileSystems::exists()} 86904fd306cSNickeau */ 87004fd306cSNickeau public function exists(): bool 87104fd306cSNickeau { 87204fd306cSNickeau return FileSystems::exists($this); 87304fd306cSNickeau } 87404fd306cSNickeau 87504fd306cSNickeau /** 87604fd306cSNickeau * @return DateTime 87704fd306cSNickeau * @throws ExceptionNotFound 87804fd306cSNickeau */ 87904fd306cSNickeau public 88004fd306cSNickeau function getPublishedElseCreationTime(): DateTime 88104fd306cSNickeau { 88204fd306cSNickeau return $this->publishedDate->getValueFromStoreOrDefault(); 88304fd306cSNickeau } 88404fd306cSNickeau 88504fd306cSNickeau 88604fd306cSNickeau public 88704fd306cSNickeau function isLatePublication(): bool 88804fd306cSNickeau { 88904fd306cSNickeau try { 89004fd306cSNickeau $dateTime = $this->getPublishedElseCreationTime(); 89104fd306cSNickeau } catch (ExceptionNotFound $e) { 89204fd306cSNickeau return false; 89304fd306cSNickeau } 89404fd306cSNickeau return $dateTime > new DateTime('now'); 89504fd306cSNickeau } 89604fd306cSNickeau 89704fd306cSNickeau /** 89804fd306cSNickeau * The unique page Url (also known as Canonical URL) used: 89904fd306cSNickeau * * in the link 90004fd306cSNickeau * * in the canonical ref 90104fd306cSNickeau * * in the site map 90204fd306cSNickeau * @return Url 90304fd306cSNickeau */ 90404fd306cSNickeau public 90504fd306cSNickeau function getCanonicalUrl(): Url 90604fd306cSNickeau { 90704fd306cSNickeau 90804fd306cSNickeau /** 90904fd306cSNickeau * Dokuwiki Methodology Taken from {@link tpl_metaheaders()} 91004fd306cSNickeau */ 91104fd306cSNickeau if ($this->isRootHomePage()) { 912*65e00826Sgerardnico return UrlEndpoint::createBaseUrl()->toAbsoluteUrl(); 91304fd306cSNickeau } 91404fd306cSNickeau 91504fd306cSNickeau try { 91604fd306cSNickeau return UrlEndpoint::createDokuUrl() 917*65e00826Sgerardnico ->setQueryParameter(DokuwikiId::DOKUWIKI_ID_ATTRIBUTE, $this->getWikiId()) 918*65e00826Sgerardnico ->toAbsoluteUrl(); 91904fd306cSNickeau } catch (ExceptionBadArgument $e) { 92004fd306cSNickeau LogUtility::error("This markup path ($this) can not be accessed externaly"); 92104fd306cSNickeau return UrlEndpoint::createBaseUrl(); 92204fd306cSNickeau } 92304fd306cSNickeau 92404fd306cSNickeau 92504fd306cSNickeau } 92604fd306cSNickeau 92704fd306cSNickeau 92804fd306cSNickeau 92904fd306cSNickeau /** 93004fd306cSNickeau * 93104fd306cSNickeau * @return string|null - the locale facebook way 93204fd306cSNickeau * @throws ExceptionNotFound 93304fd306cSNickeau * @deprecated for {@link Locale} 93404fd306cSNickeau */ 93504fd306cSNickeau public 93604fd306cSNickeau function getLocale($default = null): ?string 93704fd306cSNickeau { 93804fd306cSNickeau $value = $this->locale->getValueFromStore(); 93904fd306cSNickeau if ($value === null) { 94004fd306cSNickeau return $default; 94104fd306cSNickeau } 94204fd306cSNickeau return $value; 94304fd306cSNickeau } 94404fd306cSNickeau 94504fd306cSNickeau 94604fd306cSNickeau /** 94704fd306cSNickeau * 94804fd306cSNickeau * @deprecated use a {@link FetcherMarkup::getFetchString()} instead 94904fd306cSNickeau */ 95004fd306cSNickeau public function toXhtml(): string 95104fd306cSNickeau { 95204fd306cSNickeau 95304fd306cSNickeau $fetcherMarkup = $this->createHtmlFetcherWithItselfAsContextPath(); 95404fd306cSNickeau return $fetcherMarkup->getFetchString(); 95504fd306cSNickeau 95604fd306cSNickeau 95704fd306cSNickeau } 95804fd306cSNickeau 95904fd306cSNickeau 96004fd306cSNickeau public 96104fd306cSNickeau function getHtmlAnchorLink($logicalTag = null): string 96204fd306cSNickeau { 96304fd306cSNickeau $id = $this->getPathObject()->getWikiId(); 96404fd306cSNickeau try { 96504fd306cSNickeau return LinkMarkup::createFromPageIdOrPath($id) 96604fd306cSNickeau ->toAttributes($logicalTag) 96704fd306cSNickeau ->toHtmlEnterTag("a") 96804fd306cSNickeau . $this->getNameOrDefault() 96904fd306cSNickeau . "</a>"; 97004fd306cSNickeau } catch (ExceptionCompile $e) { 97104fd306cSNickeau LogUtility::msg("The markup ref returns an error for the creation of the page anchor html link ($this). Error: {$e->getMessage()}"); 97204fd306cSNickeau return "<a href=\"{$this->getCanonicalUrl()}\" data-wiki-id=\"$id\">{$this->getNameOrDefault()}</a>"; 97304fd306cSNickeau } 97404fd306cSNickeau } 97504fd306cSNickeau 97604fd306cSNickeau 97704fd306cSNickeau /** 97804fd306cSNickeau * Without the `:` at the end 97904fd306cSNickeau * @return string 98004fd306cSNickeau * @throws ExceptionNotFound 98104fd306cSNickeau * @deprecated / shortcut for {@link WikiPath::getParent()} 98204fd306cSNickeau * Because a page has always a parent, the string is never null. 98304fd306cSNickeau */ 98404fd306cSNickeau public function getNamespacePath(): string 98504fd306cSNickeau { 98604fd306cSNickeau 98704fd306cSNickeau return $this->getParent()->toAbsoluteId(); 98804fd306cSNickeau 98904fd306cSNickeau } 99004fd306cSNickeau 99104fd306cSNickeau 99204fd306cSNickeau /** 99304fd306cSNickeau * @return $this 99404fd306cSNickeau * @deprecated use {@link MetadataDokuWikiStore::deleteAndFlush()} 99504fd306cSNickeau */ 99604fd306cSNickeau public 99704fd306cSNickeau function deleteMetadatasAndFlush(): MarkupPath 99804fd306cSNickeau { 99904fd306cSNickeau MetadataDokuWikiStore::getOrCreateFromResource($this) 100004fd306cSNickeau ->deleteAndFlush(); 100104fd306cSNickeau return $this; 100204fd306cSNickeau } 100304fd306cSNickeau 100404fd306cSNickeau /** 100504fd306cSNickeau * @throws ExceptionNotFound 100604fd306cSNickeau */ 100704fd306cSNickeau public 100804fd306cSNickeau function getName(): string 100904fd306cSNickeau { 101004fd306cSNickeau 101104fd306cSNickeau return $this->pageName->getValue(); 101204fd306cSNickeau 101304fd306cSNickeau } 101404fd306cSNickeau 101504fd306cSNickeau public 101604fd306cSNickeau function getNameOrDefault(): string 101704fd306cSNickeau { 101804fd306cSNickeau 101904fd306cSNickeau return ResourceName::createForResource($this)->getValueOrDefault(); 102004fd306cSNickeau 102104fd306cSNickeau 102204fd306cSNickeau } 102304fd306cSNickeau 102404fd306cSNickeau /** 102504fd306cSNickeau * @param $property 102604fd306cSNickeau */ 102704fd306cSNickeau public 102804fd306cSNickeau function unsetMetadata($property) 102904fd306cSNickeau { 103004fd306cSNickeau $meta = p_read_metadata($this->getPathObject()->getWikiId()); 103104fd306cSNickeau if (isset($meta['persistent'][$property])) { 103204fd306cSNickeau unset($meta['persistent'][$property]); 103304fd306cSNickeau } 103404fd306cSNickeau p_save_metadata($this->getPathObject()->getWikiId(), $meta); 103504fd306cSNickeau 103604fd306cSNickeau } 103704fd306cSNickeau 103804fd306cSNickeau /** 103904fd306cSNickeau * @return array - return the standard / generated metadata 104004fd306cSNickeau * used to create a variable environment (context) in rendering 104104fd306cSNickeau */ 104204fd306cSNickeau public 104304fd306cSNickeau function getMetadataForRendering(): array 104404fd306cSNickeau { 104504fd306cSNickeau 104604fd306cSNickeau $metadataNames = [ 104704fd306cSNickeau PageH1::PROPERTY_NAME, 104804fd306cSNickeau PageTitle::PROPERTY_NAME, 104904fd306cSNickeau Lead::PROPERTY_NAME, 105004fd306cSNickeau Canonical::PROPERTY_NAME, 105104fd306cSNickeau PagePath::PROPERTY_NAME, 105204fd306cSNickeau Label::PROPERTY_NAME, 105304fd306cSNickeau PageDescription::PROPERTY_NAME, 105404fd306cSNickeau ResourceName::PROPERTY_NAME, 105504fd306cSNickeau PageType::PROPERTY_NAME, 105604fd306cSNickeau Slug::PROPERTY_NAME, 105704fd306cSNickeau PageTemplateName::PROPERTY_NAME, 105804fd306cSNickeau DokuwikiId::DOKUWIKI_ID_ATTRIBUTE, // Dokuwiki id is deprecated for path 105904fd306cSNickeau PageLevel::PROPERTY_NAME, 106004fd306cSNickeau PageKeywords::PROPERTY_NAME 106104fd306cSNickeau ]; 106204fd306cSNickeau 106304fd306cSNickeau /** 106404fd306cSNickeau * The metadata that works only 106504fd306cSNickeau * if the file exists 106604fd306cSNickeau */ 106704fd306cSNickeau if (FileSystems::exists($this)) { 106804fd306cSNickeau $metadataThatNeedsExistingFile = [ 106904fd306cSNickeau PageId::PROPERTY_NAME, 107004fd306cSNickeau CreationDate::PROPERTY_NAME, 107104fd306cSNickeau ModificationDate::PROPERTY_NAME, 107204fd306cSNickeau PagePublicationDate::PROPERTY_NAME, 107304fd306cSNickeau StartDate::PROPERTY_NAME, 107404fd306cSNickeau EndDate::PROPERTY_NAME, 107504fd306cSNickeau ]; 107604fd306cSNickeau $metadataNames = array_merge($metadataNames, $metadataThatNeedsExistingFile); 107704fd306cSNickeau } 107804fd306cSNickeau 107904fd306cSNickeau 108004fd306cSNickeau foreach ($metadataNames as $metadataName) { 108104fd306cSNickeau try { 108204fd306cSNickeau $metadata = Meta\Api\MetadataSystem::getForName($metadataName); 108304fd306cSNickeau } catch (ExceptionNotFound $e) { 108404fd306cSNickeau LogUtility::msg("The metadata ($metadataName) should be defined"); 108504fd306cSNickeau continue; 108604fd306cSNickeau } 108704fd306cSNickeau /** 108804fd306cSNickeau * The Value or Default is returned 108904fd306cSNickeau * 109004fd306cSNickeau * Because the title/h1 should never be null 109104fd306cSNickeau * otherwise a template link such as [[$path|$title]] will return a link without an description 109204fd306cSNickeau * and therefore will be not visible 109304fd306cSNickeau * 109404fd306cSNickeau * ToStoreValue to get the string format of date/boolean in the {@link PipelineUtility} 109504fd306cSNickeau * If we want the native value, we need to change the pipeline 109604fd306cSNickeau */ 109704fd306cSNickeau $value = $metadata 109804fd306cSNickeau ->setResource($this) 109904fd306cSNickeau ->setReadStore(MetadataDokuWikiStore::class) 110004fd306cSNickeau ->setWriteStore(TemplateStore::class) 110104fd306cSNickeau ->buildFromReadStore() 110204fd306cSNickeau ->toStoreValueOrDefault(); 110304fd306cSNickeau $array[$metadataName] = $value; 110404fd306cSNickeau } 110504fd306cSNickeau 110604fd306cSNickeau $array["url"] = $this->getCanonicalUrl()->toAbsoluteUrl()->toString(); 110704fd306cSNickeau $array["now"] = Iso8601Date::createFromNow()->toString(); 110804fd306cSNickeau return $array; 110904fd306cSNickeau 111004fd306cSNickeau } 111104fd306cSNickeau 111204fd306cSNickeau 111304fd306cSNickeau public 111404fd306cSNickeau function getPublishedTimeAsString(): ?string 111504fd306cSNickeau { 111604fd306cSNickeau return $this->getPublishedTime() !== null ? $this->getPublishedTime()->format(Iso8601Date::getFormat()) : null; 111704fd306cSNickeau } 111804fd306cSNickeau 111904fd306cSNickeau 112004fd306cSNickeau /** 112104fd306cSNickeau * @throws ExceptionNotFound 112204fd306cSNickeau */ 112304fd306cSNickeau public 112404fd306cSNickeau function getEndDate(): DateTime 112504fd306cSNickeau { 112604fd306cSNickeau return $this->endDate->getValue(); 112704fd306cSNickeau } 112804fd306cSNickeau 112904fd306cSNickeau 113004fd306cSNickeau 113104fd306cSNickeau /** 113204fd306cSNickeau * @throws ExceptionNotFound 113304fd306cSNickeau */ 113404fd306cSNickeau public 113504fd306cSNickeau function getStartDate(): DateTime 113604fd306cSNickeau { 113704fd306cSNickeau return $this->startDate->getValue(); 113804fd306cSNickeau } 113904fd306cSNickeau 114004fd306cSNickeau /** 114104fd306cSNickeau * A page id 114204fd306cSNickeau * @return string 114304fd306cSNickeau * @throws ExceptionNotFound - when the page does not exist 114404fd306cSNickeau */ 114504fd306cSNickeau public 114604fd306cSNickeau function getPageId(): string 114704fd306cSNickeau { 114804fd306cSNickeau return PageId::createForPage($this)->getValue(); 114904fd306cSNickeau } 115004fd306cSNickeau 115104fd306cSNickeau 115204fd306cSNickeau /** 115304fd306cSNickeau * @throws ExceptionNotExists 115404fd306cSNickeau */ 115504fd306cSNickeau public 115604fd306cSNickeau function fetchAnalyticsDocument(): FetcherMarkup 115704fd306cSNickeau { 115804fd306cSNickeau return renderer_plugin_combo_analytics::createAnalyticsFetcherForPageFragment($this); 115904fd306cSNickeau } 116004fd306cSNickeau 116104fd306cSNickeau /** 116204fd306cSNickeau * @throws ExceptionCompile 116304fd306cSNickeau * @throws ExceptionNotExists 116404fd306cSNickeau */ 116504fd306cSNickeau public 116604fd306cSNickeau function fetchAnalyticsPath(): Path 116704fd306cSNickeau { 116804fd306cSNickeau $fetcher = renderer_plugin_combo_analytics::createAnalyticsFetcherForPageFragment($this); 116904fd306cSNickeau return $fetcher->processIfNeededAndGetFetchPath(); 117004fd306cSNickeau 117104fd306cSNickeau } 117204fd306cSNickeau 117304fd306cSNickeau /** 117404fd306cSNickeau */ 117504fd306cSNickeau public 117604fd306cSNickeau function getDatabasePage(): DatabasePageRow 117704fd306cSNickeau { 117804fd306cSNickeau 117904fd306cSNickeau return DatabasePageRow::getFromPageObject($this); 118004fd306cSNickeau 118104fd306cSNickeau } 118204fd306cSNickeau 118304fd306cSNickeau /** 118404fd306cSNickeau * @throws ExceptionSqliteNotAvailable 118504fd306cSNickeau */ 118604fd306cSNickeau public 118704fd306cSNickeau function getOrCreateDatabasePage(): DatabasePageRow 118804fd306cSNickeau { 118904fd306cSNickeau 119004fd306cSNickeau return DatabasePageRow::getOrCreateFromPageObject($this); 119104fd306cSNickeau 119204fd306cSNickeau } 119304fd306cSNickeau 119404fd306cSNickeau public 119504fd306cSNickeau function canBeUpdatedByCurrentUser(): bool 119604fd306cSNickeau { 119704fd306cSNickeau return Identity::isWriter($this->getWikiId()); 119804fd306cSNickeau } 119904fd306cSNickeau 120004fd306cSNickeau 120104fd306cSNickeau public 120204fd306cSNickeau function isRootHomePage(): bool 120304fd306cSNickeau { 120404fd306cSNickeau global $conf; 120504fd306cSNickeau $startPageName = $conf['start']; 120604fd306cSNickeau return $this->getPathObject()->toAbsoluteId() === ":$startPageName"; 120704fd306cSNickeau 120804fd306cSNickeau } 120904fd306cSNickeau 121004fd306cSNickeau 121104fd306cSNickeau /** 121204fd306cSNickeau * @throws ExceptionNotFound 121304fd306cSNickeau */ 121404fd306cSNickeau public 121504fd306cSNickeau function getPageType(): string 121604fd306cSNickeau { 121704fd306cSNickeau return $this->type->getValueFromStore(); 121804fd306cSNickeau } 121904fd306cSNickeau 122004fd306cSNickeau /** 122104fd306cSNickeau * @throws ExceptionNotFound 122204fd306cSNickeau * @deprecated 122304fd306cSNickeau */ 122404fd306cSNickeau public 122504fd306cSNickeau function getCanonical(): WikiPath 122604fd306cSNickeau { 122704fd306cSNickeau return $this->canonical->getValue(); 122804fd306cSNickeau } 122904fd306cSNickeau 123004fd306cSNickeau /** 123104fd306cSNickeau * Create a canonical from the last page path part. 123204fd306cSNickeau * 123304fd306cSNickeau * @return string|null 123404fd306cSNickeau * @throws ExceptionNotFound 123504fd306cSNickeau */ 123604fd306cSNickeau public 123704fd306cSNickeau function getDefaultCanonical(): ?string 123804fd306cSNickeau { 123904fd306cSNickeau return $this->canonical->getDefaultValue(); 124004fd306cSNickeau } 124104fd306cSNickeau 124204fd306cSNickeau /** 124304fd306cSNickeau * @throws ExceptionNotFound 124404fd306cSNickeau */ 124504fd306cSNickeau public 124604fd306cSNickeau function getLayout() 124704fd306cSNickeau { 124804fd306cSNickeau return $this->layout->getValueFromStore(); 124904fd306cSNickeau } 125004fd306cSNickeau 125104fd306cSNickeau /** 125204fd306cSNickeau * @throws ExceptionNotFound 125304fd306cSNickeau */ 125404fd306cSNickeau public 125504fd306cSNickeau function getDefaultPageName(): string 125604fd306cSNickeau { 125704fd306cSNickeau return $this->pageName->getDefaultValue(); 125804fd306cSNickeau } 125904fd306cSNickeau 126004fd306cSNickeau public 126104fd306cSNickeau function getDefaultTitle(): string 126204fd306cSNickeau { 126304fd306cSNickeau return $this->title->getDefaultValue(); 126404fd306cSNickeau } 126504fd306cSNickeau 126604fd306cSNickeau /** 126704fd306cSNickeau * @throws ExceptionNotFound 126804fd306cSNickeau */ 126904fd306cSNickeau public 127004fd306cSNickeau function getDefaultH1() 127104fd306cSNickeau { 127204fd306cSNickeau return $this->h1->getValueOrDefault(); 127304fd306cSNickeau } 127404fd306cSNickeau 127504fd306cSNickeau public 127604fd306cSNickeau function getDefaultType(): string 127704fd306cSNickeau { 127804fd306cSNickeau return $this->type->getDefaultValue(); 127904fd306cSNickeau } 128004fd306cSNickeau 128104fd306cSNickeau public 128204fd306cSNickeau function getDefaultLayout(): string 128304fd306cSNickeau { 128404fd306cSNickeau return $this->layout->getDefaultValue(); 128504fd306cSNickeau } 128604fd306cSNickeau 128704fd306cSNickeau 128804fd306cSNickeau /** 128904fd306cSNickeau * 129004fd306cSNickeau * @throws ExceptionCompile 129104fd306cSNickeau */ 129204fd306cSNickeau public 129304fd306cSNickeau function setLowQualityIndicatorCalculation($bool): MarkupPath 129404fd306cSNickeau { 129504fd306cSNickeau return $this->setQualityIndicatorAndDeleteCacheIfNeeded($this->lowQualityIndicatorCalculated, $bool); 129604fd306cSNickeau } 129704fd306cSNickeau 129804fd306cSNickeau 129904fd306cSNickeau /** 130004fd306cSNickeau * Change the quality indicator 130104fd306cSNickeau * and if the quality level has become low 130204fd306cSNickeau * and that the protection is on, delete the cache 130304fd306cSNickeau * @param MetadataBoolean $lowQualityAttributeName 130404fd306cSNickeau * @param bool $value 130504fd306cSNickeau * @return MarkupPath 130604fd306cSNickeau * @throws ExceptionBadArgument - if the value cannot be persisted 130704fd306cSNickeau */ 130804fd306cSNickeau private 130904fd306cSNickeau function setQualityIndicatorAndDeleteCacheIfNeeded(MetadataBoolean $lowQualityAttributeName, bool $value): MarkupPath 131004fd306cSNickeau { 131104fd306cSNickeau try { 131204fd306cSNickeau $actualValue = $lowQualityAttributeName->getValue(); 131304fd306cSNickeau } catch (ExceptionNotFound $e) { 131404fd306cSNickeau $actualValue = null; 131504fd306cSNickeau } 131604fd306cSNickeau if ($value !== $actualValue) { 131704fd306cSNickeau $lowQualityAttributeName 131804fd306cSNickeau ->setValue($value) 131904fd306cSNickeau ->persist(); 132004fd306cSNickeau } 132104fd306cSNickeau return $this; 132204fd306cSNickeau } 132304fd306cSNickeau 132404fd306cSNickeau 132504fd306cSNickeau /** 132604fd306cSNickeau * @throws ExceptionNotFound 132704fd306cSNickeau */ 132804fd306cSNickeau public 132904fd306cSNickeau function getLowQualityIndicatorCalculated() 133004fd306cSNickeau { 133104fd306cSNickeau 133204fd306cSNickeau return $this->lowQualityIndicatorCalculated->getValueOrDefault(); 133304fd306cSNickeau 133404fd306cSNickeau } 133504fd306cSNickeau 133604fd306cSNickeau /** 133704fd306cSNickeau * @return PageImage[] 133804fd306cSNickeau * @deprecated 133904fd306cSNickeau */ 134004fd306cSNickeau public 134104fd306cSNickeau function getPageMetadataImages(): array 134204fd306cSNickeau { 134304fd306cSNickeau return $this->pageImages->getValueAsPageImages(); 134404fd306cSNickeau } 134504fd306cSNickeau 134604fd306cSNickeau 134704fd306cSNickeau /** 134804fd306cSNickeau * @param array|string $jsonLd 134904fd306cSNickeau * @return $this 135004fd306cSNickeau * @throws ExceptionCompile 135104fd306cSNickeau * @deprecated for {@link LdJson} 135204fd306cSNickeau */ 135304fd306cSNickeau public 135404fd306cSNickeau function setJsonLd($jsonLd): MarkupPath 135504fd306cSNickeau { 135604fd306cSNickeau $this->ldJson 135704fd306cSNickeau ->setValue($jsonLd) 135804fd306cSNickeau ->sendToWriteStore(); 135904fd306cSNickeau return $this; 136004fd306cSNickeau } 136104fd306cSNickeau 136204fd306cSNickeau /** 136304fd306cSNickeau * @throws ExceptionCompile 136404fd306cSNickeau */ 136504fd306cSNickeau public 136604fd306cSNickeau function setPageType(string $value): MarkupPath 136704fd306cSNickeau { 136804fd306cSNickeau $this->type 136904fd306cSNickeau ->setValue($value) 137004fd306cSNickeau ->sendToWriteStore(); 137104fd306cSNickeau return $this; 137204fd306cSNickeau } 137304fd306cSNickeau 137404fd306cSNickeau 137504fd306cSNickeau /** 137604fd306cSNickeau * @param $aliasPath 137704fd306cSNickeau * @param string $aliasType 137804fd306cSNickeau * @return Alias 137904fd306cSNickeau * @deprecated for {@link Aliases} 138004fd306cSNickeau */ 138104fd306cSNickeau public 138204fd306cSNickeau function addAndGetAlias($aliasPath, string $aliasType = AliasType::REDIRECT): Alias 138304fd306cSNickeau { 138404fd306cSNickeau 138504fd306cSNickeau return $this->aliases->addAndGetAlias($aliasPath, $aliasType); 138604fd306cSNickeau 138704fd306cSNickeau } 138804fd306cSNickeau 138904fd306cSNickeau 139004fd306cSNickeau /** 139104fd306cSNickeau * @return Alias[] 139204fd306cSNickeau * @throws ExceptionNotFound 139304fd306cSNickeau */ 139404fd306cSNickeau public 139504fd306cSNickeau function getAliases(): array 139604fd306cSNickeau { 139704fd306cSNickeau return $this->aliases->getValueAsAlias(); 139804fd306cSNickeau } 139904fd306cSNickeau 140004fd306cSNickeau /** 140104fd306cSNickeau * @return string 140204fd306cSNickeau */ 140304fd306cSNickeau public 140404fd306cSNickeau function getSlugOrDefault(): string 140504fd306cSNickeau { 140604fd306cSNickeau try { 140704fd306cSNickeau return $this->getSlug(); 140804fd306cSNickeau } catch (ExceptionNotFound $e) { 140904fd306cSNickeau return $this->getDefaultSlug(); 141004fd306cSNickeau } 141104fd306cSNickeau 141204fd306cSNickeau } 141304fd306cSNickeau 141404fd306cSNickeau /** 141504fd306cSNickeau * 141604fd306cSNickeau * @return string 141704fd306cSNickeau * 141804fd306cSNickeau */ 141904fd306cSNickeau public 142004fd306cSNickeau function getDefaultSlug(): string 142104fd306cSNickeau { 142204fd306cSNickeau return $this->slug->getDefaultValue(); 142304fd306cSNickeau } 142404fd306cSNickeau 142504fd306cSNickeau /** 142604fd306cSNickeau * The parent page is the parent in the page tree directory 142704fd306cSNickeau * 142804fd306cSNickeau * If the page is at the root, the parent page is the root home 142904fd306cSNickeau * Only the root home does not have any parent page and return null. 143004fd306cSNickeau * 143104fd306cSNickeau * @return MarkupPath 143204fd306cSNickeau * @throws ExceptionNotFound 143304fd306cSNickeau */ 143404fd306cSNickeau public function getParent(): MarkupPath 143504fd306cSNickeau { 143604fd306cSNickeau 143704fd306cSNickeau $names = $this->getNames(); 143804fd306cSNickeau if (sizeof($names) == 0) { 143904fd306cSNickeau throw new ExceptionNotFound("No parent page"); 144004fd306cSNickeau } 144104fd306cSNickeau $slice = 1; 144204fd306cSNickeau if ($this->isIndexPage()) { 144304fd306cSNickeau /** 144404fd306cSNickeau * The parent of a home page 144504fd306cSNickeau * is in the parent directory 144604fd306cSNickeau */ 144704fd306cSNickeau $slice = 2; 144804fd306cSNickeau } 144904fd306cSNickeau /** 145004fd306cSNickeau * Delete the last or the two last parts 145104fd306cSNickeau */ 145204fd306cSNickeau if (sizeof($names) < $slice) { 145304fd306cSNickeau throw new ExceptionNotFound("No parent page"); 145404fd306cSNickeau } 145504fd306cSNickeau /** 145604fd306cSNickeau * Get the actual directory for a page 145704fd306cSNickeau * or the parent directory for a home page 145804fd306cSNickeau */ 145904fd306cSNickeau $parentNames = array_slice($names, 0, sizeof($names) - $slice); 146004fd306cSNickeau /** 146104fd306cSNickeau * Create the parent namespace id 146204fd306cSNickeau */ 146304fd306cSNickeau $parentNamespaceId = implode(WikiPath::NAMESPACE_SEPARATOR_DOUBLE_POINT, $parentNames) . WikiPath::NAMESPACE_SEPARATOR_DOUBLE_POINT; 146404fd306cSNickeau try { 146504fd306cSNickeau return self::getIndexPageFromNamespace($parentNamespaceId); 146604fd306cSNickeau } catch (ExceptionBadSyntax $e) { 146704fd306cSNickeau $message = "Error on getParentPage, null returned - Error: {$e->getMessage()}"; 146804fd306cSNickeau LogUtility::internalError($message); 146904fd306cSNickeau throw new ExceptionNotFound($message); 147004fd306cSNickeau } 147104fd306cSNickeau 147204fd306cSNickeau } 147304fd306cSNickeau 147404fd306cSNickeau /** 147504fd306cSNickeau * @throws ExceptionCompile 147604fd306cSNickeau */ 147704fd306cSNickeau public 147804fd306cSNickeau function setDescription($description): MarkupPath 147904fd306cSNickeau { 148004fd306cSNickeau 148104fd306cSNickeau $this->description 148204fd306cSNickeau ->setValue($description) 148304fd306cSNickeau ->sendToWriteStore(); 148404fd306cSNickeau return $this; 148504fd306cSNickeau } 148604fd306cSNickeau 148704fd306cSNickeau /** 148804fd306cSNickeau * @throws ExceptionCompile 148904fd306cSNickeau * @deprecated uses {@link EndDate} instead 149004fd306cSNickeau */ 149104fd306cSNickeau public 149204fd306cSNickeau function setEndDate($value): MarkupPath 149304fd306cSNickeau { 149404fd306cSNickeau $this->endDate 149504fd306cSNickeau ->setFromStoreValue($value) 149604fd306cSNickeau ->sendToWriteStore(); 149704fd306cSNickeau return $this; 149804fd306cSNickeau } 149904fd306cSNickeau 150004fd306cSNickeau /** 150104fd306cSNickeau * @throws ExceptionCompile 150204fd306cSNickeau * @deprecated uses {@link StartDate} instead 150304fd306cSNickeau */ 150404fd306cSNickeau public 150504fd306cSNickeau function setStartDate($value): MarkupPath 150604fd306cSNickeau { 150704fd306cSNickeau $this->startDate 150804fd306cSNickeau ->setFromStoreValue($value) 150904fd306cSNickeau ->sendToWriteStore(); 151004fd306cSNickeau return $this; 151104fd306cSNickeau } 151204fd306cSNickeau 151304fd306cSNickeau /** 151404fd306cSNickeau * @throws ExceptionCompile 151504fd306cSNickeau */ 151604fd306cSNickeau public 151704fd306cSNickeau function setPublishedDate($value): MarkupPath 151804fd306cSNickeau { 151904fd306cSNickeau $this->publishedDate 152004fd306cSNickeau ->setFromStoreValue($value) 152104fd306cSNickeau ->sendToWriteStore(); 152204fd306cSNickeau return $this; 152304fd306cSNickeau } 152404fd306cSNickeau 152504fd306cSNickeau /** 152604fd306cSNickeau * Utility to {@link ResourceName::setValue()} 152704fd306cSNickeau * Used mostly to create page in test 152804fd306cSNickeau * @throws ExceptionCompile 152904fd306cSNickeau * @deprecated use not persist 153004fd306cSNickeau */ 153104fd306cSNickeau public 153204fd306cSNickeau function setPageName($value): MarkupPath 153304fd306cSNickeau { 153404fd306cSNickeau $this->pageName 153504fd306cSNickeau ->setValue($value) 153604fd306cSNickeau ->sendToWriteStore(); 153704fd306cSNickeau return $this; 153804fd306cSNickeau } 153904fd306cSNickeau 154004fd306cSNickeau 154104fd306cSNickeau /** 154204fd306cSNickeau * @throws ExceptionCompile 154304fd306cSNickeau */ 154404fd306cSNickeau public 154504fd306cSNickeau function setTitle($value): MarkupPath 154604fd306cSNickeau { 154704fd306cSNickeau $this->title 154804fd306cSNickeau ->setValue($value) 154904fd306cSNickeau ->sendToWriteStore(); 155004fd306cSNickeau return $this; 155104fd306cSNickeau } 155204fd306cSNickeau 155304fd306cSNickeau /** 155404fd306cSNickeau * @throws ExceptionCompile 155504fd306cSNickeau */ 155604fd306cSNickeau public 155704fd306cSNickeau function setH1($value): MarkupPath 155804fd306cSNickeau { 155904fd306cSNickeau $this->h1 156004fd306cSNickeau ->setValue($value) 156104fd306cSNickeau ->sendToWriteStore(); 156204fd306cSNickeau return $this; 156304fd306cSNickeau } 156404fd306cSNickeau 156504fd306cSNickeau /** 156604fd306cSNickeau * @throws Exception 156704fd306cSNickeau */ 156804fd306cSNickeau public 156904fd306cSNickeau function setRegion($value): MarkupPath 157004fd306cSNickeau { 157104fd306cSNickeau $this->region 157204fd306cSNickeau ->setFromStoreValue($value) 157304fd306cSNickeau ->sendToWriteStore(); 157404fd306cSNickeau return $this; 157504fd306cSNickeau } 157604fd306cSNickeau 157704fd306cSNickeau /** 157804fd306cSNickeau * @throws ExceptionCompile 157904fd306cSNickeau */ 158004fd306cSNickeau public 158104fd306cSNickeau function setLang($value): MarkupPath 158204fd306cSNickeau { 158304fd306cSNickeau 158404fd306cSNickeau $this->lang 158504fd306cSNickeau ->setFromStoreValue($value) 158604fd306cSNickeau ->sendToWriteStore(); 158704fd306cSNickeau return $this; 158804fd306cSNickeau } 158904fd306cSNickeau 159004fd306cSNickeau /** 159104fd306cSNickeau * @throws ExceptionCompile 159204fd306cSNickeau */ 159304fd306cSNickeau public 159404fd306cSNickeau function setLayout($value): MarkupPath 159504fd306cSNickeau { 159604fd306cSNickeau $this->layout 159704fd306cSNickeau ->setValue($value) 159804fd306cSNickeau ->sendToWriteStore(); 159904fd306cSNickeau return $this; 160004fd306cSNickeau } 160104fd306cSNickeau 160204fd306cSNickeau 160304fd306cSNickeau /** 160404fd306cSNickeau * 160504fd306cSNickeau * We manage the properties by setter and getter 160604fd306cSNickeau * 160704fd306cSNickeau * Why ? 160804fd306cSNickeau * * Because we can capture the updates 160904fd306cSNickeau * * Because setter are the entry point to good quality data 161004fd306cSNickeau * * Because dokuwiki may cache the metadata (see below) 161104fd306cSNickeau * 161204fd306cSNickeau * Note all properties have been migrated 161304fd306cSNickeau * but they should be initialized below 161404fd306cSNickeau * 161504fd306cSNickeau * Dokuwiki cache: the data may be cached without our consent 161604fd306cSNickeau * The method {@link p_get_metadata()} does it with this logic 161704fd306cSNickeau * ``` 161804fd306cSNickeau * $cache = ($ID == $id); 161904fd306cSNickeau * $meta = p_read_metadata($id, $cache); 162004fd306cSNickeau * ``` 162104fd306cSNickeau */ 162204fd306cSNickeau private 162304fd306cSNickeau function buildPropertiesFromFileSystem() 162404fd306cSNickeau { 162504fd306cSNickeau 162604fd306cSNickeau /** 162704fd306cSNickeau * New meta system 162804fd306cSNickeau * Even if it does not exist, the metadata object should be instantiated 162904fd306cSNickeau * otherwise, there is a null exception 163004fd306cSNickeau */ 163104fd306cSNickeau $this->cacheExpirationDate = CacheExpirationDate::createForPage($this); 163204fd306cSNickeau $this->aliases = Aliases::createForPage($this); 163304fd306cSNickeau $this->pageImages = PageImages::createForPage($this); 163404fd306cSNickeau $this->pageName = ResourceName::createForResource($this); 163504fd306cSNickeau $this->cacheExpirationFrequency = CacheExpirationFrequency::createForPage($this); 163604fd306cSNickeau $this->ldJson = LdJson::createForPage($this); 163704fd306cSNickeau $this->canonical = Canonical::createForPage($this); 163804fd306cSNickeau $this->description = PageDescription::createForPage($this); 163904fd306cSNickeau $this->h1 = PageH1::createForPage($this); 164004fd306cSNickeau $this->type = PageType::createForPage($this); 164104fd306cSNickeau $this->creationTime = CreationDate::createForPage($this); 164204fd306cSNickeau $this->title = PageTitle::createForMarkup($this); 164304fd306cSNickeau $this->keywords = PageKeywords::createForPage($this); 164404fd306cSNickeau $this->publishedDate = PagePublicationDate::createFromPage($this); 164504fd306cSNickeau $this->startDate = StartDate::createFromPage($this); 164604fd306cSNickeau $this->endDate = EndDate::createFromPage($this); 164704fd306cSNickeau $this->locale = Locale::createForPage($this); 164804fd306cSNickeau $this->lang = Lang::createForMarkup($this); 164904fd306cSNickeau $this->region = Region::createForPage($this); 165004fd306cSNickeau $this->slug = \ComboStrap\Slug::createForPage($this); 165104fd306cSNickeau $this->canBeOfLowQuality = LowQualityPageOverwrite::createForPage($this); 165204fd306cSNickeau $this->lowQualityIndicatorCalculated = LowQualityCalculatedIndicator::createFromPage($this); 165304fd306cSNickeau $this->qualityMonitoringIndicator = QualityDynamicMonitoringOverwrite::createFromPage($this); 165404fd306cSNickeau $this->modifiedTime = ModificationDate::createForPage($this); 165504fd306cSNickeau $this->pageUrlPath = PageUrlPath::createForPage($this); 165604fd306cSNickeau $this->layout = PageTemplateName::createFromPage($this); 165704fd306cSNickeau 165804fd306cSNickeau } 165904fd306cSNickeau 166004fd306cSNickeau 166104fd306cSNickeau function getPageIdAbbr() 166204fd306cSNickeau { 166304fd306cSNickeau 166404fd306cSNickeau if ($this->getPageId() === null) return null; 166504fd306cSNickeau return PageId::getAbbreviated($this->getPageId()); 166604fd306cSNickeau 166704fd306cSNickeau } 166804fd306cSNickeau 166904fd306cSNickeau public 167004fd306cSNickeau function setDatabasePage(DatabasePageRow $databasePage): MarkupPath 167104fd306cSNickeau { 167204fd306cSNickeau $this->databasePage = $databasePage; 167304fd306cSNickeau return $this; 167404fd306cSNickeau } 167504fd306cSNickeau 167604fd306cSNickeau 167704fd306cSNickeau /** 167804fd306cSNickeau * @return string|null 167904fd306cSNickeau * 168004fd306cSNickeau * @throws ExceptionNotFound 168104fd306cSNickeau */ 168204fd306cSNickeau public 168304fd306cSNickeau function getSlug(): string 168404fd306cSNickeau { 168504fd306cSNickeau return $this->slug->getValue(); 168604fd306cSNickeau } 168704fd306cSNickeau 168804fd306cSNickeau 168904fd306cSNickeau /** 169004fd306cSNickeau * @throws ExceptionCompile 169104fd306cSNickeau */ 169204fd306cSNickeau public 169304fd306cSNickeau function setSlug($slug): MarkupPath 169404fd306cSNickeau { 169504fd306cSNickeau $this->slug 169604fd306cSNickeau ->setFromStoreValue($slug) 169704fd306cSNickeau ->sendToWriteStore(); 169804fd306cSNickeau return $this; 169904fd306cSNickeau } 170004fd306cSNickeau 170104fd306cSNickeau 170204fd306cSNickeau /** 170304fd306cSNickeau * @return string - the id in the Url 170404fd306cSNickeau */ 170504fd306cSNickeau public function getUrlId(): string 170604fd306cSNickeau { 170704fd306cSNickeau return $this->pageUrlPath->getValueOrDefaultAsWikiId(); 170804fd306cSNickeau } 170904fd306cSNickeau 171004fd306cSNickeau 171104fd306cSNickeau /** 171204fd306cSNickeau * @throws ExceptionCompile 171304fd306cSNickeau */ 171404fd306cSNickeau public 171504fd306cSNickeau function setQualityMonitoringIndicator($boolean): MarkupPath 171604fd306cSNickeau { 171704fd306cSNickeau $this->qualityMonitoringIndicator 171804fd306cSNickeau ->setFromStoreValue($boolean) 171904fd306cSNickeau ->sendToWriteStore(); 172004fd306cSNickeau return $this; 172104fd306cSNickeau } 172204fd306cSNickeau 172304fd306cSNickeau /** 172404fd306cSNickeau * 172504fd306cSNickeau * @param $aliasPath - third information - the alias used to build this page 172604fd306cSNickeau */ 172704fd306cSNickeau public 172804fd306cSNickeau function setBuildAliasPath($aliasPath) 172904fd306cSNickeau { 173004fd306cSNickeau $this->buildAliasPath = $aliasPath; 173104fd306cSNickeau } 173204fd306cSNickeau 173304fd306cSNickeau public 173404fd306cSNickeau function getBuildAlias(): ?Alias 173504fd306cSNickeau { 173604fd306cSNickeau if ($this->buildAliasPath === null) return null; 173704fd306cSNickeau try { 173804fd306cSNickeau $aliases = $this->getAliases(); 173904fd306cSNickeau } catch (ExceptionNotFound $e) { 174004fd306cSNickeau // should not 174104fd306cSNickeau return null; 174204fd306cSNickeau } 174304fd306cSNickeau foreach ($aliases as $alias) { 174404fd306cSNickeau if ($alias->getPath() === $this->buildAliasPath) { 174504fd306cSNickeau return $alias; 174604fd306cSNickeau } 174704fd306cSNickeau } 174804fd306cSNickeau return null; 174904fd306cSNickeau } 175004fd306cSNickeau 175104fd306cSNickeau public 175204fd306cSNickeau function isDynamicQualityMonitored(): bool 175304fd306cSNickeau { 175404fd306cSNickeau if ($this->getQualityMonitoringIndicator() !== null) { 175504fd306cSNickeau return $this->getQualityMonitoringIndicator(); 175604fd306cSNickeau } 175704fd306cSNickeau return $this->getDefaultQualityMonitoring(); 175804fd306cSNickeau } 175904fd306cSNickeau 176004fd306cSNickeau public 176104fd306cSNickeau function getDefaultQualityMonitoring(): bool 176204fd306cSNickeau { 176304fd306cSNickeau if (SiteConfig::getConfValue(QualityMessageHandler::CONF_DISABLE_QUALITY_MONITORING) === 1) { 176404fd306cSNickeau return false; 176504fd306cSNickeau } else { 176604fd306cSNickeau return true; 176704fd306cSNickeau } 176804fd306cSNickeau } 176904fd306cSNickeau 177004fd306cSNickeau /** 177104fd306cSNickeau * @param MetadataStore|string $store 177204fd306cSNickeau * @return $this 177304fd306cSNickeau */ 177404fd306cSNickeau public 177504fd306cSNickeau function setReadStore($store): MarkupPath 177604fd306cSNickeau { 177704fd306cSNickeau $this->readStore = $store; 177804fd306cSNickeau return $this; 177904fd306cSNickeau } 178004fd306cSNickeau 178104fd306cSNickeau 178204fd306cSNickeau /** 178304fd306cSNickeau * @param array $usages 178404fd306cSNickeau * @return IFetcherLocalImage[] 178504fd306cSNickeau */ 178604fd306cSNickeau public 178704fd306cSNickeau function getImagesForTheFollowingUsages(array $usages): array 178804fd306cSNickeau { 178904fd306cSNickeau $usages = array_merge($usages, [PageImageUsage::ALL]); 179004fd306cSNickeau $images = []; 179104fd306cSNickeau foreach ($this->getPageMetadataImages() as $pageImage) { 179204fd306cSNickeau foreach ($usages as $usage) { 179304fd306cSNickeau if (in_array($usage, $pageImage->getUsages())) { 179404fd306cSNickeau $path = $pageImage->getImagePath(); 179504fd306cSNickeau try { 179604fd306cSNickeau $images[] = IFetcherLocalImage::createImageFetchFromPath($path); 179704fd306cSNickeau } catch (ExceptionBadArgument $e) { 179804fd306cSNickeau LogUtility::error(`The page image $path of the page $this is not an image`); 179904fd306cSNickeau } catch (ExceptionBadSyntax $e) { 180004fd306cSNickeau LogUtility::error(`The page image $path has a bad syntax`); 180104fd306cSNickeau } catch (ExceptionNotExists $e) { 180204fd306cSNickeau LogUtility::error(`The page image $path does not exists`); 180304fd306cSNickeau } 180404fd306cSNickeau continue 2; 180504fd306cSNickeau } 180604fd306cSNickeau } 180704fd306cSNickeau } 180804fd306cSNickeau return $images; 180904fd306cSNickeau 181004fd306cSNickeau } 181104fd306cSNickeau 181204fd306cSNickeau 181304fd306cSNickeau /** 181404fd306cSNickeau * @throws ExceptionNotFound 181504fd306cSNickeau */ 181604fd306cSNickeau public 181704fd306cSNickeau function getKeywords(): array 181804fd306cSNickeau { 181904fd306cSNickeau return $this->keywords->getValue(); 182004fd306cSNickeau } 182104fd306cSNickeau 182204fd306cSNickeau /** 182304fd306cSNickeau * @throws ExceptionNotFound 182404fd306cSNickeau */ 182504fd306cSNickeau public function getKeywordsOrDefault(): array 182604fd306cSNickeau { 182704fd306cSNickeau return $this->keywords->getValueOrDefaults(); 182804fd306cSNickeau } 182904fd306cSNickeau 183004fd306cSNickeau 183104fd306cSNickeau /** 183204fd306cSNickeau * @throws ExceptionCompile 183304fd306cSNickeau */ 183404fd306cSNickeau public 183504fd306cSNickeau function setKeywords($value): MarkupPath 183604fd306cSNickeau { 183704fd306cSNickeau $this->keywords 183804fd306cSNickeau ->setFromStoreValue($value) 183904fd306cSNickeau ->sendToWriteStore(); 184004fd306cSNickeau return $this; 184104fd306cSNickeau } 184204fd306cSNickeau 184304fd306cSNickeau /** 184404fd306cSNickeau * @return DateTime|null 184504fd306cSNickeau * @throws ExceptionNotFound 184604fd306cSNickeau * @deprecated for {@link CacheExpirationDate} 184704fd306cSNickeau */ 184804fd306cSNickeau public 184904fd306cSNickeau function getCacheExpirationDate(): ?DateTime 185004fd306cSNickeau { 185104fd306cSNickeau return $this->cacheExpirationDate->getValue(); 185204fd306cSNickeau } 185304fd306cSNickeau 185404fd306cSNickeau /** 185504fd306cSNickeau * @return DateTime|null 185604fd306cSNickeau * @throws ExceptionNotFound 185704fd306cSNickeau * @deprecated for {@link CacheExpirationDate} 185804fd306cSNickeau */ 185904fd306cSNickeau public 186004fd306cSNickeau function getDefaultCacheExpirationDate(): ?DateTime 186104fd306cSNickeau { 186204fd306cSNickeau return $this->cacheExpirationDate->getDefaultValue(); 186304fd306cSNickeau } 186404fd306cSNickeau 186504fd306cSNickeau /** 186604fd306cSNickeau * @return string|null 186704fd306cSNickeau * @throws ExceptionNotFound 186804fd306cSNickeau * @deprecated for {@link CacheExpirationFrequency} 186904fd306cSNickeau */ 187004fd306cSNickeau public 187104fd306cSNickeau function getCacheExpirationFrequency(): string 187204fd306cSNickeau { 187304fd306cSNickeau return $this->cacheExpirationFrequency->getValue(); 187404fd306cSNickeau } 187504fd306cSNickeau 187604fd306cSNickeau 187704fd306cSNickeau /** 187804fd306cSNickeau * @param DateTime $cacheExpirationDate 187904fd306cSNickeau * @return $this 188004fd306cSNickeau * @deprecated for {@link CacheExpirationDate} 188104fd306cSNickeau */ 188204fd306cSNickeau public 188304fd306cSNickeau function setCacheExpirationDate(DateTime $cacheExpirationDate): MarkupPath 188404fd306cSNickeau { 188504fd306cSNickeau $this->cacheExpirationDate->setValue($cacheExpirationDate); 188604fd306cSNickeau return $this; 188704fd306cSNickeau } 188804fd306cSNickeau 188904fd306cSNickeau 189004fd306cSNickeau /** 189104fd306cSNickeau * Utility class 189204fd306cSNickeau * Get the instructions document as if it was the main page. 189304fd306cSNickeau * Ie the context path is: 189404fd306cSNickeau * * the markup path itself) 189504fd306cSNickeau * * or the default context path if the path cannot be transformed as wiki path. 189604fd306cSNickeau */ 189704fd306cSNickeau public function getInstructionsDocument(): FetcherMarkup 189804fd306cSNickeau { 189904fd306cSNickeau 190004fd306cSNickeau $path = $this->getPathObject(); 190104fd306cSNickeau try { 190204fd306cSNickeau $contextPath = $path->toWikiPath(); 190304fd306cSNickeau } catch (ExceptionCast $e) { 190404fd306cSNickeau $contextPath = ExecutionContext::getActualOrCreateFromEnv() 190504fd306cSNickeau ->getDefaultContextPath(); 190604fd306cSNickeau } 190704fd306cSNickeau return FetcherMarkup::confRoot() 190804fd306cSNickeau ->setRequestedExecutingPath($path) 190904fd306cSNickeau ->setRequestedContextPath($contextPath) 191004fd306cSNickeau ->setRequestedMimeToInstructions() 191104fd306cSNickeau ->build(); 191204fd306cSNickeau 191304fd306cSNickeau } 191404fd306cSNickeau 191504fd306cSNickeau public 191604fd306cSNickeau function delete() 191704fd306cSNickeau { 191804fd306cSNickeau 191904fd306cSNickeau Index::getOrCreate()->deletePage($this); 192004fd306cSNickeau saveWikiText($this->getWikiId(), "", "Delete"); 192104fd306cSNickeau 192204fd306cSNickeau } 192304fd306cSNickeau 192404fd306cSNickeau /** 192504fd306cSNickeau * @return Url -the absolute canonical url 192604fd306cSNickeau */ 192704fd306cSNickeau public 192804fd306cSNickeau function getAbsoluteCanonicalUrl(): Url 192904fd306cSNickeau { 193004fd306cSNickeau return $this->getCanonicalUrl()->toAbsoluteUrl(); 193104fd306cSNickeau } 193204fd306cSNickeau 193304fd306cSNickeau 193404fd306cSNickeau public 193504fd306cSNickeau function getReadStoreOrDefault(): MetadataStore 193604fd306cSNickeau { 193704fd306cSNickeau if ($this->readStore === null) { 193804fd306cSNickeau /** 193904fd306cSNickeau * No cache please if not set 194004fd306cSNickeau * Cache should be in the MetadataDokuWikiStore 194104fd306cSNickeau * that is page requested scoped and not by slot 194204fd306cSNickeau */ 194304fd306cSNickeau return MetadataDokuWikiStore::getOrCreateFromResource($this); 194404fd306cSNickeau } 194504fd306cSNickeau if (!($this->readStore instanceof MetadataStore)) { 194604fd306cSNickeau $this->readStore = MetadataStoreAbs::toMetadataStore($this->readStore, $this); 194704fd306cSNickeau } 194804fd306cSNickeau return $this->readStore; 194904fd306cSNickeau } 195004fd306cSNickeau 195104fd306cSNickeau /** 195204fd306cSNickeau * @return Path 195304fd306cSNickeau * A markup path wraps a path 195404fd306cSNickeau */ 195504fd306cSNickeau public function getPathObject(): Path 195604fd306cSNickeau { 195704fd306cSNickeau return $this->path; 195804fd306cSNickeau } 195904fd306cSNickeau 196004fd306cSNickeau 196104fd306cSNickeau /** 196204fd306cSNickeau * A shortcut for {@link MarkupPath::getPathObject()::getDokuwikiId()} 196304fd306cSNickeau * 196404fd306cSNickeau * @throws ExceptionBadArgument - if the markup path is not a {@link WikiPath} 196504fd306cSNickeau */ 196604fd306cSNickeau public 196704fd306cSNickeau function getWikiId(): string 196804fd306cSNickeau { 196904fd306cSNickeau $path = $this->getPathObject(); 197004fd306cSNickeau return WikiPath::createFromPathObject($path)->getWikiId(); 197104fd306cSNickeau } 197204fd306cSNickeau 197304fd306cSNickeau public 197404fd306cSNickeau function getUid(): Metadata 197504fd306cSNickeau { 197604fd306cSNickeau return PageId::createForPage($this); 197704fd306cSNickeau } 197804fd306cSNickeau 197904fd306cSNickeau 198004fd306cSNickeau public 198104fd306cSNickeau function getAbsolutePath(): string 198204fd306cSNickeau { 198304fd306cSNickeau return WikiPath::NAMESPACE_SEPARATOR_DOUBLE_POINT . $this->getWikiId(); 198404fd306cSNickeau } 198504fd306cSNickeau 198604fd306cSNickeau /** 198704fd306cSNickeau * Todo, it should be a property of the markup not every markup file are main page markup. 198804fd306cSNickeau * @return string 198904fd306cSNickeau */ 199004fd306cSNickeau function getType(): string 199104fd306cSNickeau { 199204fd306cSNickeau return self::TYPE; 199304fd306cSNickeau } 199404fd306cSNickeau 199504fd306cSNickeau /** 199604fd306cSNickeau * @return PageUrlPath 199704fd306cSNickeau * @deprecated use {@link PageUrlPath} instead 199804fd306cSNickeau */ 199904fd306cSNickeau public 200004fd306cSNickeau function getUrlPathObject(): PageUrlPath 200104fd306cSNickeau { 200204fd306cSNickeau return $this->pageUrlPath; 200304fd306cSNickeau } 200404fd306cSNickeau 200504fd306cSNickeau 200604fd306cSNickeau public function getSideSlot(): ?MarkupPath 200704fd306cSNickeau { 200804fd306cSNickeau 200904fd306cSNickeau /** 201004fd306cSNickeau * Only primary slot have a side slot 201104fd306cSNickeau * Root Home page does not have one either 201204fd306cSNickeau */ 201304fd306cSNickeau if ($this->isSlot()) { 201404fd306cSNickeau return null; 201504fd306cSNickeau } 201604fd306cSNickeau 201704fd306cSNickeau $nearestMainFooter = $this->findNearest(SlotSystem::getSidebarName()); 201804fd306cSNickeau if ($nearestMainFooter === false) { 201904fd306cSNickeau return null; 202004fd306cSNickeau } 202104fd306cSNickeau return MarkupPath::createMarkupFromId($nearestMainFooter); 202204fd306cSNickeau 202304fd306cSNickeau 202404fd306cSNickeau } 202504fd306cSNickeau 202604fd306cSNickeau /** 202704fd306cSNickeau * @param $pageName 202804fd306cSNickeau * @return false|string 202904fd306cSNickeau */ 203004fd306cSNickeau private function findNearest($pageName) 203104fd306cSNickeau { 203204fd306cSNickeau global $ID; 203304fd306cSNickeau $keep = $ID; 203404fd306cSNickeau try { 203504fd306cSNickeau $ID = $this->getWikiId(); 203604fd306cSNickeau return page_findnearest($pageName); 203704fd306cSNickeau } finally { 203804fd306cSNickeau $ID = $keep; 203904fd306cSNickeau } 204004fd306cSNickeau 204104fd306cSNickeau } 204204fd306cSNickeau 204304fd306cSNickeau /** 204404fd306cSNickeau * The slots that are independent from the primary slot 204504fd306cSNickeau * 204604fd306cSNickeau * @return MarkupPath[] 204704fd306cSNickeau * @deprecated should be {@link TemplateForWebPage} based 204804fd306cSNickeau */ 204904fd306cSNickeau public function getPrimaryIndependentSlots(): array 205004fd306cSNickeau { 205104fd306cSNickeau $secondarySlots = []; 205204fd306cSNickeau $sideSlot = $this->getSideSlot(); 205304fd306cSNickeau if ($sideSlot !== null) { 205404fd306cSNickeau $secondarySlots[] = $sideSlot; 205504fd306cSNickeau } 205604fd306cSNickeau return $secondarySlots; 205704fd306cSNickeau } 205804fd306cSNickeau 205904fd306cSNickeau 206004fd306cSNickeau public function isHidden(): bool 206104fd306cSNickeau { 206204fd306cSNickeau return isHiddenPage($this->getWikiId()); 206304fd306cSNickeau } 206404fd306cSNickeau 206504fd306cSNickeau 206604fd306cSNickeau public function getPrimaryHeaderPage(): ?MarkupPath 206704fd306cSNickeau { 206804fd306cSNickeau $nearest = page_findnearest(SlotSystem::getMainHeaderSlotName()); 206904fd306cSNickeau if ($nearest === false) { 207004fd306cSNickeau return null; 207104fd306cSNickeau } 207204fd306cSNickeau return MarkupPath::createMarkupFromId($nearest); 207304fd306cSNickeau } 207404fd306cSNickeau 207504fd306cSNickeau public function createPageFetcherHtml(): FetcherPage 207604fd306cSNickeau { 207704fd306cSNickeau return FetcherPage::createPageFetcherFromMarkupPath($this); 207804fd306cSNickeau } 207904fd306cSNickeau 208004fd306cSNickeau public function getHttpResponse(): HttpResponse 208104fd306cSNickeau { 208204fd306cSNickeau return HttpRequest::fetchXhtmlPageResponse($this->getWikiId()); 208304fd306cSNickeau } 208404fd306cSNickeau 208504fd306cSNickeau /** 208604fd306cSNickeau * @return Outline 208704fd306cSNickeau * @deprecated uses {@link FetcherMarkup::getOutline()} instead 208804fd306cSNickeau */ 208904fd306cSNickeau public function getOutline(): Outline 209004fd306cSNickeau { 209104fd306cSNickeau 209204fd306cSNickeau return $this->getInstructionsDocument()->getOutline(); 209304fd306cSNickeau 209404fd306cSNickeau } 209504fd306cSNickeau 209604fd306cSNickeau 209704fd306cSNickeau public function persistToDefaultMetaStore(): MarkupPath 209804fd306cSNickeau { 209904fd306cSNickeau $this->getReadStoreOrDefault()->persist(); 210004fd306cSNickeau return $this; 210104fd306cSNickeau } 210204fd306cSNickeau 210304fd306cSNickeau public function getInstructionsPath(): LocalPath 210404fd306cSNickeau { 210504fd306cSNickeau 210604fd306cSNickeau $instructionsDocument = $this->getInstructionsDocument(); 210704fd306cSNickeau return $instructionsDocument->getInstructionsPath(); 210804fd306cSNickeau 210904fd306cSNickeau } 211004fd306cSNickeau 211104fd306cSNickeau public function setContent(string $textContent): MarkupPath 211204fd306cSNickeau { 211304fd306cSNickeau FileSystems::setContent($this, $textContent); 211404fd306cSNickeau return $this; 211504fd306cSNickeau } 211604fd306cSNickeau 211704fd306cSNickeau /** 211804fd306cSNickeau * @throws ExceptionNotExists - if the path does not exist 211904fd306cSNickeau */ 212004fd306cSNickeau public function createHtmlFetcherWithRequestedPathAsContextPath(): FetcherMarkup 212104fd306cSNickeau { 212204fd306cSNickeau $executionContext = ExecutionContext::getActualOrCreateFromEnv(); 212304fd306cSNickeau $executingPath = $this->getPathObject(); 212404fd306cSNickeau $requestedPath = $executionContext->getRequestedPath(); 212504fd306cSNickeau $requestedMarkupPath = MarkupPath::createPageFromPathObject($requestedPath); 212604fd306cSNickeau 212704fd306cSNickeau if ($requestedMarkupPath->isSlot()) { 212804fd306cSNickeau try { 212904fd306cSNickeau $markupContextPath = SlotSystem::getContextPath(); 213004fd306cSNickeau SlotSystem::sendContextPathMessage($markupContextPath); 213104fd306cSNickeau $requestedPath = $markupContextPath->toWikiPath(); 213204fd306cSNickeau } catch (\Exception $e) { 213304fd306cSNickeau // should not 213404fd306cSNickeau } 213504fd306cSNickeau } 213604fd306cSNickeau return FetcherMarkup::confRoot() 213704fd306cSNickeau ->setRequestedMimeToXhtml() 213804fd306cSNickeau ->setRequestedContextPath($requestedPath) 213904fd306cSNickeau ->setRequestedExecutingPath($executingPath) 214004fd306cSNickeau ->build(); 214104fd306cSNickeau } 214204fd306cSNickeau 214304fd306cSNickeau public 214404fd306cSNickeau function isRootItemPage(): bool 214504fd306cSNickeau { 214604fd306cSNickeau try { 214704fd306cSNickeau if ($this->isIndexPage()) { 214804fd306cSNickeau return false; 214904fd306cSNickeau } 215004fd306cSNickeau $parent = $this->getParent(); 215104fd306cSNickeau if ($parent->isRootHomePage()) { 215204fd306cSNickeau return true; 215304fd306cSNickeau } 215404fd306cSNickeau return false; 215504fd306cSNickeau } catch (ExceptionNotFound $e) { 215604fd306cSNickeau return false; 215704fd306cSNickeau } 215804fd306cSNickeau } 215904fd306cSNickeau 216004fd306cSNickeau private 216104fd306cSNickeau function getPrimaryFooterPage(): ?MarkupPath 216204fd306cSNickeau { 216304fd306cSNickeau $nearest = page_findnearest(SlotSystem::getMainFooterSlotName()); 216404fd306cSNickeau if ($nearest === false) { 216504fd306cSNickeau return null; 216604fd306cSNickeau } 216704fd306cSNickeau return MarkupPath::createMarkupFromId($nearest); 216804fd306cSNickeau } 216904fd306cSNickeau 217004fd306cSNickeau /** 217104fd306cSNickeau * Set the page path to an index page for a directory path 217204fd306cSNickeau * @return void 217304fd306cSNickeau */ 217404fd306cSNickeau private 217504fd306cSNickeau function setCorrectPathForDirectoryToIndexPage(): void 217604fd306cSNickeau { 217704fd306cSNickeau 217804fd306cSNickeau 217904fd306cSNickeau if (!($this->path instanceof WikiPath)) { 218004fd306cSNickeau return; 218104fd306cSNickeau } 218204fd306cSNickeau /** 218304fd306cSNickeau * @var $path WikiPath 218404fd306cSNickeau */ 218504fd306cSNickeau $path = $this->path; 218604fd306cSNickeau 218704fd306cSNickeau /** 218804fd306cSNickeau * We correct the path 218904fd306cSNickeau * We don't return a page because it does not work in a constructor 219004fd306cSNickeau */ 219104fd306cSNickeau $startPageName = Site::getIndexPageName(); 219204fd306cSNickeau $indexPath = $path->resolveId($startPageName); 219304fd306cSNickeau if (FileSystems::exists($indexPath)) { 219404fd306cSNickeau // start page inside namespace 219504fd306cSNickeau $this->path = $indexPath; 219604fd306cSNickeau return; 219704fd306cSNickeau } 219804fd306cSNickeau 219904fd306cSNickeau // page named like the NS inside the NS 220004fd306cSNickeau try { 220104fd306cSNickeau $parentName = $this->getLastNameWithoutExtension(); 220204fd306cSNickeau $nsInsideNsIndex = $this->path->resolveId($parentName); 220304fd306cSNickeau if (FileSystems::exists($nsInsideNsIndex)) { 220404fd306cSNickeau $this->path = $nsInsideNsIndex; 220504fd306cSNickeau return; 220604fd306cSNickeau } 220704fd306cSNickeau } catch (ExceptionNotFound $e) { 220804fd306cSNickeau // no last name 220904fd306cSNickeau } 221004fd306cSNickeau 221104fd306cSNickeau // We don't support the child page 221204fd306cSNickeau // Does not exist but can be used by hierarchical function 221304fd306cSNickeau $this->path = $indexPath; 221404fd306cSNickeau } 221504fd306cSNickeau 221604fd306cSNickeau 221704fd306cSNickeau public 221804fd306cSNickeau function getUidObject(): Metadata 221904fd306cSNickeau { 222004fd306cSNickeau if ($this->uidObject === null) { 222104fd306cSNickeau try { 222204fd306cSNickeau $this->uidObject = Meta\Api\MetadataSystem::toMetadataObject($this->getUid()) 222304fd306cSNickeau ->setResource($this); 222404fd306cSNickeau } catch (ExceptionBadArgument $e) { 222504fd306cSNickeau throw new ExceptionRuntimeInternal("Uid object is a metadata object. It should not happen.", self::CANONICAL_PAGE, 1, $e); 222604fd306cSNickeau } 222704fd306cSNickeau } 222804fd306cSNickeau 222904fd306cSNickeau return $this->uidObject; 223004fd306cSNickeau } 223104fd306cSNickeau 223204fd306cSNickeau function getExtension(): string 223304fd306cSNickeau { 223404fd306cSNickeau return $this->path->getExtension(); 223504fd306cSNickeau } 223604fd306cSNickeau 223704fd306cSNickeau function getLastNameWithoutExtension(): string 223804fd306cSNickeau { 223904fd306cSNickeau return $this->path->getLastNameWithoutExtension(); 224004fd306cSNickeau } 224104fd306cSNickeau 224204fd306cSNickeau function getScheme(): string 224304fd306cSNickeau { 224404fd306cSNickeau return MarkupFileSystem::SCHEME; 224504fd306cSNickeau } 224604fd306cSNickeau 224704fd306cSNickeau function getLastName(): string 224804fd306cSNickeau { 224904fd306cSNickeau return $this->path->getLastName(); 225004fd306cSNickeau } 225104fd306cSNickeau 225204fd306cSNickeau function getNames() 225304fd306cSNickeau { 225404fd306cSNickeau return $this->path->getNames(); 225504fd306cSNickeau } 225604fd306cSNickeau 225704fd306cSNickeau function toAbsoluteId(): string 225804fd306cSNickeau { 225904fd306cSNickeau return $this->path->toAbsoluteId(); 226004fd306cSNickeau } 226104fd306cSNickeau 226204fd306cSNickeau function toUriString(): string 226304fd306cSNickeau { 226404fd306cSNickeau return $this->path->toUriString(); 226504fd306cSNickeau } 226604fd306cSNickeau 226704fd306cSNickeau function toAbsolutePath(): Path 226804fd306cSNickeau { 226904fd306cSNickeau return $this->path->toAbsolutePath(); 227004fd306cSNickeau } 227104fd306cSNickeau 227204fd306cSNickeau 227304fd306cSNickeau function resolve(string $name): Path 227404fd306cSNickeau { 227504fd306cSNickeau return $this->path->resolve($name); 227604fd306cSNickeau } 227704fd306cSNickeau 227804fd306cSNickeau 227904fd306cSNickeau function getUrl(): Url 228004fd306cSNickeau { 228104fd306cSNickeau return FetcherPage::createPageFetcherFromMarkupPath($this) 228204fd306cSNickeau ->getFetchUrl(); 228304fd306cSNickeau } 228404fd306cSNickeau 228504fd306cSNickeau function getHost(): string 228604fd306cSNickeau { 228704fd306cSNickeau return $this->path->getHost(); 228804fd306cSNickeau } 228904fd306cSNickeau 229004fd306cSNickeau public 229104fd306cSNickeau function __toString(): string 229204fd306cSNickeau { 229304fd306cSNickeau return $this->path->__toString(); 229404fd306cSNickeau } 229504fd306cSNickeau 229604fd306cSNickeau /** 229704fd306cSNickeau * @throws ExceptionBadSyntax 229804fd306cSNickeau * @throws ExceptionBadArgument 229904fd306cSNickeau */ 230004fd306cSNickeau public 230104fd306cSNickeau static function createFromUri(string $uri): MarkupPath 230204fd306cSNickeau { 230304fd306cSNickeau $path = FileSystems::createPathFromUri($uri); 230404fd306cSNickeau return new MarkupPath($path); 230504fd306cSNickeau } 230604fd306cSNickeau 230704fd306cSNickeau 230804fd306cSNickeau} 2309