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