Esempio n. 1
0
 /**
  * Получение данных из суперглобальных массивов $_GET, $_POST, $_COOKIE или $_REQUEST.
  *
  * Описание методов см. в комментарии к этому классу.
  *
  * Суть: парсим запрошенный метод. Если совпадает с тем, что мы поддерживаем, подключаемся к нужному массиву.
  * По заданному количеству параметров функции пытаемся вернуть требуемое значение. В частности в методе приведения
  * к типу ожидаем имя ключа в массиве, а при регулярке еще один параметр - шаблон регулярного выражения.
  *
  * Прим: параметры в этот метод попадают в виде неассоциативного массива, приходится по порядку ключей разбирать.
  *
  * Если вызов неправильный, кидаем исключение. Если значение в массиве не найдено (или регулярке не отвечает) - NULL
  *
  * @param string $method имя метода
  * @param array  $params параметры метода
  * @return mixed
  * @throws \RuntimeException
  * @throws \LogicException
  */
 public static function __callStatic($method, $params)
 {
     if (preg_match('/^(?<verb>get|post|request|cookie)(As(?<type>Int|Bool|Regexp|Enum))?$/', $method, $m)) {
         $verb = $m['verb'];
         $type = isset($m['type']) ? $m['type'] : null;
     } else {
         throw new \RuntimeException('Неизвестный метод ' . __NAMESPACE__ . "\\Request::{$method}()");
     }
     // Прим.: нельзя использовать переменные переменных в данном случае. Поэтому - через условие.
     // {@see http://php.net/manual/ru/language.variables.variable.php}, внизу варнинг.
     switch ($verb) {
         case 'get':
             $arr =& $_GET;
             break;
         case 'post':
             $arr =& $_POST;
             break;
         case 'cookie':
             $arr =& $_COOKIE;
             break;
         case 'request':
             $arr =& $_REQUEST;
             break;
         default:
             $arr = [];
     }
     if (!$params) {
         if ($type) {
             $secondParam = $type == 'Regexp' ? ', $pattern' : ($type == 'Enum' ? ', $expect' : '');
             throw new \RuntimeException("Пропущен обязательный параметр функции: имя ключа в массиве \$_{$verb}" . PHP_EOL . "Сигнатура вызова: {$method}(\$key{$secondParam})");
         }
         return $arr;
     }
     $key =& $params[0];
     $val = utils\Arrays::getValue($arr, $key);
     if (!$type || $val == '') {
         return $val;
     }
     if (is_array($val)) {
         throw new \LogicException('Для массива данных проверки содержимого невозможны. Полученное значение:' . utils\Dumper::dumpAsString($val));
     }
     switch ($type) {
         case 'Int':
             return preg_match('~^-?\\d+$~', $val) ? intval($val) : null;
         case 'Bool':
             return preg_match('~^true|1|on|yes|checked$~i', $val) ? true : (preg_match('~^false|0|off|no|unchecked$~i', $val) ? false : null);
         case 'Regexp':
             if (!isset($params[1])) {
                 throw new \RuntimeException('Пропущен обязательный параметр функции: шаблон регулярного выражения.' . PHP_EOL . "Сигнатура вызова: {$verb}AsRegexp(\$key, \$pattern)");
             }
             $pattern =& $params[1];
             return preg_match($pattern, $val) ? $val : null;
         case 'Enum':
             if (!isset($params[1])) {
                 throw new \RuntimeException('Пропущен обязательный параметр функции: массив допустимых значений.' . PHP_EOL . "Сигнатура вызова: {$verb}AsEnum(\$key, \$expect)");
             }
             return in_array($val, $params[1]) ? $val : null;
         default:
             return null;
     }
 }
Esempio n. 2
0
 /**
  * Пробуем пробить валидаторы
  *
  * Результаты можно получить несколькими способами, аналогично с self::test_validate()
  *
  * Прим.: пересоздаем модель формы, т.к. ее повторное использование не предусмотрено.
  */
 public function test_invalid_data()
 {
     self::setUpBeforeClass();
     $form = self::$form;
     $data = ['app_path' => '\\valid\\path\\tooLong', 'app_namespace' => null, 'email' => '*****@*****.**', 'db' => ['switch' => 'on', 'base' => [' my_base ', 'base2']], 'modules' => ' user '];
     $result = $form->load($data)->validate();
     $this->assertFalse($result, 'Валидация не прошла');
     $this->assertFalse($form->isValid(), 'Результат проведенной валидации - неверные данные');
     $this->assertTrue($form->hasErrors(), 'Есть ошибки валидации');
     $errorsByField = Arrays::array_filter_recursive($form->getErrorsAsString());
     $this->assertEquals(5, count($errorsByField), 'Есть ошибки по 5 полям');
 }
Esempio n. 3
0
 /**
  * Получение всех ошибок по каждому полю, склееных в строку.
  *
  * Если контракт - сложный многомерный массив, то ошибки склеиваются из всех подмассивов для каждого старшего ключа.
  * На выходе всегда получается простой ассоциативный массив [поле => ошибки]. В случае сложного контракта полями
  * будут его старшие ключи.
  *
  * @param null   $key  ключ в массиве данных. Возможно составной ключ типа "['lvl1' => ['lvl2' => 'param1']]".
  * @param string $glue клей между соседними элементами одного массива
  * @param string $eol  клей между соседними подмассивами
  * @return array
  */
 public function getErrorsAsString($key = null, $glue = ' ', $eol = '')
 {
     $errors = $this->getErrors($key);
     foreach ($errors as &$v) {
         if (is_array($v)) {
             $v = Arrays::implode_recursive($v, $glue, $eol);
         }
     }
     return $errors;
 }
Esempio n. 4
0
 public function test_getValue()
 {
     $arr = ['path' => ['app' => ['level1' => '/home', 'level2' => '/www']]];
     $expect = Arrays::getValue($arr, ['path' => ['app' => 'level2']]);
     $this->assertEquals($expect, '/www', 'Получение значения массива по заданной цепочке ключей');
 }