137748cd8SNickeau<?php 237748cd8SNickeau 337748cd8SNickeau 437748cd8SNickeaunamespace ComboStrap; 537748cd8SNickeau 637748cd8SNickeau 704fd306cSNickeauuse ComboStrap\Meta\Api\Metadata; 804fd306cSNickeauuse ComboStrap\Meta\Api\MetadataText; 937748cd8SNickeauuse dokuwiki\Cache\Cache; 1037748cd8SNickeau 11c3437056SNickeauclass Lang extends MetadataText 1237748cd8SNickeau{ 1337748cd8SNickeau 14c3437056SNickeau public const PROPERTY_NAME = "lang"; 15c3437056SNickeau 1637748cd8SNickeau 1737748cd8SNickeau /** 1837748cd8SNickeau * Process the lang attribute 1937748cd8SNickeau * https://www.w3.org/International/questions/qa-html-language-declarations 2037748cd8SNickeau * @param TagAttributes $attributes 2137748cd8SNickeau * 2237748cd8SNickeau * Language supported: 2337748cd8SNickeau * http://www.iana.org/assignments/language-subtag-registry/language-subtag-registry 2437748cd8SNickeau * 2537748cd8SNickeau * Common Locale Data Repository 2637748cd8SNickeau * http://cldr.unicode.org/ 2737748cd8SNickeau * Data: 2837748cd8SNickeau * * http://www.unicode.org/Public/cldr/ 2937748cd8SNickeau * * https://github.com/unicode-cldr/ 3037748cd8SNickeau * * https://github.com/unicode-org/cldr-json 3137748cd8SNickeau * The ''dir'' data is known as the ''characterOrder'' 3237748cd8SNickeau * 3337748cd8SNickeau */ 3437748cd8SNickeau public static function processLangAttribute(&$attributes) 3537748cd8SNickeau { 3637748cd8SNickeau 3737748cd8SNickeau 3837748cd8SNickeau /** 3937748cd8SNickeau * Adding the lang attribute 4037748cd8SNickeau * if set 4137748cd8SNickeau */ 42c3437056SNickeau if ($attributes->hasComponentAttribute(self::PROPERTY_NAME)) { 43c3437056SNickeau $langValue = $attributes->getValueAndRemove(self::PROPERTY_NAME); 444cadd4f8SNickeau $attributes->addOutputAttributeValue("lang", $langValue); 4537748cd8SNickeau 4637748cd8SNickeau $languageDataCache = new Cache("combo_" . $langValue, ".json"); 4737748cd8SNickeau $cacheDataUsable = $languageDataCache->useCache(); 4837748cd8SNickeau if (!$cacheDataUsable) { 4937748cd8SNickeau 5037748cd8SNickeau // Language about the data 51*498fa011SNicolas GERARD $downloadUrl = "https://raw.githubusercontent.com/unicode-org/cldr-json/refs/tags/47.0.0/cldr-json/cldr-misc-full/main/$langValue/layout.json"; 5237748cd8SNickeau 5304fd306cSNickeau if (PluginUtility::isDevOrTest()) { 5404fd306cSNickeau // phpunit takes over and would catch and cache the error 5504fd306cSNickeau $filePointer = fopen($downloadUrl, 'r'); 5604fd306cSNickeau } else { 5737748cd8SNickeau $filePointer = @fopen($downloadUrl, 'r'); 5804fd306cSNickeau } 5937748cd8SNickeau if ($filePointer != false) { 6037748cd8SNickeau 6137748cd8SNickeau $numberOfByte = @file_put_contents($languageDataCache->cache, $filePointer); 6237748cd8SNickeau if ($numberOfByte != false) { 63c3437056SNickeau LogUtility::msg("The new language data ($langValue) was downloaded", LogUtility::LVL_MSG_INFO, self::PROPERTY_NAME); 6437748cd8SNickeau $cacheDataUsable = true; 6537748cd8SNickeau } else { 66c3437056SNickeau LogUtility::msg("Internal error: The language data ($langValue) could no be written to ($languageDataCache->cache)", LogUtility::LVL_MSG_ERROR, self::PROPERTY_NAME); 6737748cd8SNickeau } 6837748cd8SNickeau 6937748cd8SNickeau } else { 7037748cd8SNickeau 7104fd306cSNickeau // fopen(): Unable to find the wrapper "https" - did you forget to enable it when you configured PHP? 7204fd306cSNickeau $error_get_last = error_get_last(); 7304fd306cSNickeau $message = $error_get_last['message']; 7404fd306cSNickeau LogUtility::msg("The data for the language ($langValue) could not be downloaded at (<a href=\"$downloadUrl\">$langValue</a>). Error: " . $message, LogUtility::LVL_MSG_ERROR, self::PROPERTY_NAME); 7537748cd8SNickeau 7637748cd8SNickeau } 7737748cd8SNickeau } 7837748cd8SNickeau 7937748cd8SNickeau if ($cacheDataUsable) { 8037748cd8SNickeau $jsonAsArray = true; 8137748cd8SNickeau $languageData = json_decode(file_get_contents($languageDataCache->cache), $jsonAsArray); 8237748cd8SNickeau if ($languageData == null) { 83c3437056SNickeau LogUtility::msg("We could not read the data from the language ($langValue). No direction was set.", LogUtility::LVL_MSG_ERROR, self::PROPERTY_NAME); 8437748cd8SNickeau return; 8537748cd8SNickeau } 8637748cd8SNickeau $characterOrder = $languageData["main"][$langValue]["layout"]["orientation"]["characterOrder"]; 8737748cd8SNickeau if ($characterOrder == "right-to-left") { 884cadd4f8SNickeau $attributes->addOutputAttributeValue("dir", "rtl"); 8937748cd8SNickeau } else { 904cadd4f8SNickeau $attributes->addOutputAttributeValue("dir", "ltr"); 9137748cd8SNickeau } 9237748cd8SNickeau } else { 93c3437056SNickeau 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); 9437748cd8SNickeau } 9537748cd8SNickeau 9637748cd8SNickeau } 9737748cd8SNickeau 9837748cd8SNickeau } 9937748cd8SNickeau 10004fd306cSNickeau public static function createForMarkup(MarkupPath $markup): Lang 101c3437056SNickeau { 10204fd306cSNickeau $lang = new Lang(); 10304fd306cSNickeau $lang->setResource($markup); 10404fd306cSNickeau return $lang; 105c3437056SNickeau } 106c3437056SNickeau 10704fd306cSNickeau 10804fd306cSNickeau /** 10904fd306cSNickeau * @throws ExceptionNotFound 11004fd306cSNickeau */ 11104fd306cSNickeau public static function createFromRequestedMarkup(): Lang 11204fd306cSNickeau { 11304fd306cSNickeau return self::createForMarkup(MarkupPath::createFromRequestedPage()); 11404fd306cSNickeau } 11504fd306cSNickeau 11604fd306cSNickeau /** 11704fd306cSNickeau * Set the direction of the text 11804fd306cSNickeau * The global lang direction (not yet inside the Lang class) 11904fd306cSNickeau * @param string $string 12004fd306cSNickeau * @return void 12104fd306cSNickeau */ 12204fd306cSNickeau public static function setDirection(string $string) 12304fd306cSNickeau { 12404fd306cSNickeau global $lang; 12504fd306cSNickeau $lang["direction"] = $string; 12604fd306cSNickeau } 12704fd306cSNickeau 12804fd306cSNickeau public static function createFromValue(string $langValue): Lang 12904fd306cSNickeau { 13004fd306cSNickeau $lang = new Lang(); 13104fd306cSNickeau $lang->value = $langValue; 13204fd306cSNickeau return $lang; 13304fd306cSNickeau } 13404fd306cSNickeau 13504fd306cSNickeau static public function getTab(): ?string 136c3437056SNickeau { 137c3437056SNickeau return MetaManagerForm::TAB_LANGUAGE_VALUE; 138c3437056SNickeau } 139c3437056SNickeau 140c3437056SNickeau /** 14104fd306cSNickeau * @return string 14204fd306cSNickeau */ 14304fd306cSNickeau public function getValueOrDefault(): string 14404fd306cSNickeau { 14504fd306cSNickeau try { 14604fd306cSNickeau return $this->getValue(); 14704fd306cSNickeau } catch (ExceptionNotFound $e) { 14804fd306cSNickeau return $this->getDefaultValue(); 14904fd306cSNickeau } 15004fd306cSNickeau } 15104fd306cSNickeau 15204fd306cSNickeau 15304fd306cSNickeau /** 15404fd306cSNickeau * @throws ExceptionCompile 155c3437056SNickeau */ 156c3437056SNickeau public function setFromStoreValue($value): Metadata 157c3437056SNickeau { 158c3437056SNickeau 159c3437056SNickeau $this->validityCheck($value); 160c3437056SNickeau return parent::setFromStoreValue($value); 161c3437056SNickeau 162c3437056SNickeau } 163c3437056SNickeau 164c3437056SNickeau /** 165c3437056SNickeau * @param string|null $value 166c3437056SNickeau * @return Metadata 16704fd306cSNickeau * @throws ExceptionCompile 168c3437056SNickeau */ 169c3437056SNickeau public function setValue($value): Metadata 170c3437056SNickeau { 171c3437056SNickeau $this->validityCheck($value); 172c3437056SNickeau return parent::setValue($value); 173c3437056SNickeau } 174c3437056SNickeau 175c3437056SNickeau 17604fd306cSNickeau static public function getDescription(): string 177c3437056SNickeau { 178c3437056SNickeau return "The language of the page"; 179c3437056SNickeau } 180c3437056SNickeau 18104fd306cSNickeau static public function getLabel(): string 182c3437056SNickeau { 183c3437056SNickeau return "Language"; 184c3437056SNickeau } 185c3437056SNickeau 186c3437056SNickeau public static function getName(): string 187c3437056SNickeau { 188c3437056SNickeau return self::PROPERTY_NAME; 189c3437056SNickeau } 190c3437056SNickeau 19104fd306cSNickeau static public function getPersistenceType(): string 192c3437056SNickeau { 193c3437056SNickeau return Metadata::PERSISTENT_METADATA; 194c3437056SNickeau } 195c3437056SNickeau 19604fd306cSNickeau static public function isMutable(): bool 197c3437056SNickeau { 198c3437056SNickeau return true; 199c3437056SNickeau } 200c3437056SNickeau 20104fd306cSNickeau /** 20204fd306cSNickeau * @return string 20304fd306cSNickeau */ 20404fd306cSNickeau public function getDefaultValue(): string 205c3437056SNickeau { 206c3437056SNickeau return Site::getLang(); 207c3437056SNickeau } 208c3437056SNickeau 209c3437056SNickeau /** 21004fd306cSNickeau * @throws ExceptionCompile 211c3437056SNickeau */ 212c3437056SNickeau private function validityCheck($value) 213c3437056SNickeau { 214c3437056SNickeau if ($value === "" || $value === null) { 215c3437056SNickeau return; 216c3437056SNickeau } 217c3437056SNickeau if (!StringUtility::match($value, "^[a-zA-Z]{2}$")) { 21804fd306cSNickeau throw new ExceptionCompile("The lang value ($value) for the page ($this) does not have two letters", $this->getCanonical()); 219c3437056SNickeau } 220c3437056SNickeau } 221c3437056SNickeau 22204fd306cSNickeau static public function getCanonical(): string 223c3437056SNickeau { 224c3437056SNickeau return "lang"; 225c3437056SNickeau } 226c3437056SNickeau 22704fd306cSNickeau public function getDirection() 22804fd306cSNickeau { 22904fd306cSNickeau /** 23004fd306cSNickeau * TODO: should be base on the page value 23104fd306cSNickeau * Search PHP and CLDR 23204fd306cSNickeau * https://punic.github.io/ 23304fd306cSNickeau * https://www.php.net/manual/en/book.intl.php 23404fd306cSNickeau * 23504fd306cSNickeau * Example: 23604fd306cSNickeau * https://github.com/salarmehr/cosmopolitan 23704fd306cSNickeau * use Salarmehr\Cosmopolitan\Cosmo; 23804fd306cSNickeau * 23904fd306cSNickeau * echo Cosmo::create('fa')->direction(); // rlt 24004fd306cSNickeau * echo Cosmo::create('en')->direction(); // ltr 24104fd306cSNickeau */ 24204fd306cSNickeau return Site::getLangDirection(); 24304fd306cSNickeau } 24404fd306cSNickeau 24504fd306cSNickeau 24604fd306cSNickeau static public function isOnForm(): bool 24704fd306cSNickeau { 24804fd306cSNickeau return true; 24904fd306cSNickeau } 250c3437056SNickeau 25137748cd8SNickeau} 252