1*04fd306cSNickeau<?php 2*04fd306cSNickeau 3*04fd306cSNickeauuse ComboStrap\DokuwikiId; 4*04fd306cSNickeauuse ComboStrap\ExceptionNotFound; 5*04fd306cSNickeauuse ComboStrap\ExceptionReporter; 6*04fd306cSNickeauuse ComboStrap\ExecutionContext; 7*04fd306cSNickeauuse ComboStrap\FetcherAppPages; 8*04fd306cSNickeauuse ComboStrap\FetcherPage; 9*04fd306cSNickeauuse ComboStrap\FileSystems; 10*04fd306cSNickeauuse ComboStrap\HttpResponseStatus; 11*04fd306cSNickeauuse ComboStrap\IFetcher; 12*04fd306cSNickeauuse ComboStrap\LogUtility; 13*04fd306cSNickeauuse ComboStrap\MarkupPath; 14*04fd306cSNickeauuse ComboStrap\Mime; 15*04fd306cSNickeauuse ComboStrap\PluginUtility; 16*04fd306cSNickeauuse ComboStrap\SiteConfig; 17*04fd306cSNickeauuse ComboStrap\Web\Url; 18*04fd306cSNickeau 19*04fd306cSNickeau/** 20*04fd306cSNickeau * Implementation of custom do (ie ACT) to output {@link \ComboStrap\IFetcherString} 21*04fd306cSNickeau * 22*04fd306cSNickeau * 23*04fd306cSNickeau * 24*04fd306cSNickeau */ 25*04fd306cSNickeauclass action_plugin_combo_docustom extends DokuWiki_Action_Plugin 26*04fd306cSNickeau{ 27*04fd306cSNickeau 28*04fd306cSNickeau const DO_PREFIX = "combo_"; 29*04fd306cSNickeau 30*04fd306cSNickeau const TEMPLATE_CANONICAL = "template"; 31*04fd306cSNickeau 32*04fd306cSNickeau /** 33*04fd306cSNickeau * @var bool to avoid recursion that may happen using {@link tpl_content()} 34*04fd306cSNickeau */ 35*04fd306cSNickeau private bool $doCustomActuallyExecuting = false; 36*04fd306cSNickeau 37*04fd306cSNickeau /** 38*04fd306cSNickeau * @return bool 39*04fd306cSNickeau */ 40*04fd306cSNickeau public static function isThemeSystemEnabled(): bool 41*04fd306cSNickeau { 42*04fd306cSNickeau $confValue = SiteConfig::getConfValue(SiteConfig::CONF_ENABLE_THEME_SYSTEM, SiteConfig::CONF_ENABLE_THEME_SYSTEM_DEFAULT); 43*04fd306cSNickeau return $confValue === 1; 44*04fd306cSNickeau } 45*04fd306cSNickeau 46*04fd306cSNickeau public static function getDoParameterValue(string $fetcherName): string 47*04fd306cSNickeau { 48*04fd306cSNickeau return self::DO_PREFIX . $fetcherName; 49*04fd306cSNickeau } 50*04fd306cSNickeau 51*04fd306cSNickeau /** 52*04fd306cSNickeau * 53*04fd306cSNickeau * @param Doku_Event_Handler $controller 54*04fd306cSNickeau * @return void 55*04fd306cSNickeau */ 56*04fd306cSNickeau 57*04fd306cSNickeau public function register(\Doku_Event_Handler $controller) 58*04fd306cSNickeau { 59*04fd306cSNickeau /** 60*04fd306cSNickeau * Execute the combo action via an ACTION_ACT_PREPROCESS 61*04fd306cSNickeau * 62*04fd306cSNickeau * Not via the [TPL_ACT_UNKNOWN](https://www.dokuwiki.org/devel:event:tpl_act_unknown) 63*04fd306cSNickeau * because it would otherwise put the content in the middle of the page 64*04fd306cSNickeau * as an admin page. 65*04fd306cSNickeau * 66*04fd306cSNickeau * Not really useful if you want your own layout or do an export 67*04fd306cSNickeau */ 68*04fd306cSNickeau $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'executeComboDoAction'); 69*04fd306cSNickeau 70*04fd306cSNickeau } 71*04fd306cSNickeau 72*04fd306cSNickeau /** 73*04fd306cSNickeau * @param Doku_Event $event 74*04fd306cSNickeau * @param $param 75*04fd306cSNickeau * @return void 76*04fd306cSNickeau * 77*04fd306cSNickeau */ 78*04fd306cSNickeau public function executeComboDoAction(Doku_Event $event, $param) 79*04fd306cSNickeau { 80*04fd306cSNickeau 81*04fd306cSNickeau if ($this->doCustomActuallyExecuting) { 82*04fd306cSNickeau return; 83*04fd306cSNickeau } 84*04fd306cSNickeau 85*04fd306cSNickeau /** 86*04fd306cSNickeau * The router may have done a redirection 87*04fd306cSNickeau * (The Dokuwiki testRequest does not stop unfortunately) 88*04fd306cSNickeau */ 89*04fd306cSNickeau $executionContext = ExecutionContext::getActualOrCreateFromEnv(); 90*04fd306cSNickeau $hasEnded = $executionContext 91*04fd306cSNickeau ->response() 92*04fd306cSNickeau ->hasEnded(); 93*04fd306cSNickeau if ($hasEnded) { 94*04fd306cSNickeau if ($executionContext->isTestRun()) { 95*04fd306cSNickeau /** 96*04fd306cSNickeau * This info helps the developer to see 97*04fd306cSNickeau * why nothing happens when it sends two dokuwiki {@link TestRequest} 98*04fd306cSNickeau * 99*04fd306cSNickeau * And not two {@link \ComboStrap\HttpResponse} 100*04fd306cSNickeau * that reinitialize the global scope 101*04fd306cSNickeau */ 102*04fd306cSNickeau LogUtility::info("ExecuteDoAction: The response has already be send (ended)."); 103*04fd306cSNickeau } 104*04fd306cSNickeau return; 105*04fd306cSNickeau } 106*04fd306cSNickeau 107*04fd306cSNickeau $action = $event->data; 108*04fd306cSNickeau 109*04fd306cSNickeau if (self::isThemeSystemEnabled()) { 110*04fd306cSNickeau switch ($action) { 111*04fd306cSNickeau case "show": 112*04fd306cSNickeau try { 113*04fd306cSNickeau $id = Url::createFromGetOrPostGlobalVariable()->getPropertyValue(DokuwikiId::DOKUWIKI_ID_ATTRIBUTE); 114*04fd306cSNickeau } catch (ExceptionNotFound $e) { 115*04fd306cSNickeau // should not happen but yeah 116*04fd306cSNickeau return; 117*04fd306cSNickeau } 118*04fd306cSNickeau $path = MarkupPath::createMarkupFromId($id); 119*04fd306cSNickeau if (!FileSystems::exists($path)) { 120*04fd306cSNickeau return; 121*04fd306cSNickeau } 122*04fd306cSNickeau $action = self::getDoParameterValue(FetcherPage::NAME); 123*04fd306cSNickeau break; 124*04fd306cSNickeau case ExecutionContext::LOGIN_ACTION: 125*04fd306cSNickeau case ExecutionContext::REGISTER_ACTION: 126*04fd306cSNickeau case ExecutionContext::RESEND_PWD_ACTION: 127*04fd306cSNickeau case ExecutionContext::PROFILE_ACTION: 128*04fd306cSNickeau case ExecutionContext::EDIT_ACTION: 129*04fd306cSNickeau case ExecutionContext::PREVIEW_ACTION: 130*04fd306cSNickeau case ExecutionContext::SEARCH_ACTION: 131*04fd306cSNickeau case ExecutionContext::INDEX_ACTION: 132*04fd306cSNickeau //case ExecutionContext::REVISIONS_ACTION: 133*04fd306cSNickeau //case ExecutionContext::DIFF_ACTION: needs styling 134*04fd306cSNickeau $action = self::getDoParameterValue(FetcherAppPages::NAME); 135*04fd306cSNickeau break; 136*04fd306cSNickeau } 137*04fd306cSNickeau } 138*04fd306cSNickeau 139*04fd306cSNickeau if (!$this->isComboDoAction($action)) return; 140*04fd306cSNickeau 141*04fd306cSNickeau /** 142*04fd306cSNickeau * To avoid recursion 143*04fd306cSNickeau */ 144*04fd306cSNickeau $this->doCustomActuallyExecuting = true; 145*04fd306cSNickeau 146*04fd306cSNickeau 147*04fd306cSNickeau try { 148*04fd306cSNickeau $fetcherName = $this->getFetcherNameFromAction($action); 149*04fd306cSNickeau $url = Url::createFromGetOrPostGlobalVariable() 150*04fd306cSNickeau ->addQueryParameter(IFetcher::FETCHER_KEY, $fetcherName); 151*04fd306cSNickeau $fetcher = $executionContext->createStringMainFetcherFromRequestedUrl($url); 152*04fd306cSNickeau $body = $fetcher->getFetchString(); 153*04fd306cSNickeau $mime = $fetcher->getMime(); 154*04fd306cSNickeau $executionContext->response() 155*04fd306cSNickeau ->setStatus(HttpResponseStatus::ALL_GOOD) 156*04fd306cSNickeau ->setBody($body, $mime) 157*04fd306cSNickeau ->end(); 158*04fd306cSNickeau } catch (\Exception $e) { 159*04fd306cSNickeau 160*04fd306cSNickeau 161*04fd306cSNickeau $reporterMessage = "An error has occurred during the execution of the action ($action)"; 162*04fd306cSNickeau $html = ExceptionReporter::createForException($e) 163*04fd306cSNickeau ->getHtmlPage($reporterMessage); 164*04fd306cSNickeau if (PluginUtility::isDevOrTest()) { 165*04fd306cSNickeau // Permits to throw the error to get the stack trace 166*04fd306cSNickeau LogUtility::warning($reporterMessage, self::TEMPLATE_CANONICAL, $e); 167*04fd306cSNickeau } 168*04fd306cSNickeau $executionContext->response() 169*04fd306cSNickeau ->setException($e) 170*04fd306cSNickeau ->setBody($html, Mime::getHtml()) 171*04fd306cSNickeau ->end(); 172*04fd306cSNickeau 173*04fd306cSNickeau } finally { 174*04fd306cSNickeau $this->doCustomActuallyExecuting = false; 175*04fd306cSNickeau } 176*04fd306cSNickeau 177*04fd306cSNickeau } 178*04fd306cSNickeau 179*04fd306cSNickeau 180*04fd306cSNickeau private function isComboDoAction($actionName): bool 181*04fd306cSNickeau { 182*04fd306cSNickeau return strpos($actionName, self::DO_PREFIX) === 0; 183*04fd306cSNickeau } 184*04fd306cSNickeau 185*04fd306cSNickeau private function getFetcherNameFromAction($actionName) 186*04fd306cSNickeau { 187*04fd306cSNickeau return substr($actionName, strlen(self::DO_PREFIX)); 188*04fd306cSNickeau } 189*04fd306cSNickeau 190*04fd306cSNickeau 191*04fd306cSNickeau} 192