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