Browse Source

* Add translation handling
* begin working on making templates proper templates

Nathaniel van Diepen 7 years ago
parent
commit
badfef5aed
4 changed files with 68 additions and 5 deletions
  1. 20 5
      Data/template.class.php
  2. 6 0
      Http/request.class.php
  3. 28 0
      Http/response.class.php
  4. 14 0
      app.class.php

+ 20 - 5
Data/template.class.php

@@ -10,10 +10,17 @@
 		private static $templates = [];
 		private $template;
 		private $name;
-		public function __construct(string $name, callable $template){
+		public function __construct(string $name, string $template, bool $is_file = false){
 			if(isset(static::$templates[$name])){
 				throw new Exception("Template {$name} already exists");
 			}
+			if($is_file){
+				$path = realpath($template);
+				if(!file_exists($path)){
+					throw new Exception("Template file {$template} doesn't exist");
+				}
+				$template = file_get_contents($path);
+			}
 			$this->template = $template;
 			$this->name = $name;
 			static::$templates[$name] = $this;
@@ -23,10 +30,7 @@
 			if($this->fire('before', $data) === false){
 				throw new Exception("Render on template {$this->name} cancelled. Before.");
 			}
-			ob_start();
-			$output = \Closure::FromCallable($this->template)->call($data);
-			$output .= ob_get_contents();
-			ob_end_clean();
+			$output = static::parse($this->template, $data);
 			if($this->fire('after', $output) === false){
 				throw new Exception("Render on template {$this->name} cancelled. After");
 			}
@@ -39,5 +43,16 @@
 			}
 			return $template->run($data);
 		}
+		public static function parse(string $template, $data){
+			$output = preg_replace_callback_array([
+				'/\{([^#\/][^}\n]+?)\}/i'=> function($match) use($data){
+					return $data[$match[1]] ?? '';
+				},
+				"/_\(['\"]?([^']+)['\"]?\)/i"=> function($match){
+					return _($match[1]);
+				}
+			], $template);
+			return $output;
+		}
 	}
 ?>

+ 6 - 0
Http/request.class.php

@@ -28,6 +28,9 @@
 				case 'headers':case 'url':case 'body':case 'verb':
 					return $this->$name;
 				break;
+				case 'locale':
+					return \Locale::acceptFromHttp($this->header('Accept-Language'));
+				break;
 			}
 		}
 		public function header($name){
@@ -71,5 +74,8 @@
 		public static function get_verb(){
 			return $_SERVER['REQUEST_METHOD'];
 		}
+		public static function get_locale(){
+			Locale::acceptFromHttp($_SERVER['HTTP_ACCEPT_LANGUAGE']);
+		}
 	}
 ?>

+ 28 - 0
Http/response.class.php

@@ -125,5 +125,33 @@
 			flush();
 			$this->fire('aftershutdown');
 		}
+		public static function locale(string $locale, string $domain, string $folder, string $codeset = 'UTF-8'){
+			$path = realpath($folder);
+			if($path !== false){
+				bindtextdomain($domain, $path);
+				textdomain($domain);
+				bind_textdomain_codeset($domain, $codeset);
+				$orig_locale = $locale;
+				if(!file_exists("{$path}/$locale/LC_MESSAGES/{$domain}.mo")){
+					$locale = \Locale::getPrimaryLanguage($locale);
+					if(!file_exists("{$path}/$locale/LC_MESSAGES/{$domain}.mo")){
+						$locale = \Locale::getDefault();
+						if(!file_exists("{$path}/$locale/LC_MESSAGES/{$domain}.mo")){
+							$dir = dir("{$path}/");
+							do{
+								$locale = $dir->read();
+								if($locale === false){
+									trigger_error("Unable to find fallback locale for {$orig_locale}", E_USER_WARNING);
+									break;
+								}
+							}while(!file_exists("{$path}/$locale/LC_MESSAGES/{$domain}.mo"));
+						}
+					}
+				}
+			}else{
+				trigger_error("Locale folder {$folder} missing", E_USER_WARNING);
+			}
+			\Locale::setDefault($locale);
+		}
 	}
 ?>

+ 14 - 0
app.class.php

@@ -15,8 +15,15 @@
 		public $_onerror;
 		public $request = null;
 		public $response;
+		public $name;
+		public $textdomain;
+		public $textdomain_folder;
+		public $textdomain_codeset;
 		public function __construct(string $name, callable $fn = null, array $events = null){
 			$this->name = $name;
+			$this->textdomain = $name;
+			$this->textdomain_folder = __DIR__.'/locale/';
+			$this->textdomain_codeset = 'UFT-8';
 			$this->router = new Router();
 			$this->response = new Response();
 			$this->routers = [];
@@ -90,6 +97,7 @@
 			}
 			$res = $this->response;
 			$this->request = $req = new Request($verb, $url, $headers, $data);
+			Response::locale($req->locale, $this->textdomain, $this->textdomain_folder, $this->textdomain_codeset);
 			if($this->fire('handle', $req, $res)){
 				$self = $this;
 				$onerror = function($res, $error) use($self){
@@ -189,6 +197,12 @@
 				$fn($req, $res, $error);
 			}
 		}
+		public function locale(string $domain, string $folder, string $codeset = 'UTF-8'){
+			$this->textdomain = $domain;
+			$this->textdomain_codeset = $codeset;
+			$this->textdomain_folder = $folder;
+			return $this;
+		}
 	}
 	set_error_handler(function($errno, $errstr, $errfile, $errline){
 		App::shutdown_error(new App\Exception($errstr, $errno, null, $errfile, $errline, debug_backtrace()));