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