1<?php 2 3 4namespace ComboStrap; 5 6 7use dokuwiki\Cache\Cache; 8 9class Lang extends MetadataText 10{ 11 12 public const PROPERTY_NAME = "lang"; 13 14 15 /** 16 * Process the lang attribute 17 * https://www.w3.org/International/questions/qa-html-language-declarations 18 * @param TagAttributes $attributes 19 * 20 * Language supported: 21 * http://www.iana.org/assignments/language-subtag-registry/language-subtag-registry 22 * 23 * Common Locale Data Repository 24 * http://cldr.unicode.org/ 25 * Data: 26 * * http://www.unicode.org/Public/cldr/ 27 * * https://github.com/unicode-cldr/ 28 * * https://github.com/unicode-org/cldr-json 29 * The ''dir'' data is known as the ''characterOrder'' 30 * 31 */ 32 public static function processLangAttribute(&$attributes) 33 { 34 35 36 /** 37 * Adding the lang attribute 38 * if set 39 */ 40 if ($attributes->hasComponentAttribute(self::PROPERTY_NAME)) { 41 $langValue = $attributes->getValueAndRemove(self::PROPERTY_NAME); 42 $attributes->addOutputAttributeValue("lang", $langValue); 43 44 $languageDataCache = new Cache("combo_" . $langValue, ".json"); 45 $cacheDataUsable = $languageDataCache->useCache(); 46 if (!$cacheDataUsable) { 47 48 // Language about the data 49 $downloadUrl = "https://raw.githubusercontent.com/unicode-org/cldr-json/master/cldr-json/cldr-misc-modern/main/$langValue/layout.json"; 50 51 $filePointer = @fopen($downloadUrl, 'r'); 52 if ($filePointer != false) { 53 54 $numberOfByte = @file_put_contents($languageDataCache->cache, $filePointer); 55 if ($numberOfByte != false) { 56 LogUtility::msg("The new language data ($langValue) was downloaded", LogUtility::LVL_MSG_INFO, self::PROPERTY_NAME); 57 $cacheDataUsable = true; 58 } else { 59 LogUtility::msg("Internal error: The language data ($langValue) could no be written to ($languageDataCache->cache)", LogUtility::LVL_MSG_ERROR, self::PROPERTY_NAME); 60 } 61 62 } else { 63 64 LogUtility::msg("The data for the language ($langValue) could not be found at ($downloadUrl).", LogUtility::LVL_MSG_ERROR, self::PROPERTY_NAME); 65 66 } 67 } 68 69 if ($cacheDataUsable) { 70 $jsonAsArray = true; 71 $languageData = json_decode(file_get_contents($languageDataCache->cache), $jsonAsArray); 72 if ($languageData == null) { 73 LogUtility::msg("We could not read the data from the language ($langValue). No direction was set.", LogUtility::LVL_MSG_ERROR, self::PROPERTY_NAME); 74 return; 75 } 76 $characterOrder = $languageData["main"][$langValue]["layout"]["orientation"]["characterOrder"]; 77 if ($characterOrder == "right-to-left") { 78 $attributes->addOutputAttributeValue("dir", "rtl"); 79 } else { 80 $attributes->addOutputAttributeValue("dir", "ltr"); 81 } 82 } else { 83 LogUtility::msg("The language direction cannot be set because no language data was found for the language ($langValue)", LogUtility::LVL_MSG_WARNING, self::PROPERTY_NAME); 84 } 85 86 } 87 88 } 89 90 public static function createForPage(Page $page) 91 { 92 return (new Lang()) 93 ->setResource($page); 94 } 95 96 public function getTab(): ?string 97 { 98 return MetaManagerForm::TAB_LANGUAGE_VALUE; 99 } 100 101 /** 102 * @throws ExceptionCombo 103 */ 104 public function setFromStoreValue($value): Metadata 105 { 106 107 $this->validityCheck($value); 108 return parent::setFromStoreValue($value); 109 110 } 111 112 /** 113 * @param string|null $value 114 * @return Metadata 115 * @throws ExceptionCombo 116 */ 117 public function setValue($value): Metadata 118 { 119 $this->validityCheck($value); 120 return parent::setValue($value); 121 } 122 123 124 public function getDescription(): string 125 { 126 return "The language of the page"; 127 } 128 129 public function getLabel(): string 130 { 131 return "Language"; 132 } 133 134 public static function getName(): string 135 { 136 return self::PROPERTY_NAME; 137 } 138 139 public function getPersistenceType(): string 140 { 141 return Metadata::PERSISTENT_METADATA; 142 } 143 144 public function getMutable(): bool 145 { 146 return true; 147 } 148 149 public function getDefaultValue() 150 { 151 return Site::getLang(); 152 } 153 154 /** 155 * @throws ExceptionCombo 156 */ 157 private function validityCheck($value) 158 { 159 if ($value === "" || $value === null) { 160 return; 161 } 162 if (!StringUtility::match($value, "^[a-zA-Z]{2}$")) { 163 throw new ExceptionCombo("The lang value ($value) for the page ($this) does not have two letters", $this->getCanonical()); 164 } 165 } 166 167 public function getCanonical(): string 168 { 169 return "lang"; 170 } 171 172 173} 174