104fd306cSNickeau<?php 204fd306cSNickeau 304fd306cSNickeauuse ComboStrap\DokuwikiId; 404fd306cSNickeauuse ComboStrap\ExceptionNotFound; 504fd306cSNickeauuse ComboStrap\ExceptionReporter; 604fd306cSNickeauuse ComboStrap\ExecutionContext; 704fd306cSNickeauuse ComboStrap\FetcherAppPages; 804fd306cSNickeauuse ComboStrap\FetcherPage; 9*49b8fb24Sgerardnicouse ComboStrap\FetcherRailBar; 1004fd306cSNickeauuse ComboStrap\FileSystems; 1104fd306cSNickeauuse ComboStrap\HttpResponseStatus; 12*49b8fb24Sgerardnicouse ComboStrap\Identity; 1304fd306cSNickeauuse ComboStrap\IFetcher; 1404fd306cSNickeauuse ComboStrap\LogUtility; 1504fd306cSNickeauuse ComboStrap\MarkupPath; 1604fd306cSNickeauuse ComboStrap\Mime; 1704fd306cSNickeauuse ComboStrap\PluginUtility; 1854743e42Sgerardnicouse ComboStrap\Site; 1904fd306cSNickeauuse ComboStrap\SiteConfig; 2004fd306cSNickeauuse ComboStrap\Web\Url; 2154743e42Sgerardnicouse ComboStrap\Web\UrlRewrite; 2204fd306cSNickeau 2304fd306cSNickeau/** 2404fd306cSNickeau * Implementation of custom do (ie ACT) to output {@link \ComboStrap\IFetcherString} 2504fd306cSNickeau * 2604fd306cSNickeau * 2704fd306cSNickeau * 2804fd306cSNickeau */ 2904fd306cSNickeauclass action_plugin_combo_docustom extends DokuWiki_Action_Plugin 3004fd306cSNickeau{ 3104fd306cSNickeau 3204fd306cSNickeau const DO_PREFIX = "combo_"; 3304fd306cSNickeau 3404fd306cSNickeau const TEMPLATE_CANONICAL = "template"; 3504fd306cSNickeau 3604fd306cSNickeau /** 3704fd306cSNickeau * @var bool to avoid recursion that may happen using {@link tpl_content()} 3804fd306cSNickeau */ 3904fd306cSNickeau private bool $doCustomActuallyExecuting = false; 4004fd306cSNickeau 4104fd306cSNickeau /** 4204fd306cSNickeau * @return bool 4304fd306cSNickeau */ 4404fd306cSNickeau public static function isThemeSystemEnabled(): bool 4504fd306cSNickeau { 4604fd306cSNickeau $confValue = SiteConfig::getConfValue(SiteConfig::CONF_ENABLE_THEME_SYSTEM, SiteConfig::CONF_ENABLE_THEME_SYSTEM_DEFAULT); 4704fd306cSNickeau return $confValue === 1; 4804fd306cSNickeau } 4904fd306cSNickeau 5004fd306cSNickeau public static function getDoParameterValue(string $fetcherName): string 5104fd306cSNickeau { 5204fd306cSNickeau return self::DO_PREFIX . $fetcherName; 5304fd306cSNickeau } 5404fd306cSNickeau 5504fd306cSNickeau /** 5604fd306cSNickeau * 5704fd306cSNickeau * @param Doku_Event_Handler $controller 5804fd306cSNickeau * @return void 5904fd306cSNickeau */ 6004fd306cSNickeau 6104fd306cSNickeau public function register(\Doku_Event_Handler $controller) 6204fd306cSNickeau { 6304fd306cSNickeau /** 6404fd306cSNickeau * Execute the combo action via an ACTION_ACT_PREPROCESS 6504fd306cSNickeau * 6604fd306cSNickeau * Not via the [TPL_ACT_UNKNOWN](https://www.dokuwiki.org/devel:event:tpl_act_unknown) 6704fd306cSNickeau * because it would otherwise put the content in the middle of the page 6804fd306cSNickeau * as an admin page. 6904fd306cSNickeau * 7004fd306cSNickeau * Not really useful if you want your own layout or do an export 7104fd306cSNickeau */ 7204fd306cSNickeau $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'executeComboDoAction'); 7304fd306cSNickeau 7404fd306cSNickeau } 7504fd306cSNickeau 7604fd306cSNickeau /** 7704fd306cSNickeau * @param Doku_Event $event 7804fd306cSNickeau * @param $param 7904fd306cSNickeau * @return void 8004fd306cSNickeau * 8104fd306cSNickeau */ 8204fd306cSNickeau public function executeComboDoAction(Doku_Event $event, $param) 8304fd306cSNickeau { 8404fd306cSNickeau 8504fd306cSNickeau if ($this->doCustomActuallyExecuting) { 8604fd306cSNickeau return; 8704fd306cSNickeau } 8804fd306cSNickeau 8904fd306cSNickeau /** 9004fd306cSNickeau * The router may have done a redirection 9104fd306cSNickeau * (The Dokuwiki testRequest does not stop unfortunately) 9204fd306cSNickeau */ 9304fd306cSNickeau $executionContext = ExecutionContext::getActualOrCreateFromEnv(); 9404fd306cSNickeau $hasEnded = $executionContext 9504fd306cSNickeau ->response() 9604fd306cSNickeau ->hasEnded(); 9704fd306cSNickeau if ($hasEnded) { 9804fd306cSNickeau if ($executionContext->isTestRun()) { 9904fd306cSNickeau /** 10004fd306cSNickeau * This info helps the developer to see 10104fd306cSNickeau * why nothing happens when it sends two dokuwiki {@link TestRequest} 10204fd306cSNickeau * 10304fd306cSNickeau * And not two {@link \ComboStrap\HttpResponse} 10404fd306cSNickeau * that reinitialize the global scope 10504fd306cSNickeau */ 10604fd306cSNickeau LogUtility::info("ExecuteDoAction: The response has already be send (ended)."); 10704fd306cSNickeau } 10804fd306cSNickeau return; 10904fd306cSNickeau } 11004fd306cSNickeau 11154743e42Sgerardnico $urlRewrite = Site::getUrlRewrite(); 11254743e42Sgerardnico if ($urlRewrite == UrlRewrite::VALUE_DOKU_REWRITE) { 11354743e42Sgerardnico UrlRewrite::sendErrorMessage(); 11454743e42Sgerardnico return; 11554743e42Sgerardnico } 11654743e42Sgerardnico 11704fd306cSNickeau $action = $event->data; 11804fd306cSNickeau 119*49b8fb24Sgerardnico $privateRailbar = $executionContext->getConfig()->getBooleanValue(FetcherRailBar::CONF_PRIVATE_RAIL_BAR, FetcherRailBar::CONF_PRIVATE_RAIL_BAR_DEFAULT); 120*49b8fb24Sgerardnico $isAnonymous = Identity::isAnonymous(); 121*49b8fb24Sgerardnico if ($privateRailbar && $isAnonymous) { 122*49b8fb24Sgerardnico /** 123*49b8fb24Sgerardnico * To avoid the google console error: `Excluded by ‘noindex’ tag` 124*49b8fb24Sgerardnico * Example of URL 125*49b8fb24Sgerardnico * https://example.com/dat/bobj/central_management_server?tab_files=upload&do=media&tab_details=history&image=db:hana:hdb_thread_stat_systemdb.png&ns=web/resource 126*49b8fb24Sgerardnico */ 127*49b8fb24Sgerardnico $privateAction = [ExecutionContext::MEDIA_ACTION, ExecutionContext::DIFF_ACTION, ExecutionContext::RECENT_ACTION]; 128*49b8fb24Sgerardnico if (in_array($action, $privateAction)) { 129*49b8fb24Sgerardnico $executionContext->response() 130*49b8fb24Sgerardnico ->setStatus(HttpResponseStatus::NOT_AUTHORIZED) 131*49b8fb24Sgerardnico ->end(); 132*49b8fb24Sgerardnico return; 133*49b8fb24Sgerardnico } 134*49b8fb24Sgerardnico } 135*49b8fb24Sgerardnico 13604fd306cSNickeau if (self::isThemeSystemEnabled()) { 13704fd306cSNickeau switch ($action) { 138*49b8fb24Sgerardnico case ExecutionContext::SHOW_ACTION: 13904fd306cSNickeau try { 14004fd306cSNickeau $id = Url::createFromGetOrPostGlobalVariable()->getPropertyValue(DokuwikiId::DOKUWIKI_ID_ATTRIBUTE); 14104fd306cSNickeau } catch (ExceptionNotFound $e) { 14204fd306cSNickeau // should not happen but yeah 14304fd306cSNickeau return; 14404fd306cSNickeau } 14504fd306cSNickeau $path = MarkupPath::createMarkupFromId($id); 14604fd306cSNickeau if (!FileSystems::exists($path)) { 14704fd306cSNickeau return; 14804fd306cSNickeau } 14904fd306cSNickeau $action = self::getDoParameterValue(FetcherPage::NAME); 15004fd306cSNickeau break; 15104fd306cSNickeau case ExecutionContext::LOGIN_ACTION: 15204fd306cSNickeau case ExecutionContext::REGISTER_ACTION: 15304fd306cSNickeau case ExecutionContext::RESEND_PWD_ACTION: 15404fd306cSNickeau case ExecutionContext::PROFILE_ACTION: 15504fd306cSNickeau case ExecutionContext::EDIT_ACTION: 15604fd306cSNickeau case ExecutionContext::PREVIEW_ACTION: 15704fd306cSNickeau case ExecutionContext::SEARCH_ACTION: 15804fd306cSNickeau case ExecutionContext::INDEX_ACTION: 15904fd306cSNickeau //case ExecutionContext::REVISIONS_ACTION: 16004fd306cSNickeau //case ExecutionContext::DIFF_ACTION: needs styling 16104fd306cSNickeau $action = self::getDoParameterValue(FetcherAppPages::NAME); 16204fd306cSNickeau break; 16304fd306cSNickeau } 16404fd306cSNickeau } 16504fd306cSNickeau 166*49b8fb24Sgerardnico 16704fd306cSNickeau if (!$this->isComboDoAction($action)) return; 16804fd306cSNickeau 16904fd306cSNickeau /** 17004fd306cSNickeau * To avoid recursion 17104fd306cSNickeau */ 17204fd306cSNickeau $this->doCustomActuallyExecuting = true; 17304fd306cSNickeau 17404fd306cSNickeau 17504fd306cSNickeau try { 17604fd306cSNickeau $fetcherName = $this->getFetcherNameFromAction($action); 17704fd306cSNickeau $url = Url::createFromGetOrPostGlobalVariable() 17804fd306cSNickeau ->addQueryParameter(IFetcher::FETCHER_KEY, $fetcherName); 17904fd306cSNickeau $fetcher = $executionContext->createStringMainFetcherFromRequestedUrl($url); 18004fd306cSNickeau $body = $fetcher->getFetchString(); 18104fd306cSNickeau $mime = $fetcher->getMime(); 18204fd306cSNickeau $executionContext->response() 18304fd306cSNickeau ->setStatus(HttpResponseStatus::ALL_GOOD) 18404fd306cSNickeau ->setBody($body, $mime) 18504fd306cSNickeau ->end(); 18604fd306cSNickeau } catch (\Exception $e) { 18704fd306cSNickeau 18804fd306cSNickeau 18904fd306cSNickeau $reporterMessage = "An error has occurred during the execution of the action ($action)"; 19004fd306cSNickeau $html = ExceptionReporter::createForException($e) 19104fd306cSNickeau ->getHtmlPage($reporterMessage); 19204fd306cSNickeau if (PluginUtility::isDevOrTest()) { 19304fd306cSNickeau // Permits to throw the error to get the stack trace 19404fd306cSNickeau LogUtility::warning($reporterMessage, self::TEMPLATE_CANONICAL, $e); 19504fd306cSNickeau } 19604fd306cSNickeau $executionContext->response() 19704fd306cSNickeau ->setException($e) 19804fd306cSNickeau ->setBody($html, Mime::getHtml()) 19904fd306cSNickeau ->end(); 20004fd306cSNickeau 20104fd306cSNickeau } finally { 20204fd306cSNickeau $this->doCustomActuallyExecuting = false; 20304fd306cSNickeau } 20404fd306cSNickeau 20504fd306cSNickeau } 20604fd306cSNickeau 20704fd306cSNickeau 20804fd306cSNickeau private function isComboDoAction($actionName): bool 20904fd306cSNickeau { 21004fd306cSNickeau return strpos($actionName, self::DO_PREFIX) === 0; 21104fd306cSNickeau } 21204fd306cSNickeau 21304fd306cSNickeau private function getFetcherNameFromAction($actionName) 21404fd306cSNickeau { 21504fd306cSNickeau return substr($actionName, strlen(self::DO_PREFIX)); 21604fd306cSNickeau } 21704fd306cSNickeau 21804fd306cSNickeau 21904fd306cSNickeau} 220