Наследование форм

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
Auramel
Сообщения: 80
Зарегистрирован: 2017.11.17, 14:39
Откуда: Russia, Ufa
Контактная информация:

Наследование форм

Сообщение Auramel »

Привет. Есть 2 формы - авторизация и регистрация. Раньше делал копи-паст. У Дмитрия Елисеева, помню, была статья про композитные формы, которая натолкнула меня на мысль наследования форм. Подскажите, такой подход === хорошая практика?

Код: Выделить всё

<?php

namespace app\models\user;

/**
 * Class SignUpForm
 * @package app\models\user
 */
class SignUpForm extends SignInForm
{
    /** @var int */
    public $role = 0;

    /**
     * @return array
     */
    public function rules(): array
    {
        return array_merge(parent::rules(), [
            [['role'], 'required'],
            [['role'], 'integer']
        ]);
    }

    /**
     * @return array
     */
    public function attributeLabels(): array
    {
        return array_merge(parent::attributeLabels(), [
            'role' => 'Роль'
        ]);
    }
}

Код: Выделить всё

<?php

namespace app\models\user;

/**
 * Class SignInForm
 * @package app\models\forms
 */
class SignInForm extends \app\models\Form
{
    /** @var string */
    public $login = '';

    /** @var string */
    public $pass = '';

    /**
     * @return array
     */
    public function rules(): array
    {
        return [
            [['login', 'pass'], 'required'],
            [['login', 'pass'], 'string', 'min' => 4, 'max' => 255]
        ];
    }

    /**
     * @return array
     */
    public function attributeLabels(): array
    {
        return [
            'id'    => '№',
            'login' => 'Логин',
            'pass'  => 'Пароль'
        ];
    }
}
Nex-Otaku
Сообщения: 831
Зарегистрирован: 2016.07.09, 21:07

Re: Наследование форм

Сообщение Nex-Otaku »

Наследование - это временное решение проблемы. Вот например, вам понадобится в форме входа SignIn сделать капчу, но чтобы её не было в форме регистрации SignUp. Из-за наследования вам придётся огород городить.

Поэтому лучше сразу делайте разные формы, без наследования. Один набор полей => одна форма.

То, что поля будут частично пересекаться - ничего страшного. Если очень захочется уйти от дублирования, можно выделить дублирующиеся поля в дочернюю форму. Но это несколько усложнит код. Это обычная цена за гибкость и универсальность.
Auramel
Сообщения: 80
Зарегистрирован: 2017.11.17, 14:39
Откуда: Russia, Ufa
Контактная информация:

Re: Наследование форм

Сообщение Auramel »

тоже об этом думал... в голову приходит паттерн "стратегия" для таких целей (про капчу, например). Спасибо за ответ.
BalykhinAS
Сообщения: 179
Зарегистрирован: 2018.02.05, 13:41
Контактная информация:

Re: Наследование форм

Сообщение BalykhinAS »

Тут главное не подхватить "ООП Головного мозга", наследование форм этот перебор :D

Композитные формы и наследование как по моему это крайне разные вещи

Композитные формы - форма состоящая из нескольких форм.

к примеру, теоретически достаточно

Код: Выделить всё

class CommonForm
{
    public function __construct()
    {
        $this->product = new ProductForm();
        $this->variants = array_map(function () {
            return new VariantForm();
        }, [0, 1]);
    }

    public function load($data)
    {
        foreach($this as $name => $model) {
            if(is_object($model)) {
                $result = $model->load($data);
            } else {
                $result = Model::loadMultiple($model, $data);
            }
        }
        return $result;
    }

    public function validate()
    {
        foreach($this as $name => $model) {
            if(is_object($model)) {
                $result = $model->validate();
            } else {
               $result =  Model::validateMultiple($model);
            }
        }
        return $result;
    }
}

Код: Выделить всё

class ProductForm extends Model
{
    public $name;
    public $description;

    public function rules(): array
    {
        return [
            [['name'], 'required'],
            [['name'], 'string', 'max' => 255],
            [['description'], 'string']
        ];
    }
}

Код: Выделить всё

class VariantForm extends Model
{
    public $name;
    public $sku;
    public $price;
    public $stock;

    public function rules(): array
    {
        return [
            [['name'], 'required'],
            [['name', 'sku'], 'string', 'max' => 255],
            [['price', 'stock'], 'integer', 'min' => 0]
        ];
    }
}

Код: Выделить всё

        $form = new CommonForm();
        if ($form->load(\Yii::$app->request->post()) && $form->validate()) {
		...
        }
и подключайте сюда формы изображений, категорий и всего чего надо. если передавать в конструктор Common состав форм то этот класс может стать общим для всех составных форм
Ответить