xref: /plugin/combo/ComboStrap/Bootstrap.php (revision 0f82904abf9037d1c740effc75b0f56aecc89feb)
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
1504fd306cSNickeauuse ComboStrap\Web\Url;
1604fd306cSNickeau
1737748cd8SNickeauclass Bootstrap
1837748cd8SNickeau{
1904fd306cSNickeau    const DEFAULT_STYLESHEET_NAME = "bootstrap";
2004fd306cSNickeau    const TAG = self::CANONICAL;
2104fd306cSNickeau    public const DEFAULT_MAJOR = 5;
2204fd306cSNickeau    public const VERSION_501 = self::DEFAULT_MAJOR . ".0.1";
2304fd306cSNickeau    public const DEFAULT_BOOTSTRAP_4_VERSION = "4.5.0";
2404fd306cSNickeau    public const DEFAULT_BOOTSTRAP_5_VERSION = self::VERSION_501;
2504fd306cSNickeau    public const DEFAULT_BOOTSTRAP_STYLESHEET_4_VERSION = self::DEFAULT_BOOTSTRAP_4_VERSION . " - " . self::DEFAULT_STYLESHEET_NAME;
2604fd306cSNickeau    public const DEFAULT_BOOTSTRAP_STYLESHEET_5_VERSION = self::DEFAULT_BOOTSTRAP_5_VERSION . " - " . self::DEFAULT_STYLESHEET_NAME;
2737748cd8SNickeau
2804fd306cSNickeau    private Snippet $jquerySnippet;
2904fd306cSNickeau    private Snippet $jsSnippet;
3004fd306cSNickeau    private Snippet $popperSnippet;
3104fd306cSNickeau    private Snippet $cssSnippet;
3237748cd8SNickeau
3304fd306cSNickeau    /**
3404fd306cSNickeau     * @param string $qualifiedVersion - the bootstrap version separated by the stylesheet
3504fd306cSNickeau     */
3604fd306cSNickeau    public function __construct(string $qualifiedVersion)
3704fd306cSNickeau    {
3804fd306cSNickeau        $bootstrapStyleSheetArray = explode(Bootstrap::BOOTSTRAP_VERSION_STYLESHEET_SEPARATOR, $qualifiedVersion);
3904fd306cSNickeau        $this->version = $bootstrapStyleSheetArray[0];
4004fd306cSNickeau        /**
4104fd306cSNickeau         * In case the input is just the major version
4204fd306cSNickeau         */
4304fd306cSNickeau        switch ($this->version) {
4404fd306cSNickeau            case "4":
4504fd306cSNickeau                $this->version = self::DEFAULT_BOOTSTRAP_4_VERSION;
4604fd306cSNickeau                break;
4704fd306cSNickeau            case "5":
4804fd306cSNickeau                $this->version = self::DEFAULT_BOOTSTRAP_5_VERSION;
4904fd306cSNickeau                break;
5004fd306cSNickeau        }
5104fd306cSNickeau
5204fd306cSNickeau        /**
5304fd306cSNickeau         * Stylesheet
5404fd306cSNickeau         */
5504fd306cSNickeau        if (isset($bootstrapStyleSheetArray[1])) {
5604fd306cSNickeau            $this->styleSheetName = $bootstrapStyleSheetArray[1];
5704fd306cSNickeau        } else {
5804fd306cSNickeau            $this->styleSheetName = self::DEFAULT_STYLESHEET_NAME;
5904fd306cSNickeau        }
6004fd306cSNickeau
6104fd306cSNickeau        $this->build();
6204fd306cSNickeau
6304fd306cSNickeau    }
6404fd306cSNickeau
6504fd306cSNickeau
6604fd306cSNickeau    const BootStrapFiveMajorVersion = 5;
6704fd306cSNickeau    const BootStrapFourMajorVersion = 4;
6837748cd8SNickeau    const CANONICAL = "bootstrap";
6904fd306cSNickeau    /**
7004fd306cSNickeau     * Stylesheet and Boostrap should have the same version
7104fd306cSNickeau     * This conf is a mix between the version and the stylesheet
7204fd306cSNickeau     *
7304fd306cSNickeau     * majorVersion.0.0 - stylesheetname
7404fd306cSNickeau     */
7504fd306cSNickeau    public const CONF_BOOTSTRAP_VERSION_STYLESHEET = "bootstrapVersionStylesheet";
7604fd306cSNickeau    /**
7704fd306cSNickeau     * The separator in {@link Bootstrap::CONF_BOOTSTRAP_VERSION_STYLESHEET}
7804fd306cSNickeau     */
7904fd306cSNickeau    public const BOOTSTRAP_VERSION_STYLESHEET_SEPARATOR = " - ";
8004fd306cSNickeau    public const DEFAULT_BOOTSTRAP_VERSION_STYLESHEET = "5.0.1" . Bootstrap::BOOTSTRAP_VERSION_STYLESHEET_SEPARATOR . "bootstrap";
8104fd306cSNickeau
8204fd306cSNickeau    /**
8304fd306cSNickeau     * @var mixed|string
8404fd306cSNickeau     */
8504fd306cSNickeau    private $version;
8604fd306cSNickeau    /**
8704fd306cSNickeau     * @var string - the stylesheet name
8804fd306cSNickeau     */
8904fd306cSNickeau    private $styleSheetName;
9037748cd8SNickeau
9137748cd8SNickeau    public static function getDataNamespace()
9237748cd8SNickeau    {
9337748cd8SNickeau        $dataToggleNamespace = "";
9437748cd8SNickeau        if (self::getBootStrapMajorVersion() == self::BootStrapFiveMajorVersion) {
9537748cd8SNickeau            $dataToggleNamespace = "-bs";
9637748cd8SNickeau        }
9737748cd8SNickeau        return $dataToggleNamespace;
9837748cd8SNickeau    }
9937748cd8SNickeau
10004fd306cSNickeau    public function getMajorVersion(): int
10137748cd8SNickeau    {
10204fd306cSNickeau        $bootstrapMajorVersion = $this->getVersion()[0];
1034cadd4f8SNickeau        try {
10404fd306cSNickeau            return DataType::toInteger($bootstrapMajorVersion);
10504fd306cSNickeau        } catch (ExceptionBadArgument $e) {
10604fd306cSNickeau            LogUtility::internalError("The bootstrap major version ($bootstrapMajorVersion) is not an integer, default taken");
10704fd306cSNickeau            return self::DEFAULT_MAJOR;
1084cadd4f8SNickeau        }
10904fd306cSNickeau
11037748cd8SNickeau    }
11104fd306cSNickeau
11204fd306cSNickeau    /**
11304fd306cSNickeau     * Utility function that returns the major version
11404fd306cSNickeau     * because this is really common in code
11504fd306cSNickeau     * @return int - the major version
11604fd306cSNickeau     */
11704fd306cSNickeau    public static function getBootStrapMajorVersion(): int
11804fd306cSNickeau    {
11904fd306cSNickeau        return Bootstrap::getFromContext()->getMajorVersion();
12004fd306cSNickeau    }
12137748cd8SNickeau
12237748cd8SNickeau
12304fd306cSNickeau    public function getVersion(): string
12404fd306cSNickeau    {
12504fd306cSNickeau        return $this->version;
12604fd306cSNickeau    }
12704fd306cSNickeau
12804fd306cSNickeau    public static function createFromQualifiedVersion(string $boostrapVersion): Bootstrap
12904fd306cSNickeau    {
13004fd306cSNickeau        return new Bootstrap($boostrapVersion);
13104fd306cSNickeau    }
13204fd306cSNickeau
13304fd306cSNickeau
13404fd306cSNickeau    public function getStyleSheetName(): string
13504fd306cSNickeau    {
13604fd306cSNickeau        return $this->styleSheetName;
13704fd306cSNickeau    }
13804fd306cSNickeau
13904fd306cSNickeau    /**
14004fd306cSNickeau     *
14104fd306cSNickeau     * @return array - an array of stylesheet tag
14204fd306cSNickeau     */
14304fd306cSNickeau    public static function getStyleSheetMetas(): array
14404fd306cSNickeau    {
14504fd306cSNickeau
14604fd306cSNickeau        /**
14704fd306cSNickeau         * Standard stylesheet
14804fd306cSNickeau         */
14904fd306cSNickeau        $stylesheetsFile = WikiPath::createComboResource(':library:bootstrap:bootstrapStylesheet.json');
15004fd306cSNickeau        try {
15104fd306cSNickeau            $styleSheets = Json::createFromPath($stylesheetsFile)->toArray();
15204fd306cSNickeau        } catch (ExceptionNotFound|ExceptionBadSyntax $e) {
15304fd306cSNickeau            LogUtility::internalError("An error has occurred reading the file ($stylesheetsFile). Error:{$e->getMessage()}", self::CANONICAL);
15404fd306cSNickeau            return [];
15504fd306cSNickeau        }
15604fd306cSNickeau
15704fd306cSNickeau        /**
15804fd306cSNickeau         * User defined stylesheet
15904fd306cSNickeau         */
16004fd306cSNickeau        $localStyleSheetsFile = WikiPath::createComboResource(':library:bootstrap:bootstrapLocal.json');
16104fd306cSNickeau        try {
16204fd306cSNickeau            $localStyleSheets = Json::createFromPath($localStyleSheetsFile)->toArray();
16304fd306cSNickeau            foreach ($localStyleSheets as $bootstrapVersion => &$localStyleSheetData) {
16404fd306cSNickeau                $actualStyleSheet = $styleSheets[$bootstrapVersion];
16504fd306cSNickeau                if (isset($actualStyleSheet)) {
16604fd306cSNickeau                    $styleSheets[$bootstrapVersion] = array_merge($actualStyleSheet, $localStyleSheetData);
16704fd306cSNickeau                } else {
16804fd306cSNickeau                    $styleSheets[$bootstrapVersion] = $localStyleSheetData;
16904fd306cSNickeau                }
17004fd306cSNickeau            }
17104fd306cSNickeau        } catch (ExceptionBadSyntax|ExceptionNotFound $e) {
17204fd306cSNickeau            // user file does not exists and that's okay
17304fd306cSNickeau        }
17404fd306cSNickeau        return $styleSheets;
17504fd306cSNickeau
17604fd306cSNickeau
17704fd306cSNickeau    }
17804fd306cSNickeau
17904fd306cSNickeau
18004fd306cSNickeau    /**
18104fd306cSNickeau     * @return array - A list of all available stylesheets
18204fd306cSNickeau     * This function is used to build the configuration as a list of files
18304fd306cSNickeau     */
18404fd306cSNickeau    public static function getQualifiedVersions(): array
18504fd306cSNickeau    {
18604fd306cSNickeau        $cssVersionsMetas = Bootstrap::getStyleSheetMetas();
18704fd306cSNickeau        $listVersionStylesheetMeta = array();
18804fd306cSNickeau        foreach ($cssVersionsMetas as $bootstrapVersion => $cssVersionMeta) {
18904fd306cSNickeau            foreach ($cssVersionMeta as $fileName => $values) {
19004fd306cSNickeau                $listVersionStylesheetMeta[] = $bootstrapVersion . Bootstrap::BOOTSTRAP_VERSION_STYLESHEET_SEPARATOR . $fileName;
19104fd306cSNickeau            }
19204fd306cSNickeau        }
19304fd306cSNickeau        return $listVersionStylesheetMeta;
19404fd306cSNickeau    }
19504fd306cSNickeau
19604fd306cSNickeau
19704fd306cSNickeau    /**
19804fd306cSNickeau     * @return Bootstrap
19904fd306cSNickeau     */
20004fd306cSNickeau    public static function getFromContext(): Bootstrap
20104fd306cSNickeau    {
20204fd306cSNickeau        $executionContext = ExecutionContext::getActualOrCreateFromEnv();
20304fd306cSNickeau        try {
20404fd306cSNickeau            return $executionContext->getRuntimeObject(self::CANONICAL);
20504fd306cSNickeau        } catch (ExceptionNotFound $e) {
20604fd306cSNickeau            $bootstrapStyleSheetVersion = ExecutionContext::getActualOrCreateFromEnv()
20704fd306cSNickeau                ->getConfValue(Bootstrap::CONF_BOOTSTRAP_VERSION_STYLESHEET, Bootstrap::DEFAULT_BOOTSTRAP_VERSION_STYLESHEET);
20804fd306cSNickeau            $bootstrap = new Bootstrap($bootstrapStyleSheetVersion);
20904fd306cSNickeau            $executionContext->setRuntimeObject(self::CANONICAL, $bootstrap);
21004fd306cSNickeau            return $bootstrap;
21104fd306cSNickeau        }
21204fd306cSNickeau
21304fd306cSNickeau    }
21404fd306cSNickeau
21504fd306cSNickeau
21604fd306cSNickeau    /**
21704fd306cSNickeau     * @throws ExceptionNotFound
21804fd306cSNickeau     */
21904fd306cSNickeau    public function getCssSnippet(): Snippet
22004fd306cSNickeau    {
22104fd306cSNickeau        if (isset($this->cssSnippet)) {
22204fd306cSNickeau            return $this->cssSnippet;
22304fd306cSNickeau        }
22404fd306cSNickeau        throw new ExceptionNotFound("No css snippet");
22504fd306cSNickeau    }
22604fd306cSNickeau
22704fd306cSNickeau    /**
22804fd306cSNickeau     * @return Snippet[] the js snippets in order
22904fd306cSNickeau     */
23004fd306cSNickeau    public function getJsSnippets(): array
23104fd306cSNickeau    {
23204fd306cSNickeau
23304fd306cSNickeau        /**
23404fd306cSNickeau         * The javascript snippet order is important
23504fd306cSNickeau         */
23604fd306cSNickeau        $snippets = [];
23704fd306cSNickeau        try {
23804fd306cSNickeau            $snippets[] = $this->getJquerySnippet();
23904fd306cSNickeau        } catch (ExceptionNotFound $e) {
24004fd306cSNickeau            // error already send at build time
24104fd306cSNickeau            // or just not present
24204fd306cSNickeau        }
24304fd306cSNickeau        try {
24404fd306cSNickeau            $snippets[] = $this->getPopperSnippet();
24504fd306cSNickeau        } catch (ExceptionNotFound $e) {
24604fd306cSNickeau            // error already send at build time
24704fd306cSNickeau        }
24804fd306cSNickeau        try {
24904fd306cSNickeau            $snippets[] = $this->getBootstrapJsSnippet();
25004fd306cSNickeau        } catch (ExceptionNotFound $e) {
25104fd306cSNickeau            // error already send at build time
25204fd306cSNickeau        }
25304fd306cSNickeau        return $snippets;
25404fd306cSNickeau
25504fd306cSNickeau    }
25604fd306cSNickeau
25704fd306cSNickeau    /**
25804fd306cSNickeau     *
25904fd306cSNickeau     */
26004fd306cSNickeau    private function build(): void
26104fd306cSNickeau    {
26204fd306cSNickeau
26304fd306cSNickeau
26404fd306cSNickeau        $version = $this->getVersion();
26504fd306cSNickeau
26604fd306cSNickeau        // Javascript
26704fd306cSNickeau        $bootstrapJsonFile = WikiPath::createComboResource(Snippet::LIBRARY_BASE . ":bootstrap:bootstrapJavascript.json");
26804fd306cSNickeau        try {
26904fd306cSNickeau            $bootstrapJsonMetas = Json::createFromPath($bootstrapJsonFile)->toArray();
27004fd306cSNickeau        } catch (ExceptionBadSyntax|ExceptionNotFound $e) {
27104fd306cSNickeau            // should not happen, no need to advertise it
27204fd306cSNickeau            throw new ExceptionRuntimeInternal("Unable to read the file {$bootstrapJsonFile} as json.", self::CANONICAL, 1, $e);
27304fd306cSNickeau        }
27404fd306cSNickeau        if (!isset($bootstrapJsonMetas[$version])) {
27504fd306cSNickeau            throw new ExceptionRuntimeInternal("The bootstrap version ($version) could not be found in the file $bootstrapJsonFile");
27604fd306cSNickeau        }
27704fd306cSNickeau        $bootstrapMetas = $bootstrapJsonMetas[$version];
27804fd306cSNickeau
27904fd306cSNickeau        // Css
28004fd306cSNickeau        $bootstrapMetas["stylesheet"] = $this->getStyleSheetMeta();
28104fd306cSNickeau
28204fd306cSNickeau
28304fd306cSNickeau        foreach ($bootstrapMetas as $key => $script) {
28404fd306cSNickeau            $fileNameWithExtension = $script["file"];
28504fd306cSNickeau            $file = LocalPath::createFromPathString($fileNameWithExtension);
28604fd306cSNickeau
28704fd306cSNickeau            $path = WikiPath::createComboResource(":library:bootstrap:$version:$fileNameWithExtension");
28804fd306cSNickeau            $snippet = Snippet::createSnippet($path)
28904fd306cSNickeau                ->setComponentId(self::TAG);
290*70bbd7f1Sgerardnico            $url = $script["url"] ?? null;
29104fd306cSNickeau            if (!empty($url)) {
29204fd306cSNickeau                try {
29304fd306cSNickeau                    $url = Url::createFromString($url);
29404fd306cSNickeau                    $snippet->setRemoteUrl($url);
29504fd306cSNickeau                    if (isset($script['integrity'])) {
29604fd306cSNickeau                        $snippet->setIntegrity($script['integrity']);
29704fd306cSNickeau                    }
29804fd306cSNickeau                } catch (ExceptionBadArgument|ExceptionBadSyntax $e) {
29904fd306cSNickeau                    LogUtility::internalError("The url ($url) for the bootstrap metadata ($fileNameWithExtension) from the bootstrap dictionary is not valid. Error:{$e->getMessage()}", self::CANONICAL);
30004fd306cSNickeau                }
30104fd306cSNickeau            }
30204fd306cSNickeau
30304fd306cSNickeau            try {
30404fd306cSNickeau                $extension = $file->getExtension();
30504fd306cSNickeau            } catch (ExceptionNotFound $e) {
30604fd306cSNickeau                LogUtility::internalError("No extension was found on the file metadata ($fileNameWithExtension) from the bootstrap dictionary", self::CANONICAL);
30704fd306cSNickeau                continue;
30804fd306cSNickeau            }
30904fd306cSNickeau            switch ($extension) {
31004fd306cSNickeau                case Snippet::EXTENSION_JS:
31104fd306cSNickeau                    $snippet->setCritical(false);
31204fd306cSNickeau                    switch ($key) {
31304fd306cSNickeau                        case "jquery":
31404fd306cSNickeau                            $this->jquerySnippet = $snippet;
31504fd306cSNickeau                            break;
31604fd306cSNickeau                        case "js":
31704fd306cSNickeau                            $this->jsSnippet = $snippet;
31804fd306cSNickeau                            break;
31904fd306cSNickeau                        case "popper":
32004fd306cSNickeau                            $this->popperSnippet = $snippet;
32104fd306cSNickeau                            break;
32204fd306cSNickeau                        default:
32304fd306cSNickeau                            LogUtility::internalError("The snippet key ($key) is unknown for bootstrap", self::CANONICAL);
32404fd306cSNickeau                            break;
32504fd306cSNickeau                    }
32604fd306cSNickeau                    break;
32704fd306cSNickeau                case Snippet::EXTENSION_CSS:
32804fd306cSNickeau                    switch ($key) {
32904fd306cSNickeau                        case "stylesheet":
33004fd306cSNickeau                            $this->cssSnippet = $snippet;
33104fd306cSNickeau                            break;
33204fd306cSNickeau                        default:
33304fd306cSNickeau                            LogUtility::internalError("The snippet key ($key) is unknown for bootstrap");
33404fd306cSNickeau                            break;
33504fd306cSNickeau                    }
33604fd306cSNickeau            }
33704fd306cSNickeau        }
33804fd306cSNickeau
33904fd306cSNickeau
34004fd306cSNickeau    }
34104fd306cSNickeau
34204fd306cSNickeau    public function getSnippets(): array
34304fd306cSNickeau    {
34404fd306cSNickeau
34504fd306cSNickeau        $snippets = [];
34604fd306cSNickeau        try {
34704fd306cSNickeau            $snippets[] = $this->getCssSnippet();
34804fd306cSNickeau        } catch (ExceptionNotFound $e) {
34904fd306cSNickeau            // error already send at build time
35004fd306cSNickeau        }
35104fd306cSNickeau
35204fd306cSNickeau        /**
35304fd306cSNickeau         * The javascript snippet
35404fd306cSNickeau         */
35504fd306cSNickeau        return array_merge($snippets, $this->getJsSnippets());
35604fd306cSNickeau    }
35704fd306cSNickeau
35804fd306cSNickeau    /**
35904fd306cSNickeau     * @throws ExceptionNotFound
36004fd306cSNickeau     */
36104fd306cSNickeau    public function getPopperSnippet(): Snippet
36204fd306cSNickeau    {
36304fd306cSNickeau        if (isset($this->popperSnippet)) {
36404fd306cSNickeau            return $this->popperSnippet;
36504fd306cSNickeau        }
36604fd306cSNickeau        throw new ExceptionNotFound("No popper snippet");
36704fd306cSNickeau    }
36804fd306cSNickeau
36904fd306cSNickeau    /**
37004fd306cSNickeau     * @throws ExceptionNotFound
37104fd306cSNickeau     */
37204fd306cSNickeau    public function getBootstrapJsSnippet(): Snippet
37304fd306cSNickeau    {
37404fd306cSNickeau        if (isset($this->jsSnippet)) {
37504fd306cSNickeau            return $this->jsSnippet;
37604fd306cSNickeau        }
37704fd306cSNickeau        throw new ExceptionNotFound("No js snippet");
37804fd306cSNickeau    }
37904fd306cSNickeau
38004fd306cSNickeau    /**
38104fd306cSNickeau     * @throws ExceptionNotFound
38204fd306cSNickeau     */
38304fd306cSNickeau    private function getJquerySnippet(): Snippet
38404fd306cSNickeau    {
38504fd306cSNickeau        if (isset($this->jquerySnippet)) {
38604fd306cSNickeau            return $this->jquerySnippet;
38704fd306cSNickeau        }
38804fd306cSNickeau        throw new ExceptionNotFound("No jquery snippet");
38904fd306cSNickeau    }
39004fd306cSNickeau
39104fd306cSNickeau    /**
39204fd306cSNickeau     * @return array - the stylesheet meta (file, url, ...) for the version
39304fd306cSNickeau     */
39404fd306cSNickeau    private function getStyleSheetMeta(): array
39504fd306cSNickeau    {
39604fd306cSNickeau
39704fd306cSNickeau        $styleSheets = self::getStyleSheetMetas();
39804fd306cSNickeau
39904fd306cSNickeau        $version = $this->getVersion();
40004fd306cSNickeau        if (!isset($styleSheets[$version])) {
40104fd306cSNickeau            LogUtility::internalError("The bootstrap version ($version) could not be found");
40204fd306cSNickeau            return [];
40304fd306cSNickeau        }
40404fd306cSNickeau        $styleSheetsForVersion = $styleSheets[$version];
40504fd306cSNickeau
40604fd306cSNickeau        $styleSheetName = $this->getStyleSheetName();
40704fd306cSNickeau        if (!isset($styleSheetsForVersion[$styleSheetName])) {
40804fd306cSNickeau            LogUtility::internalError("The bootstrap stylesheet ($styleSheetName) could not be found for the version ($version) in the distribution or custom configuration files");
40904fd306cSNickeau            return [];
41004fd306cSNickeau        }
41104fd306cSNickeau        $styleSheetForVersionAndName = $styleSheetsForVersion[$styleSheetName];
41204fd306cSNickeau
41304fd306cSNickeau        /**
41404fd306cSNickeau         * Select Rtl or Ltr
41504fd306cSNickeau         * Stylesheet name may have another level
41604fd306cSNickeau         * with direction property of the language
41704fd306cSNickeau         *
41804fd306cSNickeau         * Bootstrap needs another stylesheet
41904fd306cSNickeau         * See https://getbootstrap.com/docs/5.0/getting-started/rtl/
42004fd306cSNickeau         */
42104fd306cSNickeau        try {
42204fd306cSNickeau            $direction = Lang::createFromRequestedMarkup()->getDirection();
42304fd306cSNickeau        } catch (ExceptionNotFound $e) {
42404fd306cSNickeau            $direction = Site::getLangObject()->getDirection();
42504fd306cSNickeau        }
42604fd306cSNickeau        if (isset($styleSheetForVersionAndName[$direction])) {
42704fd306cSNickeau            return $styleSheetForVersionAndName[$direction];
42804fd306cSNickeau        }
42904fd306cSNickeau        if (!isset($styleSheetForVersionAndName['file'])) {
43004fd306cSNickeau            LogUtility::internalError('The file stylesheet attribute is unknown (' . DataType::toString($styleSheetForVersionAndName) . ')');
43104fd306cSNickeau        }
43204fd306cSNickeau        return $styleSheetForVersionAndName;
43337748cd8SNickeau    }
43437748cd8SNickeau}
435