xref: /template/strap/ComboStrap/RouterBestEndPage.php (revision 45a874f4355f8bee7459e5d3b79e86e68468b316)
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
30*45a874f4SNico     * @return array - the best page 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) {
39ad79af66SNico            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     */
5104fd306cSNickeau    public static function process(MarkupPath $missingPage): array
5204fd306cSNickeau    {
5304fd306cSNickeau
54ad79af66SNico        $return = [null, null];
5504fd306cSNickeau
5604fd306cSNickeau        $minimalScoreForARedirect = SiteConfig::getConfValue(self::CONF_MINIMAL_SCORE_FOR_REDIRECT, self::CONF_MINIMAL_SCORE_FOR_REDIRECT_DEFAULT);
5704fd306cSNickeau
5804fd306cSNickeau        list($bestPage, $bestScore) = self::getBestEndPageId($missingPage);
5904fd306cSNickeau        if ($bestPage != null) {
60*45a874f4SNico            $redirectType = RouterRedirection::REDIRECT_NOTFOUND_METHOD;
6104fd306cSNickeau            if ($minimalScoreForARedirect != 0 && $bestScore >= $minimalScoreForARedirect) {
62*45a874f4SNico                try {
6304fd306cSNickeau                    Aliases::createForPage($bestPage)
6404fd306cSNickeau                        ->addAlias($missingPage, AliasType::REDIRECT)
6504fd306cSNickeau                        ->sendToWriteStore()
6604fd306cSNickeau                        ->setReadStore(MetadataDbStore::getOrCreateFromResource($bestPage))
6704fd306cSNickeau                        ->sendToWriteStore();
68*45a874f4SNico                } catch (ExceptionBadArgument|ExceptionCompile $e) {
69*45a874f4SNico                    LogUtility::error("Error while creating an alias",LogUtility::SUPPORT_CANONICAL,$e);
70*45a874f4SNico                    return $return;
71*45a874f4SNico                }
72*45a874f4SNico                $redirectType = RouterRedirection::REDIRECT_PERMANENT_METHOD;
7304fd306cSNickeau            }
7404fd306cSNickeau            $return = array(
7504fd306cSNickeau                $bestPage,
7604fd306cSNickeau                $redirectType
7704fd306cSNickeau            );
7804fd306cSNickeau        }
7904fd306cSNickeau        return $return;
8004fd306cSNickeau
8104fd306cSNickeau    }
8204fd306cSNickeau
8304fd306cSNickeau    /**
8404fd306cSNickeau     * @param MarkupPath[] $candidatePagesWithSameLastName
8504fd306cSNickeau     * @param MarkupPath $requestedPage
8604fd306cSNickeau     * @return array
8704fd306cSNickeau     */
8804fd306cSNickeau    public static function getBestEndPageIdFromPages(array $candidatePagesWithSameLastName, MarkupPath $requestedPage): array
8904fd306cSNickeau    {
9004fd306cSNickeau        // Default value
9104fd306cSNickeau        $bestScore = 0;
9204fd306cSNickeau        $bestPage = $candidatePagesWithSameLastName[0];
9304fd306cSNickeau
9404fd306cSNickeau        // The name of the dokuwiki id
9504fd306cSNickeau        $requestedPageNames = $requestedPage->getPathObject()->getNames();
9604fd306cSNickeau
9704fd306cSNickeau        // Loop
9804fd306cSNickeau        foreach ($candidatePagesWithSameLastName as $candidatePage) {
9904fd306cSNickeau
100ea801fd8Sgerardnico            try {
101ea801fd8Sgerardnico                if ($candidatePage->getWikiId() === $requestedPage->getWikiId()) {
102ea801fd8Sgerardnico                    // when the index is not up to date
103ea801fd8Sgerardnico                    continue;
104ea801fd8Sgerardnico                }
105ea801fd8Sgerardnico            } catch (ExceptionBadArgument $e) {
106ea801fd8Sgerardnico                // should not happen but yeah
107ea801fd8Sgerardnico            }
108ea801fd8Sgerardnico
10904fd306cSNickeau            $candidatePageNames = $candidatePage->getPathObject()->getNames();
11004fd306cSNickeau            $score = 0;
11104fd306cSNickeau            foreach ($candidatePageNames as $candidatePageName) {
11204fd306cSNickeau                if (in_array($candidatePageName, $requestedPageNames)) {
11304fd306cSNickeau                    $score++;
11404fd306cSNickeau                }
11504fd306cSNickeau            }
11604fd306cSNickeau            if ($score > $bestScore) {
11704fd306cSNickeau                $bestScore = $score;
11804fd306cSNickeau                $bestPage = $candidatePage;
11904fd306cSNickeau            } else if ($score === $bestScore) {
12004fd306cSNickeau                /**
12104fd306cSNickeau                 * Best backlink count
12204fd306cSNickeau                 */
12304fd306cSNickeau                $candidateBacklinksCount = sizeof($candidatePage->getBacklinks());
12404fd306cSNickeau                $bestPageBacklinksCount = sizeof($bestPage->getBacklinks());
12504fd306cSNickeau                if ($candidateBacklinksCount > $bestPageBacklinksCount) {
12604fd306cSNickeau                    $bestPage = $candidatePage;
12704fd306cSNickeau                }
12804fd306cSNickeau            }
12904fd306cSNickeau
13004fd306cSNickeau        }
13104fd306cSNickeau
13204fd306cSNickeau        return array(
13304fd306cSNickeau            $bestPage,
13404fd306cSNickeau            $bestScore
13504fd306cSNickeau        );
13604fd306cSNickeau    }
13704fd306cSNickeau}
138