MVC и валидация

  • Автор темы Автор темы vanicon
  • Дата начала Дата начала
GusakovNick
вопросы вкуса и привычек. мне легче на php написать за день набор хэлпеов, которые все тоже самое будут делать
 
GusakovNick
Не знаю что легче будет выучить дизайнеру, синтаксис php, или целый twig перелопатить, с всякими там наследованиями.
Ведь представление как бы должен дизайнер делать...
Не отрицаю может и есть проекты когда без шаблонизатора и их фичей не обойтись, но мне лично таких проектов не попадалось...
Не знаю-не знаю. Даже самые простые магазины содержат в себе по 10-15 страниц. Вот тут наследование очень помогает, чтобы через пол года не ходить по всем шаблонам и не прамить футер. Да, можно все вытаскивать по файлам - но это какое-то сомнительное удовольствие
 
GusakovNick
вопросы вкуса и привычек. мне легче на php написать за день набор хэлпеов, которые все тоже самое будут делать
Зачем? Зачем тратить свое время на то, что уже решили, и решили надо сказать хорошо.
Вы можете в любой момент отключить экранирование внутри блока с экранированием, можете поменять тип, или еще что-то, а так нагородите хелперов
 
Да, можно все вытаскивать по файлам - но это какое-то сомнительное удовольствие
Так разве это не одно и тоже, общие элемента типа шапки и футера вынести в файлы, и вызывать там где надо, в чем сложность?
А самое главное разницы нет, хоть с помощью твига наследуя, хоть так, результат один...
 
Повторяю ребят не в ту сторону нас понесло, твиг или чистый пхп с хелперами, отношение к валидации это не имеет никакого.
 
Так разве это не одно и тоже, общие элемента типа шапки и футера вынести в файлы, и вызывать там где надо, в чем сложность?
А самое главное разницы нет, хоть с помощью твига наследуя, хоть так, результат один...
Нет! Там вверху ссылку кинули, не одно и то же, я не могу взять и что-то переопределить в подключенном шаблоне. А тут - запросто. Вместо того как в очередной раз сядете писать хелперы - советую попробовать потратить час на чтение документации и примеров использования. Я думаю вы отложите надуманные проблемы в виде создания хелперов и сядете писать шаблон)
 
Ну как где? Опять создаем фильтр isMyDataBaseHaveThisData($data) и проверяем)
assertEquals($data1, $data2)
isCapchaRight($capchaCode)
что здесь не так-то?)
Поясните куда, где и как это надо писать.
Я лично с сф не знаком...
 
Код:
{% autoescape true %}
Покажи, как это сделать на чистом PHP.
Лягко! :D
PHP:
<?php

class ViewData implements ArrayAccess {

    protected $data;

    protected $filter = null;

    public function __construct($data) {
        $this->data = $data;
    }

    public function setFilter(Callable $filter = null) {
        $this->filter = $filter;
        return $this;
    }

    public function offsetExists($key) {
        return null !== $this->getProperty($key);
    }

    public function offsetGet($key) {
        return $this->handleValue($this->getProperty($key));
    }

    public function offsetSet($offset, $value) { }
    public function offsetUnset($offset) { }

    public function __get($key) {
        return $this->offsetGet($key);
    }

    public function exportArray() {
        $result = [];
        foreach ($this->data as $key => $value) {
            $result[$key] = $this->offsetGet($key);
        }
        return $result;
    }

    public function __call($method, $args) {
        if (!is_object($this->data) || !method_exists($this->data, $method)) {
            return null;
        }
        return $this->handleValue(call_user_func_array([$this->data, $method], $args));
    }

    public function __toString() {
        return $this->filter(strval($this->data));
    }

    protected function handleValue($value) {
        if (null === $value || is_resource($value)) {
            return null;
        }
        if (is_scalar($value)) {
            return $this->filter($value);
        }
        return $this->constructSubview($value);
    }

    protected function constructSubview($value) {
        return (new self($value))->setFilter($this->filter);
    }

    protected function getProperty($key) {
        if (is_array($this->data)) {
            return isset($this->data[$key]) ? $this->data[$key] : null;
        } else {
            return property_exists($this->data, $key) ? $this->data->$key : null;
        }
    }

    protected function filter($value) {
        if ($this->filter) {
            $value = call_user_func($this->filter, $value);
        }
        return $value;
    }

}

class Model {

    public $foo = '<b>FOO</b>';

    public function getBar() {
        return (object)['value' => '<h1>BAR</h1>'];
    }

}

$ViewData = new ViewData([
    'title' => '<h1>Title</h1>',
    'a' => ['b' => '<i>Hello</i>'],
    'b' => [
        'c' => 1,
        'model' => new Model,
    ],
]);

$ViewData->setFilter('htmlspecialchars');

extract($ViewData->exportArray());

?>
<!DOCTYPE html>
<html>
<head>
    <?=$title?>
</head>
<body>
    <h1><?=$a['b']?></h1>
    <ul>
        <li>
            b.c = <?=$b->c?>
        </li>
        <li>
            b.model.foo = <?=$b->model->foo?>
        </li>
        <li>
            b.model.getBar().value = <?=$b->model->getBar()->value?>
        </li>
    </ul>
