diff --git a/bootstrap.php b/bootstrap.php index 1e026060..0168e834 100644 --- a/bootstrap.php +++ b/bootstrap.php @@ -3,6 +3,7 @@ declare(strict_types=1); namespace JKingWeb\NewsSync; const BASE = __DIR__.DIRECTORY_SEPARATOR; +const NS_BASE = __NAMESPACE__."\\"; spl_autoload_register(function ($class) { if($class=="SimplePie") return; diff --git a/locale/en.php b/locale/en.php new file mode 100644 index 00000000..7b99d963 --- /dev/null +++ b/locale/en.php @@ -0,0 +1,8 @@ + "Default language file \"{0}\" missing", + "Exception.JKingWeb/NewsSync/Lang/Exception.fileMissing" => "Language file \"{0}\" is not available", + "Exception.JKingWeb/NewsSync/Lang/Exception.fileUnreadable" => "Insufficient permissions to read language file \"{0}\"", + "Exception.JKingWeb/NewsSync/Lang/Exception.fileCorrupt" => "Language file \"{0}\" is corrupt or does not conform to expected format", + "Exception.JKingWeb/NewsSync/Lang/Exception.stringMissing" => "Message string \"{msgID}\" missing from all loaded language files ({fileList})", +]; \ No newline at end of file diff --git a/vendor/JKingWeb/NewsSync/Auth/AuthInterface.php b/vendor/JKingWeb/NewsSync/Auth/AuthInterface.php new file mode 100644 index 00000000..59928c87 --- /dev/null +++ b/vendor/JKingWeb/NewsSync/Auth/AuthInterface.php @@ -0,0 +1,10 @@ +import($import_file); + public function __construct(string $import_file = "") { + if($import_file != "") $this->import_file($import_file); } - function import(string $file): bool { + public function importFile(string $file): self { + if(!file_exists($file)) throw new Conf\Exception("fileMissing"); + if(!is_readable($file)) throw new Conf\Exception("fileUnreadable"); $json = @file_get_contents($file); - if($json===false) return false; + if($json===false) throw new Conf\Exception("fileUnreadable"); + return $this->import($json); + } + + public function import(string $json): self { + if($json=="") throw new Conf\Exception("blank"); $json = json_decode($json, true); - if(!is_array(json)) return false; + if(!is_array($json)) throw new Conf\Exception("corrupt"); foreach($json as $key => $value) { $this->$$key = $value; } - return true; + return $this; + } - function export(string $file = ""): string { + public function export(string $file = ""): string { return json_encode($this, JSON_PRETTY_PRINT); } - function __toString(): string { + public function __toString(): string { return $this->export(); } } \ No newline at end of file diff --git a/vendor/JKingWeb/NewsSync/Conf/Exception.php b/vendor/JKingWeb/NewsSync/Conf/Exception.php new file mode 100644 index 00000000..d9a6b18d --- /dev/null +++ b/vendor/JKingWeb/NewsSync/Conf/Exception.php @@ -0,0 +1,6 @@ + 10000, + "Lang/Exception.defaultFileMissing" => 10101, + "Lang/Exception.fileMissing" => 10102, + "Lang/Exception.fileUnreadable" => 10103, + "Lang/Exception.fileCorrupt" => 10104, + "Lang/Exception.stringMissing" => 10105, + ]; + + public function __construct(string $msgID = "", $vars = null, Throwable $e = null) { + if($msgID=="") { + $msg = ""; + $code = 0; + } else { + $msg = "Exception.".str_replace("\\","/",get_called_class()).".$msgID"; + $msg = Lang::msg($msg, $vars); + $codeID = str_replace("\\", "/", str_replace(NS_BASE, "", get_called_class())); + if(!array_key_exists($codeID,self::CODES)) { + $code = 0; + } else { + $code = self::CODES[$codeID]; + } + } + parent::__construct($msg, $code, $e); + } +} \ No newline at end of file diff --git a/vendor/JKingWeb/NewsSync/Lang.php b/vendor/JKingWeb/NewsSync/Lang.php new file mode 100644 index 00000000..1065bce4 --- /dev/null +++ b/vendor/JKingWeb/NewsSync/Lang.php @@ -0,0 +1,126 @@ + "Default language file ({0}) missing", + "Exception.JKingWeb/NewsSync/Lang/Exception.stringMissing" => "Message string \"{msgID}\" missing from all loaded language files ({fileList})" + ]; + + static protected $requirementsMet = false; + static protected $synched = false; + static protected $wanted = "fr"; + static protected $locale = ""; + static protected $loaded = []; + static protected $strings = self::REQUIRED; + + protected function __construct() {} + + static public function set(string $locale = "", bool $immediate = false): string { + if(!self::$requirementsMet) self::checkRequirements(); + if($locale=="") $locale = self::DEFAULT; + if($locale==self::$wanted) return $locale; + $list = self::listFiles(); + if(!in_array(self::DEFAULT, $list)) throw new Lang\Exception("defaultFileMissing", self::DEFAULT); + self::$wanted = self::match($locale, $list); + self::$synched = false; + if($immediate) self::load(); + return self::$wanted; + } + + static public function get(): string { + return (self::$locale=="") ? self::DEFAULT : self::$locale; + } + + static public function msg(string $msgID, $vars = null): string { + // if we're trying to load the system default language and it fails, we have a chicken and egg problem, so we catch the exception and load no language file instead + if(!self::$synched) try {self::load();} catch(Lang\Exception $e) { + if(self::$wanted==self::DEFAULT) { + self::set(); + self::load(); + } else { + throw $e; + } + } + if(!array_key_exists($msgID, self::$strings)) throw new Lang\Exception("stringMissing", ['msgID' => $msgID, 'fileList' => implode(", ",self::$loaded)]); + // variables fed to MessageFormatter must be contained in array + if($vars !== null && !is_array($vars)) $vars = [$vars]; + return \MessageFormatter::formatMessage(self::$locale, self::$strings[$msgID], $vars); + } + + static public function list(string $locale = ""): array { + $out = []; + $files = self::listFiles(); + foreach($files as $tag) { + $out[$tag] = \Locale::getDisplayName($tag, ($locale=="") ? $tag : $locale); + } + return $out; + } + + static public function match(string $locale, array $list = null): string { + if($list===null) $list = self::listFiles(); + $default = (self::$locale=="") ? self::DEFAULT : self::$locale; + return \Locale::lookup($list,$locale, true, $default); + } + + static protected function checkRequirements(): bool { + if(!extension_loaded("intl")) throw new FatalException("The \"Intl\" extension is required, but not loaded"); + self::$requirementsMet = true; + return true; + } + + static protected function listFiles(string $path = self::PATH): array { + $out = glob($path."*.php"); + return array_map(function($file) { + $file = substr($file,strrpos($file,DIRECTORY_SEPARATOR)+1); + return strtolower(substr($file,0,strrpos($file,"."))); + },$out); + } + + static protected function load(): bool { + self::$synched = true; + if(!self::$requirementsMet) self::checkRequirements(); + // if we've yet to request a locale, just load the fallback strings and return + if(self::$wanted=="") { + self::$strings = self::REQUIRED; + self::$locale = self::$wanted; + return true; + } + // decompose the requested locale from specific to general, building a list of files to load + $tags = \Locale::parseLocale(self::$wanted); + $files = []; + $loaded = []; + $strings = []; + while(sizeof($tags) > 0) { + $files[] = \Locale::composeLocale($tags); + $tag = array_pop($tags); + } + // include the default locale as the base if the most general locale requested is not the default + if($tag != self::DEFAULT) $files[] = self::DEFAULT; + // save the list of files to be loaded for later reference + $loaded = $files; + // reduce the list of files to be loaded to the minimum necessary (e.g. if we go from "fr" to "fr_ca", we don't need to load "fr" or "en") + $files = []; + foreach($loaded as $file) { + if($file==self::$locale) break; + $files[] = $file; + } + // if we need to load all files, start with the fallback strings + if($files==$loaded) $strings[] = self::REQUIRED; + // read files in reverse order + $files = array_reverse($files); + foreach($files as $file) { + if(!file_exists(self::PATH."$file.php")) throw new Lang\Exception("fileMissing", $file); + if(!is_readable(self::PATH."$file.php")) throw new Lang\Exception("fileUnreadable", $file); + if(!@include(self::PATH."$file.php")) throw new Lang\Exception("fileCorrupt", $file); + } + // apply the results and return + self::$strings = call_user_func_array("array_replace_recursive", $strings); + self::$loaded = $loaded; + self::$locale = self::$wanted; + return true; + } +} \ No newline at end of file diff --git a/vendor/JKingWeb/NewsSync/Lang/Exception.php b/vendor/JKingWeb/NewsSync/Lang/Exception.php new file mode 100644 index 00000000..c2c96638 --- /dev/null +++ b/vendor/JKingWeb/NewsSync/Lang/Exception.php @@ -0,0 +1,6 @@ +conf = $conf; + //$this->db = new Database($this); + //$this->auth = new Authenticator($this); + } +} \ No newline at end of file