xref: /plugin/combo/ComboStrap/SiteConfig.php (revision 04fd306c7c155fa133ebb3669986875d65988276)
1*04fd306cSNickeau<?php
2*04fd306cSNickeau
3*04fd306cSNickeaunamespace ComboStrap;
4*04fd306cSNickeau
5*04fd306cSNickeau
6*04fd306cSNickeauuse ComboStrap\Meta\Field\PageTemplateName;
7*04fd306cSNickeauuse dokuwiki\Extension\PluginTrait;
8*04fd306cSNickeau
9*04fd306cSNickeauclass SiteConfig
10*04fd306cSNickeau{
11*04fd306cSNickeau    const LOG_EXCEPTION_LEVEL = 'log-exception-level';
12*04fd306cSNickeau
13*04fd306cSNickeau    /**
14*04fd306cSNickeau     * A configuration to enable the theme/template system
15*04fd306cSNickeau     */
16*04fd306cSNickeau    public const CONF_ENABLE_THEME_SYSTEM = "combo-conf-001";
17*04fd306cSNickeau    public const CONF_ENABLE_THEME_SYSTEM_DEFAULT = 1;
18*04fd306cSNickeau
19*04fd306cSNickeau    /**
20*04fd306cSNickeau     * The default font-size for the pages
21*04fd306cSNickeau     */
22*04fd306cSNickeau    const REM_CONF = "combo-conf-002";
23*04fd306cSNickeau    const REM_CANONICAL = "rfs";
24*04fd306cSNickeau
25*04fd306cSNickeau    /**
26*04fd306cSNickeau     * The maximum size to be embedded
27*04fd306cSNickeau     * Above this size limit they are fetched
28*04fd306cSNickeau     *
29*04fd306cSNickeau     * 2kb is too small for icon.
30*04fd306cSNickeau     * For instance, the et:twitter is 2,600b
31*04fd306cSNickeau     */
32*04fd306cSNickeau    public const HTML_MAX_KB_SIZE_FOR_INLINE_ELEMENT = "combo-conf-003";
33*04fd306cSNickeau    public const HTML_MAX_KB_SIZE_FOR_INLINE_ELEMENT_DEFAULT = 4;
34*04fd306cSNickeau    /**
35*04fd306cSNickeau     * Private configuration used in test
36*04fd306cSNickeau     * When set to true, all javascript snippet will be inlined
37*04fd306cSNickeau     */
38*04fd306cSNickeau    public const HTML_ALWAYS_INLINE_LOCAL_JAVASCRIPT = "combo-conf-004";
39*04fd306cSNickeau    const CANONICAL = "site-config";
40*04fd306cSNickeau    const GLOBAL_SCOPE = null;
41*04fd306cSNickeau    /**
42*04fd306cSNickeau     * The default name
43*04fd306cSNickeau     */
44*04fd306cSNickeau    public const CONF_DEFAULT_INDEX_NAME = "start";
45*04fd306cSNickeau
46*04fd306cSNickeau
47*04fd306cSNickeau    /**
48*04fd306cSNickeau     * @var WikiPath the {@link self::getContextPath()} when no context could be determined
49*04fd306cSNickeau     */
50*04fd306cSNickeau    private WikiPath $defaultContextPath;
51*04fd306cSNickeau
52*04fd306cSNickeau    /**
53*04fd306cSNickeau     * @var array - the configuration value to restore
54*04fd306cSNickeau     *
55*04fd306cSNickeau     * Note we can't capture the whole global $conf
56*04fd306cSNickeau     * because the configuration are loaded at runtime via {@link PluginTrait::loadConfig()}
57*04fd306cSNickeau     *
58*04fd306cSNickeau     * Meaning that the configuration environment at the start is not fully loaded
59*04fd306cSNickeau     * and does not represent the environment totally
60*04fd306cSNickeau     *
61*04fd306cSNickeau     * We capture then the change and restore them at the end
62*04fd306cSNickeau     */
63*04fd306cSNickeau    private array $configurationValuesToRestore = [];
64*04fd306cSNickeau    private ExecutionContext $executionContext;
65*04fd306cSNickeau    private array $interWikis;
66*04fd306cSNickeau
67*04fd306cSNickeau    /**
68*04fd306cSNickeau     * @param ExecutionContext $executionContext
69*04fd306cSNickeau     */
70*04fd306cSNickeau    public function __construct(ExecutionContext $executionContext)
71*04fd306cSNickeau    {
72*04fd306cSNickeau        $this->executionContext = $executionContext;
73*04fd306cSNickeau    }
74*04fd306cSNickeau
75*04fd306cSNickeau    /**
76*04fd306cSNickeau     * TODO: Default: Note that the config of plugin are loaded
77*04fd306cSNickeau     *   via {@link PluginTrait::loadConfig()}
78*04fd306cSNickeau     *   when {@link PluginTrait::getConf()} is used
79*04fd306cSNickeau     *   Therefore whenever possible, for now {@link PluginTrait::getConf()}
80*04fd306cSNickeau     *   should be used otherwise, there is no default
81*04fd306cSNickeau     *   Or best, the default should be also in the code
82*04fd306cSNickeau     *
83*04fd306cSNickeau     */
84*04fd306cSNickeau    public static function getConfValue($confName, $defaultValue = null, ?string $namespace = PluginUtility::PLUGIN_BASE_NAME)
85*04fd306cSNickeau    {
86*04fd306cSNickeau        global $conf;
87*04fd306cSNickeau        if ($namespace !== null) {
88*04fd306cSNickeau
89*04fd306cSNickeau            $value = $conf['plugin'][$namespace][$confName];
90*04fd306cSNickeau        } else {
91*04fd306cSNickeau            $value = $conf[$confName];
92*04fd306cSNickeau        }
93*04fd306cSNickeau        if(DataType::isBoolean($value)){
94*04fd306cSNickeau            /**
95*04fd306cSNickeau             * Because the next line
96*04fd306cSNickeau             * `trim($value) === ""`
97*04fd306cSNickeau             * is true for a false value
98*04fd306cSNickeau             */
99*04fd306cSNickeau            return $value;
100*04fd306cSNickeau        }
101*04fd306cSNickeau        if ($value === null || trim($value) === "") {
102*04fd306cSNickeau            return $defaultValue;
103*04fd306cSNickeau        }
104*04fd306cSNickeau        return $value;
105*04fd306cSNickeau    }
106*04fd306cSNickeau
107*04fd306cSNickeau
108*04fd306cSNickeau    /**
109*04fd306cSNickeau     * @param string $key
110*04fd306cSNickeau     * @param $value
111*04fd306cSNickeau     * @param string|null $pluginNamespace - null for the global namespace
112*04fd306cSNickeau     * @return $this
113*04fd306cSNickeau     */
114*04fd306cSNickeau    public function setConf(string $key, $value, ?string $pluginNamespace = PluginUtility::PLUGIN_BASE_NAME): SiteConfig
115*04fd306cSNickeau    {
116*04fd306cSNickeau        /**
117*04fd306cSNickeau         * Environment within dokuwiki is a global variable
118*04fd306cSNickeau         *
119*04fd306cSNickeau         * We set it the global variable
120*04fd306cSNickeau         *
121*04fd306cSNickeau         * but we capture it {@link ExecutionContext::$capturedConf}
122*04fd306cSNickeau         * to restore it when the execution context os {@link ExecutionContext::close()}
123*04fd306cSNickeau         */
124*04fd306cSNickeau        $globalKey = "$pluginNamespace:$key";
125*04fd306cSNickeau        if (!isset($this->configurationValuesToRestore[$globalKey])) {
126*04fd306cSNickeau            $oldValue = self::getConfValue($key, $value, $pluginNamespace);
127*04fd306cSNickeau            $this->configurationValuesToRestore[$globalKey] = $oldValue;
128*04fd306cSNickeau        }
129*04fd306cSNickeau        Site::setConf($key, $value, $pluginNamespace);
130*04fd306cSNickeau        return $this;
131*04fd306cSNickeau    }
132*04fd306cSNickeau
133*04fd306cSNickeau    /**
134*04fd306cSNickeau     * Restore the configuration
135*04fd306cSNickeau     * as it was when php started
136*04fd306cSNickeau     * @return void
137*04fd306cSNickeau     */
138*04fd306cSNickeau    public function restoreConfigState()
139*04fd306cSNickeau    {
140*04fd306cSNickeau
141*04fd306cSNickeau        foreach ($this->configurationValuesToRestore as $guid => $value) {
142*04fd306cSNickeau            [$plugin, $confKey] = explode(":", $guid);
143*04fd306cSNickeau            Site::setConf($confKey, $value, $plugin);
144*04fd306cSNickeau        }
145*04fd306cSNickeau    }
146*04fd306cSNickeau
147*04fd306cSNickeau    public function setDisableThemeSystem(): SiteConfig
148*04fd306cSNickeau    {
149*04fd306cSNickeau        $this->setConf(self::CONF_ENABLE_THEME_SYSTEM, 0);
150*04fd306cSNickeau        return $this;
151*04fd306cSNickeau    }
152*04fd306cSNickeau
153*04fd306cSNickeau    public function isThemeSystemEnabled(): bool
154*04fd306cSNickeau    {
155*04fd306cSNickeau        return $this->getBooleanValue(self::CONF_ENABLE_THEME_SYSTEM, self::CONF_ENABLE_THEME_SYSTEM_DEFAULT);
156*04fd306cSNickeau    }
157*04fd306cSNickeau
158*04fd306cSNickeau    public function getValue(string $key, ?string $default = null, ?string $scope = PluginUtility::PLUGIN_BASE_NAME)
159*04fd306cSNickeau    {
160*04fd306cSNickeau        return self::getConfValue($key, $default, $scope);
161*04fd306cSNickeau    }
162*04fd306cSNickeau
163*04fd306cSNickeau    /**
164*04fd306cSNickeau     * @param string $key
165*04fd306cSNickeau     * @param int $default - the default value (1=true,0=false in the dokuwiki config system)
166*04fd306cSNickeau     * @return bool
167*04fd306cSNickeau     */
168*04fd306cSNickeau    public function getBooleanValue(string $key, int $default): bool
169*04fd306cSNickeau    {
170*04fd306cSNickeau        $value = $this->getValue($key, $default);
171*04fd306cSNickeau        /**
172*04fd306cSNickeau         * Boolean in config is normally the value 1
173*04fd306cSNickeau         */
174*04fd306cSNickeau        return DataType::toBoolean($value);
175*04fd306cSNickeau    }
176*04fd306cSNickeau
177*04fd306cSNickeau    public function setCacheXhtmlOn()
178*04fd306cSNickeau    {
179*04fd306cSNickeau        // ensure the value is not -1, which disables caching
180*04fd306cSNickeau        // https://www.dokuwiki.org/config:cachetime
181*04fd306cSNickeau
182*04fd306cSNickeau        $this->setConf('cachetime', 60 * 60, null);
183*04fd306cSNickeau        return $this;
184*04fd306cSNickeau    }
185*04fd306cSNickeau
186*04fd306cSNickeau    public function setConsoleOn(): SiteConfig
187*04fd306cSNickeau    {
188*04fd306cSNickeau        $this->setConf('console', 1);
189*04fd306cSNickeau        return $this;
190*04fd306cSNickeau    }
191*04fd306cSNickeau
192*04fd306cSNickeau    public function isConsoleOn(): bool
193*04fd306cSNickeau    {
194*04fd306cSNickeau        return $this->getBooleanValue('console', 0);
195*04fd306cSNickeau    }
196*04fd306cSNickeau
197*04fd306cSNickeau    public function getExecutionContext(): ExecutionContext
198*04fd306cSNickeau    {
199*04fd306cSNickeau        return $this->executionContext;
200*04fd306cSNickeau    }
201*04fd306cSNickeau
202*04fd306cSNickeau    public function setConsoleOff(): SiteConfig
203*04fd306cSNickeau    {
204*04fd306cSNickeau        $this->setConf('console', 0);
205*04fd306cSNickeau        return $this;
206*04fd306cSNickeau    }
207*04fd306cSNickeau
208*04fd306cSNickeau    public function setLogExceptionToError(): SiteConfig
209*04fd306cSNickeau    {
210*04fd306cSNickeau        $this->setLogExceptionLevel(LogUtility::LVL_MSG_ERROR);
211*04fd306cSNickeau        return $this;
212*04fd306cSNickeau    }
213*04fd306cSNickeau
214*04fd306cSNickeau    public function setDisableLogException(): SiteConfig
215*04fd306cSNickeau    {
216*04fd306cSNickeau        $this->setLogExceptionLevel(LogUtility::LVL_MSG_ABOVE_ERROR);
217*04fd306cSNickeau        return $this;
218*04fd306cSNickeau    }
219*04fd306cSNickeau
220*04fd306cSNickeau    public function setLogExceptionLevel(int $level): SiteConfig
221*04fd306cSNickeau    {
222*04fd306cSNickeau        $this->setConf(self::LOG_EXCEPTION_LEVEL, $level);
223*04fd306cSNickeau        return $this;
224*04fd306cSNickeau    }
225*04fd306cSNickeau
226*04fd306cSNickeau    public function getLogExceptionLevel(): int
227*04fd306cSNickeau    {
228*04fd306cSNickeau        return $this->getValue(self::LOG_EXCEPTION_LEVEL, LogUtility::DEFAULT_THROW_LEVEL);
229*04fd306cSNickeau    }
230*04fd306cSNickeau
231*04fd306cSNickeau    /**
232*04fd306cSNickeau     * @throws ExceptionNotFound
233*04fd306cSNickeau     */
234*04fd306cSNickeau    public function getRemFontSize(): int
235*04fd306cSNickeau    {
236*04fd306cSNickeau
237*04fd306cSNickeau        $value = $this->getValue(self::REM_CONF);
238*04fd306cSNickeau        if ($value === null) {
239*04fd306cSNickeau            throw new ExceptionNotFound("No rem sized defined");
240*04fd306cSNickeau        }
241*04fd306cSNickeau        try {
242*04fd306cSNickeau            return DataType::toInteger($value);
243*04fd306cSNickeau        } catch (ExceptionCompile $e) {
244*04fd306cSNickeau            $message = "The rem configuration value ($value) is not a integer. Error: {$e->getMessage()}";
245*04fd306cSNickeau            LogUtility::msg($message);
246*04fd306cSNickeau            throw new ExceptionNotFound($message);
247*04fd306cSNickeau        }
248*04fd306cSNickeau
249*04fd306cSNickeau    }
250*04fd306cSNickeau
251*04fd306cSNickeau    public function setDefaultContextPath(WikiPath $contextPath)
252*04fd306cSNickeau    {
253*04fd306cSNickeau        $this->defaultContextPath = $contextPath;
254*04fd306cSNickeau        if (FileSystems::isDirectory($this->defaultContextPath)) {
255*04fd306cSNickeau            /**
256*04fd306cSNickeau             * Not a directory.
257*04fd306cSNickeau             *
258*04fd306cSNickeau             * If the link or path is the empty path, the path is not the directory
259*04fd306cSNickeau             * but the actual markup
260*04fd306cSNickeau             */
261*04fd306cSNickeau            throw new ExceptionRuntimeInternal("The path ($contextPath) should not be a namespace path");
262*04fd306cSNickeau        }
263*04fd306cSNickeau        return $this;
264*04fd306cSNickeau    }
265*04fd306cSNickeau
266*04fd306cSNickeau    /**
267*04fd306cSNickeau     * @return WikiPath - the default context path is if not set the root page
268*04fd306cSNickeau     */
269*04fd306cSNickeau    public function getDefaultContextPath(): WikiPath
270*04fd306cSNickeau    {
271*04fd306cSNickeau        if (isset($this->defaultContextPath)) {
272*04fd306cSNickeau            return $this->defaultContextPath;
273*04fd306cSNickeau        }
274*04fd306cSNickeau        // in a admin or dynamic rendering
275*04fd306cSNickeau        // dokuwiki may have set a $ID
276*04fd306cSNickeau        global $ID;
277*04fd306cSNickeau        if (isset($ID)) {
278*04fd306cSNickeau            return WikiPath::createMarkupPathFromId($ID);
279*04fd306cSNickeau        }
280*04fd306cSNickeau        return WikiPath::createRootNamespacePathOnMarkupDrive()->resolve(Site::getIndexPageName() . "." . WikiPath::MARKUP_DEFAULT_TXT_EXTENSION);
281*04fd306cSNickeau    }
282*04fd306cSNickeau
283*04fd306cSNickeau    public function getHtmlMaxInlineResourceSize()
284*04fd306cSNickeau    {
285*04fd306cSNickeau        try {
286*04fd306cSNickeau            return DataType::toInteger($this->getValue(SiteConfig::HTML_MAX_KB_SIZE_FOR_INLINE_ELEMENT, self::HTML_MAX_KB_SIZE_FOR_INLINE_ELEMENT_DEFAULT)) * 1024;
287*04fd306cSNickeau        } catch (ExceptionBadArgument $e) {
288*04fd306cSNickeau            LogUtility::internalError("Max in line size error.", self::CANONICAL, $e);
289*04fd306cSNickeau            return self::HTML_MAX_KB_SIZE_FOR_INLINE_ELEMENT_DEFAULT * 1024;
290*04fd306cSNickeau        }
291*04fd306cSNickeau    }
292*04fd306cSNickeau
293*04fd306cSNickeau    public function setHtmlMaxInlineResourceSize(int $kbSize): SiteConfig
294*04fd306cSNickeau    {
295*04fd306cSNickeau        $this->setConf(SiteConfig::HTML_MAX_KB_SIZE_FOR_INLINE_ELEMENT, $kbSize);
296*04fd306cSNickeau        return $this;
297*04fd306cSNickeau    }
298*04fd306cSNickeau
299*04fd306cSNickeau    public function setDisableHeadingSectionEditing(): SiteConfig
300*04fd306cSNickeau    {
301*04fd306cSNickeau        $this->setConf('maxseclevel', 0, null);
302*04fd306cSNickeau        return $this;
303*04fd306cSNickeau    }
304*04fd306cSNickeau
305*04fd306cSNickeau    public function setHtmlEnableAlwaysInlineLocalJavascript(): SiteConfig
306*04fd306cSNickeau    {
307*04fd306cSNickeau        $this->setConf(self::HTML_ALWAYS_INLINE_LOCAL_JAVASCRIPT, 1);
308*04fd306cSNickeau        return $this;
309*04fd306cSNickeau    }
310*04fd306cSNickeau
311*04fd306cSNickeau    public function setHtmlDisableAlwaysInlineLocalJavascript(): SiteConfig
312*04fd306cSNickeau    {
313*04fd306cSNickeau        $this->setConf(self::HTML_ALWAYS_INLINE_LOCAL_JAVASCRIPT, 0);
314*04fd306cSNickeau        return $this;
315*04fd306cSNickeau    }
316*04fd306cSNickeau
317*04fd306cSNickeau    public function isLocalJavascriptAlwaysInlined(): bool
318*04fd306cSNickeau    {
319*04fd306cSNickeau        return $this->getBooleanValue(self::HTML_ALWAYS_INLINE_LOCAL_JAVASCRIPT, 0);
320*04fd306cSNickeau    }
321*04fd306cSNickeau
322*04fd306cSNickeau
323*04fd306cSNickeau    public function disableLazyLoad(): SiteConfig
324*04fd306cSNickeau    {
325*04fd306cSNickeau        return $this->setConf(SvgImageLink::CONF_LAZY_LOAD_ENABLE, 0)
326*04fd306cSNickeau            ->setConf(LazyLoad::CONF_RASTER_ENABLE, 0);
327*04fd306cSNickeau
328*04fd306cSNickeau    }
329*04fd306cSNickeau
330*04fd306cSNickeau    public function setUseHeadingAsTitle(): SiteConfig
331*04fd306cSNickeau    {
332*04fd306cSNickeau        return $this->setConf('useheading', 1, self::GLOBAL_SCOPE);
333*04fd306cSNickeau    }
334*04fd306cSNickeau
335*04fd306cSNickeau    public function setEnableSectionEditing(): SiteConfig
336*04fd306cSNickeau    {
337*04fd306cSNickeau        return $this->setConf('maxseclevel', 999, self::GLOBAL_SCOPE);
338*04fd306cSNickeau    }
339*04fd306cSNickeau
340*04fd306cSNickeau    public function isSectionEditingEnabled(): bool
341*04fd306cSNickeau    {
342*04fd306cSNickeau        return $this->getTocMaxLevel() > 0;
343*04fd306cSNickeau    }
344*04fd306cSNickeau
345*04fd306cSNickeau    public function getTocMaxLevel(): int
346*04fd306cSNickeau    {
347*04fd306cSNickeau        $value = $this->getValue('maxseclevel', null, self::GLOBAL_SCOPE);
348*04fd306cSNickeau        try {
349*04fd306cSNickeau            return DataType::toInteger($value);
350*04fd306cSNickeau        } catch (ExceptionBadArgument $e) {
351*04fd306cSNickeau            LogUtility::internalError("Unable to the the maxseclevel as integer. Error: {$e->getMessage()}", Toc::CANONICAL);
352*04fd306cSNickeau            return 0;
353*04fd306cSNickeau        }
354*04fd306cSNickeau    }
355*04fd306cSNickeau
356*04fd306cSNickeau    public function setTocMinHeading(int $int): SiteConfig
357*04fd306cSNickeau    {
358*04fd306cSNickeau        return $this->setConf('tocminheads', $int, self::GLOBAL_SCOPE);
359*04fd306cSNickeau    }
360*04fd306cSNickeau
361*04fd306cSNickeau    public function getIndexPageName()
362*04fd306cSNickeau    {
363*04fd306cSNickeau        return $this->getValue("start", self::CONF_DEFAULT_INDEX_NAME, self::GLOBAL_SCOPE);
364*04fd306cSNickeau    }
365*04fd306cSNickeau
366*04fd306cSNickeau    public function getAuthorizedUrlSchemes(): ?array
367*04fd306cSNickeau    {
368*04fd306cSNickeau        if (isset($this->authorizedUrlSchemes)) {
369*04fd306cSNickeau            return $this->authorizedUrlSchemes;
370*04fd306cSNickeau        }
371*04fd306cSNickeau        $this->authorizedUrlSchemes = getSchemes();
372*04fd306cSNickeau        $this->authorizedUrlSchemes[] = "whatsapp";
373*04fd306cSNickeau        $this->authorizedUrlSchemes[] = "mailto";
374*04fd306cSNickeau        return $this->authorizedUrlSchemes;
375*04fd306cSNickeau    }
376*04fd306cSNickeau
377*04fd306cSNickeau    public function getInterWikis(): array
378*04fd306cSNickeau    {
379*04fd306cSNickeau        $this->loadInterWikiIfNeeded();
380*04fd306cSNickeau        return $this->interWikis;
381*04fd306cSNickeau    }
382*04fd306cSNickeau
383*04fd306cSNickeau    public function addInterWiki(string $name, string $value): SiteConfig
384*04fd306cSNickeau    {
385*04fd306cSNickeau        $this->loadInterWikiIfNeeded();
386*04fd306cSNickeau        $this->interWikis[$name] = $value;
387*04fd306cSNickeau        return $this;
388*04fd306cSNickeau    }
389*04fd306cSNickeau
390*04fd306cSNickeau    private function loadInterWikiIfNeeded(): void
391*04fd306cSNickeau    {
392*04fd306cSNickeau        if (isset($this->interWikis)) {
393*04fd306cSNickeau            return;
394*04fd306cSNickeau        }
395*04fd306cSNickeau        $this->interWikis = getInterwiki();
396*04fd306cSNickeau    }
397*04fd306cSNickeau
398*04fd306cSNickeau    public function setTocTopLevel(int $int): SiteConfig
399*04fd306cSNickeau    {
400*04fd306cSNickeau        return $this->setConf('toptoclevel', $int, self::GLOBAL_SCOPE);
401*04fd306cSNickeau    }
402*04fd306cSNickeau
403*04fd306cSNickeau    public function getMetaDataDirectory(): LocalPath
404*04fd306cSNickeau    {
405*04fd306cSNickeau        $metadataDirectory = $this->getValue('metadir', null, self::GLOBAL_SCOPE);
406*04fd306cSNickeau        if ($metadataDirectory === null) {
407*04fd306cSNickeau            throw new ExceptionRuntime("The meta directory configuration value ('metadir') is null");
408*04fd306cSNickeau        }
409*04fd306cSNickeau        return LocalPath::createFromPathString($metadataDirectory);
410*04fd306cSNickeau    }
411*04fd306cSNickeau
412*04fd306cSNickeau    public function setCanonicalUrlType(string $value): SiteConfig
413*04fd306cSNickeau    {
414*04fd306cSNickeau        return $this->setConf(PageUrlType::CONF_CANONICAL_URL_TYPE, $value);
415*04fd306cSNickeau    }
416*04fd306cSNickeau
417*04fd306cSNickeau    public function setEnableTheming(): SiteConfig
418*04fd306cSNickeau    {
419*04fd306cSNickeau        $this->setConf(SiteConfig::CONF_ENABLE_THEME_SYSTEM, 1);
420*04fd306cSNickeau        return $this;
421*04fd306cSNickeau    }
422*04fd306cSNickeau
423*04fd306cSNickeau    public function getTheme(): string
424*04fd306cSNickeau    {
425*04fd306cSNickeau        return $this->getValue(TemplateEngine::CONF_THEME, TemplateEngine::CONF_THEME_DEFAULT);
426*04fd306cSNickeau    }
427*04fd306cSNickeau
428*04fd306cSNickeau    /**
429*04fd306cSNickeau     * Note: in test to speed the test execution,
430*04fd306cSNickeau     * the default is set to {@link PageTemplateName::BLANK_TEMPLATE_VALUE}
431*04fd306cSNickeau     */
432*04fd306cSNickeau    public function getDefaultLayoutName()
433*04fd306cSNickeau    {
434*04fd306cSNickeau        return $this->getValue(PageTemplateName::CONF_DEFAULT_NAME, PageTemplateName::HOLY_TEMPLATE_VALUE);
435*04fd306cSNickeau    }
436*04fd306cSNickeau
437*04fd306cSNickeau    public function setEnableThemeSystem(): SiteConfig
438*04fd306cSNickeau    {
439*04fd306cSNickeau        // this is the default but yeah
440*04fd306cSNickeau        $this->setConf(self::CONF_ENABLE_THEME_SYSTEM, 1);
441*04fd306cSNickeau        return $this;
442*04fd306cSNickeau    }
443*04fd306cSNickeau
444*04fd306cSNickeau    /**
445*04fd306cSNickeau     * DokuRewrite
446*04fd306cSNickeau     * `doku.php/id/...`
447*04fd306cSNickeau     * https://www.dokuwiki.org/config:userewrite
448*04fd306cSNickeau     * @return $this
449*04fd306cSNickeau     */
450*04fd306cSNickeau    public function setUrlRewriteToDoku(): SiteConfig
451*04fd306cSNickeau    {
452*04fd306cSNickeau        $this->setConf('userewrite', '2', self::GLOBAL_SCOPE);
453*04fd306cSNickeau        return $this;
454*04fd306cSNickeau    }
455*04fd306cSNickeau
456*04fd306cSNickeau    /**
457*04fd306cSNickeau     * Web server rewrite (Apache rewrite (htaccess), Nginx)
458*04fd306cSNickeau     * https://www.dokuwiki.org/config:userewrite
459*04fd306cSNickeau     * @return $this
460*04fd306cSNickeau     */
461*04fd306cSNickeau    public function setUrlRewriteToWebServer(): SiteConfig
462*04fd306cSNickeau    {
463*04fd306cSNickeau        $this->setConf('userewrite', '1', self::GLOBAL_SCOPE);
464*04fd306cSNickeau        return $this;
465*04fd306cSNickeau    }
466*04fd306cSNickeau
467*04fd306cSNickeau    public function getRemFontSizeOrDefault(): int
468*04fd306cSNickeau    {
469*04fd306cSNickeau        try {
470*04fd306cSNickeau            return $this->getRemFontSize();
471*04fd306cSNickeau        } catch (ExceptionNotFound $e) {
472*04fd306cSNickeau            return 16;
473*04fd306cSNickeau        }
474*04fd306cSNickeau    }
475*04fd306cSNickeau
476*04fd306cSNickeau    public function getDataDirectory(): LocalPath
477*04fd306cSNickeau    {
478*04fd306cSNickeau        global $conf;
479*04fd306cSNickeau        $dataDirectory = $conf['savedir'];
480*04fd306cSNickeau        if ($dataDirectory === null) {
481*04fd306cSNickeau            throw new ExceptionRuntime("The data directory ($dataDirectory) is null");
482*04fd306cSNickeau        }
483*04fd306cSNickeau        return LocalPath::createFromPathString($dataDirectory);
484*04fd306cSNickeau    }
485*04fd306cSNickeau
486*04fd306cSNickeau    public function setTheme(string $themeName): SiteConfig
487*04fd306cSNickeau    {
488*04fd306cSNickeau        $this->setConf(TemplateEngine::CONF_THEME, $themeName);
489*04fd306cSNickeau        return $this;
490*04fd306cSNickeau    }
491*04fd306cSNickeau
492*04fd306cSNickeau    public function getPageHeaderSlotName()
493*04fd306cSNickeau    {
494*04fd306cSNickeau        return $this->getValue(TemplateSlot::CONF_PAGE_HEADER_NAME, TemplateSlot::CONF_PAGE_HEADER_NAME_DEFAULT);
495*04fd306cSNickeau    }
496*04fd306cSNickeau
497*04fd306cSNickeau    public function setConfDokuWiki(string $key, $value): SiteConfig
498*04fd306cSNickeau    {
499*04fd306cSNickeau        return $this->setConf($key,$value, self::GLOBAL_SCOPE);
500*04fd306cSNickeau    }
501*04fd306cSNickeau
502*04fd306cSNickeau    /**
503*04fd306cSNickeau     * @throws ExceptionNotFound
504*04fd306cSNickeau     */
505*04fd306cSNickeau    public function getPrimaryColor(): ColorRgb
506*04fd306cSNickeau    {
507*04fd306cSNickeau        $value = Site::getPrimaryColorValue();
508*04fd306cSNickeau        if (
509*04fd306cSNickeau            $value === null ||
510*04fd306cSNickeau            (trim($value) === "")) {
511*04fd306cSNickeau            throw new ExceptionNotFound();
512*04fd306cSNickeau        }
513*04fd306cSNickeau        try {
514*04fd306cSNickeau            return ColorRgb::createFromString($value);
515*04fd306cSNickeau        } catch (ExceptionCompile $e) {
516*04fd306cSNickeau            LogUtility::msg("The primary color value configuration ($value) is not valid. Error: {$e->getMessage()}");
517*04fd306cSNickeau            throw new ExceptionNotFound();
518*04fd306cSNickeau        }
519*04fd306cSNickeau    }
520*04fd306cSNickeau
521*04fd306cSNickeau    public function setPrimaryColor(string $primaryColorValue): SiteConfig
522*04fd306cSNickeau    {
523*04fd306cSNickeau        self::setConf(BrandingColors::PRIMARY_COLOR_CONF, $primaryColorValue);
524*04fd306cSNickeau        return $this;
525*04fd306cSNickeau    }
526*04fd306cSNickeau
527*04fd306cSNickeau    public function getPrimaryColorOrDefault(string $defaultColor): ColorRgb
528*04fd306cSNickeau    {
529*04fd306cSNickeau        try {
530*04fd306cSNickeau            return $this->getPrimaryColor();
531*04fd306cSNickeau        } catch (ExceptionNotFound $e) {
532*04fd306cSNickeau            try {
533*04fd306cSNickeau                return ColorRgb::createFromString($defaultColor);
534*04fd306cSNickeau            } catch (ExceptionBadArgument $e) {
535*04fd306cSNickeau                LogUtility::internalError("The default color $defaultColor is not a color string.",self::CANONICAL, $e);
536*04fd306cSNickeau                return ColorRgb::getDefaultPrimary();
537*04fd306cSNickeau            }
538*04fd306cSNickeau        }
539*04fd306cSNickeau    }
540*04fd306cSNickeau
541*04fd306cSNickeau    public function isBrandingColorInheritanceEnabled(): bool
542*04fd306cSNickeau    {
543*04fd306cSNickeau        return $this->getValue(BrandingColors::BRANDING_COLOR_INHERITANCE_ENABLE_CONF, BrandingColors::BRANDING_COLOR_INHERITANCE_ENABLE_CONF_DEFAULT) === 1;
544*04fd306cSNickeau    }
545*04fd306cSNickeau
546*04fd306cSNickeau    /**
547*04fd306cSNickeau     * @throws ExceptionNotFound
548*04fd306cSNickeau     */
549*04fd306cSNickeau    public function getSecondaryColor(): ColorRgb
550*04fd306cSNickeau    {
551*04fd306cSNickeau        $secondaryColor = Site::getSecondaryColor();
552*04fd306cSNickeau        if($secondaryColor===null){
553*04fd306cSNickeau            throw new ExceptionNotFound();
554*04fd306cSNickeau        }
555*04fd306cSNickeau        return $secondaryColor;
556*04fd306cSNickeau    }
557*04fd306cSNickeau
558*04fd306cSNickeau    public function isXhtmlCacheOn(): bool
559*04fd306cSNickeau    {
560*04fd306cSNickeau        global $conf;
561*04fd306cSNickeau        return $conf['cachetime'] !== -1;
562*04fd306cSNickeau    }
563*04fd306cSNickeau
564*04fd306cSNickeau
565*04fd306cSNickeau}
566