1*04fd306cSNickeau<?php 2*04fd306cSNickeau 3*04fd306cSNickeaunamespace ComboStrap; 4*04fd306cSNickeau 5*04fd306cSNickeauuse action_plugin_combo_router; 6*04fd306cSNickeauuse ComboStrap\Meta\Field\Aliases; 7*04fd306cSNickeauuse ComboStrap\Meta\Field\AliasType; 8*04fd306cSNickeauuse ComboStrap\Meta\Store\MetadataDbStore; 9*04fd306cSNickeau 10*04fd306cSNickeau 11*04fd306cSNickeau/** 12*04fd306cSNickeau * Class UrlManagerBestEndPage 13*04fd306cSNickeau * 14*04fd306cSNickeau * A class that implements the BestEndPage Algorithm for the {@link action_plugin_combo_router urlManager} 15*04fd306cSNickeau */ 16*04fd306cSNickeauclass RouterBestEndPage 17*04fd306cSNickeau{ 18*04fd306cSNickeau 19*04fd306cSNickeau /** 20*04fd306cSNickeau * If the number of names part that match is greater or equal to 21*04fd306cSNickeau * this configuration, an Id Redirect is performed 22*04fd306cSNickeau * A value of 0 disable and send only HTTP redirect 23*04fd306cSNickeau */ 24*04fd306cSNickeau const CONF_MINIMAL_SCORE_FOR_REDIRECT = 'BestEndPageMinimalScoreForAliasCreation'; 25*04fd306cSNickeau const CONF_MINIMAL_SCORE_FOR_REDIRECT_DEFAULT = '2'; 26*04fd306cSNickeau 27*04fd306cSNickeau 28*04fd306cSNickeau /** 29*04fd306cSNickeau * @param MarkupPath $requestedPage 30*04fd306cSNickeau * @return array - the best poge id and its score 31*04fd306cSNickeau * The score is the number of name that matches 32*04fd306cSNickeau */ 33*04fd306cSNickeau public static function getBestEndPageId(MarkupPath $requestedPage): array 34*04fd306cSNickeau { 35*04fd306cSNickeau 36*04fd306cSNickeau $pagesWithSameName = Index::getOrCreate() 37*04fd306cSNickeau ->getPagesWithSameLastName($requestedPage); 38*04fd306cSNickeau if (sizeof($pagesWithSameName) == 0) { 39*04fd306cSNickeau return []; 40*04fd306cSNickeau } 41*04fd306cSNickeau return self::getBestEndPageIdFromPages($pagesWithSameName, $requestedPage); 42*04fd306cSNickeau 43*04fd306cSNickeau 44*04fd306cSNickeau } 45*04fd306cSNickeau 46*04fd306cSNickeau 47*04fd306cSNickeau /** 48*04fd306cSNickeau * @param MarkupPath $missingPage 49*04fd306cSNickeau * @return array with the best page and the type of redirect 50*04fd306cSNickeau * @throws ExceptionCompile 51*04fd306cSNickeau */ 52*04fd306cSNickeau public static function process(MarkupPath $missingPage): array 53*04fd306cSNickeau { 54*04fd306cSNickeau 55*04fd306cSNickeau $return = array(); 56*04fd306cSNickeau 57*04fd306cSNickeau $minimalScoreForARedirect = SiteConfig::getConfValue(self::CONF_MINIMAL_SCORE_FOR_REDIRECT, self::CONF_MINIMAL_SCORE_FOR_REDIRECT_DEFAULT); 58*04fd306cSNickeau 59*04fd306cSNickeau list($bestPage, $bestScore) = self::getBestEndPageId($missingPage); 60*04fd306cSNickeau if ($bestPage != null) { 61*04fd306cSNickeau $redirectType = action_plugin_combo_router::REDIRECT_NOTFOUND_METHOD; 62*04fd306cSNickeau if ($minimalScoreForARedirect != 0 && $bestScore >= $minimalScoreForARedirect) { 63*04fd306cSNickeau Aliases::createForPage($bestPage) 64*04fd306cSNickeau ->addAlias($missingPage, AliasType::REDIRECT) 65*04fd306cSNickeau ->sendToWriteStore() 66*04fd306cSNickeau ->setReadStore(MetadataDbStore::getOrCreateFromResource($bestPage)) 67*04fd306cSNickeau ->sendToWriteStore(); 68*04fd306cSNickeau $redirectType = action_plugin_combo_router::REDIRECT_PERMANENT_METHOD; 69*04fd306cSNickeau } 70*04fd306cSNickeau $return = array( 71*04fd306cSNickeau $bestPage, 72*04fd306cSNickeau $redirectType 73*04fd306cSNickeau ); 74*04fd306cSNickeau } 75*04fd306cSNickeau return $return; 76*04fd306cSNickeau 77*04fd306cSNickeau } 78*04fd306cSNickeau 79*04fd306cSNickeau /** 80*04fd306cSNickeau * @param MarkupPath[] $candidatePagesWithSameLastName 81*04fd306cSNickeau * @param MarkupPath $requestedPage 82*04fd306cSNickeau * @return array 83*04fd306cSNickeau */ 84*04fd306cSNickeau public static function getBestEndPageIdFromPages(array $candidatePagesWithSameLastName, MarkupPath $requestedPage): array 85*04fd306cSNickeau { 86*04fd306cSNickeau // Default value 87*04fd306cSNickeau $bestScore = 0; 88*04fd306cSNickeau $bestPage = $candidatePagesWithSameLastName[0]; 89*04fd306cSNickeau 90*04fd306cSNickeau // The name of the dokuwiki id 91*04fd306cSNickeau $requestedPageNames = $requestedPage->getPathObject()->getNames(); 92*04fd306cSNickeau 93*04fd306cSNickeau // Loop 94*04fd306cSNickeau foreach ($candidatePagesWithSameLastName as $candidatePage) { 95*04fd306cSNickeau 96*04fd306cSNickeau $candidatePageNames = $candidatePage->getPathObject()->getNames(); 97*04fd306cSNickeau $score = 0; 98*04fd306cSNickeau foreach ($candidatePageNames as $candidatePageName) { 99*04fd306cSNickeau if (in_array($candidatePageName, $requestedPageNames)) { 100*04fd306cSNickeau $score++; 101*04fd306cSNickeau } 102*04fd306cSNickeau } 103*04fd306cSNickeau if ($score > $bestScore) { 104*04fd306cSNickeau $bestScore = $score; 105*04fd306cSNickeau $bestPage = $candidatePage; 106*04fd306cSNickeau } else if ($score === $bestScore) { 107*04fd306cSNickeau /** 108*04fd306cSNickeau * Best backlink count 109*04fd306cSNickeau */ 110*04fd306cSNickeau $candidateBacklinksCount = sizeof($candidatePage->getBacklinks()); 111*04fd306cSNickeau $bestPageBacklinksCount = sizeof($bestPage->getBacklinks()); 112*04fd306cSNickeau if ($candidateBacklinksCount > $bestPageBacklinksCount) { 113*04fd306cSNickeau $bestPage = $candidatePage; 114*04fd306cSNickeau } 115*04fd306cSNickeau } 116*04fd306cSNickeau 117*04fd306cSNickeau } 118*04fd306cSNickeau 119*04fd306cSNickeau return array( 120*04fd306cSNickeau $bestPage, 121*04fd306cSNickeau $bestScore 122*04fd306cSNickeau ); 123*04fd306cSNickeau } 124*04fd306cSNickeau} 125