xref: /template/strap/ComboStrap/SiteConfig.php (revision 6b325b4bf6533684d15f43c9e39e47e2bad26246)
104fd306cSNickeau<?php
204fd306cSNickeau
304fd306cSNickeaunamespace ComboStrap;
404fd306cSNickeau
504fd306cSNickeau
604fd306cSNickeauuse ComboStrap\Meta\Field\PageTemplateName;
704fd306cSNickeauuse dokuwiki\Extension\PluginTrait;
804fd306cSNickeau
904fd306cSNickeauclass SiteConfig
1004fd306cSNickeau{
1104fd306cSNickeau    const LOG_EXCEPTION_LEVEL = 'log-exception-level';
1204fd306cSNickeau
1304fd306cSNickeau    /**
1404fd306cSNickeau     * A configuration to enable the theme/template system
1504fd306cSNickeau     */
1604fd306cSNickeau    public const CONF_ENABLE_THEME_SYSTEM = "combo-conf-001";
1704fd306cSNickeau    public const CONF_ENABLE_THEME_SYSTEM_DEFAULT = 1;
1804fd306cSNickeau
1904fd306cSNickeau    /**
2004fd306cSNickeau     * The default font-size for the pages
2104fd306cSNickeau     */
2204fd306cSNickeau    const REM_CONF = "combo-conf-002";
2304fd306cSNickeau    const REM_CANONICAL = "rfs";
2404fd306cSNickeau
2504fd306cSNickeau    /**
2604fd306cSNickeau     * The maximum size to be embedded
2704fd306cSNickeau     * Above this size limit they are fetched
2804fd306cSNickeau     *
2904fd306cSNickeau     * 2kb is too small for icon.
3004fd306cSNickeau     * For instance, the et:twitter is 2,600b
3104fd306cSNickeau     */
3204fd306cSNickeau    public const HTML_MAX_KB_SIZE_FOR_INLINE_ELEMENT = "combo-conf-003";
3304fd306cSNickeau    public const HTML_MAX_KB_SIZE_FOR_INLINE_ELEMENT_DEFAULT = 4;
3404fd306cSNickeau    /**
3504fd306cSNickeau     * Private configuration used in test
3604fd306cSNickeau     * When set to true, all javascript snippet will be inlined
3704fd306cSNickeau     */
3804fd306cSNickeau    public const HTML_ALWAYS_INLINE_LOCAL_JAVASCRIPT = "combo-conf-004";
3904fd306cSNickeau    const CANONICAL = "site-config";
4004fd306cSNickeau    const GLOBAL_SCOPE = null;
4104fd306cSNickeau    /**
4204fd306cSNickeau     * The default name
4304fd306cSNickeau     */
4404fd306cSNickeau    public const CONF_DEFAULT_INDEX_NAME = "start";
4504fd306cSNickeau
4604fd306cSNickeau
4704fd306cSNickeau    /**
4804fd306cSNickeau     * @var WikiPath the {@link self::getContextPath()} when no context could be determined
4904fd306cSNickeau     */
5004fd306cSNickeau    private WikiPath $defaultContextPath;
5104fd306cSNickeau
5204fd306cSNickeau    /**
5304fd306cSNickeau     * @var array - the configuration value to restore
5404fd306cSNickeau     *
5504fd306cSNickeau     * Note we can't capture the whole global $conf
5604fd306cSNickeau     * because the configuration are loaded at runtime via {@link PluginTrait::loadConfig()}
5704fd306cSNickeau     *
5804fd306cSNickeau     * Meaning that the configuration environment at the start is not fully loaded
5904fd306cSNickeau     * and does not represent the environment totally
6004fd306cSNickeau     *
6104fd306cSNickeau     * We capture then the change and restore them at the end
6204fd306cSNickeau     */
6304fd306cSNickeau    private array $configurationValuesToRestore = [];
6404fd306cSNickeau    private ExecutionContext $executionContext;
6504fd306cSNickeau    private array $interWikis;
6604fd306cSNickeau
6704fd306cSNickeau    /**
6804fd306cSNickeau     * @param ExecutionContext $executionContext
6904fd306cSNickeau     */
7004fd306cSNickeau    public function __construct(ExecutionContext $executionContext)
7104fd306cSNickeau    {
7204fd306cSNickeau        $this->executionContext = $executionContext;
7304fd306cSNickeau    }
7404fd306cSNickeau
7504fd306cSNickeau    /**
7604fd306cSNickeau     * TODO: Default: Note that the config of plugin are loaded
7704fd306cSNickeau     *   via {@link PluginTrait::loadConfig()}
7804fd306cSNickeau     *   when {@link PluginTrait::getConf()} is used
7904fd306cSNickeau     *   Therefore whenever possible, for now {@link PluginTrait::getConf()}
8004fd306cSNickeau     *   should be used otherwise, there is no default
8104fd306cSNickeau     *   Or best, the default should be also in the code
8204fd306cSNickeau     *
8304fd306cSNickeau     */
8404fd306cSNickeau    public static function getConfValue($confName, $defaultValue = null, ?string $namespace = PluginUtility::PLUGIN_BASE_NAME)
8504fd306cSNickeau    {
8604fd306cSNickeau        global $conf;
8704fd306cSNickeau        if ($namespace !== null) {
8804fd306cSNickeau
89*6b325b4bSgerardnico            $namespace = $conf['plugin'][$namespace] ?? null;
90*6b325b4bSgerardnico            if ($namespace === null) {
91*6b325b4bSgerardnico                return $defaultValue;
92*6b325b4bSgerardnico            }
93*6b325b4bSgerardnico            $value = $conf['plugin'][$namespace][$confName] ?? null;
94*6b325b4bSgerardnico
9504fd306cSNickeau        } else {
96*6b325b4bSgerardnico
97*6b325b4bSgerardnico            $value = $conf[$confName] ?? null;
98*6b325b4bSgerardnico
9904fd306cSNickeau        }
10004fd306cSNickeau        if (DataType::isBoolean($value)) {
10104fd306cSNickeau            /**
10204fd306cSNickeau             * Because the next line
10304fd306cSNickeau             * `trim($value) === ""`
10404fd306cSNickeau             * is true for a false value
10504fd306cSNickeau             */
10604fd306cSNickeau            return $value;
10704fd306cSNickeau        }
10804fd306cSNickeau        if ($value === null || trim($value) === "") {
10904fd306cSNickeau            return $defaultValue;
11004fd306cSNickeau        }
11104fd306cSNickeau        return $value;
11204fd306cSNickeau    }
11304fd306cSNickeau
11404fd306cSNickeau
11504fd306cSNickeau    /**
11604fd306cSNickeau     * @param string $key
11704fd306cSNickeau     * @param $value
11804fd306cSNickeau     * @param string|null $pluginNamespace - null for the global namespace
11904fd306cSNickeau     * @return $this
12004fd306cSNickeau     */
12104fd306cSNickeau    public function setConf(string $key, $value, ?string $pluginNamespace = PluginUtility::PLUGIN_BASE_NAME): SiteConfig
12204fd306cSNickeau    {
12304fd306cSNickeau        /**
12404fd306cSNickeau         * Environment within dokuwiki is a global variable
12504fd306cSNickeau         *
12604fd306cSNickeau         * We set it the global variable
12704fd306cSNickeau         *
12804fd306cSNickeau         * but we capture it {@link ExecutionContext::$capturedConf}
12904fd306cSNickeau         * to restore it when the execution context os {@link ExecutionContext::close()}
13004fd306cSNickeau         */
13104fd306cSNickeau        $globalKey = "$pluginNamespace:$key";
13204fd306cSNickeau        if (!isset($this->configurationValuesToRestore[$globalKey])) {
13304fd306cSNickeau            $oldValue = self::getConfValue($key, $value, $pluginNamespace);
13404fd306cSNickeau            $this->configurationValuesToRestore[$globalKey] = $oldValue;
13504fd306cSNickeau        }
13604fd306cSNickeau        Site::setConf($key, $value, $pluginNamespace);
13704fd306cSNickeau        return $this;
13804fd306cSNickeau    }
13904fd306cSNickeau
14004fd306cSNickeau    /**
14104fd306cSNickeau     * Restore the configuration
14204fd306cSNickeau     * as it was when php started
14304fd306cSNickeau     * @return void
14404fd306cSNickeau     */
14504fd306cSNickeau    public function restoreConfigState()
14604fd306cSNickeau    {
14704fd306cSNickeau
14804fd306cSNickeau        foreach ($this->configurationValuesToRestore as $guid => $value) {
14904fd306cSNickeau            [$plugin, $confKey] = explode(":", $guid);
15004fd306cSNickeau            Site::setConf($confKey, $value, $plugin);
15104fd306cSNickeau        }
15204fd306cSNickeau    }
15304fd306cSNickeau
15404fd306cSNickeau    public function setDisableThemeSystem(): SiteConfig
15504fd306cSNickeau    {
15604fd306cSNickeau        $this->setConf(self::CONF_ENABLE_THEME_SYSTEM, 0);
15704fd306cSNickeau        return $this;
15804fd306cSNickeau    }
15904fd306cSNickeau
16004fd306cSNickeau    public function isThemeSystemEnabled(): bool
16104fd306cSNickeau    {
16204fd306cSNickeau        return $this->getBooleanValue(self::CONF_ENABLE_THEME_SYSTEM, self::CONF_ENABLE_THEME_SYSTEM_DEFAULT);
16304fd306cSNickeau    }
16404fd306cSNickeau
16504fd306cSNickeau    public function getValue(string $key, ?string $default = null, ?string $scope = PluginUtility::PLUGIN_BASE_NAME)
16604fd306cSNickeau    {
16704fd306cSNickeau        return self::getConfValue($key, $default, $scope);
16804fd306cSNickeau    }
16904fd306cSNickeau
17004fd306cSNickeau    /**
17104fd306cSNickeau     * @param string $key
17204fd306cSNickeau     * @param int $default - the default value (1=true,0=false in the dokuwiki config system)
17304fd306cSNickeau     * @return bool
17404fd306cSNickeau     */
17504fd306cSNickeau    public function getBooleanValue(string $key, int $default): bool
17604fd306cSNickeau    {
17704fd306cSNickeau        $value = $this->getValue($key, $default);
17804fd306cSNickeau        /**
17904fd306cSNickeau         * Boolean in config is normally the value 1
18004fd306cSNickeau         */
18104fd306cSNickeau        return DataType::toBoolean($value);
18204fd306cSNickeau    }
18304fd306cSNickeau
18404fd306cSNickeau    public function setCacheXhtmlOn()
18504fd306cSNickeau    {
18604fd306cSNickeau        // ensure the value is not -1, which disables caching
18704fd306cSNickeau        // https://www.dokuwiki.org/config:cachetime
18804fd306cSNickeau
18904fd306cSNickeau        $this->setConf('cachetime', 60 * 60, null);
19004fd306cSNickeau        return $this;
19104fd306cSNickeau    }
19204fd306cSNickeau
19304fd306cSNickeau    public function setConsoleOn(): SiteConfig
19404fd306cSNickeau    {
19504fd306cSNickeau        $this->setConf('console', 1);
19604fd306cSNickeau        return $this;
19704fd306cSNickeau    }
19804fd306cSNickeau
19904fd306cSNickeau    public function isConsoleOn(): bool
20004fd306cSNickeau    {
20104fd306cSNickeau        return $this->getBooleanValue('console', 0);
20204fd306cSNickeau    }
20304fd306cSNickeau
20404fd306cSNickeau    public function getExecutionContext(): ExecutionContext
20504fd306cSNickeau    {
20604fd306cSNickeau        return $this->executionContext;
20704fd306cSNickeau    }
20804fd306cSNickeau
20904fd306cSNickeau    public function setConsoleOff(): SiteConfig
21004fd306cSNickeau    {
21104fd306cSNickeau        $this->setConf('console', 0);
21204fd306cSNickeau        return $this;
21304fd306cSNickeau    }
21404fd306cSNickeau
21504fd306cSNickeau    public function setLogExceptionToError(): SiteConfig
21604fd306cSNickeau    {
21704fd306cSNickeau        $this->setLogExceptionLevel(LogUtility::LVL_MSG_ERROR);
21804fd306cSNickeau        return $this;
21904fd306cSNickeau    }
22004fd306cSNickeau
22104fd306cSNickeau    public function setDisableLogException(): SiteConfig
22204fd306cSNickeau    {
22304fd306cSNickeau        $this->setLogExceptionLevel(LogUtility::LVL_MSG_ABOVE_ERROR);
22404fd306cSNickeau        return $this;
22504fd306cSNickeau    }
22604fd306cSNickeau
22704fd306cSNickeau    public function setLogExceptionLevel(int $level): SiteConfig
22804fd306cSNickeau    {
22904fd306cSNickeau        $this->setConf(self::LOG_EXCEPTION_LEVEL, $level);
23004fd306cSNickeau        return $this;
23104fd306cSNickeau    }
23204fd306cSNickeau
23304fd306cSNickeau    public function getLogExceptionLevel(): int
23404fd306cSNickeau    {
23504fd306cSNickeau        return $this->getValue(self::LOG_EXCEPTION_LEVEL, LogUtility::DEFAULT_THROW_LEVEL);
23604fd306cSNickeau    }
23704fd306cSNickeau
23804fd306cSNickeau    /**
23904fd306cSNickeau     * @throws ExceptionNotFound
24004fd306cSNickeau     */
24104fd306cSNickeau    public function getRemFontSize(): int
24204fd306cSNickeau    {
24304fd306cSNickeau
24404fd306cSNickeau        $value = $this->getValue(self::REM_CONF);
24504fd306cSNickeau        if ($value === null) {
24604fd306cSNickeau            throw new ExceptionNotFound("No rem sized defined");
24704fd306cSNickeau        }
24804fd306cSNickeau        try {
24904fd306cSNickeau            return DataType::toInteger($value);
25004fd306cSNickeau        } catch (ExceptionCompile $e) {
25104fd306cSNickeau            $message = "The rem configuration value ($value) is not a integer. Error: {$e->getMessage()}";
25204fd306cSNickeau            LogUtility::msg($message);
25304fd306cSNickeau            throw new ExceptionNotFound($message);
25404fd306cSNickeau        }
25504fd306cSNickeau
25604fd306cSNickeau    }
25704fd306cSNickeau
25804fd306cSNickeau    public function setDefaultContextPath(WikiPath $contextPath)
25904fd306cSNickeau    {
26004fd306cSNickeau        $this->defaultContextPath = $contextPath;
26104fd306cSNickeau        if (FileSystems::isDirectory($this->defaultContextPath)) {
26204fd306cSNickeau            /**
26304fd306cSNickeau             * Not a directory.
26404fd306cSNickeau             *
26504fd306cSNickeau             * If the link or path is the empty path, the path is not the directory
26604fd306cSNickeau             * but the actual markup
26704fd306cSNickeau             */
26804fd306cSNickeau            throw new ExceptionRuntimeInternal("The path ($contextPath) should not be a namespace path");
26904fd306cSNickeau        }
27004fd306cSNickeau        return $this;
27104fd306cSNickeau    }
27204fd306cSNickeau
27304fd306cSNickeau    /**
27404fd306cSNickeau     * @return WikiPath - the default context path is if not set the root page
27504fd306cSNickeau     */
27604fd306cSNickeau    public function getDefaultContextPath(): WikiPath
27704fd306cSNickeau    {
27804fd306cSNickeau        if (isset($this->defaultContextPath)) {
27904fd306cSNickeau            return $this->defaultContextPath;
28004fd306cSNickeau        }
28104fd306cSNickeau        // in a admin or dynamic rendering
28204fd306cSNickeau        // dokuwiki may have set a $ID
28304fd306cSNickeau        global $ID;
28404fd306cSNickeau        if (isset($ID)) {
28504fd306cSNickeau            return WikiPath::createMarkupPathFromId($ID);
28604fd306cSNickeau        }
28704fd306cSNickeau        return WikiPath::createRootNamespacePathOnMarkupDrive()->resolve(Site::getIndexPageName() . "." . WikiPath::MARKUP_DEFAULT_TXT_EXTENSION);
28804fd306cSNickeau    }
28904fd306cSNickeau
29004fd306cSNickeau    public function getHtmlMaxInlineResourceSize()
29104fd306cSNickeau    {
29204fd306cSNickeau        try {
29304fd306cSNickeau            return DataType::toInteger($this->getValue(SiteConfig::HTML_MAX_KB_SIZE_FOR_INLINE_ELEMENT, self::HTML_MAX_KB_SIZE_FOR_INLINE_ELEMENT_DEFAULT)) * 1024;
29404fd306cSNickeau        } catch (ExceptionBadArgument $e) {
29504fd306cSNickeau            LogUtility::internalError("Max in line size error.", self::CANONICAL, $e);
29604fd306cSNickeau            return self::HTML_MAX_KB_SIZE_FOR_INLINE_ELEMENT_DEFAULT * 1024;
29704fd306cSNickeau        }
29804fd306cSNickeau    }
29904fd306cSNickeau
30004fd306cSNickeau    public function setHtmlMaxInlineResourceSize(int $kbSize): SiteConfig
30104fd306cSNickeau    {
30204fd306cSNickeau        $this->setConf(SiteConfig::HTML_MAX_KB_SIZE_FOR_INLINE_ELEMENT, $kbSize);
30304fd306cSNickeau        return $this;
30404fd306cSNickeau    }
30504fd306cSNickeau
30604fd306cSNickeau    public function setDisableHeadingSectionEditing(): SiteConfig
30704fd306cSNickeau    {
30804fd306cSNickeau        $this->setConf('maxseclevel', 0, null);
30904fd306cSNickeau        return $this;
31004fd306cSNickeau    }
31104fd306cSNickeau
31204fd306cSNickeau    public function setHtmlEnableAlwaysInlineLocalJavascript(): SiteConfig
31304fd306cSNickeau    {
31404fd306cSNickeau        $this->setConf(self::HTML_ALWAYS_INLINE_LOCAL_JAVASCRIPT, 1);
31504fd306cSNickeau        return $this;
31604fd306cSNickeau    }
31704fd306cSNickeau
31804fd306cSNickeau    public function setHtmlDisableAlwaysInlineLocalJavascript(): SiteConfig
31904fd306cSNickeau    {
32004fd306cSNickeau        $this->setConf(self::HTML_ALWAYS_INLINE_LOCAL_JAVASCRIPT, 0);
32104fd306cSNickeau        return $this;
32204fd306cSNickeau    }
32304fd306cSNickeau
32404fd306cSNickeau    public function isLocalJavascriptAlwaysInlined(): bool
32504fd306cSNickeau    {
32604fd306cSNickeau        return $this->getBooleanValue(self::HTML_ALWAYS_INLINE_LOCAL_JAVASCRIPT, 0);
32704fd306cSNickeau    }
32804fd306cSNickeau
32904fd306cSNickeau
33004fd306cSNickeau    public function disableLazyLoad(): SiteConfig
33104fd306cSNickeau    {
33204fd306cSNickeau        return $this->setConf(SvgImageLink::CONF_LAZY_LOAD_ENABLE, 0)
33304fd306cSNickeau            ->setConf(LazyLoad::CONF_RASTER_ENABLE, 0);
33404fd306cSNickeau
33504fd306cSNickeau    }
33604fd306cSNickeau
33704fd306cSNickeau    public function setUseHeadingAsTitle(): SiteConfig
33804fd306cSNickeau    {
33904fd306cSNickeau        return $this->setConf('useheading', 1, self::GLOBAL_SCOPE);
34004fd306cSNickeau    }
34104fd306cSNickeau
34204fd306cSNickeau    public function setEnableSectionEditing(): SiteConfig
34304fd306cSNickeau    {
34404fd306cSNickeau        return $this->setConf('maxseclevel', 999, self::GLOBAL_SCOPE);
34504fd306cSNickeau    }
34604fd306cSNickeau
34704fd306cSNickeau    public function isSectionEditingEnabled(): bool
34804fd306cSNickeau    {
34904fd306cSNickeau        return $this->getTocMaxLevel() > 0;
35004fd306cSNickeau    }
35104fd306cSNickeau
35204fd306cSNickeau    public function getTocMaxLevel(): int
35304fd306cSNickeau    {
35404fd306cSNickeau        $value = $this->getValue('maxseclevel', null, self::GLOBAL_SCOPE);
35504fd306cSNickeau        try {
35604fd306cSNickeau            return DataType::toInteger($value);
35704fd306cSNickeau        } catch (ExceptionBadArgument $e) {
35804fd306cSNickeau            LogUtility::internalError("Unable to the the maxseclevel as integer. Error: {$e->getMessage()}", Toc::CANONICAL);
35904fd306cSNickeau            return 0;
36004fd306cSNickeau        }
36104fd306cSNickeau    }
36204fd306cSNickeau
36304fd306cSNickeau    public function setTocMinHeading(int $int): SiteConfig
36404fd306cSNickeau    {
36504fd306cSNickeau        return $this->setConf('tocminheads', $int, self::GLOBAL_SCOPE);
36604fd306cSNickeau    }
36704fd306cSNickeau
36804fd306cSNickeau    public function getIndexPageName()
36904fd306cSNickeau    {
37004fd306cSNickeau        return $this->getValue("start", self::CONF_DEFAULT_INDEX_NAME, self::GLOBAL_SCOPE);
37104fd306cSNickeau    }
37204fd306cSNickeau
37304fd306cSNickeau    public function getAuthorizedUrlSchemes(): ?array
37404fd306cSNickeau    {
37504fd306cSNickeau        if (isset($this->authorizedUrlSchemes)) {
37604fd306cSNickeau            return $this->authorizedUrlSchemes;
37704fd306cSNickeau        }
37804fd306cSNickeau        $this->authorizedUrlSchemes = getSchemes();
37904fd306cSNickeau        $this->authorizedUrlSchemes[] = "whatsapp";
38004fd306cSNickeau        $this->authorizedUrlSchemes[] = "mailto";
38104fd306cSNickeau        return $this->authorizedUrlSchemes;
38204fd306cSNickeau    }
38304fd306cSNickeau
38404fd306cSNickeau    public function getInterWikis(): array
38504fd306cSNickeau    {
38604fd306cSNickeau        $this->loadInterWikiIfNeeded();
38704fd306cSNickeau        return $this->interWikis;
38804fd306cSNickeau    }
38904fd306cSNickeau
39004fd306cSNickeau    public function addInterWiki(string $name, string $value): SiteConfig
39104fd306cSNickeau    {
39204fd306cSNickeau        $this->loadInterWikiIfNeeded();
39304fd306cSNickeau        $this->interWikis[$name] = $value;
39404fd306cSNickeau        return $this;
39504fd306cSNickeau    }
39604fd306cSNickeau
39704fd306cSNickeau    private function loadInterWikiIfNeeded(): void
39804fd306cSNickeau    {
39904fd306cSNickeau        if (isset($this->interWikis)) {
40004fd306cSNickeau            return;
40104fd306cSNickeau        }
40204fd306cSNickeau        $this->interWikis = getInterwiki();
40304fd306cSNickeau    }
40404fd306cSNickeau
40504fd306cSNickeau    public function setTocTopLevel(int $int): SiteConfig
40604fd306cSNickeau    {
40704fd306cSNickeau        return $this->setConf('toptoclevel', $int, self::GLOBAL_SCOPE);
40804fd306cSNickeau    }
40904fd306cSNickeau
41004fd306cSNickeau    public function getMetaDataDirectory(): LocalPath
41104fd306cSNickeau    {
41204fd306cSNickeau        $metadataDirectory = $this->getValue('metadir', null, self::GLOBAL_SCOPE);
41304fd306cSNickeau        if ($metadataDirectory === null) {
41404fd306cSNickeau            throw new ExceptionRuntime("The meta directory configuration value ('metadir') is null");
41504fd306cSNickeau        }
41604fd306cSNickeau        return LocalPath::createFromPathString($metadataDirectory);
41704fd306cSNickeau    }
41804fd306cSNickeau
41904fd306cSNickeau    public function setCanonicalUrlType(string $value): SiteConfig
42004fd306cSNickeau    {
42104fd306cSNickeau        return $this->setConf(PageUrlType::CONF_CANONICAL_URL_TYPE, $value);
42204fd306cSNickeau    }
42304fd306cSNickeau
42404fd306cSNickeau    public function setEnableTheming(): SiteConfig
42504fd306cSNickeau    {
42604fd306cSNickeau        $this->setConf(SiteConfig::CONF_ENABLE_THEME_SYSTEM, 1);
42704fd306cSNickeau        return $this;
42804fd306cSNickeau    }
42904fd306cSNickeau
43004fd306cSNickeau    public function getTheme(): string
43104fd306cSNickeau    {
43204fd306cSNickeau        return $this->getValue(TemplateEngine::CONF_THEME, TemplateEngine::CONF_THEME_DEFAULT);
43304fd306cSNickeau    }
43404fd306cSNickeau
43504fd306cSNickeau    /**
43604fd306cSNickeau     * Note: in test to speed the test execution,
43704fd306cSNickeau     * the default is set to {@link PageTemplateName::BLANK_TEMPLATE_VALUE}
43804fd306cSNickeau     */
43904fd306cSNickeau    public function getDefaultLayoutName()
44004fd306cSNickeau    {
44104fd306cSNickeau        return $this->getValue(PageTemplateName::CONF_DEFAULT_NAME, PageTemplateName::HOLY_TEMPLATE_VALUE);
44204fd306cSNickeau    }
44304fd306cSNickeau
44404fd306cSNickeau    public function setEnableThemeSystem(): SiteConfig
44504fd306cSNickeau    {
44604fd306cSNickeau        // this is the default but yeah
44704fd306cSNickeau        $this->setConf(self::CONF_ENABLE_THEME_SYSTEM, 1);
44804fd306cSNickeau        return $this;
44904fd306cSNickeau    }
45004fd306cSNickeau
45104fd306cSNickeau    /**
45204fd306cSNickeau     * DokuRewrite
45304fd306cSNickeau     * `doku.php/id/...`
45404fd306cSNickeau     * https://www.dokuwiki.org/config:userewrite
45504fd306cSNickeau     * @return $this
45604fd306cSNickeau     */
45704fd306cSNickeau    public function setUrlRewriteToDoku(): SiteConfig
45804fd306cSNickeau    {
45904fd306cSNickeau        $this->setConf('userewrite', '2', self::GLOBAL_SCOPE);
46004fd306cSNickeau        return $this;
46104fd306cSNickeau    }
46204fd306cSNickeau
46304fd306cSNickeau    /**
46404fd306cSNickeau     * Web server rewrite (Apache rewrite (htaccess), Nginx)
46504fd306cSNickeau     * https://www.dokuwiki.org/config:userewrite
46604fd306cSNickeau     * @return $this
46704fd306cSNickeau     */
46804fd306cSNickeau    public function setUrlRewriteToWebServer(): SiteConfig
46904fd306cSNickeau    {
47004fd306cSNickeau        $this->setConf('userewrite', '1', self::GLOBAL_SCOPE);
47104fd306cSNickeau        return $this;
47204fd306cSNickeau    }
47304fd306cSNickeau
47404fd306cSNickeau    public function getRemFontSizeOrDefault(): int
47504fd306cSNickeau    {
47604fd306cSNickeau        try {
47704fd306cSNickeau            return $this->getRemFontSize();
47804fd306cSNickeau        } catch (ExceptionNotFound $e) {
47904fd306cSNickeau            return 16;
48004fd306cSNickeau        }
48104fd306cSNickeau    }
48204fd306cSNickeau
48304fd306cSNickeau    public function getDataDirectory(): LocalPath
48404fd306cSNickeau    {
48504fd306cSNickeau        global $conf;
48604fd306cSNickeau        $dataDirectory = $conf['savedir'];
48704fd306cSNickeau        if ($dataDirectory === null) {
48804fd306cSNickeau            throw new ExceptionRuntime("The data directory ($dataDirectory) is null");
48904fd306cSNickeau        }
49004fd306cSNickeau        return LocalPath::createFromPathString($dataDirectory);
49104fd306cSNickeau    }
49204fd306cSNickeau
49304fd306cSNickeau    public function setTheme(string $themeName): SiteConfig
49404fd306cSNickeau    {
49504fd306cSNickeau        $this->setConf(TemplateEngine::CONF_THEME, $themeName);
49604fd306cSNickeau        return $this;
49704fd306cSNickeau    }
49804fd306cSNickeau
49904fd306cSNickeau    public function getPageHeaderSlotName()
50004fd306cSNickeau    {
50104fd306cSNickeau        return $this->getValue(TemplateSlot::CONF_PAGE_HEADER_NAME, TemplateSlot::CONF_PAGE_HEADER_NAME_DEFAULT);
50204fd306cSNickeau    }
50304fd306cSNickeau
50404fd306cSNickeau    public function setConfDokuWiki(string $key, $value): SiteConfig
50504fd306cSNickeau    {
50604fd306cSNickeau        return $this->setConf($key, $value, self::GLOBAL_SCOPE);
50704fd306cSNickeau    }
50804fd306cSNickeau
50904fd306cSNickeau    /**
51004fd306cSNickeau     * @throws ExceptionNotFound
51104fd306cSNickeau     */
51204fd306cSNickeau    public function getPrimaryColor(): ColorRgb
51304fd306cSNickeau    {
51404fd306cSNickeau        $value = Site::getPrimaryColorValue();
51504fd306cSNickeau        if (
51604fd306cSNickeau            $value === null ||
51704fd306cSNickeau            (trim($value) === "")) {
51804fd306cSNickeau            throw new ExceptionNotFound();
51904fd306cSNickeau        }
52004fd306cSNickeau        try {
52104fd306cSNickeau            return ColorRgb::createFromString($value);
52204fd306cSNickeau        } catch (ExceptionCompile $e) {
52304fd306cSNickeau            LogUtility::msg("The primary color value configuration ($value) is not valid. Error: {$e->getMessage()}");
52404fd306cSNickeau            throw new ExceptionNotFound();
52504fd306cSNickeau        }
52604fd306cSNickeau    }
52704fd306cSNickeau
52804fd306cSNickeau    public function setPrimaryColor(string $primaryColorValue): SiteConfig
52904fd306cSNickeau    {
53004fd306cSNickeau        self::setConf(BrandingColors::PRIMARY_COLOR_CONF, $primaryColorValue);
53104fd306cSNickeau        return $this;
53204fd306cSNickeau    }
53304fd306cSNickeau
53404fd306cSNickeau    public function getPrimaryColorOrDefault(string $defaultColor): ColorRgb
53504fd306cSNickeau    {
53604fd306cSNickeau        try {
53704fd306cSNickeau            return $this->getPrimaryColor();
53804fd306cSNickeau        } catch (ExceptionNotFound $e) {
53904fd306cSNickeau            try {
54004fd306cSNickeau                return ColorRgb::createFromString($defaultColor);
54104fd306cSNickeau            } catch (ExceptionBadArgument $e) {
54204fd306cSNickeau                LogUtility::internalError("The default color $defaultColor is not a color string.", self::CANONICAL, $e);
54304fd306cSNickeau                return ColorRgb::getDefaultPrimary();
54404fd306cSNickeau            }
54504fd306cSNickeau        }
54604fd306cSNickeau    }
54704fd306cSNickeau
54804fd306cSNickeau    public function isBrandingColorInheritanceEnabled(): bool
54904fd306cSNickeau    {
55004fd306cSNickeau        return $this->getValue(BrandingColors::BRANDING_COLOR_INHERITANCE_ENABLE_CONF, BrandingColors::BRANDING_COLOR_INHERITANCE_ENABLE_CONF_DEFAULT) === 1;
55104fd306cSNickeau    }
55204fd306cSNickeau
55304fd306cSNickeau    /**
55404fd306cSNickeau     * @throws ExceptionNotFound
55504fd306cSNickeau     */
55604fd306cSNickeau    public function getSecondaryColor(): ColorRgb
55704fd306cSNickeau    {
55804fd306cSNickeau        $secondaryColor = Site::getSecondaryColor();
55904fd306cSNickeau        if ($secondaryColor === null) {
56004fd306cSNickeau            throw new ExceptionNotFound();
56104fd306cSNickeau        }
56204fd306cSNickeau        return $secondaryColor;
56304fd306cSNickeau    }
56404fd306cSNickeau
56504fd306cSNickeau    public function isXhtmlCacheOn(): bool
56604fd306cSNickeau    {
56704fd306cSNickeau        global $conf;
56804fd306cSNickeau        return $conf['cachetime'] !== -1;
56904fd306cSNickeau    }
57004fd306cSNickeau
57104fd306cSNickeau
57204fd306cSNickeau}
573