</body>
</html>
 
Поясните куда, где и как это надо писать.
Я лично с сф не знаком...
Это я привел абстрактно названия)
Ну вот повторы(ЗЛО ЖЕ!!!) уже реализованы в формах, а капча - первый найденный бандл: https://github.com/Gregwar/CaptchaBundle
Вы должны понять - используете свое, или берете готовое.
Либо продумать архитектуру своих валидаций, либо разобраться в готовом. Думаю примерно одинаково по времени:)
 
Ты хотел autoescape true, я тебе сделал =)

Можно запросто добавить ->filter('html'|'js'|'off'), завернув скаляры тоже в ViewData (там toString не просто так есть=)). Ну там еще итератора не хватает. Смысл-то не меняется.

UPD: Если нужен выборочный скоуп - итератор же в любом случае как будет работать - extract, а потом за собой подбирать. Ну так и никто не мешает вывалить $autoescape() closure, забинженную в нужный $this =)
 
$user->name->raw() устроит? ;)

хотя и raw($user->name) можно, каэш.
UPD
PHP:
<?php

class ViewData implements ArrayAccess {

    protected $data;

    protected $filter = null;
    protected $override_filter = null;

    public function __construct($data) {
        $this->data = $data;
    }

    public function setFilter(Callable $filter = null) {
        $this->filter = $filter;
        return $this;
    }

    public function escape(Callable $filter) {
        $this->override_filter = $filter;
        return $this;
    }

    public function raw() {
        $this->override_filter = false;
        return $this;
    }

    public function offsetExists($key) {
        return null !== $this->getProperty($key);
    }

    public function offsetGet($key) {
        return $this->handleValue($this->getProperty($key));
    }

    public function offsetSet($offset, $value) { }
    public function offsetUnset($offset) { }

    public function __get($key) {
        return $this->offsetGet($key);
    }

    public function exportArray() {
        $result = [];
        foreach ($this->data as $key => $value) {
            $result[$key] = $this->offsetGet($key);
        }
        return $result;
    }

    public function __call($method, $args) {
        if (!is_object($this->data) || !method_exists($this->data, $method)) {
            return null;
        }
        return $this->handleValue(call_user_func_array([$this->data, $method], $args));
    }

    public function __toString() {
        return (string)$this->filter($this->data);
    }

    protected function handleValue($value) {
        if (null === $value || is_resource($value)) {
            return null;
        }
        return $this->constructSubview($value);
    }

    protected function constructSubview($value) {
        return (new self($value))->setFilter($this->filter);
    }

    protected function getProperty($key) {
        if (is_array($this->data)) {
            return isset($this->data[$key]) ? $this->data[$key] : null;
        } elseif (is_object($this->data)) {
            return property_exists($this->data, $key) ? $this->data->$key : null;
        } else {
            return null;
        }
    }

    protected function filter($value) {
        if (null !== $this->override_filter) {
            $value = $this->override_filter ? call_user_func($this->override_filter, $value) : $value;
            $this->override_filter = null;
        } elseif ($this->filter) {
            $value = call_user_func($this->filter, $value);
        }
        return $value;
    }

}

class Model {

    public $foo = '<b>FOO</b>';

    public function getBar() {
        return (object)['value' => '<h1>BAR</h1>'];
    }

}

$ViewData = new ViewData([
    'title' => '<h1>Title</h1>',
    'a' => ['b' => '<i>Hello</i>'],
    'b' => [
        'c' => 1,
        'model' => new Model,
    ],
]);

$ViewData->setFilter('htmlspecialchars');

extract($ViewData->exportArray());

function raw($v) {
    return $v->raw();
}

function json($v) {
    return $v->escape('json_encode');
}

?>
<!DOCTYPE html>
<html>
<head>
    <?=$title?>
</head>
<body>
<h1><?=$a['b']?></h1>
<ul>
    <li>
        b.c = <?=$b->c?>
    </li>
    <li>
        b.model.foo = <?=$b->model->foo?>
    </li>
    <li>
        b.model.getBar().value = <?=$b->model->getBar()->value?>
    </li>
</ul>

Raw HTML: <xmp><?=$b->model->getBar()->value->raw()?></xmp>

Raw HTML 2: <xmp><?=raw($b->model->getBar()->value)?></xmp>

JSON: <script>var json = <?=$a->escape('json_encode')?></script>
JSON 2: <script>var json = <?=json($a)?></script>

</body>
</html>

во. )

с итерацией самое сложное, это уж сам =) мне чот надоело
 
fixxxer как это будет реализовано для mixed данных?
К примеру, чобы работало как на $var->raw(), так и на func1()->raw().
 
Василий М. сам же успел поучаствовать.
Но однако никто не срется, лишь обсуждают. И так понятно, что PHP-шаблоны слабенькие и неспособные.
Но послушать про хак с автоэкранированием интересно.
 
Absinthe
ну покрути мой код в разных комбинациях =) я толком не тестировал но должно работать по задумке
 
Сверху