- First commit, some small work porting an old lib I had done into this first draft
This commit is contained in:
commit
a58efcdef4
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"name": "mcnd/tell",
|
||||
"description": "JSON-based i18n library.",
|
||||
"type": "library",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Dave Mc Nicoll",
|
||||
"email": "mcndave@gmail.com"
|
||||
}
|
||||
],
|
||||
"require": {},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Tell\\": "src/"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
<?php
|
||||
|
||||
namespace Tell;
|
||||
|
||||
class I18n
|
||||
{
|
||||
const DELIMITER = '.';
|
||||
|
||||
protected bool $updatedData = false;
|
||||
|
||||
protected array $data = [];
|
||||
|
||||
protected array $cache = [];
|
||||
|
||||
protected array $engine = [];
|
||||
|
||||
protected string $currentLanguage = "";
|
||||
|
||||
protected array $fileStack = [];
|
||||
|
||||
protected function __construct(bool $enableCache = false) {
|
||||
|
||||
# $this->persistent = new Persistent(static::class);
|
||||
if ( $enableCache ) {
|
||||
# $data = $this->persistent->load();
|
||||
# $this->data = $data['data'];
|
||||
# $this->fileStack = $data['fileStack'];
|
||||
}
|
||||
}
|
||||
|
||||
public function __destruct() {
|
||||
# $this->update_data() && $this->persistent->save([
|
||||
# 'fileStack' => $this->fileStack,
|
||||
# 'data' => $this->data
|
||||
# ]);
|
||||
}
|
||||
|
||||
public function updateData() {
|
||||
return $this->updatedData;
|
||||
}
|
||||
|
||||
public static function get(?string $key = null) {
|
||||
if ( $key === null ) {
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
return isset( $this->cache[$key] ) ? $this->cache[$key] : $this->cache[$key] = Iterate::arrayGet($this->data, ( $this->currentLanguage ? $this->currentLanguage."." : "").$key, static::DELIMITER);
|
||||
}
|
||||
|
||||
public static function set(string $key, $value) {
|
||||
$cache = explode(static::DELIMITER, $key);
|
||||
|
||||
while ( !empty($cache) ) {
|
||||
$imp = implode(static::DELIMITER, $cache);
|
||||
array_pop($cache);
|
||||
unset( $this->cache[$imp] );
|
||||
}
|
||||
|
||||
$this->cache[$key] = $value ;
|
||||
|
||||
return Iterate::arraySet($this->data, $key, $value, static::DELIMITER);
|
||||
}
|
||||
|
||||
public function addEngine($engine) {
|
||||
$this->engine[] = $engine;
|
||||
}
|
||||
|
||||
public function load(string $path, bool $filenameAsKey = false) {
|
||||
if ( !in_array($path, $this->fileStack) ) {
|
||||
$this->updatedData = true;
|
||||
$this->fileStack[] = $path;
|
||||
|
||||
foreach(Iterate::files($path) as $item) {
|
||||
foreach($this->engine as $engine) {
|
||||
if ( $engine->accept($item )) {
|
||||
|
||||
if ( $array = $engine->translate( $item ) ){
|
||||
if ($filenameAsKey ) {
|
||||
$base = basename($item);
|
||||
|
||||
$key = substr($base,0, strrpos($base, "."));
|
||||
$keysplit = explode(".", $key);
|
||||
$key = array_pop($keysplit);
|
||||
|
||||
$this->mergeData([ $keysplit ? "{".implode(".", array_merge([ $key ], $keysplit))."}" : $key => $array ]);
|
||||
}
|
||||
else {
|
||||
$this->mergeData($array);
|
||||
}
|
||||
}
|
||||
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function currentLanguage($set = null) {
|
||||
return $set === null ? $this->currentLanguage : $this->currentLanguage = $set;
|
||||
}
|
||||
|
||||
protected function mergeData($data) {
|
||||
$this->data = array_replace_recursive($this->data, Iterate::splitKeys($data));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
<?php
|
||||
|
||||
namespace Tell;
|
||||
|
||||
use RecursiveDirectoryIterator,
|
||||
RecursiveIteratorIterator,
|
||||
RecursiveRegexIterator,
|
||||
RegexIterator;
|
||||
|
||||
class Iterate
|
||||
{
|
||||
/**
|
||||
* Set value to array with a given path using recursion
|
||||
* @param array $array - array to set passed by reference !
|
||||
* @param string $path - path like 'person.name.first'
|
||||
* @param string $value - value to set
|
||||
*/
|
||||
public static function arraySet(array &$array, string $path, string $value = '', string $delimiter = '.') {
|
||||
$pathArr = explode($delimiter, $path);
|
||||
|
||||
// Go to next node
|
||||
if ( isset($pathArr[1])) {
|
||||
static::arraySet($array[ array_shift($pathArr) ], implode($delimiter, $pathArr), $value);
|
||||
}
|
||||
// We are at the end of the path, set value
|
||||
else {
|
||||
$array[ $pathArr[0] ] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
public static function arrayGet(array $array, string $path, string $delimiter = '.') {
|
||||
$pathArr = explode($delimiter, $path);
|
||||
|
||||
if (isset($array[$pathArr[0]])) {
|
||||
if ( isset($pathArr[1]) ) {
|
||||
return static::arrayGet($array[array_shift($pathArr)], implode($delimiter, $pathArr));
|
||||
}
|
||||
else {
|
||||
return $array[$pathArr[0]];
|
||||
}
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static function splitKeys(array &$array, string $delimiter = ".", string $enclosed = '{}') {
|
||||
if ( is_array($array) ) {
|
||||
$swap = [];
|
||||
|
||||
foreach($array as $key => &$value) {
|
||||
$process = strstr($key, $delimiter);
|
||||
|
||||
if ( $enclosed ) {
|
||||
if ( ( strlen($key) - 2 ) !== strlen( $tkey = trim($key, $enclosed) ) ) {
|
||||
$process = false;
|
||||
}
|
||||
else {
|
||||
$oldKey = $key;
|
||||
$key = $tkey;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $process ) {
|
||||
$tmp = [];
|
||||
$keylist = explode($delimiter, $key);
|
||||
$finalKey = array_shift($keylist);
|
||||
# Arrayobj::iterate_set($keylist, $tmp, $value);
|
||||
static::arraySet($tmp, $key, $value);
|
||||
$swap[$finalKey] = static::splitKeys($tmp, $delimiter);
|
||||
|
||||
unset($array[isset($oldKey) ? $oldKey : $key]);
|
||||
}
|
||||
else if ( is_array($value) ) {
|
||||
$value = static::splitKeys($value, $delimiter);
|
||||
}
|
||||
}
|
||||
|
||||
foreach($swap as $key => $item) {
|
||||
if ( $enclosed ) {
|
||||
if ( ( strlen($key) - 2 ) === ( $tkey = trim($key, $enclosed)) ) {
|
||||
$key = $tkey;
|
||||
}
|
||||
}
|
||||
|
||||
$array[$key] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
public static function files(string $path, string $fileExtension = "") {
|
||||
$retval = [];
|
||||
|
||||
if ( \file_exists($path) ) {
|
||||
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST, RecursiveIteratorIterator::CATCH_GET_CHILD);
|
||||
|
||||
if ($fileExtension) {
|
||||
$iterator = new RegexIterator($iterator, '/^.+\.'.$fileExtension.'$/i', RecursiveRegexIterator::GET_MATCH);
|
||||
}
|
||||
|
||||
foreach ($iterator as $file) {
|
||||
if ($fileExtension) {
|
||||
$retval[] = $file[0];
|
||||
}
|
||||
else {
|
||||
if ( $file->isFile() || $file->isDir() ) {
|
||||
$retval[] = $file->getRealPath();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $retval;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
namespace Tell;
|
||||
|
||||
trait TellTrait {
|
||||
|
||||
public function lang(...$args)
|
||||
{
|
||||
static $vars_pattern = null;
|
||||
|
||||
$vars_pattern || ( $vars_pattern = $this->config('Eckinox.language.vars.pattern') );
|
||||
|
||||
switch ( count($args) ) {
|
||||
case 1:
|
||||
return ( $value = Language::get( $args[0] ) ) !== null ? $value : ( Eckinox::debug() ? "'{$args[0]}'" : "" );
|
||||
|
||||
case 0:
|
||||
return Language::instance();
|
||||
|
||||
case 2:
|
||||
if ( empty($args[1]) ) {
|
||||
return $this->lang($args[0]);
|
||||
}
|
||||
|
||||
/* Handling arrays with keys */
|
||||
if ( Arrayobj::array_is_associative($args[1]) ) {
|
||||
$content = $this->lang($args[0]);
|
||||
|
||||
if ( preg_match_all("~\\{\\$(.*?)\\}~si", $this->lang($args[0]), $matches, PREG_SET_ORDER) ) {
|
||||
$search = [];
|
||||
|
||||
foreach($matches as $item) {
|
||||
$search[ $item[0] ] = $a = iterate::array_get($args[1], $item[1]);
|
||||
}
|
||||
|
||||
$content = str_replace(array_keys($search), array_values($search), $content);
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
default:
|
||||
/* Handling arrays with indexes */
|
||||
return call_user_func_array('sprintf', array_merge([ $this->lang( array_shift($args) ) ], $args));
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue