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