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