xref: /plugin/combo/ComboStrap/RouterBestEndPage.php (revision 04fd306c7c155fa133ebb3669986875d65988276)
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