diff --git a/src/Controller/Action.php b/src/Controller/Action.php index 72222c8..5d2d13e 100644 --- a/src/Controller/Action.php +++ b/src/Controller/Action.php @@ -1,8 +1,5 @@ access; if ($access == null || $access->checkAction($name)) { - return lcurry(array($this, 'postUrl'), $name, $param); + return Functions::lcurry(array($this, 'postUrl'), $name, $param); } return null; } diff --git a/src/Functions.php b/src/Functions.php new file mode 100644 index 0000000..785e893 --- /dev/null +++ b/src/Functions.php @@ -0,0 +1,380 @@ +fn = array_shift($params); + $this->params = $params; + } + + function apply() { + $params = func_get_args(); + array_splice($params, count($params), 0, $this->params); + return call_user_func_array($this->fn, $params); + } +} + +class __left { + protected $params; + protected $fn; + + public function __construct($params) { + $this->fn = array_shift($params); + $this->params = $params; + } + + function apply() { + $params = func_get_args(); + array_splice ($params, 0, 0, $this->params); + return call_user_func_array ($this->fn, $params); + } +} + +define('__', '_ARGUMENT_PLACE_'); +class __partial { + protected $params; + protected $fn; + + public function __construct($params) { + $this->fn = array_shift($params); + $this->params = $params; + } + + function apply() { + $params = func_get_args(); + $result = array(); + for($i = 0, $j = 0; $i < count($this->params); $i++) { + if ($this->params[$i] == __) { + $result [] = $params[$j]; + $j++; + } else { + $result [] = $this->params[$i]; + } + } + return call_user_func_array ($this->fn, $result); + } +} + +/** + * Композиция функций + */ +class __compose { + protected $fns; + function __construct($list) { + $this->fns = array_reverse($list); + } + + function apply () { + $params = func_get_args (); + $result = call_user_func_array($this->fns[0], $params); + for ($i = 1; $i < count($this->fns); $i++) { + $result = call_user_func($this->fns[$i], $result); + } + return $result; + } +} + +class Functions { + + static function partial() { + $closure = new __partial(func_get_args()); + return array($closure, 'apply'); + } + + + /** + * Композиция функций + * @param mixed $a + * @param mixed $b + * + * @return array[int]mixed + */ + static function compose() { + $closure = new __compose(func_get_args()); + return array($closure, 'apply'); + } + + /** + * Карирование справа + * + * @return array[int]mixed + */ + static function rcurry($_rest) { + $closure = new __right(func_get_args ()); + return array($closure, 'apply'); + } + + /** + * Карирование слева + * + * @return array[int]mixed + */ + static function lcurry($_rest) { + $closure = new __left(func_get_args ()); + return array($closure, 'apply'); + } + + /** + * Разделение массива на два по условию + * @param mixed $pred Условие по которому разделяется массив + * @param array $lst + * + * @return array[int]mixed + */ + static function partition($pred, $lst) { + $left = array (); + $right = array (); + foreach ($lst as $n) { + if (call_user_func($pred, $n) !== false) { + $left [] = $n; + } else { + $right [] = $n; + } + } + return array ($left, $right); + } + + /** + * @param array $value + * @param string $name + * + * @return mixed + */ + static function __key($value, $name) { + return $value[$name]; + } + + static function identity($value) { + return $value; + } + + /** + * @param array $a + * @param array $b + * @param $key + * + * @return int + */ + static function __cmp($a, $b, $key) { + if ($a[$key] == $b[$key]) { + return 0; + } + return ($a[$key] > $b[$key]) ? -1 : 1; + } + + static function __cmp_less($a, $b, $key) { + if ($a[$key] == $b[$key]) { + return 0; + } + return ($a[$key] < $b[$key]) ? -1 : 1; + } + + // Сравнение по ключу массиве + static function __index($n, $key, $row) { + return ($row[$key] == $n); + } + + static function __div($x, $y) { + return $x / $y; + } + + static function __self($name, $o) { + return call_user_func(array($o, $name)); + } + + static function concat(/* $args ...*/) { + $args = func_get_args(); + return implode("", $args); + } + + static function __empty($x) { + return empty($x); + } + + // Отрицание + static function __not($x) { + return !$x; + } + + // Не равно + static function __neq($x, $y) { + return $x != $y; + } + + // Равно + static function __eq($x, $y) { + return $x == $y; + } + + /** + * Извлекает из многомерого массива значения с определенным ключом + * @example key_values('a', array(1 => array('a' => 1, 'b' => 2))) => array(1) + * + * @return mixed + */ + static function key_values($key, /*array|ArrayIterator*/ $array) { + $result = array(); + + foreach($array as $item) { + $result[] = $item[$key]; + } + return $result; + } + + static function key_values_object($key, /*array|ArrayIterator*/ $array) { + $result = array(); + + foreach($array as $item) { + $result[] = $item->{$key}; + } + return $result; + } + + static function assoc_key_values($key, $value, $array) { + $result = array(); + foreach ($array as $item) { + $result[$item[$key]] = $item[$value]; + } + return $result; + } + + static function assoc_key($key, $array) { + $result = array(); + foreach ($array as $item) { + $result[$item[$key]] = $item; + } + return $result; + } + + static function _get($key, /*.any.*/$value, /*.array.*/$array) { + foreach ($array as $item) { + if ($item[$key] == $value) return $item; + } + return null; + } + + static function _get_key($key, $value, $array) { + foreach ($array as $name => $item) { + if ($item[$key] == $value) return $name; + } + return null; + } + + + /** + * Логическа операция && ко всем элементам массива + * @return bool + */ + static function every(array $array, $callback) { + foreach ($array as $value) { + if (call_user_func($callback, $value) === false) { + return false; + } + } + return true; + } + + /** + * Логическа операция || ко всем элементам массива + * @param array $array + * @param mixed $callback + * + * @return mixed + */ + static function some(array $array, $callback) { + assert(is_callable($callback)); + + foreach ($array as $key => $value) { + if (call_user_func($callback, $value) === true) { + return $key; + } + } + return false; + } + + static function span($length, array $array) { + assert(is_int($length)); + + $result = array(); + for($i = 0; $i < count($array); $i += $length) { + $result [] = array_slice($array, $i, $length); + } + return $result; + } + + static function array_ref($data, $n) { + return $data[$n]; + } + + static function call() { + $args = func_get_args(); + $name = array_shift($args); + return call_user_func_array($name, $args); + } + + /** + * Поиск элемента в массиве + * @param function $cb сравнение с элементом массива + * @param array $hs массив в котором ищется значение + * + * @return int|string ключ найденого элемента в массиве + */ + static function array_usearch($cb, array $hs, $strict = false) { + foreach($hs as $key => $value) if (call_user_func_array($cb, array($value, $key, $strict))) return $key; + } + + /** + * Выбирает все сроки из таблицы с уникальными значениями ключа + * @param $name Имя ключа + * @param $table Двухмерный массив + * @example + * key_unique_values ('name', array (array ('name' => 1), array ('name' => 2), array ('name' => 1))) + => array (1, 2) + * @end example + */ + static function key_unique_values ($name, $table) { + // Ищем уникальные значения для заданного ключа + $keys = array (); + foreach ($table as $row) { + if (!in_array ($row[$name], $keys)) + $keys[] = $row[$name]; + } + return $keys; + } + + /** + * Сортировка двумерного массива по заданному ключу + * @param $array Массив + * @param $key Имя ключа по значению которого будет идти сравнение + * @return Отсортированный массив + */ + static function sortOn($array, $key, $fn = '__cmp') { + usort ($array, Functions::rcurry($fn, $key)); + //usort ($array, create_function ('$x,$y', 'return __cmp ($x, $y, "'.$key.'");')); + return $array; + } + + /** + * Преобразует ключи элементов для многомерного массива + * @return mixed + */ + static function hash_key ($key_name,/*. array .*/ $array) { + $result = array(); + + foreach($array as $value) { + $result[$value[$key_name]] = $value; + } + return $result; + } +} + diff --git a/src/Layout/Manager.php b/src/Layout/Manager.php index 965207d..942a8fd 100644 --- a/src/Layout/Manager.php +++ b/src/Layout/Manager.php @@ -1,8 +1,5 @@ addCondition(rcurry(array($this, 'checkGet'), $get), $layout); + $this->addCondition(Functions::rcurry(array($this, 'checkGet'), $get), $layout); } /** @@ -30,7 +27,7 @@ class Layout_Manager extends Filter_Filter */ public function addConditionXHR($get, Filter_Filter $layout) { - $this->addCondition(rcurry(array($this, 'checkXHR'), $get), $layout); + $this->addCondition(Functions::rcurry(array($this, 'checkXHR'), $get), $layout); } public function checkGet($request, $get) diff --git a/src/MailAlt.php b/src/MailAlt.php index 2c8c017..48f9a60 100644 --- a/src/MailAlt.php +++ b/src/MailAlt.php @@ -4,6 +4,7 @@ class MailAlt { public $mailer; public $_notify; + public $encoding; function __construct() { $this->mailer = new PHPMailer(); diff --git a/src/Tools/String.php b/src/Tools/String.php index 32aeb3b..bd6c2de 100644 --- a/src/Tools/String.php +++ b/src/Tools/String.php @@ -1,107 +1,110 @@ 0) { // already in sub-array? - $subarr[$in_subarr][] = $tok; - if ('}' === substr($tok, -1, 1)) { // check to see if we just added last component - $res[] = strToArray(implode(',', $subarr[$in_subarr])); - $in_subarr--; - } - } elseif ($tok{0} === '{') { // we're inside a new sub-array - if ('}' !== substr($tok, -1, 1)) { - $in_subarr++; - // if sub-array has more than one element - $subarr[$in_subarr] = array(); - $subarr[$in_subarr][] = $tok; - } else { - $res[] = strToArray($tok); - } - } else { // not sub-array - $val = trim($tok, '"'); // remove " (surrounding strings) - // perform type castng here? - $res[] = $val; - } - } - - return $res; -} +class Tools_String { -//Нормализация строк на русском -function normalizeRussian($str) { - $result = preg_replace('/\s+/',' ', $str); - if (is_string($result)) { - $result = trim($result); //Замена длинных пробелов на одинарные, пробелы по краям - $result = mb_strtolower($result); - $result = preg_replace('/ё/','е', $str); //е на ё + // from creole + static function strToArray($str) { + $str = substr($str, 1, -1); // remove { } + $res = array(); + + $subarr = array(); + $in_subarr = 0; + + $toks = explode(',', $str); + foreach($toks as $tok) { + if ($in_subarr > 0) { // already in sub-array? + $subarr[$in_subarr][] = $tok; + if ('}' === substr($tok, -1, 1)) { // check to see if we just added last component + $res[] = strToArray(implode(',', $subarr[$in_subarr])); + $in_subarr--; + } + } elseif ($tok{0} === '{') { // we're inside a new sub-array + if ('}' !== substr($tok, -1, 1)) { + $in_subarr++; + // if sub-array has more than one element + $subarr[$in_subarr] = array(); + $subarr[$in_subarr][] = $tok; + } else { + $res[] = strToArray($tok); + } + } else { // not sub-array + $val = trim($tok, '"'); // remove " (surrounding strings) + // perform type castng here? + $res[] = $val; + } + } + + return $res; } - return $result; -} -//Проверка равенства двух строк на русском языке. -function equalRussianCheck($str1,$str2) { - return normalizeRussian($str1) == normalizeRussian($str2); -} - - -/** - * Попадает ли строка в список вариантов - * input: $str="foo1" $variants="foo1|foo2|foo3" - * output: true - * input: $str="foo" $variants="foo1|foo2|foo3" - * output: false -*/ -function compare_string_to_variants($str, $variants){ - $variants_array = explode('|', $variants); - $founded = false; - foreach ($variants_array as $variant) { - $founded = $founded || equalRussianCheck($variant, $str); + //Нормализация строк на русском + static function normalizeRussian($str) { + $result = preg_replace('/\s+/',' ', $str); + if (is_string($result)) { + $result = trim($result); //Замена длинных пробелов на одинарные, пробелы по краям + $result = mb_strtolower($result); + $result = preg_replace('/ё/','е', $str); //е на ё + } + return $result; } - return $founded; -} + + //Проверка равенства двух строк на русском языке. + static function equalRussianCheck($str1,$str2) { + return self::normalizeRussian($str1) == self::normalizeRussian($str2); + } + -function mb_str_split($str) { - return preg_split('~~u', $str, null, PREG_SPLIT_NO_EMPTY); -} + /** + * Попадает ли строка в список вариантов + * input: $str="foo1" $variants="foo1|foo2|foo3" + * output: true + * input: $str="foo" $variants="foo1|foo2|foo3" + * output: false +*/ + static function compare_string_to_variants($str, $variants){ + $variants_array = explode('|', $variants); + $founded = false; + foreach ($variants_array as $variant) { + $founded = $founded || self::equalRussianCheck($variant, $str); + } + return $founded; + } + + static function mb_str_split($str) { + return preg_split('~~u', $str, null, PREG_SPLIT_NO_EMPTY); + } + + static function mb_strtr($str, $from, $to) { + return str_replace(self::mb_str_split($from), self::mb_str_split($to), $str); + } + + static function encodestring($st) { + $st = self::mb_strtr($st,"абвгдеёзийклмнопрстуфхъыэ !+-()", "abvgdeeziyklmnoprstufh_ie______"); + $st = self::mb_strtr($st,"АБВГДЕЁЗИЙКЛМНОПРСТУФХЪЫЭ", "ABVGDEEZIYKLMNOPRSTUFH_IE"); + $st = strtr($st, array( + " " => '_', + "." => '_', + "," => '_', + "?" => '_', + "\"" => '_', + "'" => '_', + "/" => '_', + "\\" => '_', + "%" => '_', + "#" => '_', + "*" => '_', + "ж"=>"zh", "ц"=>"ts", "ч"=>"ch", "ш"=>"sh", + "щ"=>"shch","ь"=>"", "ю"=>"yu", "я"=>"ya", + "Ж"=>"ZH", "Ц"=>"TS", "Ч"=>"CH", "Ш"=>"SH", + "Щ"=>"SHCH","Ь"=>"", "Ю"=>"YU", "Я"=>"YA", + "Й"=>"i", "й"=>"ie", "ё"=>"Ye", + "№"=>"N" + )); + return strtolower($st); + } -function mb_strtr($str, $from, $to) { - return str_replace(mb_str_split($from), mb_str_split($to), $str); -} - -function encodestring($st) { - $st = mb_strtr($st,"абвгдеёзийклмнопрстуфхъыэ !+-()", "abvgdeeziyklmnoprstufh_ie______"); - $st = mb_strtr($st,"АБВГДЕЁЗИЙКЛМНОПРСТУФХЪЫЭ", "ABVGDEEZIYKLMNOPRSTUFH_IE"); - $st = strtr($st, array( - " " => '_', - "." => '_', - "," => '_', - "?" => '_', - "\"" => '_', - "'" => '_', - "/" => '_', - "\\" => '_', - "%" => '_', - "#" => '_', - "*" => '_', - "ж"=>"zh", "ц"=>"ts", "ч"=>"ch", "ш"=>"sh", - "щ"=>"shch","ь"=>"", "ю"=>"yu", "я"=>"ya", - "Ж"=>"ZH", "Ц"=>"TS", "Ч"=>"CH", "Ш"=>"SH", - "Щ"=>"SHCH","Ь"=>"", "Ю"=>"YU", "Я"=>"YA", - "Й"=>"i", "й"=>"ie", "ё"=>"Ye", - "№"=>"N" - )); - return strtolower($st); -} - -function validate_encoded_string($st) { - $enc_st = encodestring($st); - return preg_match('/^[\w_-]+(\.[\w_-]+)?$/', $enc_st); + static function validate_encoded_string($st) { + $enc_st = self::encodestring($st); + return preg_match('/^[\w_-]+(\.[\w_-]+)?$/', $enc_st); + } } diff --git a/src/Validator/Validator.php b/src/Validator/Validator.php index c429efe..0af90e3 100644 --- a/src/Validator/Validator.php +++ b/src/Validator/Validator.php @@ -77,7 +77,7 @@ class Validator_Validator } } - public function skip($rule, $container) // -> Rule_Abstract + public function skip(/*.Validator_Rule_Abstract.*/$rule, /*.Collection.*/$container) // -> Rule_Abstract { if ($rule->skipEmpty()) { $data = $container->get($rule->field); diff --git a/src/functions.php b/src/functions.php deleted file mode 100644 index e9ae380..0000000 --- a/src/functions.php +++ /dev/null @@ -1,378 +0,0 @@ -fn = array_shift($params); - $this->params = $params; - } - - function apply() { - $params = func_get_args(); - array_splice($params, count($params), 0, $this->params); - return call_user_func_array($this->fn, $params); - } -} - -class __left { - protected $params; - protected $fn; - - public function __construct($params) { - $this->fn = array_shift($params); - $this->params = $params; - } - - function apply() { - $params = func_get_args(); - array_splice ($params, 0, 0, $this->params); - return call_user_func_array ($this->fn, $params); - } -} - -define('__', '_ARGUMENT_PLACE_'); -class __partial { - protected $params; - protected $fn; - - public function __construct($params) { - $this->fn = array_shift($params); - $this->params = $params; - } - - function apply() { - $params = func_get_args(); - $result = array(); - for($i = 0, $j = 0; $i < count($this->params); $i++) { - if ($this->params[$i] == __) { - $result [] = $params[$j]; - $j++; - } else { - $result [] = $this->params[$i]; - } - } - return call_user_func_array ($this->fn, $result); - } -} - -function partial() { - $closure = new __partial(func_get_args()); - return array($closure, 'apply'); -} - - -/** - * Композиция функций - */ -class __compose { - protected $fns; - function __construct($list) { - $this->fns = array_reverse($list); - } - - function apply () { - $params = func_get_args (); - $result = call_user_func_array($this->fns[0], $params); - for ($i = 1; $i < count($this->fns); $i++) { - $result = call_user_func($this->fns[$i], $result); - } - return $result; - } -} - -/** - * Композиция функций - * @param mixed $a - * @param mixed $b - * - * @return array[int]mixed - */ -function compose() { - $closure = new __compose(func_get_args()); - return array($closure, 'apply'); -} - -/** - * Карирование справа - * - * @return array[int]mixed - */ -function rcurry($_rest) { - $closure = new __right(func_get_args ()); - return array($closure, 'apply'); -} - -/** - * Карирование слева - * - * @return array[int]mixed - */ -function lcurry($_rest) { - $closure = new __left(func_get_args ()); - return array($closure, 'apply'); -} - -/** - * Разделение массива на два по условию - * @param mixed $pred Условие по которому разделяется массив - * @param array $lst - * - * @return array[int]mixed - */ -function partition($pred, $lst) { - $left = array (); - $right = array (); - foreach ($lst as $n) { - if (call_user_func($pred, $n) !== false) { - $left [] = $n; - } else { - $right [] = $n; - } - } - return array ($left, $right); -} - -/** - * @param array $value - * @param string $name - * - * @return mixed - */ -function __key($value, $name) { - return $value[$name]; -} - -function identity($value) { - return $value; -} - -/** - * @param array $a - * @param array $b - * @param $key - * - * @return int - */ -function __cmp($a, $b, $key) { - if ($a[$key] == $b[$key]) { - return 0; - } - return ($a[$key] > $b[$key]) ? -1 : 1; -} - -function __cmp_less($a, $b, $key) { - if ($a[$key] == $b[$key]) { - return 0; - } - return ($a[$key] < $b[$key]) ? -1 : 1; -} - -// Сравнение по ключу массиве -function __index($n, $key, $row) { - return ($row[$key] == $n); -} - -function __div($x, $y) { - return $x / $y; -} - -function __self($name, $o) { - return call_user_func(array($o, $name)); -} - -function concat(/* $args ...*/) { - $args = func_get_args(); - return implode("", $args); -} - -function __empty($x) { - return empty($x); -} - -// Отрицание -function __not($x) { - return !$x; -} - -// Не равно -function __neq($x, $y) { - return $x != $y; -} - -// Равно -function __eq($x, $y) { - return $x == $y; -} - -/** - * Извлекает из многомерого массива значения с определенным ключом - * @example key_values('a', array(1 => array('a' => 1, 'b' => 2))) => array(1) - * - * @return mixed - */ -function key_values($key, /*array|ArrayIterator*/ $array) { - $result = array(); - - foreach($array as $item) { - $result[] = $item[$key]; - } - return $result; -} - -function key_values_object($key, /*array|ArrayIterator*/ $array) { - $result = array(); - - foreach($array as $item) { - $result[] = $item->{$key}; - } - return $result; -} - -function assoc_key_values($key, $value, $array) { - $result = array(); - foreach ($array as $item) { - $result[$item[$key]] = $item[$value]; - } - return $result; -} - -function assoc_key($key, $array) { - $result = array(); - foreach ($array as $item) { - $result[$item[$key]] = $item; - } - return $result; -} - -function _get($key, /*.any.*/$value, /*.array.*/$array) { - foreach ($array as $item) { - if ($item[$key] == $value) return $item; - } - return null; -} - -function _get_key($key, $value, $array) { - foreach ($array as $name => $item) { - if ($item[$key] == $value) return $name; - } - return null; -} - - -/** - * Логическа операция && ко всем элементам массива - * @return bool - */ -function every(array $array, $callback) { - foreach ($array as $value) { - if (call_user_func($callback, $value) === false) { - return false; - } - } - return true; -} - -/** - * Логическа операция || ко всем элементам массива - * @param array $array - * @param mixed $callback - * - * @return mixed - */ -function some(array $array, $callback) { - assert(is_callable($callback)); - - foreach ($array as $key => $value) { - if (call_user_func($callback, $value) === true) { - return $key; - } - } - return false; -} - -function span($length, array $array) { - assert(is_int($length)); - - $result = array(); - for($i = 0; $i < count($array); $i += $length) { - $result [] = array_slice($array, $i, $length); - } - return $result; -} - -function array_ref($data, $n) { - return $data[$n]; -} - -function call() { - $args = func_get_args(); - $name = array_shift($args); - return call_user_func_array($name, $args); -} - -/** - * Поиск элемента в массиве - * @param function $cb сравнение с элементом массива - * @param array $hs массив в котором ищется значение - * - * @return int|string ключ найденого элемента в массиве - */ -function array_usearch($cb, array $hs, $strict = false) { - foreach($hs as $key => $value) if (call_user_func_array($cb, array($value, $key, $strict))) return $key; -} - -if (!function_exists('hash_key')) { - /** - * Преобразует ключи элементов для многомерного массива - * @return mixed - */ - function hash_key ($key_name,/*. array .*/ $array) { - $result = array(); - - foreach($array as $value) { - $result[$value[$key_name]] = $value; - } - return $result; - }; -} - -/** - * Выбирает все сроки из таблицы с уникальными значениями ключа - * @param $name Имя ключа - * @param $table Двухмерный массив - * @example - * key_unique_values ('name', array (array ('name' => 1), array ('name' => 2), array ('name' => 1))) - => array (1, 2) - * @end example - */ -function key_unique_values ($name, $table) { - // Ищем уникальные значения для заданного ключа - $keys = array (); - foreach ($table as $row) { - if (!in_array ($row[$name], $keys)) - $keys[] = $row[$name]; - } - return $keys; -} - -/** - * Сортировка двумерного массива по заданному ключу - * @param $array Массив - * @param $key Имя ключа по значению которого будет идти сравнение - * @return Отсортированный массив - */ -function sortOn($array, $key, $fn = '__cmp') { - usort ($array, rcurry($fn, $key)); - //usort ($array, create_function ('$x,$y', 'return __cmp ($x, $y, "'.$key.'");')); - return $array; -} diff --git a/src/tabletree.php b/src/tabletree.php index b8f12c2..8c586c6 100644 --- a/src/tabletree.php +++ b/src/tabletree.php @@ -4,9 +4,6 @@ * Преобразование дерева из модели Plain в массив массивов (Adjacency List) */ -require_once 'functions.php'; - - /** * Обходит таблицу как дерево * $fn ($name, $index, $rows, $cc) @@ -23,10 +20,10 @@ function tableTreeWalk($level, $table, $fn) { if (empty ($level)) return $table; $name = array_shift ($level); - $keys = key_unique_values($name, $table); + $keys = Functions::key_unique_values($name, $table); $data = array (); foreach ($keys as $index) { - list($rows, $table) = partition (lcurry('__index', $index, $name), $table); + list($rows, $table) = Functions::partition (Functions::lcurry(['Functions', '__index'], $index, $name), $table); // $rows = array_filter ($table, lcurry('__index', intval($index), $name)); //$rows = array_filter ($table, create_function ('$x', 'return __index ('.intval($index).', \''.$name.'\', $x);')); $data[$index] = call_user_func ($fn, $name, $index, $rows, tableTreeWalk ($level, $rows, $fn));