xref: /template/strap/ComboStrap/Site.php (revision 4cadd4f8c541149bdda95f080e38a6d4e3a640ca)
137748cd8SNickeau<?php
237748cd8SNickeau/**
337748cd8SNickeau * Copyright (c) 2021. ComboStrap, Inc. and its affiliates. All Rights Reserved.
437748cd8SNickeau *
537748cd8SNickeau * This source code is licensed under the GPL license found in the
637748cd8SNickeau * COPYING  file in the root directory of this source tree.
737748cd8SNickeau *
837748cd8SNickeau * @license  GPL 3 (https://www.gnu.org/licenses/gpl-3.0.en.html)
937748cd8SNickeau * @author   ComboStrap <support@combostrap.com>
1037748cd8SNickeau *
1137748cd8SNickeau */
1237748cd8SNickeau
1337748cd8SNickeaunamespace ComboStrap;
1437748cd8SNickeau
1537748cd8SNickeau
1682a60d03SNickeauuse Exception;
17c3437056SNickeau
1837748cd8SNickeauclass Site
1937748cd8SNickeau{
2037748cd8SNickeau
2137748cd8SNickeau    const STRAP_TEMPLATE_NAME = "strap";
2237748cd8SNickeau
2337748cd8SNickeau    const SVG_LOGO_IDS = array(
2437748cd8SNickeau        ':wiki:logo.svg',
2537748cd8SNickeau        ':logo.svg'
2637748cd8SNickeau    );
2737748cd8SNickeau
2837748cd8SNickeau    const PNG_LOGO_IDS = array(
2937748cd8SNickeau        ':logo.png',
3037748cd8SNickeau        ':wiki:logo.png',
3137748cd8SNickeau        ':favicon-32×32.png',
3237748cd8SNickeau        ':favicon-16×16.png',
3337748cd8SNickeau        ':apple-touch-icon.png',
3437748cd8SNickeau        ':android-chrome-192x192.png'
3537748cd8SNickeau    );
3637748cd8SNickeau
3737748cd8SNickeau
3837748cd8SNickeau    /**
391fa8c418SNickeau     * @return Image[]
401fa8c418SNickeau     */
41*4cadd4f8SNickeau    public static function getLogoImages(): array
4237748cd8SNickeau    {
431fa8c418SNickeau        $logosPaths = PluginUtility::mergeAttributes(self::PNG_LOGO_IDS, self::SVG_LOGO_IDS);
441fa8c418SNickeau        $logos = [];
451fa8c418SNickeau        foreach ($logosPaths as $logoPath) {
46c3437056SNickeau            $dokuPath = DokuPath::createMediaPathFromId($logoPath);
4782a60d03SNickeau            if (FileSystems::exists($dokuPath)) {
4882a60d03SNickeau                try {
49c3437056SNickeau                    $logos[] = Image::createImageFromPath($dokuPath);
5082a60d03SNickeau                } catch (Exception $e) {
5182a60d03SNickeau                    // The image is not valid
5282a60d03SNickeau                    LogUtility::msg("The logo ($logoPath) is not a valid image. {$e->getMessage()}");
5382a60d03SNickeau                }
5482a60d03SNickeau            }
551fa8c418SNickeau        }
561fa8c418SNickeau        return $logos;
5737748cd8SNickeau    }
5837748cd8SNickeau
5937748cd8SNickeau
6037748cd8SNickeau    /**
6137748cd8SNickeau     * @return string|null
6237748cd8SNickeau     */
63*4cadd4f8SNickeau    public static function getLogoUrlAsSvg(): ?string
6437748cd8SNickeau    {
6537748cd8SNickeau
6637748cd8SNickeau
6737748cd8SNickeau        $url = null;
6837748cd8SNickeau        foreach (self::SVG_LOGO_IDS as $svgLogo) {
6937748cd8SNickeau
7037748cd8SNickeau            $svgLogoFN = mediaFN($svgLogo);
7137748cd8SNickeau            if (file_exists($svgLogoFN)) {
7237748cd8SNickeau                $url = ml($svgLogo, '', true, '', true);
7337748cd8SNickeau                break;
74*4cadd4f8SNickeau            }
7537748cd8SNickeau        }
7637748cd8SNickeau        return $url;
7737748cd8SNickeau    }
7837748cd8SNickeau
79*4cadd4f8SNickeau    public static function getLogoAsSvgImage(): ?ImageSvg
80*4cadd4f8SNickeau    {
81*4cadd4f8SNickeau        foreach (self::SVG_LOGO_IDS as $svgLogo) {
82*4cadd4f8SNickeau
83*4cadd4f8SNickeau            try {
84*4cadd4f8SNickeau                $image = ImageSvg::createImageFromId($svgLogo);
85*4cadd4f8SNickeau            } catch (ExceptionCombo $e) {
86*4cadd4f8SNickeau                LogUtility::msg("The svg ($svgLogo) returns an error. {$e->getMessage()}");
87*4cadd4f8SNickeau                continue;
88*4cadd4f8SNickeau            }
89*4cadd4f8SNickeau            if ($image->exists()) {
90*4cadd4f8SNickeau                return $image;
91*4cadd4f8SNickeau            }
92*4cadd4f8SNickeau        }
93*4cadd4f8SNickeau        return null;
94*4cadd4f8SNickeau    }
95*4cadd4f8SNickeau
9637748cd8SNickeau    public static function getLogoUrlAsPng()
9737748cd8SNickeau    {
9837748cd8SNickeau
9937748cd8SNickeau        $url = null;
10037748cd8SNickeau        foreach (self::PNG_LOGO_IDS as $svgLogo) {
10137748cd8SNickeau
10237748cd8SNickeau            $svgLogoFN = mediaFN($svgLogo);
10337748cd8SNickeau
10437748cd8SNickeau            if (file_exists($svgLogoFN)) {
10537748cd8SNickeau                $url = ml($svgLogo, '', true, '', true);
10637748cd8SNickeau                break;
10737748cd8SNickeau            };
10837748cd8SNickeau        }
10937748cd8SNickeau        return $url;
11037748cd8SNickeau    }
11137748cd8SNickeau
11237748cd8SNickeau    /**
11337748cd8SNickeau     * @return mixed
114*4cadd4f8SNickeau     * @deprecated use {@link Site::getName()} instead
115*4cadd4f8SNickeau     * https://www.dokuwiki.org/config:title
11637748cd8SNickeau     */
11737748cd8SNickeau    public static function getTitle()
11837748cd8SNickeau    {
11937748cd8SNickeau        global $conf;
12037748cd8SNickeau        return $conf['title'];
12137748cd8SNickeau    }
12237748cd8SNickeau
12337748cd8SNickeau    /**
124*4cadd4f8SNickeau     * https://www.dokuwiki.org/config:title
125*4cadd4f8SNickeau     */
126*4cadd4f8SNickeau    public static function setName($name)
127*4cadd4f8SNickeau    {
128*4cadd4f8SNickeau        global $conf;
129*4cadd4f8SNickeau        $conf['title'] = $name;
130*4cadd4f8SNickeau    }
131*4cadd4f8SNickeau
132*4cadd4f8SNickeau    /**
13337748cd8SNickeau     * @param string $sep - the separator - generally ("-") but not always
13437748cd8SNickeau     * @return string
13537748cd8SNickeau     *
13637748cd8SNickeau     * Locale always canonicalizes to upper case.
13737748cd8SNickeau     */
138c3437056SNickeau    public static function getLocale(string $sep = "-"): ?string
13937748cd8SNickeau    {
14037748cd8SNickeau
14137748cd8SNickeau        $locale = null;
14237748cd8SNickeau
14337748cd8SNickeau        $lang = self::getLang();
14437748cd8SNickeau        if ($lang != null) {
145c3437056SNickeau            $country = self::getLanguageRegion();
14637748cd8SNickeau            if ($country != null) {
14737748cd8SNickeau                $locale = strtolower($lang) . $sep . strtoupper($country);
14837748cd8SNickeau            }
14937748cd8SNickeau        }
15037748cd8SNickeau
15137748cd8SNickeau        return $locale;
15237748cd8SNickeau    }
15337748cd8SNickeau
15437748cd8SNickeau    /**
15537748cd8SNickeau     *
15637748cd8SNickeau     * ISO 3166 alpha-2 country code
15737748cd8SNickeau     *
15837748cd8SNickeau     */
159c3437056SNickeau    public static function getLanguageRegion()
16037748cd8SNickeau    {
161c3437056SNickeau        $region = PluginUtility::getConfValue(Region::CONF_SITE_LANGUAGE_REGION);
162c3437056SNickeau        if (!empty($region)) {
163c3437056SNickeau            return $region;
16437748cd8SNickeau        } else {
165c3437056SNickeau
166c3437056SNickeau            if (extension_loaded("intl")) {
167c3437056SNickeau                $locale = locale_get_default();
168c3437056SNickeau                $localeParts = preg_split("/_/", $locale, 2);
169c3437056SNickeau                if (sizeof($localeParts) === 2) {
170c3437056SNickeau                    return $localeParts[1];
171c3437056SNickeau                }
172c3437056SNickeau            }
173c3437056SNickeau
17437748cd8SNickeau            return null;
17537748cd8SNickeau        }
17637748cd8SNickeau
17737748cd8SNickeau    }
17837748cd8SNickeau
17937748cd8SNickeau    /**
18037748cd8SNickeau     * @return mixed|null
18137748cd8SNickeau     * Wrapper around  https://www.dokuwiki.org/config:lang
18237748cd8SNickeau     */
183c3437056SNickeau    public static function getLang()
18437748cd8SNickeau    {
18537748cd8SNickeau
18637748cd8SNickeau        global $conf;
187c3437056SNickeau        $lang = $conf['lang'];
188c3437056SNickeau        return ($lang ?: null);
18937748cd8SNickeau    }
19037748cd8SNickeau
191c3437056SNickeau    public static function getBaseUrl(): string
19237748cd8SNickeau    {
19337748cd8SNickeau
19437748cd8SNickeau        /**
19537748cd8SNickeau         * In a {@link PluginUtility::isDevOrTest()} dev environment,
19637748cd8SNickeau         * don't set the
19737748cd8SNickeau         * https://www.dokuwiki.org/config:baseurl
19837748cd8SNickeau         * to be able to test the metadata / social integration
19937748cd8SNickeau         * via a tunnel
200c3437056SNickeau         *
201c3437056SNickeau         * Same as {@link getBaseURL()} ??
202*4cadd4f8SNickeau         * Same as {@link wl()} without nothing
20337748cd8SNickeau         */
20437748cd8SNickeau
20537748cd8SNickeau        return DOKU_URL;
20637748cd8SNickeau
20737748cd8SNickeau    }
20837748cd8SNickeau
20937748cd8SNickeau    public static function getTag()
21037748cd8SNickeau    {
21137748cd8SNickeau        global $conf;
21237748cd8SNickeau        $tag = $conf['tag'];
21337748cd8SNickeau        return ($tag ? $tag : null);
21437748cd8SNickeau    }
21537748cd8SNickeau
21637748cd8SNickeau    /**
21737748cd8SNickeau     * @return string - the name of the sidebar page
21837748cd8SNickeau     */
21937748cd8SNickeau    public static function getSidebarName()
22037748cd8SNickeau    {
22137748cd8SNickeau        global $conf;
22237748cd8SNickeau        return $conf["sidebar"];
22337748cd8SNickeau    }
22437748cd8SNickeau
22537748cd8SNickeau    public static function setTemplate($template)
22637748cd8SNickeau    {
22737748cd8SNickeau        global $conf;
22837748cd8SNickeau        $conf['template'] = $template;
22937748cd8SNickeau    }
23037748cd8SNickeau
231c3437056SNickeau    public static function setCacheXhtmlOn()
23237748cd8SNickeau    {
23337748cd8SNickeau        // ensure the value is not -1, which disables caching
23437748cd8SNickeau        // https://www.dokuwiki.org/config:cachetime
23537748cd8SNickeau        global $conf;
23637748cd8SNickeau        $conf['cachetime'] = 60 * 60;
23737748cd8SNickeau    }
23837748cd8SNickeau
23937748cd8SNickeau    public static function debugIsOn()
24037748cd8SNickeau    {
24137748cd8SNickeau        global $conf;
24237748cd8SNickeau        return $conf['allowdebug'];
24337748cd8SNickeau    }
24437748cd8SNickeau
24537748cd8SNickeau    public static function setTemplateToStrap()
24637748cd8SNickeau    {
24737748cd8SNickeau        global $conf;
248*4cadd4f8SNickeau        $conf['template'] = self::STRAP_TEMPLATE_NAME;
24937748cd8SNickeau    }
25037748cd8SNickeau
25137748cd8SNickeau    public static function setTemplateToDefault()
25237748cd8SNickeau    {
25337748cd8SNickeau        global $conf;
25437748cd8SNickeau        $conf['template'] = 'dokuwiki';
25537748cd8SNickeau    }
25637748cd8SNickeau
25737748cd8SNickeau    public static function setCacheDefault()
25837748cd8SNickeau    {
25937748cd8SNickeau        // The value is -1, which disables caching
26037748cd8SNickeau        // https://www.dokuwiki.org/config:cachetime
26137748cd8SNickeau        global $conf;
26237748cd8SNickeau        $conf['cachetime'] = -1;
26337748cd8SNickeau    }
26437748cd8SNickeau
26537748cd8SNickeau    public static function useHeadingAsTitle()
26637748cd8SNickeau    {
26737748cd8SNickeau        // https://www.dokuwiki.org/config:useheading
26837748cd8SNickeau        global $conf;
26937748cd8SNickeau        $conf['useheading'] = 1;
27037748cd8SNickeau    }
27137748cd8SNickeau
27237748cd8SNickeau    public static function useHeadingDefault()
27337748cd8SNickeau    {
27437748cd8SNickeau        // https://www.dokuwiki.org/config:useheading
27537748cd8SNickeau        global $conf;
27637748cd8SNickeau        $conf['useheading'] = 0;
27737748cd8SNickeau    }
27837748cd8SNickeau
27937748cd8SNickeau    public static function getTemplate()
28037748cd8SNickeau    {
28137748cd8SNickeau        global $conf;
28237748cd8SNickeau        return $conf['template'];
28337748cd8SNickeau
28437748cd8SNickeau    }
28537748cd8SNickeau
28637748cd8SNickeau    public static function isStrapTemplate()
28737748cd8SNickeau    {
28837748cd8SNickeau        global $conf;
28937748cd8SNickeau        return $conf['template'] == self::STRAP_TEMPLATE_NAME;
29037748cd8SNickeau    }
29137748cd8SNickeau
292*4cadd4f8SNickeau    public static function getAjaxUrl(): string
29337748cd8SNickeau    {
294c3437056SNickeau        return self::getBaseUrl() . "lib/exe/ajax.php";
29537748cd8SNickeau    }
29637748cd8SNickeau
29737748cd8SNickeau    public static function getPageDirectory()
29837748cd8SNickeau    {
29937748cd8SNickeau        global $conf;
300c3437056SNickeau        /**
301*4cadd4f8SNickeau         * Data dir is the pages dir (savedir is the data dir)
302c3437056SNickeau         */
303*4cadd4f8SNickeau        $pageDirectory = $conf['datadir'];
304*4cadd4f8SNickeau        if ($pageDirectory === null) {
305*4cadd4f8SNickeau            throw new ExceptionComboRuntime("The page directory ($pageDirectory) is null");
306*4cadd4f8SNickeau        }
307*4cadd4f8SNickeau        return LocalPath::createFromPath($pageDirectory);
30837748cd8SNickeau    }
30937748cd8SNickeau
31037748cd8SNickeau    public static function disableHeadingSectionEditing()
31137748cd8SNickeau    {
31237748cd8SNickeau        global $conf;
31337748cd8SNickeau        $conf['maxseclevel'] = 0;
31437748cd8SNickeau    }
31537748cd8SNickeau
31637748cd8SNickeau    public static function setBreadCrumbOn()
31737748cd8SNickeau    {
31837748cd8SNickeau        global $conf;
31937748cd8SNickeau        $conf['youarehere'] = 1;
32037748cd8SNickeau    }
32137748cd8SNickeau
322c3437056SNickeau    public static function isHtmlRenderCacheOn(): bool
323c3437056SNickeau    {
324c3437056SNickeau        global $conf;
325c3437056SNickeau        return $conf['cachetime'] !== -1;
326c3437056SNickeau    }
327c3437056SNickeau
328*4cadd4f8SNickeau    public static function getDataDirectory(): LocalPath
329c3437056SNickeau    {
330c3437056SNickeau        global $conf;
331*4cadd4f8SNickeau        $dataDirectory = $conf['savedir'];
332c3437056SNickeau        if ($dataDirectory === null) {
333*4cadd4f8SNickeau            throw new ExceptionComboRuntime("The data directory ($dataDirectory) is null");
334c3437056SNickeau        }
335*4cadd4f8SNickeau        return LocalPath::createFromPath($dataDirectory);
336c3437056SNickeau    }
337c3437056SNickeau
338c3437056SNickeau    public static function isLowQualityProtectionEnable(): bool
339c3437056SNickeau    {
340c3437056SNickeau        return PluginUtility::getConfValue(LowQualityPage::CONF_LOW_QUALITY_PAGE_PROTECTION_ENABLE) === 1;
341c3437056SNickeau    }
342c3437056SNickeau
343c3437056SNickeau    public static function getHomePageName()
344c3437056SNickeau    {
345c3437056SNickeau        global $conf;
346c3437056SNickeau        return $conf["start"];
347c3437056SNickeau    }
348c3437056SNickeau
349c3437056SNickeau    /**
350c3437056SNickeau     * @return mixed - Application / Website name
351c3437056SNickeau     */
352c3437056SNickeau    public static function getName()
353c3437056SNickeau    {
354*4cadd4f8SNickeau        return self::getTitle();
355c3437056SNickeau    }
356c3437056SNickeau
357c3437056SNickeau    public static function getTagLine()
358c3437056SNickeau    {
359c3437056SNickeau        global $conf;
360c3437056SNickeau        return $conf['tagline'];
361c3437056SNickeau    }
362c3437056SNickeau
363c3437056SNickeau    /**
364c3437056SNickeau     * @return int|null
365c3437056SNickeau     */
366c3437056SNickeau    public static function getCacheTime(): ?int
367c3437056SNickeau    {
368c3437056SNickeau        global $conf;
369c3437056SNickeau        $cacheTime = $conf['cachetime'];
370c3437056SNickeau        if ($cacheTime === null) {
371c3437056SNickeau            return null;
372c3437056SNickeau        }
373c3437056SNickeau        if (is_numeric($cacheTime)) {
374c3437056SNickeau            return intval($cacheTime);
375c3437056SNickeau        }
376c3437056SNickeau        return null;
377c3437056SNickeau    }
378c3437056SNickeau
379c3437056SNickeau    /**
380c3437056SNickeau     * Absolute vs Relative URL
381c3437056SNickeau     * https://www.dokuwiki.org/config:canonical
382c3437056SNickeau     */
383*4cadd4f8SNickeau    public static function shouldUrlBeAbsolute(): bool
384c3437056SNickeau    {
385c3437056SNickeau        global $conf;
386*4cadd4f8SNickeau        $value = $conf['canonical'];
387*4cadd4f8SNickeau        if ($value === 1) {
388*4cadd4f8SNickeau            return true;
389*4cadd4f8SNickeau        }
390*4cadd4f8SNickeau        return false;
391*4cadd4f8SNickeau    }
392*4cadd4f8SNickeau
393*4cadd4f8SNickeau    /**
394*4cadd4f8SNickeau     * @param string $description
395*4cadd4f8SNickeau     * Same as {@link Site::setDescription()}
396*4cadd4f8SNickeau     */
397*4cadd4f8SNickeau    public static function setTagLine(string $description)
398*4cadd4f8SNickeau    {
399*4cadd4f8SNickeau        global $conf;
400*4cadd4f8SNickeau        $conf['tagline'] = $description;
401*4cadd4f8SNickeau    }
402*4cadd4f8SNickeau
403*4cadd4f8SNickeau    /**
404*4cadd4f8SNickeau     * @param string $description
405*4cadd4f8SNickeau     *
406*4cadd4f8SNickeau     */
407*4cadd4f8SNickeau    public static function setDescription(string $description)
408*4cadd4f8SNickeau    {
409*4cadd4f8SNickeau        self::setTagLine($description);
410*4cadd4f8SNickeau    }
411*4cadd4f8SNickeau
412*4cadd4f8SNickeau    public static function setPrimaryColor(string $primaryColorValue)
413*4cadd4f8SNickeau    {
414*4cadd4f8SNickeau        PluginUtility::setConf(ColorRgb::PRIMARY_COLOR_CONF, $primaryColorValue);
415*4cadd4f8SNickeau    }
416*4cadd4f8SNickeau
417*4cadd4f8SNickeau    public static function getPrimaryColor($default = null): ?ColorRgb
418*4cadd4f8SNickeau    {
419*4cadd4f8SNickeau        $value = self::getPrimaryColorValue($default);
420*4cadd4f8SNickeau        if (
421*4cadd4f8SNickeau            $value === null ||
422*4cadd4f8SNickeau            (trim($value) === "")) {
423*4cadd4f8SNickeau            return null;
424*4cadd4f8SNickeau        }
425*4cadd4f8SNickeau        try {
426*4cadd4f8SNickeau            return ColorRgb::createFromString($value);
427*4cadd4f8SNickeau        } catch
428*4cadd4f8SNickeau        (ExceptionCombo $e) {
429*4cadd4f8SNickeau            LogUtility::msg("The primary color value configuration ($value) is not valid. Error: {$e->getMessage()}");
430*4cadd4f8SNickeau            return null;
431*4cadd4f8SNickeau        }
432*4cadd4f8SNickeau    }
433*4cadd4f8SNickeau
434*4cadd4f8SNickeau    public static function getSecondaryColor($default = null): ?ColorRgb
435*4cadd4f8SNickeau    {
436*4cadd4f8SNickeau        $value = Site::getSecondaryColorValue($default);
437*4cadd4f8SNickeau        if ($value === null) {
438*4cadd4f8SNickeau            return null;
439*4cadd4f8SNickeau        }
440*4cadd4f8SNickeau        try {
441*4cadd4f8SNickeau            return ColorRgb::createFromString($value);
442*4cadd4f8SNickeau        } catch (ExceptionCombo $e) {
443*4cadd4f8SNickeau            LogUtility::msg("The secondary color value configuration ($value) is not valid. Error: {$e->getMessage()}");
444*4cadd4f8SNickeau            return null;
445*4cadd4f8SNickeau        }
446*4cadd4f8SNickeau    }
447*4cadd4f8SNickeau
448*4cadd4f8SNickeau    public static function setSecondaryColor(string $secondaryColorValue)
449*4cadd4f8SNickeau    {
450*4cadd4f8SNickeau        PluginUtility::setConf(ColorRgb::SECONDARY_COLOR_CONF, $secondaryColorValue);
451*4cadd4f8SNickeau    }
452*4cadd4f8SNickeau
453*4cadd4f8SNickeau    public static function unsetPrimaryColor()
454*4cadd4f8SNickeau    {
455*4cadd4f8SNickeau        PluginUtility::setConf(ColorRgb::PRIMARY_COLOR_CONF, null);
456*4cadd4f8SNickeau    }
457*4cadd4f8SNickeau
458*4cadd4f8SNickeau
459*4cadd4f8SNickeau    public static function isBrandingColorInheritanceEnabled(): bool
460*4cadd4f8SNickeau    {
461*4cadd4f8SNickeau        return PluginUtility::getConfValue(ColorRgb::BRANDING_COLOR_INHERITANCE_ENABLE_CONF, ColorRgb::BRANDING_COLOR_INHERITANCE_ENABLE_CONF_DEFAULT) === 1;
462*4cadd4f8SNickeau    }
463*4cadd4f8SNickeau
464*4cadd4f8SNickeau    public static function getRem(): int
465*4cadd4f8SNickeau    {
466*4cadd4f8SNickeau        $defaultRem = 16;
467*4cadd4f8SNickeau        if (Site::getTemplate() === self::STRAP_TEMPLATE_NAME) {
468*4cadd4f8SNickeau            $loaded = self::loadStrapUtilityTemplateIfPresentAndSameVersion();
469*4cadd4f8SNickeau            if ($loaded) {
470*4cadd4f8SNickeau                $value = TplUtility::getRem();
471*4cadd4f8SNickeau                if ($value === null) {
472*4cadd4f8SNickeau                    return $defaultRem;
473*4cadd4f8SNickeau                }
474*4cadd4f8SNickeau                try {
475*4cadd4f8SNickeau                    return DataType::toInteger($value);
476*4cadd4f8SNickeau                } catch (ExceptionCombo $e) {
477*4cadd4f8SNickeau                    LogUtility::msg("The rem configuration value ($value) is not a integer. Error: {$e->getMessage()}");
478*4cadd4f8SNickeau                }
479*4cadd4f8SNickeau            }
480*4cadd4f8SNickeau        }
481*4cadd4f8SNickeau        return $defaultRem;
482*4cadd4f8SNickeau    }
483*4cadd4f8SNickeau
484*4cadd4f8SNickeau    public static function enableBrandingColorInheritance()
485*4cadd4f8SNickeau    {
486*4cadd4f8SNickeau        PluginUtility::setConf(ColorRgb::BRANDING_COLOR_INHERITANCE_ENABLE_CONF, 1);
487*4cadd4f8SNickeau    }
488*4cadd4f8SNickeau
489*4cadd4f8SNickeau    public static function setBrandingColorInheritanceToDefault()
490*4cadd4f8SNickeau    {
491*4cadd4f8SNickeau        PluginUtility::setConf(ColorRgb::BRANDING_COLOR_INHERITANCE_ENABLE_CONF, ColorRgb::BRANDING_COLOR_INHERITANCE_ENABLE_CONF_DEFAULT);
492*4cadd4f8SNickeau    }
493*4cadd4f8SNickeau
494*4cadd4f8SNickeau    public static function getPrimaryColorForText(string $default = null): ?ColorRgb
495*4cadd4f8SNickeau    {
496*4cadd4f8SNickeau        $primaryColor = self::getPrimaryColor($default);
497*4cadd4f8SNickeau        if ($primaryColor === null) {
498*4cadd4f8SNickeau            return null;
499*4cadd4f8SNickeau        }
500*4cadd4f8SNickeau        try {
501*4cadd4f8SNickeau            return $primaryColor
502*4cadd4f8SNickeau                ->toHsl()
503*4cadd4f8SNickeau                ->setSaturation(30)
504*4cadd4f8SNickeau                ->setLightness(40)
505*4cadd4f8SNickeau                ->toRgb()
506*4cadd4f8SNickeau                ->toMinimumContrastRatioAgainstWhite();
507*4cadd4f8SNickeau        } catch (ExceptionCombo $e) {
508*4cadd4f8SNickeau            LogUtility::msg("Error while calculating the primary text color. {$e->getMessage()}");
509*4cadd4f8SNickeau            return null;
510*4cadd4f8SNickeau        }
511*4cadd4f8SNickeau    }
512*4cadd4f8SNickeau
513*4cadd4f8SNickeau    /**
514*4cadd4f8SNickeau     * More lightness than the text
515*4cadd4f8SNickeau     * @return ColorRgb|null
516*4cadd4f8SNickeau     */
517*4cadd4f8SNickeau    public static function getPrimaryColorTextHover(): ?ColorRgb
518*4cadd4f8SNickeau    {
519*4cadd4f8SNickeau
520*4cadd4f8SNickeau        $primaryColor = self::getPrimaryColor();
521*4cadd4f8SNickeau        if ($primaryColor === null) {
522*4cadd4f8SNickeau            return null;
523*4cadd4f8SNickeau        }
524*4cadd4f8SNickeau        try {
525*4cadd4f8SNickeau            return $primaryColor
526*4cadd4f8SNickeau                ->toHsl()
527*4cadd4f8SNickeau                ->setSaturation(88)
528*4cadd4f8SNickeau                ->setLightness(53)
529*4cadd4f8SNickeau                ->toRgb()
530*4cadd4f8SNickeau                ->toMinimumContrastRatioAgainstWhite();
531*4cadd4f8SNickeau        } catch (ExceptionCombo $e) {
532*4cadd4f8SNickeau            LogUtility::msg("Error while calculating the secondary text color. {$e->getMessage()}");
533*4cadd4f8SNickeau            return null;
534*4cadd4f8SNickeau        }
535*4cadd4f8SNickeau
536*4cadd4f8SNickeau    }
537*4cadd4f8SNickeau
538*4cadd4f8SNickeau
539*4cadd4f8SNickeau    public static function getSecondarySlotNames(): array
540*4cadd4f8SNickeau    {
541*4cadd4f8SNickeau
542*4cadd4f8SNickeau        try {
543*4cadd4f8SNickeau            return [
544*4cadd4f8SNickeau                Site::getSidebarName(),
545*4cadd4f8SNickeau                Site::getHeaderSlotPageName(),
546*4cadd4f8SNickeau                Site::getFooterSlotPageName(),
547*4cadd4f8SNickeau                Site::getMainHeaderSlotName(),
548*4cadd4f8SNickeau                Site::getMainFooterSlotName()
549*4cadd4f8SNickeau            ];
550*4cadd4f8SNickeau        } catch (ExceptionCombo $e) {
551*4cadd4f8SNickeau            // We known at least this one
552*4cadd4f8SNickeau            return [Site::getSidebarName()];
553*4cadd4f8SNickeau        }
554*4cadd4f8SNickeau
555*4cadd4f8SNickeau
556*4cadd4f8SNickeau    }
557*4cadd4f8SNickeau
558*4cadd4f8SNickeau
559*4cadd4f8SNickeau    /**
560*4cadd4f8SNickeau     * @throws ExceptionCombo if the strap template is not installed or could not be loaded
561*4cadd4f8SNickeau     */
562*4cadd4f8SNickeau    public static function getMainHeaderSlotName(): ?string
563*4cadd4f8SNickeau    {
564*4cadd4f8SNickeau        self::loadStrapUtilityTemplateIfPresentAndSameVersion();
565*4cadd4f8SNickeau        return TplUtility::getMainHeaderSlotName();
566*4cadd4f8SNickeau    }
567*4cadd4f8SNickeau
568*4cadd4f8SNickeau    /**
569*4cadd4f8SNickeau     * Strap is loaded only if this is the same version
570*4cadd4f8SNickeau     * to avoid function, class, or members that does not exist
571*4cadd4f8SNickeau     * @throws ExceptionCombo if strap template utility class could not be loaded
572*4cadd4f8SNickeau     */
573*4cadd4f8SNickeau    public static function loadStrapUtilityTemplateIfPresentAndSameVersion(): void
574*4cadd4f8SNickeau    {
575*4cadd4f8SNickeau
576*4cadd4f8SNickeau        if (class_exists("ComboStrap\TplUtility")) {
577*4cadd4f8SNickeau            return;
578*4cadd4f8SNickeau        }
579*4cadd4f8SNickeau
580*4cadd4f8SNickeau        $templateUtilityFile = __DIR__ . '/../../../tpl/strap/class/TplUtility.php';
581*4cadd4f8SNickeau        if (file_exists($templateUtilityFile)) {
582*4cadd4f8SNickeau            /**
583*4cadd4f8SNickeau             * Check the version
584*4cadd4f8SNickeau             */
585*4cadd4f8SNickeau            $templateInfo = confToHash(__DIR__ . '/../../../tpl/strap/template.info.txt');
586*4cadd4f8SNickeau            $templateVersion = $templateInfo['version'];
587*4cadd4f8SNickeau            $comboVersion = PluginUtility::$INFO_PLUGIN['version'];
588*4cadd4f8SNickeau            if ($templateVersion != $comboVersion) {
589*4cadd4f8SNickeau                $strapName = "Strap";
590*4cadd4f8SNickeau                $comboName = "Combo";
591*4cadd4f8SNickeau                $strapLink = "<a href=\"https://www.dokuwiki.org/template:strap\">$strapName</a>";
592*4cadd4f8SNickeau                $comboLink = "<a href=\"https://www.dokuwiki.org/plugin:combo\">$comboName</a>";
593*4cadd4f8SNickeau                if ($comboVersion > $templateVersion) {
594*4cadd4f8SNickeau                    $upgradeTarget = $strapName;
595*4cadd4f8SNickeau                } else {
596*4cadd4f8SNickeau                    $upgradeTarget = $comboName;
597*4cadd4f8SNickeau                }
598*4cadd4f8SNickeau                $upgradeLink = "<a href=\"" . wl() . "&do=admin&page=extension" . "\">upgrade <b>$upgradeTarget</b> via the extension manager</a>";
599*4cadd4f8SNickeau                $message = "You should $upgradeLink to the latest version to get a fully functional experience. The version of $comboLink is ($comboVersion) while the version of $strapLink is ($templateVersion).";
600*4cadd4f8SNickeau                LogUtility::msg($message);
601*4cadd4f8SNickeau                throw new ExceptionCombo($message);
602*4cadd4f8SNickeau            } else {
603*4cadd4f8SNickeau                /** @noinspection PhpIncludeInspection */
604*4cadd4f8SNickeau                require_once($templateUtilityFile);
605*4cadd4f8SNickeau
606*4cadd4f8SNickeau            }
607*4cadd4f8SNickeau        }
608*4cadd4f8SNickeau
609*4cadd4f8SNickeau        if (Site::getTemplate() !== self::STRAP_TEMPLATE_NAME) {
610*4cadd4f8SNickeau            $message = "The strap template is not installed";
611*4cadd4f8SNickeau        } else {
612*4cadd4f8SNickeau            $message = "The file ($templateUtilityFile) was not found";
613*4cadd4f8SNickeau        }
614*4cadd4f8SNickeau        throw new ExceptionCombo($message);
615*4cadd4f8SNickeau
616*4cadd4f8SNickeau    }
617*4cadd4f8SNickeau
618*4cadd4f8SNickeau    /**
619*4cadd4f8SNickeau     * @throws ExceptionCombo
620*4cadd4f8SNickeau     */
621*4cadd4f8SNickeau    public static function getSideKickSlotPageName()
622*4cadd4f8SNickeau    {
623*4cadd4f8SNickeau
624*4cadd4f8SNickeau        Site::loadStrapUtilityTemplateIfPresentAndSameVersion();
625*4cadd4f8SNickeau        return TplUtility::getSideKickSlotPageName();
626*4cadd4f8SNickeau
627*4cadd4f8SNickeau    }
628*4cadd4f8SNickeau
629*4cadd4f8SNickeau    /**
630*4cadd4f8SNickeau     * @throws ExceptionCombo
631*4cadd4f8SNickeau     */
632*4cadd4f8SNickeau    public static function getFooterSlotPageName()
633*4cadd4f8SNickeau    {
634*4cadd4f8SNickeau        Site::loadStrapUtilityTemplateIfPresentAndSameVersion();
635*4cadd4f8SNickeau        return TplUtility::getFooterSlotPageName();
636*4cadd4f8SNickeau    }
637*4cadd4f8SNickeau
638*4cadd4f8SNickeau    /**
639*4cadd4f8SNickeau     * @throws ExceptionCombo
640*4cadd4f8SNickeau     */
641*4cadd4f8SNickeau    public static function getHeaderSlotPageName()
642*4cadd4f8SNickeau    {
643*4cadd4f8SNickeau        Site::loadStrapUtilityTemplateIfPresentAndSameVersion();
644*4cadd4f8SNickeau        return TplUtility::getHeaderSlotPageName();
645*4cadd4f8SNickeau    }
646*4cadd4f8SNickeau
647*4cadd4f8SNickeau    /**
648*4cadd4f8SNickeau     * @throws ExceptionCombo
649*4cadd4f8SNickeau     */
650*4cadd4f8SNickeau    public static function setConfStrapTemplate($name, $value)
651*4cadd4f8SNickeau    {
652*4cadd4f8SNickeau        Site::loadStrapUtilityTemplateIfPresentAndSameVersion();
653*4cadd4f8SNickeau        TplUtility::setConf($name, $value);
654*4cadd4f8SNickeau
655*4cadd4f8SNickeau    }
656*4cadd4f8SNickeau
657*4cadd4f8SNickeau    /**
658*4cadd4f8SNickeau     * @throws ExceptionCombo
659*4cadd4f8SNickeau     */
660*4cadd4f8SNickeau    public static function getMainFooterSlotName(): string
661*4cadd4f8SNickeau    {
662*4cadd4f8SNickeau        self::loadStrapUtilityTemplateIfPresentAndSameVersion();
663*4cadd4f8SNickeau        return TplUtility::getMainFooterSlotName();
664*4cadd4f8SNickeau    }
665*4cadd4f8SNickeau
666*4cadd4f8SNickeau    public static function getPrimaryColorValue($default = null)
667*4cadd4f8SNickeau    {
668*4cadd4f8SNickeau        $value = PluginUtility::getConfValue(ColorRgb::PRIMARY_COLOR_CONF, $default);
669*4cadd4f8SNickeau        if ($value !== null && trim($value) !== "") {
670*4cadd4f8SNickeau            return $value;
671*4cadd4f8SNickeau        }
672*4cadd4f8SNickeau        if (PluginUtility::isTest()) {
673*4cadd4f8SNickeau            // too much trouble
674*4cadd4f8SNickeau            // the load of styles is not consistent
675*4cadd4f8SNickeau            return null;
676*4cadd4f8SNickeau        }
677*4cadd4f8SNickeau        $styles = ColorRgb::getDokuWikiStyles();
678*4cadd4f8SNickeau        return $styles["replacements"]["__theme_color__"];
679*4cadd4f8SNickeau
680*4cadd4f8SNickeau    }
681*4cadd4f8SNickeau
682*4cadd4f8SNickeau    public static function getSecondaryColorValue($default = null)
683*4cadd4f8SNickeau    {
684*4cadd4f8SNickeau        $value = PluginUtility::getConfValue(ColorRgb::SECONDARY_COLOR_CONF, $default);
685*4cadd4f8SNickeau        if ($value === null || trim($value) === "") {
686*4cadd4f8SNickeau            return null;
687*4cadd4f8SNickeau        }
688*4cadd4f8SNickeau        return $value;
689*4cadd4f8SNickeau    }
690*4cadd4f8SNickeau
691*4cadd4f8SNickeau    public static function setCanonicalUrlType(string $value)
692*4cadd4f8SNickeau    {
693*4cadd4f8SNickeau        PluginUtility::setConf(PageUrlType::CONF_CANONICAL_URL_TYPE, $value);
694*4cadd4f8SNickeau    }
695*4cadd4f8SNickeau
696*4cadd4f8SNickeau    public static function setCanonicalUrlTypeToDefault()
697*4cadd4f8SNickeau    {
698*4cadd4f8SNickeau        PluginUtility::setConf(PageUrlType::CONF_CANONICAL_URL_TYPE, null);
699*4cadd4f8SNickeau    }
700*4cadd4f8SNickeau
701*4cadd4f8SNickeau    public static function isBrandingColorInheritanceFunctional(): bool
702*4cadd4f8SNickeau    {
703*4cadd4f8SNickeau        return self::isBrandingColorInheritanceEnabled() && Site::getPrimaryColorValue() !== null;
704*4cadd4f8SNickeau    }
705*4cadd4f8SNickeau
706*4cadd4f8SNickeau    public static function getMediaDirectory(): LocalPath
707*4cadd4f8SNickeau    {
708*4cadd4f8SNickeau        global $conf;
709*4cadd4f8SNickeau        $mediaDirectory = $conf['mediadir'];
710*4cadd4f8SNickeau        if ($mediaDirectory === null) {
711*4cadd4f8SNickeau            throw new ExceptionComboRuntime("The media directory ($mediaDirectory) is null");
712*4cadd4f8SNickeau        }
713*4cadd4f8SNickeau        return LocalPath::createFromPath($mediaDirectory);
714*4cadd4f8SNickeau    }
715*4cadd4f8SNickeau
716*4cadd4f8SNickeau    public static function getCacheDirectory(): LocalPath
717*4cadd4f8SNickeau    {
718*4cadd4f8SNickeau        global $conf;
719*4cadd4f8SNickeau        $cacheDirectory = $conf['cachedir'];
720*4cadd4f8SNickeau        if ($cacheDirectory === null) {
721*4cadd4f8SNickeau            throw new ExceptionComboRuntime("The cache directory ($cacheDirectory) is null");
722*4cadd4f8SNickeau        }
723*4cadd4f8SNickeau        return LocalPath::createFromPath($cacheDirectory);
724*4cadd4f8SNickeau    }
725*4cadd4f8SNickeau
726*4cadd4f8SNickeau
727*4cadd4f8SNickeau    public static function getComboHome(): LocalPath
728*4cadd4f8SNickeau    {
729*4cadd4f8SNickeau        return LocalPath::create(DOKU_PLUGIN . PluginUtility::PLUGIN_BASE_NAME);
730*4cadd4f8SNickeau    }
731*4cadd4f8SNickeau
732*4cadd4f8SNickeau    public static function getComboImagesDirectory(): LocalPath
733*4cadd4f8SNickeau    {
734*4cadd4f8SNickeau        return self::getComboResourcesDirectory()->resolve("images");
735*4cadd4f8SNickeau    }
736*4cadd4f8SNickeau
737*4cadd4f8SNickeau    public static function getComboResourcesDirectory(): LocalPath
738*4cadd4f8SNickeau    {
739*4cadd4f8SNickeau        return Site::getComboHome()->resolve("resources");
740*4cadd4f8SNickeau    }
741*4cadd4f8SNickeau
742*4cadd4f8SNickeau    public static function getComboDictionaryDirectory(): LocalPath
743*4cadd4f8SNickeau    {
744*4cadd4f8SNickeau        return Site::getComboResourcesDirectory()->resolve("dictionary");
745*4cadd4f8SNickeau    }
746*4cadd4f8SNickeau
747*4cadd4f8SNickeau    public static function getComboResourceSnippetDirectory(): LocalPath
748*4cadd4f8SNickeau    {
749*4cadd4f8SNickeau        return Site::getComboResourcesDirectory()->resolve("snippet");
750*4cadd4f8SNickeau    }
751*4cadd4f8SNickeau
752*4cadd4f8SNickeau    public static function getLogoHtml(): ?string
753*4cadd4f8SNickeau    {
754*4cadd4f8SNickeau
755*4cadd4f8SNickeau        $tagAttributes = TagAttributes::createEmpty("identity");
756*4cadd4f8SNickeau        $tagAttributes->addComponentAttributeValue(Dimension::WIDTH_KEY, "72");
757*4cadd4f8SNickeau        $tagAttributes->addComponentAttributeValue(Dimension::HEIGHT_KEY, "72");
758*4cadd4f8SNickeau        $tagAttributes->addComponentAttributeValue(TagAttributes::TYPE_KEY, SvgDocument::ICON_TYPE);
759*4cadd4f8SNickeau        $tagAttributes->addClassName("logo");
760*4cadd4f8SNickeau
761*4cadd4f8SNickeau
762*4cadd4f8SNickeau        /**
763*4cadd4f8SNickeau         * Logo
764*4cadd4f8SNickeau         */
765*4cadd4f8SNickeau        $logoImages = Site::getLogoImages();
766*4cadd4f8SNickeau        foreach ($logoImages as $logoImage) {
767*4cadd4f8SNickeau            $path = $logoImage->getPath();
768*4cadd4f8SNickeau            $mediaLink = MediaLink::createMediaLinkFromPath($path, $tagAttributes)
769*4cadd4f8SNickeau                ->setLazyLoad(false);
770*4cadd4f8SNickeau            try {
771*4cadd4f8SNickeau                return $mediaLink->renderMediaTag();
772*4cadd4f8SNickeau            } catch (ExceptionCombo $e) {
773*4cadd4f8SNickeau                LogUtility::msg("Error while rendering the logo $logoImage");
774*4cadd4f8SNickeau            }
775*4cadd4f8SNickeau        }
776*4cadd4f8SNickeau
777*4cadd4f8SNickeau        return null;
778c3437056SNickeau    }
779c3437056SNickeau
78037748cd8SNickeau
78137748cd8SNickeau}
782