xref: /plugin/combo/ComboStrap/Web/UrlRewrite.php (revision 04fd306c7c155fa133ebb3669986875d65988276)
1<?php
2
3namespace ComboStrap\Web;
4
5use ComboStrap\DokuWikiId;
6use ComboStrap\ExceptionNotFound;
7use ComboStrap\FetcherRawLocalPath;
8use ComboStrap\LogUtility;
9use ComboStrap\MarkupPath;
10use ComboStrap\PageUrlPath;
11use ComboStrap\Site;
12use ComboStrap\Web\Url;
13use ComboStrap\Web\UrlEndpoint;
14use ComboStrap\WikiPath;
15
16/**
17 * Dokuwiki Rewrite
18 */
19class UrlRewrite
20{
21
22    public const CONF_KEY = 'userewrite';
23
24    public const NO_REWRITE_DOKU_VALUE = 0;
25    public const NO_REWRITE = "no_rewrite";
26    public const WEB_SERVER_REWRITE_DOKU_VALUE = 1;
27    public const WEB_SERVER_REWRITE = "web_server";
28    public const DOKU_REWRITE_DOKU_VALUE = 2;
29    /**
30     * Doku Rewrite is value 2
31     * https://www.dokuwiki.org/rewrite#further_details_for_the_technically_savvy
32     */
33    public const VALUE_DOKU_REWRITE = "doku_rewrite";
34
35
36    const EXPORT_DO_PREFIX = "export_";
37    const CANONICAL = "url_rewrite";
38    const MEDIA_PREFIX = "/_media";
39    const EXPORT_PATH_PREFIX = "/_export";
40
41
42    /**
43     * Apply all rewrite URL logic (from relative to absolute
44     * passing by web server url rewrite)
45     *
46     * Note that an URL may already have been rewritten
47     *
48     */
49    public static function rewrite(Url $url)
50    {
51
52        try {
53            $scheme = $url->getScheme();
54        } catch (ExceptionNotFound $e) {
55            /**
56             * we don't set, we just tell that that this is a http scheme
57             * the conditional {@link Url::toAbsoluteUrlString()}
58             * will set it
59             */
60            $scheme = "http";
61        }
62        switch ($scheme) {
63            case "https":
64            case "http":
65                self::pathRewrite($url);
66                self::baseRewrite($url);
67                if (Site::shouldEndpointUrlBeAbsolute()) {
68                    $url->toAbsoluteUrl();
69                }
70                break;
71        }
72
73
74    }
75
76    /**
77     * Rewrite the path
78     *
79     * Doc: https://www.dokuwiki.org/rewrite
80     * https://www.dokuwiki.org/config:userewrite
81     * @param Url $url
82     * @return void
83     */
84    private static function pathRewrite(Url $url)
85    {
86
87        try {
88            $path = $url->getPath();
89        } catch (ExceptionNotFound $e) {
90            // no path, no rewrite
91            return;
92        }
93
94        $rewrite = Site::getUrlRewrite();
95        switch ($path) {
96            case UrlEndpoint::LIB_EXE_FETCH_PHP:
97                if ($rewrite !== self::WEB_SERVER_REWRITE) {
98                    return;
99                }
100                try {
101                    $dokuwikiId = $url->getQueryPropertyValueAndRemoveIfPresent(FetcherRawLocalPath::$MEDIA_QUERY_PARAMETER);
102                } catch (ExceptionNotFound $e) {
103                    LogUtility::internalError("The media query should be present for a fetch. No Url rewrite could be done.");
104                    return;
105                }
106                $webUrlPath = str_replace(WikiPath::NAMESPACE_SEPARATOR_DOUBLE_POINT, "/", $dokuwikiId);
107                $url->setPath(self::MEDIA_PREFIX . "/$webUrlPath");
108                return;
109            case UrlEndpoint::LIB_EXE_DETAIL_PHP:
110                if ($rewrite !== self::WEB_SERVER_REWRITE) {
111                    return;
112                }
113                try {
114                    $dokuwikiId = $url->getQueryPropertyValueAndRemoveIfPresent(FetcherRawLocalPath::$MEDIA_QUERY_PARAMETER);
115                } catch (ExceptionNotFound $e) {
116                    LogUtility::internalError("The media query should be present for a detail page fetch. No Url rewrite could be done.");
117                    return;
118                }
119                $webUrlPath = str_replace(WikiPath::NAMESPACE_SEPARATOR_DOUBLE_POINT, "/", $dokuwikiId);
120                $url->setPath("/_detail/$webUrlPath");
121                return;
122            case UrlEndpoint::DOKU_PHP:
123                try {
124                    $dokuwikiId = $url->getQueryPropertyValueAndRemoveIfPresent(DokuWikiId::DOKUWIKI_ID_ATTRIBUTE);
125                } catch (ExceptionNotFound $e) {
126                    // no id (case of action such as login, ...)
127                    return;
128                }
129
130                /**
131                 * Permanent Id Rewrite
132                 * The page url path will return the original dokuwiki id
133                 * if there is no configuration
134                 */
135                $urlId = PageUrlPath::createForPage(MarkupPath::createMarkupFromId($dokuwikiId))->getValueOrDefaultAsWikiId();
136
137                /**
138                 * Rewrite Processing
139                 */
140                switch ($rewrite) {
141                    case self::WEB_SERVER_REWRITE:
142                        try {
143                            $do = $url->getQueryPropertyValueAndRemoveIfPresent("do");
144                            if (strpos($do, self::EXPORT_DO_PREFIX) === 0) {
145                                $exportFormat = substr($do, strlen(self::EXPORT_DO_PREFIX));
146                                $webUrlPath = str_replace(WikiPath::NAMESPACE_SEPARATOR_DOUBLE_POINT, "/", $urlId);
147                                $url->setPath(self::EXPORT_PATH_PREFIX . "/$exportFormat/$webUrlPath");
148                                return;
149                            }
150                        } catch (ExceptionNotFound $e) {
151                            // no do
152                        }
153                        $webUrlPath = str_replace(WikiPath::NAMESPACE_SEPARATOR_DOUBLE_POINT, "/", $urlId);
154                        $url->setPath($webUrlPath);
155                        return;
156                    case self::VALUE_DOKU_REWRITE:
157                        $url->setPath("$path/$urlId");
158                        return;
159                    default:
160                        $url->setQueryParameter(DokuWikiId::DOKUWIKI_ID_ATTRIBUTE, $urlId);
161                        return;
162                }
163
164        }
165
166    }
167
168    private
169    static function baseRewrite(Url $url)
170    {
171        try {
172            $urlPathBaseDir = Site::getUrlPathBaseDir();
173        } catch (ExceptionNotFound $e) {
174            // ok, no base dir
175            return;
176        }
177        try {
178            $path = $url->getPath();
179        } catch (ExceptionNotFound $e) {
180            return;
181        }
182        if (strpos($path, $urlPathBaseDir) === 0) {
183            /**
184             * The base dir is already present
185             */
186            return;
187        }
188        if ($urlPathBaseDir[strlen($urlPathBaseDir) - 1] === "/") {
189            $url->setPath("$urlPathBaseDir$path");
190        } else {
191            $url->setPath("$urlPathBaseDir/$path");
192        }
193
194    }
195
196}
197