MVC и валидация

Василий М.

Новичок
GusakovNick
вопросы вкуса и привычек. мне легче на php написать за день набор хэлпеов, которые все тоже самое будут делать
 

hell0w0rd

Продвинутый новичок
GusakovNick
Не знаю что легче будет выучить дизайнеру, синтаксис php, или целый twig перелопатить, с всякими там наследованиями.
Ведь представление как бы должен дизайнер делать...
Не отрицаю может и есть проекты когда без шаблонизатора и их фичей не обойтись, но мне лично таких проектов не попадалось...
Не знаю-не знаю. Даже самые простые магазины содержат в себе по 10-15 страниц. Вот тут наследование очень помогает, чтобы через пол года не ходить по всем шаблонам и не прамить футер. Да, можно все вытаскивать по файлам - но это какое-то сомнительное удовольствие
 

hell0w0rd

Продвинутый новичок
GusakovNick
вопросы вкуса и привычек. мне легче на php написать за день набор хэлпеов, которые все тоже самое будут делать
Зачем? Зачем тратить свое время на то, что уже решили, и решили надо сказать хорошо.
Вы можете в любой момент отключить экранирование внутри блока с экранированием, можете поменять тип, или еще что-то, а так нагородите хелперов
 

vanicon

Новичок
Да, можно все вытаскивать по файлам - но это какое-то сомнительное удовольствие
Так разве это не одно и тоже, общие элемента типа шапки и футера вынести в файлы, и вызывать там где надо, в чем сложность?
А самое главное разницы нет, хоть с помощью твига наследуя, хоть так, результат один...
 

vanicon

Новичок
Повторяю ребят не в ту сторону нас понесло, твиг или чистый пхп с хелперами, отношение к валидации это не имеет никакого.
 

hell0w0rd

Продвинутый новичок
Так разве это не одно и тоже, общие элемента типа шапки и футера вынести в файлы, и вызывать там где надо, в чем сложность?
А самое главное разницы нет, хоть с помощью твига наследуя, хоть так, результат один...
Нет! Там вверху ссылку кинули, не одно и то же, я не могу взять и что-то переопределить в подключенном шаблоне. А тут - запросто. Вместо того как в очередной раз сядете писать хелперы - советую попробовать потратить час на чтение документации и примеров использования. Я думаю вы отложите надуманные проблемы в виде создания хелперов и сядете писать шаблон)
 

vanicon

Новичок
Ну как где? Опять создаем фильтр isMyDataBaseHaveThisData($data) и проверяем)
assertEquals($data1, $data2)
isCapchaRight($capchaCode)
что здесь не так-то?)
Поясните куда, где и как это надо писать.
Я лично с сф не знаком...
 

fixxxer

К.О.
Партнер клуба
Код:
{% 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>
 

hell0w0rd

Продвинутый новичок
Поясните куда, где и как это надо писать.
Я лично с сф не знаком...
Это я привел абстрактно названия)
Ну вот повторы(ЗЛО ЖЕ!!!) уже реализованы в формах, а капча - первый найденный бандл: https://github.com/Gregwar/CaptchaBundle
Вы должны понять - используете свое, или берете готовое.
Либо продумать архитектуру своих валидаций, либо разобраться в готовом. Думаю примерно одинаково по времени:)
 

fixxxer

К.О.
Партнер клуба
Ты хотел autoescape true, я тебе сделал =)

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

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

Absinthe

жожо
fixxxer каким образом мне сделать <?= raw($user->name) ?> при твоем способе?
 

fixxxer

К.О.
Партнер клуба
$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>
во. )

с итерацией самое сложное, это уж сам =) мне чот надоело
 

Absinthe

жожо
fixxxer как это будет реализовано для mixed данных?
К примеру, чобы работало как на $var->raw(), так и на func1()->raw().
 

Absinthe

жожо
Василий М. сам же успел поучаствовать.
Но однако никто не срется, лишь обсуждают. И так понятно, что PHP-шаблоны слабенькие и неспособные.
Но послушать про хак с автоэкранированием интересно.
 

fixxxer

К.О.
Партнер клуба
Absinthe
ну покрути мой код в разных комбинациях =) я толком не тестировал но должно работать по задумке
 
Сверху