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