xref: /template/strap/ComboStrap/RouterBestEndPage.php (revision ad79af66a70046d40e27ff4cc82d28834afaf49b)
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