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 15*04fd306cSNickeauuse action_plugin_combo_snippetsbootstrap; 16*04fd306cSNickeauuse ComboStrap\Web\Url; 17*04fd306cSNickeauuse Exception; 18*04fd306cSNickeau 1937748cd8SNickeauclass Bootstrap 2037748cd8SNickeau{ 21*04fd306cSNickeau const DEFAULT_STYLESHEET_NAME = "bootstrap"; 22*04fd306cSNickeau const TAG = self::CANONICAL; 23*04fd306cSNickeau public const DEFAULT_MAJOR = 5; 24*04fd306cSNickeau public const VERSION_501 = self::DEFAULT_MAJOR . ".0.1"; 25*04fd306cSNickeau public const DEFAULT_BOOTSTRAP_4_VERSION = "4.5.0"; 26*04fd306cSNickeau public const DEFAULT_BOOTSTRAP_5_VERSION = self::VERSION_501; 27*04fd306cSNickeau public const DEFAULT_BOOTSTRAP_STYLESHEET_4_VERSION = self::DEFAULT_BOOTSTRAP_4_VERSION . " - " . self::DEFAULT_STYLESHEET_NAME; 28*04fd306cSNickeau public const DEFAULT_BOOTSTRAP_STYLESHEET_5_VERSION = self::DEFAULT_BOOTSTRAP_5_VERSION . " - " . self::DEFAULT_STYLESHEET_NAME; 2937748cd8SNickeau 30*04fd306cSNickeau private Snippet $jquerySnippet; 31*04fd306cSNickeau private Snippet $jsSnippet; 32*04fd306cSNickeau private Snippet $popperSnippet; 33*04fd306cSNickeau private Snippet $cssSnippet; 3437748cd8SNickeau 35*04fd306cSNickeau /** 36*04fd306cSNickeau * @param string $qualifiedVersion - the bootstrap version separated by the stylesheet 37*04fd306cSNickeau */ 38*04fd306cSNickeau public function __construct(string $qualifiedVersion) 39*04fd306cSNickeau { 40*04fd306cSNickeau $bootstrapStyleSheetArray = explode(Bootstrap::BOOTSTRAP_VERSION_STYLESHEET_SEPARATOR, $qualifiedVersion); 41*04fd306cSNickeau $this->version = $bootstrapStyleSheetArray[0]; 42*04fd306cSNickeau /** 43*04fd306cSNickeau * In case the input is just the major version 44*04fd306cSNickeau */ 45*04fd306cSNickeau switch ($this->version) { 46*04fd306cSNickeau case "4": 47*04fd306cSNickeau $this->version = self::DEFAULT_BOOTSTRAP_4_VERSION; 48*04fd306cSNickeau break; 49*04fd306cSNickeau case "5": 50*04fd306cSNickeau $this->version = self::DEFAULT_BOOTSTRAP_5_VERSION; 51*04fd306cSNickeau break; 52*04fd306cSNickeau } 53*04fd306cSNickeau 54*04fd306cSNickeau /** 55*04fd306cSNickeau * Stylesheet 56*04fd306cSNickeau */ 57*04fd306cSNickeau if (isset($bootstrapStyleSheetArray[1])) { 58*04fd306cSNickeau $this->styleSheetName = $bootstrapStyleSheetArray[1]; 59*04fd306cSNickeau } else { 60*04fd306cSNickeau $this->styleSheetName = self::DEFAULT_STYLESHEET_NAME; 61*04fd306cSNickeau } 62*04fd306cSNickeau 63*04fd306cSNickeau $this->build(); 64*04fd306cSNickeau 65*04fd306cSNickeau } 66*04fd306cSNickeau 67*04fd306cSNickeau 68*04fd306cSNickeau const BootStrapFiveMajorVersion = 5; 69*04fd306cSNickeau const BootStrapFourMajorVersion = 4; 7037748cd8SNickeau const CANONICAL = "bootstrap"; 71*04fd306cSNickeau /** 72*04fd306cSNickeau * Stylesheet and Boostrap should have the same version 73*04fd306cSNickeau * This conf is a mix between the version and the stylesheet 74*04fd306cSNickeau * 75*04fd306cSNickeau * majorVersion.0.0 - stylesheetname 76*04fd306cSNickeau */ 77*04fd306cSNickeau public const CONF_BOOTSTRAP_VERSION_STYLESHEET = "bootstrapVersionStylesheet"; 78*04fd306cSNickeau /** 79*04fd306cSNickeau * The separator in {@link Bootstrap::CONF_BOOTSTRAP_VERSION_STYLESHEET} 80*04fd306cSNickeau */ 81*04fd306cSNickeau public const BOOTSTRAP_VERSION_STYLESHEET_SEPARATOR = " - "; 82*04fd306cSNickeau public const DEFAULT_BOOTSTRAP_VERSION_STYLESHEET = "5.0.1" . Bootstrap::BOOTSTRAP_VERSION_STYLESHEET_SEPARATOR . "bootstrap"; 83*04fd306cSNickeau 84*04fd306cSNickeau /** 85*04fd306cSNickeau * @var mixed|string 86*04fd306cSNickeau */ 87*04fd306cSNickeau private $version; 88*04fd306cSNickeau /** 89*04fd306cSNickeau * @var string - the stylesheet name 90*04fd306cSNickeau */ 91*04fd306cSNickeau private $styleSheetName; 9237748cd8SNickeau 9337748cd8SNickeau public static function getDataNamespace() 9437748cd8SNickeau { 9537748cd8SNickeau $dataToggleNamespace = ""; 9637748cd8SNickeau if (self::getBootStrapMajorVersion() == self::BootStrapFiveMajorVersion) { 9737748cd8SNickeau $dataToggleNamespace = "-bs"; 9837748cd8SNickeau } 9937748cd8SNickeau return $dataToggleNamespace; 10037748cd8SNickeau } 10137748cd8SNickeau 102*04fd306cSNickeau public function getMajorVersion(): int 10337748cd8SNickeau { 104*04fd306cSNickeau $bootstrapMajorVersion = $this->getVersion()[0]; 1054cadd4f8SNickeau try { 106*04fd306cSNickeau return DataType::toInteger($bootstrapMajorVersion); 107*04fd306cSNickeau } catch (ExceptionBadArgument $e) { 108*04fd306cSNickeau LogUtility::internalError("The bootstrap major version ($bootstrapMajorVersion) is not an integer, default taken"); 109*04fd306cSNickeau return self::DEFAULT_MAJOR; 1104cadd4f8SNickeau } 111*04fd306cSNickeau 11237748cd8SNickeau } 113*04fd306cSNickeau 114*04fd306cSNickeau /** 115*04fd306cSNickeau * Utility function that returns the major version 116*04fd306cSNickeau * because this is really common in code 117*04fd306cSNickeau * @return int - the major version 118*04fd306cSNickeau */ 119*04fd306cSNickeau public static function getBootStrapMajorVersion(): int 120*04fd306cSNickeau { 121*04fd306cSNickeau return Bootstrap::getFromContext()->getMajorVersion(); 122*04fd306cSNickeau } 12337748cd8SNickeau 12437748cd8SNickeau 125*04fd306cSNickeau public function getVersion(): string 126*04fd306cSNickeau { 127*04fd306cSNickeau return $this->version; 128*04fd306cSNickeau } 129*04fd306cSNickeau 130*04fd306cSNickeau public static function createFromQualifiedVersion(string $boostrapVersion): Bootstrap 131*04fd306cSNickeau { 132*04fd306cSNickeau return new Bootstrap($boostrapVersion); 133*04fd306cSNickeau } 134*04fd306cSNickeau 135*04fd306cSNickeau 136*04fd306cSNickeau public function getStyleSheetName(): string 137*04fd306cSNickeau { 138*04fd306cSNickeau return $this->styleSheetName; 139*04fd306cSNickeau } 140*04fd306cSNickeau 141*04fd306cSNickeau /** 142*04fd306cSNickeau * 143*04fd306cSNickeau * @return array - an array of stylesheet tag 144*04fd306cSNickeau */ 145*04fd306cSNickeau public static function getStyleSheetMetas(): array 146*04fd306cSNickeau { 147*04fd306cSNickeau 148*04fd306cSNickeau /** 149*04fd306cSNickeau * Standard stylesheet 150*04fd306cSNickeau */ 151*04fd306cSNickeau $stylesheetsFile = WikiPath::createComboResource(':library:bootstrap:bootstrapStylesheet.json'); 152*04fd306cSNickeau try { 153*04fd306cSNickeau $styleSheets = Json::createFromPath($stylesheetsFile)->toArray(); 154*04fd306cSNickeau } catch (ExceptionNotFound|ExceptionBadSyntax $e) { 155*04fd306cSNickeau LogUtility::internalError("An error has occurred reading the file ($stylesheetsFile). Error:{$e->getMessage()}", self::CANONICAL); 156*04fd306cSNickeau return []; 157*04fd306cSNickeau } 158*04fd306cSNickeau 159*04fd306cSNickeau /** 160*04fd306cSNickeau * User defined stylesheet 161*04fd306cSNickeau */ 162*04fd306cSNickeau $localStyleSheetsFile = WikiPath::createComboResource(':library:bootstrap:bootstrapLocal.json'); 163*04fd306cSNickeau try { 164*04fd306cSNickeau $localStyleSheets = Json::createFromPath($localStyleSheetsFile)->toArray(); 165*04fd306cSNickeau foreach ($localStyleSheets as $bootstrapVersion => &$localStyleSheetData) { 166*04fd306cSNickeau $actualStyleSheet = $styleSheets[$bootstrapVersion]; 167*04fd306cSNickeau if (isset($actualStyleSheet)) { 168*04fd306cSNickeau $styleSheets[$bootstrapVersion] = array_merge($actualStyleSheet, $localStyleSheetData); 169*04fd306cSNickeau } else { 170*04fd306cSNickeau $styleSheets[$bootstrapVersion] = $localStyleSheetData; 171*04fd306cSNickeau } 172*04fd306cSNickeau } 173*04fd306cSNickeau } catch (ExceptionBadSyntax|ExceptionNotFound $e) { 174*04fd306cSNickeau // user file does not exists and that's okay 175*04fd306cSNickeau } 176*04fd306cSNickeau return $styleSheets; 177*04fd306cSNickeau 178*04fd306cSNickeau 179*04fd306cSNickeau } 180*04fd306cSNickeau 181*04fd306cSNickeau 182*04fd306cSNickeau /** 183*04fd306cSNickeau * @return array - A list of all available stylesheets 184*04fd306cSNickeau * This function is used to build the configuration as a list of files 185*04fd306cSNickeau */ 186*04fd306cSNickeau public static function getQualifiedVersions(): array 187*04fd306cSNickeau { 188*04fd306cSNickeau $cssVersionsMetas = Bootstrap::getStyleSheetMetas(); 189*04fd306cSNickeau $listVersionStylesheetMeta = array(); 190*04fd306cSNickeau foreach ($cssVersionsMetas as $bootstrapVersion => $cssVersionMeta) { 191*04fd306cSNickeau foreach ($cssVersionMeta as $fileName => $values) { 192*04fd306cSNickeau $listVersionStylesheetMeta[] = $bootstrapVersion . Bootstrap::BOOTSTRAP_VERSION_STYLESHEET_SEPARATOR . $fileName; 193*04fd306cSNickeau } 194*04fd306cSNickeau } 195*04fd306cSNickeau return $listVersionStylesheetMeta; 196*04fd306cSNickeau } 197*04fd306cSNickeau 198*04fd306cSNickeau 199*04fd306cSNickeau /** 200*04fd306cSNickeau * @return Bootstrap 201*04fd306cSNickeau */ 202*04fd306cSNickeau public static function getFromContext(): Bootstrap 203*04fd306cSNickeau { 204*04fd306cSNickeau $executionContext = ExecutionContext::getActualOrCreateFromEnv(); 205*04fd306cSNickeau try { 206*04fd306cSNickeau return $executionContext->getRuntimeObject(self::CANONICAL); 207*04fd306cSNickeau } catch (ExceptionNotFound $e) { 208*04fd306cSNickeau $bootstrapStyleSheetVersion = ExecutionContext::getActualOrCreateFromEnv() 209*04fd306cSNickeau ->getConfValue(Bootstrap::CONF_BOOTSTRAP_VERSION_STYLESHEET, Bootstrap::DEFAULT_BOOTSTRAP_VERSION_STYLESHEET); 210*04fd306cSNickeau $bootstrap = new Bootstrap($bootstrapStyleSheetVersion); 211*04fd306cSNickeau $executionContext->setRuntimeObject(self::CANONICAL, $bootstrap); 212*04fd306cSNickeau return $bootstrap; 213*04fd306cSNickeau } 214*04fd306cSNickeau 215*04fd306cSNickeau } 216*04fd306cSNickeau 217*04fd306cSNickeau 218*04fd306cSNickeau /** 219*04fd306cSNickeau * @throws ExceptionNotFound 220*04fd306cSNickeau */ 221*04fd306cSNickeau public function getCssSnippet(): Snippet 222*04fd306cSNickeau { 223*04fd306cSNickeau if (isset($this->cssSnippet)) { 224*04fd306cSNickeau return $this->cssSnippet; 225*04fd306cSNickeau } 226*04fd306cSNickeau throw new ExceptionNotFound("No css snippet"); 227*04fd306cSNickeau } 228*04fd306cSNickeau 229*04fd306cSNickeau /** 230*04fd306cSNickeau * @return Snippet[] the js snippets in order 231*04fd306cSNickeau */ 232*04fd306cSNickeau public function getJsSnippets(): array 233*04fd306cSNickeau { 234*04fd306cSNickeau 235*04fd306cSNickeau /** 236*04fd306cSNickeau * The javascript snippet order is important 237*04fd306cSNickeau */ 238*04fd306cSNickeau $snippets = []; 239*04fd306cSNickeau try { 240*04fd306cSNickeau $snippets[] = $this->getJquerySnippet(); 241*04fd306cSNickeau } catch (ExceptionNotFound $e) { 242*04fd306cSNickeau // error already send at build time 243*04fd306cSNickeau // or just not present 244*04fd306cSNickeau } 245*04fd306cSNickeau try { 246*04fd306cSNickeau $snippets[] = $this->getPopperSnippet(); 247*04fd306cSNickeau } catch (ExceptionNotFound $e) { 248*04fd306cSNickeau // error already send at build time 249*04fd306cSNickeau } 250*04fd306cSNickeau try { 251*04fd306cSNickeau $snippets[] = $this->getBootstrapJsSnippet(); 252*04fd306cSNickeau } catch (ExceptionNotFound $e) { 253*04fd306cSNickeau // error already send at build time 254*04fd306cSNickeau } 255*04fd306cSNickeau return $snippets; 256*04fd306cSNickeau 257*04fd306cSNickeau } 258*04fd306cSNickeau 259*04fd306cSNickeau /** 260*04fd306cSNickeau * 261*04fd306cSNickeau */ 262*04fd306cSNickeau private function build(): void 263*04fd306cSNickeau { 264*04fd306cSNickeau 265*04fd306cSNickeau 266*04fd306cSNickeau $version = $this->getVersion(); 267*04fd306cSNickeau 268*04fd306cSNickeau // Javascript 269*04fd306cSNickeau $bootstrapJsonFile = WikiPath::createComboResource(Snippet::LIBRARY_BASE . ":bootstrap:bootstrapJavascript.json"); 270*04fd306cSNickeau try { 271*04fd306cSNickeau $bootstrapJsonMetas = Json::createFromPath($bootstrapJsonFile)->toArray(); 272*04fd306cSNickeau } catch (ExceptionBadSyntax|ExceptionNotFound $e) { 273*04fd306cSNickeau // should not happen, no need to advertise it 274*04fd306cSNickeau throw new ExceptionRuntimeInternal("Unable to read the file {$bootstrapJsonFile} as json.", self::CANONICAL, 1, $e); 275*04fd306cSNickeau } 276*04fd306cSNickeau if (!isset($bootstrapJsonMetas[$version])) { 277*04fd306cSNickeau throw new ExceptionRuntimeInternal("The bootstrap version ($version) could not be found in the file $bootstrapJsonFile"); 278*04fd306cSNickeau } 279*04fd306cSNickeau $bootstrapMetas = $bootstrapJsonMetas[$version]; 280*04fd306cSNickeau 281*04fd306cSNickeau // Css 282*04fd306cSNickeau $bootstrapMetas["stylesheet"] = $this->getStyleSheetMeta(); 283*04fd306cSNickeau 284*04fd306cSNickeau 285*04fd306cSNickeau foreach ($bootstrapMetas as $key => $script) { 286*04fd306cSNickeau $fileNameWithExtension = $script["file"]; 287*04fd306cSNickeau $file = LocalPath::createFromPathString($fileNameWithExtension); 288*04fd306cSNickeau 289*04fd306cSNickeau $path = WikiPath::createComboResource(":library:bootstrap:$version:$fileNameWithExtension"); 290*04fd306cSNickeau $snippet = Snippet::createSnippet($path) 291*04fd306cSNickeau ->setComponentId(self::TAG); 292*04fd306cSNickeau $url = $script["url"]; 293*04fd306cSNickeau if (!empty($url)) { 294*04fd306cSNickeau try { 295*04fd306cSNickeau $url = Url::createFromString($url); 296*04fd306cSNickeau $snippet->setRemoteUrl($url); 297*04fd306cSNickeau if (isset($script['integrity'])) { 298*04fd306cSNickeau $snippet->setIntegrity($script['integrity']); 299*04fd306cSNickeau } 300*04fd306cSNickeau } catch (ExceptionBadArgument|ExceptionBadSyntax $e) { 301*04fd306cSNickeau LogUtility::internalError("The url ($url) for the bootstrap metadata ($fileNameWithExtension) from the bootstrap dictionary is not valid. Error:{$e->getMessage()}", self::CANONICAL); 302*04fd306cSNickeau } 303*04fd306cSNickeau } 304*04fd306cSNickeau 305*04fd306cSNickeau try { 306*04fd306cSNickeau $extension = $file->getExtension(); 307*04fd306cSNickeau } catch (ExceptionNotFound $e) { 308*04fd306cSNickeau LogUtility::internalError("No extension was found on the file metadata ($fileNameWithExtension) from the bootstrap dictionary", self::CANONICAL); 309*04fd306cSNickeau continue; 310*04fd306cSNickeau } 311*04fd306cSNickeau switch ($extension) { 312*04fd306cSNickeau case Snippet::EXTENSION_JS: 313*04fd306cSNickeau $snippet->setCritical(false); 314*04fd306cSNickeau switch ($key) { 315*04fd306cSNickeau case "jquery": 316*04fd306cSNickeau $this->jquerySnippet = $snippet; 317*04fd306cSNickeau break; 318*04fd306cSNickeau case "js": 319*04fd306cSNickeau $this->jsSnippet = $snippet; 320*04fd306cSNickeau break; 321*04fd306cSNickeau case "popper": 322*04fd306cSNickeau $this->popperSnippet = $snippet; 323*04fd306cSNickeau break; 324*04fd306cSNickeau default: 325*04fd306cSNickeau LogUtility::internalError("The snippet key ($key) is unknown for bootstrap", self::CANONICAL); 326*04fd306cSNickeau break; 327*04fd306cSNickeau } 328*04fd306cSNickeau break; 329*04fd306cSNickeau case Snippet::EXTENSION_CSS: 330*04fd306cSNickeau switch ($key) { 331*04fd306cSNickeau case "stylesheet": 332*04fd306cSNickeau $this->cssSnippet = $snippet; 333*04fd306cSNickeau break; 334*04fd306cSNickeau default: 335*04fd306cSNickeau LogUtility::internalError("The snippet key ($key) is unknown for bootstrap"); 336*04fd306cSNickeau break; 337*04fd306cSNickeau } 338*04fd306cSNickeau } 339*04fd306cSNickeau } 340*04fd306cSNickeau 341*04fd306cSNickeau 342*04fd306cSNickeau } 343*04fd306cSNickeau 344*04fd306cSNickeau public function getSnippets(): array 345*04fd306cSNickeau { 346*04fd306cSNickeau 347*04fd306cSNickeau $snippets = []; 348*04fd306cSNickeau try { 349*04fd306cSNickeau $snippets[] = $this->getCssSnippet(); 350*04fd306cSNickeau } catch (ExceptionNotFound $e) { 351*04fd306cSNickeau // error already send at build time 352*04fd306cSNickeau } 353*04fd306cSNickeau 354*04fd306cSNickeau /** 355*04fd306cSNickeau * The javascript snippet 356*04fd306cSNickeau */ 357*04fd306cSNickeau return array_merge($snippets, $this->getJsSnippets()); 358*04fd306cSNickeau } 359*04fd306cSNickeau 360*04fd306cSNickeau /** 361*04fd306cSNickeau * @throws ExceptionNotFound 362*04fd306cSNickeau */ 363*04fd306cSNickeau public function getPopperSnippet(): Snippet 364*04fd306cSNickeau { 365*04fd306cSNickeau if (isset($this->popperSnippet)) { 366*04fd306cSNickeau return $this->popperSnippet; 367*04fd306cSNickeau } 368*04fd306cSNickeau throw new ExceptionNotFound("No popper snippet"); 369*04fd306cSNickeau } 370*04fd306cSNickeau 371*04fd306cSNickeau /** 372*04fd306cSNickeau * @throws ExceptionNotFound 373*04fd306cSNickeau */ 374*04fd306cSNickeau public function getBootstrapJsSnippet(): Snippet 375*04fd306cSNickeau { 376*04fd306cSNickeau if (isset($this->jsSnippet)) { 377*04fd306cSNickeau return $this->jsSnippet; 378*04fd306cSNickeau } 379*04fd306cSNickeau throw new ExceptionNotFound("No js snippet"); 380*04fd306cSNickeau } 381*04fd306cSNickeau 382*04fd306cSNickeau /** 383*04fd306cSNickeau * @throws ExceptionNotFound 384*04fd306cSNickeau */ 385*04fd306cSNickeau private function getJquerySnippet(): Snippet 386*04fd306cSNickeau { 387*04fd306cSNickeau if (isset($this->jquerySnippet)) { 388*04fd306cSNickeau return $this->jquerySnippet; 389*04fd306cSNickeau } 390*04fd306cSNickeau throw new ExceptionNotFound("No jquery snippet"); 391*04fd306cSNickeau } 392*04fd306cSNickeau 393*04fd306cSNickeau /** 394*04fd306cSNickeau * @return array - the stylesheet meta (file, url, ...) for the version 395*04fd306cSNickeau */ 396*04fd306cSNickeau private function getStyleSheetMeta(): array 397*04fd306cSNickeau { 398*04fd306cSNickeau 399*04fd306cSNickeau $styleSheets = self::getStyleSheetMetas(); 400*04fd306cSNickeau 401*04fd306cSNickeau $version = $this->getVersion(); 402*04fd306cSNickeau if (!isset($styleSheets[$version])) { 403*04fd306cSNickeau LogUtility::internalError("The bootstrap version ($version) could not be found"); 404*04fd306cSNickeau return []; 405*04fd306cSNickeau } 406*04fd306cSNickeau $styleSheetsForVersion = $styleSheets[$version]; 407*04fd306cSNickeau 408*04fd306cSNickeau $styleSheetName = $this->getStyleSheetName(); 409*04fd306cSNickeau if (!isset($styleSheetsForVersion[$styleSheetName])) { 410*04fd306cSNickeau LogUtility::internalError("The bootstrap stylesheet ($styleSheetName) could not be found for the version ($version) in the distribution or custom configuration files"); 411*04fd306cSNickeau return []; 412*04fd306cSNickeau } 413*04fd306cSNickeau $styleSheetForVersionAndName = $styleSheetsForVersion[$styleSheetName]; 414*04fd306cSNickeau 415*04fd306cSNickeau /** 416*04fd306cSNickeau * Select Rtl or Ltr 417*04fd306cSNickeau * Stylesheet name may have another level 418*04fd306cSNickeau * with direction property of the language 419*04fd306cSNickeau * 420*04fd306cSNickeau * Bootstrap needs another stylesheet 421*04fd306cSNickeau * See https://getbootstrap.com/docs/5.0/getting-started/rtl/ 422*04fd306cSNickeau */ 423*04fd306cSNickeau try { 424*04fd306cSNickeau $direction = Lang::createFromRequestedMarkup()->getDirection(); 425*04fd306cSNickeau } catch (ExceptionNotFound $e) { 426*04fd306cSNickeau $direction = Site::getLangObject()->getDirection(); 427*04fd306cSNickeau } 428*04fd306cSNickeau if (isset($styleSheetForVersionAndName[$direction])) { 429*04fd306cSNickeau return $styleSheetForVersionAndName[$direction]; 430*04fd306cSNickeau } 431*04fd306cSNickeau if (!isset($styleSheetForVersionAndName['file'])) { 432*04fd306cSNickeau LogUtility::internalError('The file stylesheet attribute is unknown (' . DataType::toString($styleSheetForVersionAndName) . ')'); 433*04fd306cSNickeau } 434*04fd306cSNickeau return $styleSheetForVersionAndName; 43537748cd8SNickeau } 43637748cd8SNickeau} 437