1<?php
2
3namespace ComboStrap;
4
5use action_plugin_combo_router;
6
7
8/**
9 * Class UrlManagerBestEndPage
10 *
11 * A class that implements the BestEndPage Algorithm for the {@link action_plugin_combo_router urlManager}
12 */
13class UrlManagerBestEndPage
14{
15
16    /**
17     * If the number of names part that match is greater or equal to
18     * this configuration, an Id Redirect is performed
19     * A value of 0 disable and send only HTTP redirect
20     */
21    const CONF_MINIMAL_SCORE_FOR_REDIRECT = 'BestEndPageMinimalScoreForAliasCreation';
22    const CONF_MINIMAL_SCORE_FOR_REDIRECT_DEFAULT = '2';
23
24
25    /**
26     * @param $pageId
27     * @return array - the best poge id and its score
28     * The score is the number of name that matches
29     */
30    public static function getBestEndPageId($pageId): array
31    {
32
33        $result = array();
34
35        $pagesWithSameName = Index::getOrCreate()->getPagesWithSameLastName($pageId);
36        if (count($pagesWithSameName) > 0) {
37
38            // Default value
39            $bestScore = 0;
40            $bestPage = $pagesWithSameName[0];
41
42            // The name of the dokuwiki id
43            $missingPageIdNames = explode(':', $pageId);
44
45            // Loop
46            foreach ($pagesWithSameName as $pageIdWithSameName => $pageTitle) {
47
48                $targetPageNames = explode(':', $pageIdWithSameName);
49                $score = 0;
50                foreach($targetPageNames as $targetPageName){
51                    if(in_array($targetPageName,$missingPageIdNames)){
52                        $score++;
53                    }
54                }
55                if($score>$bestScore){
56                    $bestScore = $score;
57                    $bestPage = $pageIdWithSameName;
58                }
59
60            }
61
62            $result = array(
63                $bestPage,
64                $bestScore
65            );
66
67        }
68        return $result;
69
70    }
71
72
73    /**
74     * @param $missingPageId
75     * @return array with the best page and the type of redirect
76     */
77    public static function process($missingPageId): array
78    {
79
80        $return = array();
81
82        $minimalScoreForARedirect = PluginUtility::getConfValue(self::CONF_MINIMAL_SCORE_FOR_REDIRECT, self::CONF_MINIMAL_SCORE_FOR_REDIRECT_DEFAULT);
83
84        list($bestPageId, $bestScore) = self::getBestEndPageId($missingPageId);
85        if ($bestPageId != null) {
86            $redirectType = action_plugin_combo_router::REDIRECT_NOTFOUND_METHOD;
87            if ($minimalScoreForARedirect != 0 && $bestScore >= $minimalScoreForARedirect) {
88                $page = Page::createPageFromId($bestPageId);
89                Aliases::createForPage($page)
90                    ->addAlias($missingPageId, AliasType::REDIRECT)
91                    ->sendToWriteStore()
92                    ->setReadStore(MetadataDbStore::createForPage())
93                    ->sendToWriteStore();
94                $redirectType = action_plugin_combo_router::REDIRECT_PERMANENT_METHOD;
95            }
96            $return = array(
97                $bestPageId,
98                $redirectType
99            );
100        }
101        return $return;
102
103    }
104}
105