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