xref: /plugin/combo/ComboStrap/Web/UrlRewrite.php (revision 8b985170cd57593f69788c3328594a23c40a41f5)
104fd306cSNickeau<?php
204fd306cSNickeau
304fd306cSNickeaunamespace ComboStrap\Web;
404fd306cSNickeau
504fd306cSNickeauuse ComboStrap\DokuWikiId;
604fd306cSNickeauuse ComboStrap\ExceptionNotFound;
7078e2b46Sgerardnicouse ComboStrap\ExecutionContext;
804fd306cSNickeauuse ComboStrap\LogUtility;
904fd306cSNickeauuse ComboStrap\MarkupPath;
1070bbd7f1Sgerardnicouse ComboStrap\MediaMarkup;
1104fd306cSNickeauuse ComboStrap\PageUrlPath;
1204fd306cSNickeauuse ComboStrap\Site;
1304fd306cSNickeauuse ComboStrap\WikiPath;
1404fd306cSNickeau
1504fd306cSNickeau/**
1604fd306cSNickeau * Dokuwiki Rewrite
1704fd306cSNickeau */
1804fd306cSNickeauclass UrlRewrite
1904fd306cSNickeau{
2004fd306cSNickeau
2104fd306cSNickeau    public const CONF_KEY = 'userewrite';
2204fd306cSNickeau
2304fd306cSNickeau    public const NO_REWRITE_DOKU_VALUE = 0;
2404fd306cSNickeau    public const NO_REWRITE = "no_rewrite";
2504fd306cSNickeau    public const WEB_SERVER_REWRITE_DOKU_VALUE = 1;
2604fd306cSNickeau    public const WEB_SERVER_REWRITE = "web_server";
2704fd306cSNickeau    public const DOKU_REWRITE_DOKU_VALUE = 2;
2804fd306cSNickeau    /**
2904fd306cSNickeau     * Doku Rewrite is value 2
3004fd306cSNickeau     * https://www.dokuwiki.org/rewrite#further_details_for_the_technically_savvy
3104fd306cSNickeau     */
3204fd306cSNickeau    public const VALUE_DOKU_REWRITE = "doku_rewrite";
3304fd306cSNickeau
3404fd306cSNickeau
3504fd306cSNickeau    const EXPORT_DO_PREFIX = "export_";
3604fd306cSNickeau    const CANONICAL = "url_rewrite";
3704fd306cSNickeau    const MEDIA_PREFIX = "/_media";
3804fd306cSNickeau    const EXPORT_PATH_PREFIX = "/_export";
3904fd306cSNickeau
4004fd306cSNickeau
4104fd306cSNickeau    /**
4204fd306cSNickeau     * Apply all rewrite URL logic (from relative to absolute
4304fd306cSNickeau     * passing by web server url rewrite)
4404fd306cSNickeau     *
4504fd306cSNickeau     * Note that an URL may already have been rewritten
4604fd306cSNickeau     *
4704fd306cSNickeau     */
4804fd306cSNickeau    public static function rewrite(Url $url)
4904fd306cSNickeau    {
5004fd306cSNickeau
5104fd306cSNickeau        try {
5204fd306cSNickeau            $scheme = $url->getScheme();
5304fd306cSNickeau        } catch (ExceptionNotFound $e) {
5404fd306cSNickeau            /**
5504fd306cSNickeau             * we don't set, we just tell that that this is a http scheme
5604fd306cSNickeau             * the conditional {@link Url::toAbsoluteUrlString()}
5704fd306cSNickeau             * will set it
5804fd306cSNickeau             */
5904fd306cSNickeau            $scheme = "http";
6004fd306cSNickeau        }
6104fd306cSNickeau        switch ($scheme) {
6204fd306cSNickeau            case "https":
6304fd306cSNickeau            case "http":
6404fd306cSNickeau                self::pathRewrite($url);
6504fd306cSNickeau                self::baseRewrite($url);
6604fd306cSNickeau                if (Site::shouldEndpointUrlBeAbsolute()) {
6704fd306cSNickeau                    $url->toAbsoluteUrl();
6804fd306cSNickeau                }
6904fd306cSNickeau                break;
7004fd306cSNickeau        }
7104fd306cSNickeau
7204fd306cSNickeau
7304fd306cSNickeau    }
7404fd306cSNickeau
7504fd306cSNickeau    /**
7604fd306cSNickeau     * Rewrite the path
7704fd306cSNickeau     *
7804fd306cSNickeau     * Doc: https://www.dokuwiki.org/rewrite
7904fd306cSNickeau     * https://www.dokuwiki.org/config:userewrite
8004fd306cSNickeau     * @param Url $url
8104fd306cSNickeau     * @return void
8204fd306cSNickeau     */
8304fd306cSNickeau    private static function pathRewrite(Url $url)
8404fd306cSNickeau    {
8504fd306cSNickeau
8604fd306cSNickeau        try {
8704fd306cSNickeau            $path = $url->getPath();
8804fd306cSNickeau        } catch (ExceptionNotFound $e) {
8904fd306cSNickeau            // no path, no rewrite
9004fd306cSNickeau            return;
9104fd306cSNickeau        }
9204fd306cSNickeau
9304fd306cSNickeau        $rewrite = Site::getUrlRewrite();
9404fd306cSNickeau        switch ($path) {
9504fd306cSNickeau            case UrlEndpoint::LIB_EXE_FETCH_PHP:
9604fd306cSNickeau                if ($rewrite !== self::WEB_SERVER_REWRITE) {
9704fd306cSNickeau                    return;
9804fd306cSNickeau                }
9904fd306cSNickeau                try {
10070bbd7f1Sgerardnico                    $dokuwikiId = $url->getQueryPropertyValueAndRemoveIfPresent(MediaMarkup::$MEDIA_QUERY_PARAMETER);
10104fd306cSNickeau                } catch (ExceptionNotFound $e) {
10204fd306cSNickeau                    LogUtility::internalError("The media query should be present for a fetch. No Url rewrite could be done.");
10304fd306cSNickeau                    return;
10404fd306cSNickeau                }
10504fd306cSNickeau                $webUrlPath = str_replace(WikiPath::NAMESPACE_SEPARATOR_DOUBLE_POINT, "/", $dokuwikiId);
10604fd306cSNickeau                $url->setPath(self::MEDIA_PREFIX . "/$webUrlPath");
10704fd306cSNickeau                return;
10804fd306cSNickeau            case UrlEndpoint::LIB_EXE_DETAIL_PHP:
10904fd306cSNickeau                if ($rewrite !== self::WEB_SERVER_REWRITE) {
11004fd306cSNickeau                    return;
11104fd306cSNickeau                }
11204fd306cSNickeau                try {
11370bbd7f1Sgerardnico                    $dokuwikiId = $url->getQueryPropertyValueAndRemoveIfPresent(MediaMarkup::$MEDIA_QUERY_PARAMETER);
11404fd306cSNickeau                } catch (ExceptionNotFound $e) {
11504fd306cSNickeau                    LogUtility::internalError("The media query should be present for a detail page fetch. No Url rewrite could be done.");
11604fd306cSNickeau                    return;
11704fd306cSNickeau                }
11804fd306cSNickeau                $webUrlPath = str_replace(WikiPath::NAMESPACE_SEPARATOR_DOUBLE_POINT, "/", $dokuwikiId);
11904fd306cSNickeau                $url->setPath("/_detail/$webUrlPath");
12004fd306cSNickeau                return;
12104fd306cSNickeau            case UrlEndpoint::DOKU_PHP:
12204fd306cSNickeau                try {
12304fd306cSNickeau                    $dokuwikiId = $url->getQueryPropertyValueAndRemoveIfPresent(DokuWikiId::DOKUWIKI_ID_ATTRIBUTE);
12404fd306cSNickeau                } catch (ExceptionNotFound $e) {
12504fd306cSNickeau                    // no id (case of action such as login, ...)
12604fd306cSNickeau                    return;
12704fd306cSNickeau                }
12804fd306cSNickeau
12904fd306cSNickeau                /**
13004fd306cSNickeau                 * Permanent Id Rewrite
13104fd306cSNickeau                 * The page url path will return the original dokuwiki id
13204fd306cSNickeau                 * if there is no configuration
13304fd306cSNickeau                 */
13404fd306cSNickeau                $urlId = PageUrlPath::createForPage(MarkupPath::createMarkupFromId($dokuwikiId))->getValueOrDefaultAsWikiId();
13504fd306cSNickeau
13604fd306cSNickeau                /**
13704fd306cSNickeau                 * Rewrite Processing
13804fd306cSNickeau                 */
13904fd306cSNickeau                switch ($rewrite) {
14004fd306cSNickeau                    case self::WEB_SERVER_REWRITE:
14104fd306cSNickeau                        try {
142078e2b46Sgerardnico                            $do = $url->getQueryPropertyValue(ExecutionContext::DO_ATTRIBUTE);
14304fd306cSNickeau                            if (strpos($do, self::EXPORT_DO_PREFIX) === 0) {
14404fd306cSNickeau                                $exportFormat = substr($do, strlen(self::EXPORT_DO_PREFIX));
14504fd306cSNickeau                                $webUrlPath = str_replace(WikiPath::NAMESPACE_SEPARATOR_DOUBLE_POINT, "/", $urlId);
14604fd306cSNickeau                                $url->setPath(self::EXPORT_PATH_PREFIX . "/$exportFormat/$webUrlPath");
147*8b985170Sgerardnico                                $url->deleteQueryParameter(ExecutionContext::DO_ATTRIBUTE);
14804fd306cSNickeau                                return;
14904fd306cSNickeau                            }
150078e2b46Sgerardnico                            if ($do == ExecutionContext::SHOW_ACTION) {
151078e2b46Sgerardnico                                $url->deleteQueryParameter(ExecutionContext::DO_ATTRIBUTE);
152078e2b46Sgerardnico                            }
15304fd306cSNickeau                        } catch (ExceptionNotFound $e) {
15404fd306cSNickeau                            // no do
15504fd306cSNickeau                        }
15604fd306cSNickeau                        $webUrlPath = str_replace(WikiPath::NAMESPACE_SEPARATOR_DOUBLE_POINT, "/", $urlId);
15704fd306cSNickeau                        $url->setPath($webUrlPath);
15804fd306cSNickeau                        return;
15904fd306cSNickeau                    case self::VALUE_DOKU_REWRITE:
16004fd306cSNickeau                        $url->setPath("$path/$urlId");
16104fd306cSNickeau                        return;
16204fd306cSNickeau                    default:
16304fd306cSNickeau                        $url->setQueryParameter(DokuWikiId::DOKUWIKI_ID_ATTRIBUTE, $urlId);
16404fd306cSNickeau                        return;
16504fd306cSNickeau                }
16604fd306cSNickeau
16704fd306cSNickeau        }
16804fd306cSNickeau
16904fd306cSNickeau    }
17004fd306cSNickeau
17104fd306cSNickeau    private
17204fd306cSNickeau    static function baseRewrite(Url $url)
17304fd306cSNickeau    {
17404fd306cSNickeau        try {
17504fd306cSNickeau            $urlPathBaseDir = Site::getUrlPathBaseDir();
17604fd306cSNickeau        } catch (ExceptionNotFound $e) {
17704fd306cSNickeau            // ok, no base dir
17804fd306cSNickeau            return;
17904fd306cSNickeau        }
18004fd306cSNickeau        try {
18104fd306cSNickeau            $path = $url->getPath();
18204fd306cSNickeau        } catch (ExceptionNotFound $e) {
18304fd306cSNickeau            return;
18404fd306cSNickeau        }
18504fd306cSNickeau        if (strpos($path, $urlPathBaseDir) === 0) {
18604fd306cSNickeau            /**
18704fd306cSNickeau             * The base dir is already present
18804fd306cSNickeau             */
18904fd306cSNickeau            return;
19004fd306cSNickeau        }
19104fd306cSNickeau        if ($urlPathBaseDir[strlen($urlPathBaseDir) - 1] === "/") {
19204fd306cSNickeau            $url->setPath("$urlPathBaseDir$path");
19304fd306cSNickeau        } else {
19404fd306cSNickeau            $url->setPath("$urlPathBaseDir/$path");
19504fd306cSNickeau        }
19604fd306cSNickeau
19704fd306cSNickeau    }
19804fd306cSNickeau
19954743e42Sgerardnico    public static function sendErrorMessage()
20054743e42Sgerardnico    {
20154743e42Sgerardnico        $rewriteOption2 = "https://www.dokuwiki.org/rewrite#option_2dokuwiki";
20254743e42Sgerardnico        $rewriteOption1 = "https://www.dokuwiki.org/rewrite#option_1web_server";
20354743e42Sgerardnico        $hrefPermanentFunctionality = "https://combostrap.com/page/canonical-url-4kxbb9fd#permanent";
20454743e42Sgerardnico        $hrefNiceUrl = "https://combostrap.com/admin/nice-url-noln5keo";
20554743e42Sgerardnico        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);
20654743e42Sgerardnico    }
20754743e42Sgerardnico
20804fd306cSNickeau}
209