104fd306cSNickeau<?php 204fd306cSNickeau 304fd306cSNickeaunamespace ComboStrap; 404fd306cSNickeau 504fd306cSNickeauuse action_plugin_combo_router; 604fd306cSNickeauuse ComboStrap\Meta\Field\Aliases; 704fd306cSNickeauuse ComboStrap\Meta\Field\AliasType; 804fd306cSNickeauuse ComboStrap\Meta\Store\MetadataDbStore; 904fd306cSNickeau 1004fd306cSNickeau 1104fd306cSNickeau/** 1204fd306cSNickeau * Class UrlManagerBestEndPage 1304fd306cSNickeau * 1404fd306cSNickeau * A class that implements the BestEndPage Algorithm for the {@link action_plugin_combo_router urlManager} 1504fd306cSNickeau */ 1604fd306cSNickeauclass RouterBestEndPage 1704fd306cSNickeau{ 1804fd306cSNickeau 1904fd306cSNickeau /** 2004fd306cSNickeau * If the number of names part that match is greater or equal to 2104fd306cSNickeau * this configuration, an Id Redirect is performed 2204fd306cSNickeau * A value of 0 disable and send only HTTP redirect 2304fd306cSNickeau */ 2404fd306cSNickeau const CONF_MINIMAL_SCORE_FOR_REDIRECT = 'BestEndPageMinimalScoreForAliasCreation'; 2504fd306cSNickeau const CONF_MINIMAL_SCORE_FOR_REDIRECT_DEFAULT = '2'; 2604fd306cSNickeau 2704fd306cSNickeau 2804fd306cSNickeau /** 2904fd306cSNickeau * @param MarkupPath $requestedPage 3004fd306cSNickeau * @return array - the best poge id and its score 3104fd306cSNickeau * The score is the number of name that matches 3204fd306cSNickeau */ 3304fd306cSNickeau public static function getBestEndPageId(MarkupPath $requestedPage): array 3404fd306cSNickeau { 3504fd306cSNickeau 3604fd306cSNickeau $pagesWithSameName = Index::getOrCreate() 3704fd306cSNickeau ->getPagesWithSameLastName($requestedPage); 3804fd306cSNickeau if (sizeof($pagesWithSameName) == 0) { 39*ad79af66SNico return [null, null]; 4004fd306cSNickeau } 4104fd306cSNickeau return self::getBestEndPageIdFromPages($pagesWithSameName, $requestedPage); 4204fd306cSNickeau 4304fd306cSNickeau 4404fd306cSNickeau } 4504fd306cSNickeau 4604fd306cSNickeau 4704fd306cSNickeau /** 4804fd306cSNickeau * @param MarkupPath $missingPage 4904fd306cSNickeau * @return array with the best page and the type of redirect 5004fd306cSNickeau * @throws ExceptionCompile 5104fd306cSNickeau */ 5204fd306cSNickeau public static function process(MarkupPath $missingPage): array 5304fd306cSNickeau { 5404fd306cSNickeau 55*ad79af66SNico $return = [null, null]; 5604fd306cSNickeau 5704fd306cSNickeau $minimalScoreForARedirect = SiteConfig::getConfValue(self::CONF_MINIMAL_SCORE_FOR_REDIRECT, self::CONF_MINIMAL_SCORE_FOR_REDIRECT_DEFAULT); 5804fd306cSNickeau 5904fd306cSNickeau list($bestPage, $bestScore) = self::getBestEndPageId($missingPage); 6004fd306cSNickeau if ($bestPage != null) { 6104fd306cSNickeau $redirectType = action_plugin_combo_router::REDIRECT_NOTFOUND_METHOD; 6204fd306cSNickeau if ($minimalScoreForARedirect != 0 && $bestScore >= $minimalScoreForARedirect) { 6304fd306cSNickeau Aliases::createForPage($bestPage) 6404fd306cSNickeau ->addAlias($missingPage, AliasType::REDIRECT) 6504fd306cSNickeau ->sendToWriteStore() 6604fd306cSNickeau ->setReadStore(MetadataDbStore::getOrCreateFromResource($bestPage)) 6704fd306cSNickeau ->sendToWriteStore(); 6804fd306cSNickeau $redirectType = action_plugin_combo_router::REDIRECT_PERMANENT_METHOD; 6904fd306cSNickeau } 7004fd306cSNickeau $return = array( 7104fd306cSNickeau $bestPage, 7204fd306cSNickeau $redirectType 7304fd306cSNickeau ); 7404fd306cSNickeau } 7504fd306cSNickeau return $return; 7604fd306cSNickeau 7704fd306cSNickeau } 7804fd306cSNickeau 7904fd306cSNickeau /** 8004fd306cSNickeau * @param MarkupPath[] $candidatePagesWithSameLastName 8104fd306cSNickeau * @param MarkupPath $requestedPage 8204fd306cSNickeau * @return array 8304fd306cSNickeau */ 8404fd306cSNickeau public static function getBestEndPageIdFromPages(array $candidatePagesWithSameLastName, MarkupPath $requestedPage): array 8504fd306cSNickeau { 8604fd306cSNickeau // Default value 8704fd306cSNickeau $bestScore = 0; 8804fd306cSNickeau $bestPage = $candidatePagesWithSameLastName[0]; 8904fd306cSNickeau 9004fd306cSNickeau // The name of the dokuwiki id 9104fd306cSNickeau $requestedPageNames = $requestedPage->getPathObject()->getNames(); 9204fd306cSNickeau 9304fd306cSNickeau // Loop 9404fd306cSNickeau foreach ($candidatePagesWithSameLastName as $candidatePage) { 9504fd306cSNickeau 96ea801fd8Sgerardnico try { 97ea801fd8Sgerardnico if ($candidatePage->getWikiId() === $requestedPage->getWikiId()) { 98ea801fd8Sgerardnico // when the index is not up to date 99ea801fd8Sgerardnico continue; 100ea801fd8Sgerardnico } 101ea801fd8Sgerardnico } catch (ExceptionBadArgument $e) { 102ea801fd8Sgerardnico // should not happen but yeah 103ea801fd8Sgerardnico } 104ea801fd8Sgerardnico 10504fd306cSNickeau $candidatePageNames = $candidatePage->getPathObject()->getNames(); 10604fd306cSNickeau $score = 0; 10704fd306cSNickeau foreach ($candidatePageNames as $candidatePageName) { 10804fd306cSNickeau if (in_array($candidatePageName, $requestedPageNames)) { 10904fd306cSNickeau $score++; 11004fd306cSNickeau } 11104fd306cSNickeau } 11204fd306cSNickeau if ($score > $bestScore) { 11304fd306cSNickeau $bestScore = $score; 11404fd306cSNickeau $bestPage = $candidatePage; 11504fd306cSNickeau } else if ($score === $bestScore) { 11604fd306cSNickeau /** 11704fd306cSNickeau * Best backlink count 11804fd306cSNickeau */ 11904fd306cSNickeau $candidateBacklinksCount = sizeof($candidatePage->getBacklinks()); 12004fd306cSNickeau $bestPageBacklinksCount = sizeof($bestPage->getBacklinks()); 12104fd306cSNickeau if ($candidateBacklinksCount > $bestPageBacklinksCount) { 12204fd306cSNickeau $bestPage = $candidatePage; 12304fd306cSNickeau } 12404fd306cSNickeau } 12504fd306cSNickeau 12604fd306cSNickeau } 12704fd306cSNickeau 12804fd306cSNickeau return array( 12904fd306cSNickeau $bestPage, 13004fd306cSNickeau $bestScore 13104fd306cSNickeau ); 13204fd306cSNickeau } 13304fd306cSNickeau} 134