154 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			154 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| 
 | |
| namespace Core\Objects\DatabaseEntity {
 | |
| 
 | |
|   use Core\Objects\DatabaseEntity\Attribute\MaxLength;
 | |
|   use Core\Objects\DatabaseEntity\Attribute\Transient;
 | |
|   use Core\Objects\DatabaseEntity\Controller\DatabaseEntity;
 | |
| 
 | |
|   // TODO: language from cookie?
 | |
|   class Language extends DatabaseEntity {
 | |
| 
 | |
|     const AMERICAN_ENGLISH = 1;
 | |
|     const GERMAN_STANDARD = 2;
 | |
| 
 | |
|     const LANG_CODE_PATTERN = "/^[a-zA-Z]{2}_[a-zA-Z]{2}$/";
 | |
|     const LANG_MODULE_PATTERN = "/[a-zA-Z0-9_-]/";
 | |
| 
 | |
|     #[MaxLength(5)] private string $code;
 | |
|     #[MaxLength(32)] private string $name;
 | |
| 
 | |
|     #[Transient] protected array $entries = [];
 | |
| 
 | |
|     public function __construct(int $id, string $code, string $name) {
 | |
|       parent::__construct($id);
 | |
|       $this->code = $code;
 | |
|       $this->name = $name;
 | |
|     }
 | |
| 
 | |
|     public function getCode(): string {
 | |
|       return $this->code;
 | |
|     }
 | |
| 
 | |
|     public function getShortCode(): string {
 | |
|       return substr($this->code, 0, 2);
 | |
|     }
 | |
| 
 | |
|     public function getName(): string {
 | |
|       return $this->name;
 | |
|     }
 | |
| 
 | |
|     public function sendCookie(string $domain) {
 | |
|       setcookie('lang', $this->code, 0, "/", $domain, false, false);
 | |
|     }
 | |
| 
 | |
|     public function jsonSerialize(): array {
 | |
|       return array(
 | |
|         'id' => $this->getId(),
 | |
|         'code' => $this->code,
 | |
|         'shortCode' => explode("_", $this->code)[0],
 | |
|         'name' => $this->name,
 | |
|       );
 | |
|     }
 | |
| 
 | |
|     public function activate() {
 | |
|       global $LANGUAGE;
 | |
|       $LANGUAGE = $this;
 | |
|     }
 | |
| 
 | |
|     public static function getInstance(): Language {
 | |
|       global $LANGUAGE;
 | |
|       return $LANGUAGE;
 | |
|     }
 | |
| 
 | |
|     public static function DEFAULT_LANGUAGE(bool $fromCookie = true): Language {
 | |
|       if ($fromCookie && isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
 | |
|         $acceptLanguage = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
 | |
|         $acceptedLanguages = explode(',', $acceptLanguage);
 | |
|         foreach ($acceptedLanguages as $code) {
 | |
|           if (strlen($code) == 2) {
 | |
|             $code = $code . '_' . strtoupper($code);
 | |
|           }
 | |
| 
 | |
|           $code = str_replace("-", "_", $code);
 | |
|           if (!preg_match(self::LANG_CODE_PATTERN, $code)) {
 | |
|             continue;
 | |
|           }
 | |
| 
 | |
|           return new Language(0, $code, "");
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       return new Language(1, "en_US", "American English");
 | |
|     }
 | |
| 
 | |
|     public function getEntries(?string $module = null): ?array {
 | |
|       if (!$module) {
 | |
|         return $this->entries;
 | |
|       } else {
 | |
|         return $this->entries[$module] ?? null;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     public function translate(string $key): string {
 | |
|       if (preg_match("/(\w+)\.(\w+)/", $key, $matches)) {
 | |
|         $module = $matches[1];
 | |
|         $moduleKey = $matches[2];
 | |
|         if ($this->hasModule($module) && array_key_exists($moduleKey, $this->entries[$module])) {
 | |
|           return $this->entries[$module][$moduleKey];
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       return "[$key]";
 | |
|     }
 | |
| 
 | |
|     public function addModule(string $module, array $entries) {
 | |
|       if ($this->hasModule($module)) {
 | |
|         $this->entries[$module] = array_merge($this->entries[$module], $entries);
 | |
|       } else {
 | |
|         $this->entries[$module] = $entries;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     public function loadModule(string $module, bool $forceReload=false): bool {
 | |
|       if ($this->hasModule($module) && !$forceReload) {
 | |
|         return true;
 | |
|       }
 | |
| 
 | |
|       if (!preg_match(self::LANG_MODULE_PATTERN, $module)) {
 | |
|         return false;
 | |
|       }
 | |
| 
 | |
|       if (!preg_match(self::LANG_CODE_PATTERN, $this->code)) {
 | |
|         return false;
 | |
|       }
 | |
| 
 | |
|       foreach (["Site", "Core"] as $baseDir) {
 | |
|         $filePath = realpath(implode("/", [$baseDir, "Localization", $this->code, "$module.php"]));
 | |
|         if ($filePath && is_file($filePath)) {
 | |
|           $moduleEntries = @include_once $filePath;
 | |
|           $this->addModule($module, $moduleEntries);
 | |
|           return true;
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       return false;
 | |
|     }
 | |
| 
 | |
|     public function hasModule(string $module): bool {
 | |
|       return array_key_exists($module, $this->entries);
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| namespace {
 | |
|   function L(string $key): string {
 | |
|     if (!array_key_exists('LANGUAGE', $GLOBALS)) {
 | |
|       return "[$key]";
 | |
|     }
 | |
| 
 | |
|     global $LANGUAGE;
 | |
|     return $LANGUAGE->translate($key);
 | |
|   }
 | |
| }
 |