xref: /plugin/combo/action/docustom.php (revision 54743e42e98b8cc4f9d7df000ae3be1d8edf18ff)
104fd306cSNickeau<?php
204fd306cSNickeau
304fd306cSNickeauuse ComboStrap\DokuwikiId;
404fd306cSNickeauuse ComboStrap\ExceptionNotFound;
504fd306cSNickeauuse ComboStrap\ExceptionReporter;
604fd306cSNickeauuse ComboStrap\ExecutionContext;
704fd306cSNickeauuse ComboStrap\FetcherAppPages;
804fd306cSNickeauuse ComboStrap\FetcherPage;
904fd306cSNickeauuse ComboStrap\FileSystems;
1004fd306cSNickeauuse ComboStrap\HttpResponseStatus;
1104fd306cSNickeauuse ComboStrap\IFetcher;
1204fd306cSNickeauuse ComboStrap\LogUtility;
1304fd306cSNickeauuse ComboStrap\MarkupPath;
1404fd306cSNickeauuse ComboStrap\Mime;
1504fd306cSNickeauuse ComboStrap\PluginUtility;
16*54743e42Sgerardnicouse ComboStrap\Site;
1704fd306cSNickeauuse ComboStrap\SiteConfig;
1804fd306cSNickeauuse ComboStrap\Web\Url;
19*54743e42Sgerardnicouse ComboStrap\Web\UrlRewrite;
2004fd306cSNickeau
2104fd306cSNickeau/**
2204fd306cSNickeau * Implementation of custom do (ie ACT) to output {@link \ComboStrap\IFetcherString}
2304fd306cSNickeau *
2404fd306cSNickeau *
2504fd306cSNickeau *
2604fd306cSNickeau */
2704fd306cSNickeauclass action_plugin_combo_docustom extends DokuWiki_Action_Plugin
2804fd306cSNickeau{
2904fd306cSNickeau
3004fd306cSNickeau    const DO_PREFIX = "combo_";
3104fd306cSNickeau
3204fd306cSNickeau    const TEMPLATE_CANONICAL = "template";
3304fd306cSNickeau
3404fd306cSNickeau    /**
3504fd306cSNickeau     * @var bool to avoid recursion that may happen using {@link tpl_content()}
3604fd306cSNickeau     */
3704fd306cSNickeau    private bool $doCustomActuallyExecuting = false;
3804fd306cSNickeau
3904fd306cSNickeau    /**
4004fd306cSNickeau     * @return bool
4104fd306cSNickeau     */
4204fd306cSNickeau    public static function isThemeSystemEnabled(): bool
4304fd306cSNickeau    {
4404fd306cSNickeau        $confValue = SiteConfig::getConfValue(SiteConfig::CONF_ENABLE_THEME_SYSTEM, SiteConfig::CONF_ENABLE_THEME_SYSTEM_DEFAULT);
4504fd306cSNickeau        return $confValue === 1;
4604fd306cSNickeau    }
4704fd306cSNickeau
4804fd306cSNickeau    public static function getDoParameterValue(string $fetcherName): string
4904fd306cSNickeau    {
5004fd306cSNickeau        return self::DO_PREFIX . $fetcherName;
5104fd306cSNickeau    }
5204fd306cSNickeau
5304fd306cSNickeau    /**
5404fd306cSNickeau     *
5504fd306cSNickeau     * @param Doku_Event_Handler $controller
5604fd306cSNickeau     * @return void
5704fd306cSNickeau     */
5804fd306cSNickeau
5904fd306cSNickeau    public function register(\Doku_Event_Handler $controller)
6004fd306cSNickeau    {
6104fd306cSNickeau        /**
6204fd306cSNickeau         * Execute the combo action via an ACTION_ACT_PREPROCESS
6304fd306cSNickeau         *
6404fd306cSNickeau         * Not via the [TPL_ACT_UNKNOWN](https://www.dokuwiki.org/devel:event:tpl_act_unknown)
6504fd306cSNickeau         * because it would otherwise put the content in the middle of the page
6604fd306cSNickeau         * as an admin page.
6704fd306cSNickeau         *
6804fd306cSNickeau         * Not really useful if you want your own layout or do an export
6904fd306cSNickeau         */
7004fd306cSNickeau        $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'executeComboDoAction');
7104fd306cSNickeau
7204fd306cSNickeau    }
7304fd306cSNickeau
7404fd306cSNickeau    /**
7504fd306cSNickeau     * @param Doku_Event $event
7604fd306cSNickeau     * @param $param
7704fd306cSNickeau     * @return void
7804fd306cSNickeau     *
7904fd306cSNickeau     */
8004fd306cSNickeau    public function executeComboDoAction(Doku_Event $event, $param)
8104fd306cSNickeau    {
8204fd306cSNickeau
8304fd306cSNickeau        if ($this->doCustomActuallyExecuting) {
8404fd306cSNickeau            return;
8504fd306cSNickeau        }
8604fd306cSNickeau
8704fd306cSNickeau        /**
8804fd306cSNickeau         * The router may have done a redirection
8904fd306cSNickeau         * (The Dokuwiki testRequest does not stop unfortunately)
9004fd306cSNickeau         */
9104fd306cSNickeau        $executionContext = ExecutionContext::getActualOrCreateFromEnv();
9204fd306cSNickeau        $hasEnded = $executionContext
9304fd306cSNickeau            ->response()
9404fd306cSNickeau            ->hasEnded();
9504fd306cSNickeau        if ($hasEnded) {
9604fd306cSNickeau            if ($executionContext->isTestRun()) {
9704fd306cSNickeau                /**
9804fd306cSNickeau                 * This info helps the developer to see
9904fd306cSNickeau                 * why nothing happens when it sends two dokuwiki {@link TestRequest}
10004fd306cSNickeau                 *
10104fd306cSNickeau                 * And not two {@link \ComboStrap\HttpResponse}
10204fd306cSNickeau                 * that reinitialize the global scope
10304fd306cSNickeau                 */
10404fd306cSNickeau                LogUtility::info("ExecuteDoAction: The response has already be send (ended).");
10504fd306cSNickeau            }
10604fd306cSNickeau            return;
10704fd306cSNickeau        }
10804fd306cSNickeau
109*54743e42Sgerardnico        $urlRewrite = Site::getUrlRewrite();
110*54743e42Sgerardnico        if ($urlRewrite == UrlRewrite::VALUE_DOKU_REWRITE) {
111*54743e42Sgerardnico            UrlRewrite::sendErrorMessage();
112*54743e42Sgerardnico            return;
113*54743e42Sgerardnico        }
114*54743e42Sgerardnico
11504fd306cSNickeau        $action = $event->data;
11604fd306cSNickeau
11704fd306cSNickeau        if (self::isThemeSystemEnabled()) {
11804fd306cSNickeau            switch ($action) {
11904fd306cSNickeau                case "show":
12004fd306cSNickeau                    try {
12104fd306cSNickeau                        $id = Url::createFromGetOrPostGlobalVariable()->getPropertyValue(DokuwikiId::DOKUWIKI_ID_ATTRIBUTE);
12204fd306cSNickeau                    } catch (ExceptionNotFound $e) {
12304fd306cSNickeau                        // should not happen but yeah
12404fd306cSNickeau                        return;
12504fd306cSNickeau                    }
12604fd306cSNickeau                    $path = MarkupPath::createMarkupFromId($id);
12704fd306cSNickeau                    if (!FileSystems::exists($path)) {
12804fd306cSNickeau                        return;
12904fd306cSNickeau                    }
13004fd306cSNickeau                    $action = self::getDoParameterValue(FetcherPage::NAME);
13104fd306cSNickeau                    break;
13204fd306cSNickeau                case ExecutionContext::LOGIN_ACTION:
13304fd306cSNickeau                case ExecutionContext::REGISTER_ACTION:
13404fd306cSNickeau                case ExecutionContext::RESEND_PWD_ACTION:
13504fd306cSNickeau                case ExecutionContext::PROFILE_ACTION:
13604fd306cSNickeau                case ExecutionContext::EDIT_ACTION:
13704fd306cSNickeau                case ExecutionContext::PREVIEW_ACTION:
13804fd306cSNickeau                case ExecutionContext::SEARCH_ACTION:
13904fd306cSNickeau                case ExecutionContext::INDEX_ACTION:
14004fd306cSNickeau                    //case ExecutionContext::REVISIONS_ACTION:
14104fd306cSNickeau                    //case ExecutionContext::DIFF_ACTION: needs styling
14204fd306cSNickeau                    $action = self::getDoParameterValue(FetcherAppPages::NAME);
14304fd306cSNickeau                    break;
14404fd306cSNickeau            }
14504fd306cSNickeau        }
14604fd306cSNickeau
14704fd306cSNickeau        if (!$this->isComboDoAction($action)) return;
14804fd306cSNickeau
14904fd306cSNickeau        /**
15004fd306cSNickeau         * To avoid recursion
15104fd306cSNickeau         */
15204fd306cSNickeau        $this->doCustomActuallyExecuting = true;
15304fd306cSNickeau
15404fd306cSNickeau
15504fd306cSNickeau        try {
15604fd306cSNickeau            $fetcherName = $this->getFetcherNameFromAction($action);
15704fd306cSNickeau            $url = Url::createFromGetOrPostGlobalVariable()
15804fd306cSNickeau                ->addQueryParameter(IFetcher::FETCHER_KEY, $fetcherName);
15904fd306cSNickeau            $fetcher = $executionContext->createStringMainFetcherFromRequestedUrl($url);
16004fd306cSNickeau            $body = $fetcher->getFetchString();
16104fd306cSNickeau            $mime = $fetcher->getMime();
16204fd306cSNickeau            $executionContext->response()
16304fd306cSNickeau                ->setStatus(HttpResponseStatus::ALL_GOOD)
16404fd306cSNickeau                ->setBody($body, $mime)
16504fd306cSNickeau                ->end();
16604fd306cSNickeau        } catch (\Exception $e) {
16704fd306cSNickeau
16804fd306cSNickeau
16904fd306cSNickeau            $reporterMessage = "An error has occurred during the execution of the action ($action)";
17004fd306cSNickeau            $html = ExceptionReporter::createForException($e)
17104fd306cSNickeau                ->getHtmlPage($reporterMessage);
17204fd306cSNickeau            if (PluginUtility::isDevOrTest()) {
17304fd306cSNickeau                // Permits to throw the error to get the stack trace
17404fd306cSNickeau                LogUtility::warning($reporterMessage, self::TEMPLATE_CANONICAL, $e);
17504fd306cSNickeau            }
17604fd306cSNickeau            $executionContext->response()
17704fd306cSNickeau                ->setException($e)
17804fd306cSNickeau                ->setBody($html, Mime::getHtml())
17904fd306cSNickeau                ->end();
18004fd306cSNickeau
18104fd306cSNickeau        } finally {
18204fd306cSNickeau            $this->doCustomActuallyExecuting = false;
18304fd306cSNickeau        }
18404fd306cSNickeau
18504fd306cSNickeau    }
18604fd306cSNickeau
18704fd306cSNickeau
18804fd306cSNickeau    private function isComboDoAction($actionName): bool
18904fd306cSNickeau    {
19004fd306cSNickeau        return strpos($actionName, self::DO_PREFIX) === 0;
19104fd306cSNickeau    }
19204fd306cSNickeau
19304fd306cSNickeau    private function getFetcherNameFromAction($actionName)
19404fd306cSNickeau    {
19504fd306cSNickeau        return substr($actionName, strlen(self::DO_PREFIX));
19604fd306cSNickeau    }
19704fd306cSNickeau
19804fd306cSNickeau
19904fd306cSNickeau}
200