Phalcon\Forms\Form - это компонент, который помогает создавать и поддерживать формы в веб-приложениях.

В следующем примере показано его основное использование:

<?php

use Phalcon\Forms\Form;
use Phalcon\Forms\Element\Text;
use Phalcon\Forms\Element\Select;

$form = new Form();

$form->add(
    new Text(
        'name'
    )
);

$form->add(
    new Text(
        'telephone'
    )
);

$form->add(
    new Select(
        'telephoneType',
        [
            'H' => 'Home',
            'C' => 'Cell',
        ]
    )
);

Формы могут отображаться на основе определения формы:

<h1>
    Contacts
</h1>

<form method='post'>

    <p>
        <label>
            Name
        </label>

        <?php echo $form->render('name'); ?>
    </p>

    <p>
        <label>
            Telephone
        </label>

        <?php echo $form->render('telephone'); ?>
    </p>

    <p>
        <label>
            Type
        </label>

        <?php echo $form->render('telephoneType'); ?>
    </p>

    <p>
        <input type='submit' value='Save' />
    </p>

</form>

Каждый элемент формы может быть отрисован в соответствии с требованиями разработчика. Внутренне, Phalcon\Tag используется для создания правильного HTML для каждого элемента, и вы можете передать дополнительные атрибуты HTML в качестве второго параметр render():

<p>
    <label>
        Name
    </label>

    <?php echo $form->render('name', ['maxlength' => 30, 'placeholder' => 'Введите свое имя']); ?>
</p>

HTML атрибуты также могут быть установлены в определении элемента:

<?php

$form->add(
    new Text(
        'name',
        [
            'maxlength'   => 30,
            'placeholder' => 'Введите свое имя',
        ]
    )
);

Инициализация форм

Как было показано ранее, формы можно инициализировать вне класса формы путем добавления в него элементов. Можно повторно использовать код или организовать классы формы, реализующие форму в отдельном файле:

<?php

use Phalcon\Forms\Form;
use Phalcon\Forms\Element\Text;
use Phalcon\Forms\Element\Select;

class ContactForm extends Form
{
    public function initialize()
    {
        $this->add(
            new Text(
                'name'
            )
        );

        $this->add(
            new Text(
                'telephone'
            )
        );

        $this->add(
            new Select(
                'telephoneType',
                TelephoneTypes::find(),
                [
                    'using'      => [
                        'id',
                        'name',
                    ],
                    'useEmpty'   => true,
                    'emptyText'  => 'Выбирать один...',
                    'emptyValue' => '',
                ]
            )
        );
    }
}

Кроме того, Select elements поддерживает параметр useEmpty, позволяющий использовать пустой элемент в списке доступных параметров. Варианты emptyText andemptyValue являются необязательными, которые позволяют настраивать, соответственно, текст и значение пустой элемент

Phalcon\Forms\Form расширяет Phalcon\Di\Injectable так что у вас есть доступ к службам приложений, если это необходимо:

<?php

use Phalcon\Forms\Form;
use Phalcon\Forms\Element\Text;
use Phalcon\Forms\Element\Hidden;

class ContactForm extends Form
{
    /**
     * Этот метод возвращает значение по умолчанию для поля 'csrf'
     */
    public function getCsrf()
    {
        return $this->security->getToken();
    }

    public function initialize()
    {
        // Задать ту же форму, что и сущность
        $this->setEntity($this);

        // Добавьте текстовый элемент для 'email'
        $this->add(
            new Text(
                'email'
            )
        );

        // Добавить текстовый элемент, чтобы поместить скрытый CSRF
        $this->add(
            new Hidden(
                'csrf'
            )
        );
    }
}

Связанный объект, добавленный в форму в параметрах инициализации и созданных пользователей, передается конструктору формы:

<?php

use Phalcon\Forms\Form;
use Phalcon\Forms\Element\Text;
use Phalcon\Forms\Element\Hidden;

class UsersForm extends Form
{
    /**
     * Forms initializer
     *
     * @param Users $user
     * @param array $options
     */
    public function initialize(Users $user, array $options)
    {
        if ($options['edit']) {
            $this->add(
                new Hidden(
                    'id'
                )
            );
        } else {
            $this->add(
                new Text(
                    'id'
                )
            );
        }

        $this->add(
            new Text(
                'name'
            )
        );
    }
}

В экземпляре формы необходимо использовать:

<?php

$form = new UsersForm(
    new Users(),
    [
        'edit' => true,
    ]
);

Валидация

Формы Phalcon интегрированы с компонентом validation для мгновенной проверки. Для каждого элемента могут быть установлены встроенные или настраиваемые валидаторы:

<?php

use Phalcon\Forms\Element\Text;
use Phalcon\Validation\Validator\PresenceOf;
use Phalcon\Validation\Validator\StringLength;

$name = new Text(
    'name'
);

$name->addValidator(
    new PresenceOf(
        [
            'message' => 'Имя обязательное',
        ]
    )
);

$name->addValidator(
    new StringLength(
        [
            'min'            => 10,
            'messageMinimum' => 'Это слишком короткое имя',
        ]
    )
);

$form->add($name);

Затем вы можете проверить форму в соответствии с введенным пользователем пользователем:

<?php

if (!$form->isValid($_POST)) {
    $messages = $form->getMessages();

    foreach ($messages as $message) {
        echo $message, '<br>';
    }
}

Валидаторы выполняются в том же порядке, в каком они были зарегистрированы.

По умолчанию сообщения, сгенерированные всеми элементами в форме, объединяются, чтобы их можно было перемещать с помощью одного foreach, вы можете изменить это поведение, чтобы получить сообщения, разделенные полем:

<?php

foreach ($form->getMessages(false) as $attribute => $messages) {
    echo 'Сообщения, созданные ', $attribute, ':', "\n";

    foreach ($messages as $message) {
        echo $message, '<br>';
    }
}

Или получить конкретные сообщения для элемента:

<?php

$messages = $form->getMessagesFor('name');

foreach ($messages as $message) {
    echo $message, '<br>';
}

Фильтрация

Форма также может фильтровать данные до их проверки. Вы можете устанавливать фильтры в каждом элементе:

<?php

use Phalcon\Forms\Element\Text;

$name = new Text(
    'name'
);

// Set multiple filters
$name->setFilters(
    [
        'string',
        'trim',
    ]
);

$form->add($name);

$email = new Text(
    'email'
);

// Установить один фильтр
$email->setFilters(
    'email'
);

$form->add($email);

Forms + Entities

Сущность, такая как экземпляр model/collection/plainили просто простой PHP-класс, может быть привязана к форме, чтобы устанавливать значения по умолчанию в элементах формы или легко присваивать значения из формы объекту:

<?php

$robot = Robots::findFirst();

$form = new Form($robot);

$form->add(
    new Text(
        'name'
    )
);

$form->add(
    new Text(
        'year'
    )
);

Когда форма отображается, если нет значений по умолчанию, назначенных элементам, они будут использовать те, которые предоставляются объектом:

<?php echo $form->render('name'); ?>

Вы можете проверить форму и присвоить значения с пользовательского ввода следующим образом:

<?php

$form->bind($_POST, $robot);

// Проверить, действительна ли форма
if ($form->isValid()) {
    // Save the entity
    $robot->save();
}

Также возможно создание простого класса как объекта:

<?php

class Preferences
{
    public $timezone = 'Europe/Amsterdam';

    public $receiveEmails = 'No';
}

Используя этот класс как сущность, он позволяет форме принимать значения по умолчанию из него:

<?php

$form = new Form(
    new Preferences()
);

$form->add(
    new Select(
        'timezone',
        [
            'America/New_York'  => 'New York',
            'Europe/Amsterdam'  => 'Amsterdam',
            'America/Sao_Paulo' => 'Sao Paulo',
            'Asia/Tokyo'        => 'Tokyo',
        ]
    )
);

$form->add(
    new Select(
        'receiveEmails',
        [
            'Yes' => 'Yes, please!',
            'No'  => 'No, thanks',
        ]
    )
);

Сущности могут реализовывать методы get, которые имеют более высокий приоритет, чем открытые свойства. Эти методы предоставляют больше свободы для создания значений:

<?php

class Preferences
{
    public $timezone;

    public $receiveEmails;

    public function getTimezone()
    {
        return 'Europe/Amsterdam';
    }

    public function getReceiveEmails()
    {
        return 'No';
    }
}

Элемент формы

Phalcon предоставляет набор встроенных элементов для использования в формах, все эти элементы расположены в пространстве имен Phalcon\Forms\Element:

NameDescription
Phalcon\Forms\Element\Check Генерирует элементы INPUT[type=check]
Phalcon\Forms\Element\Date Генерирует элементы INPUT[type=date]
Phalcon\Forms\Element\Email Генерирует элементы INPUT[type=email]
Phalcon\Forms\Element\File Генерирует элементы INPUT[type=file]
Phalcon\Forms\Element\Hidden Генерирует элементы INPUT[type=hidden]
Phalcon\Forms\Element\Numeric Генерирует элементы INPUT[type=number]
Phalcon\Forms\Element\Password Генерирует элементы INPUT[type=password]
Phalcon\Forms\Element\Radio Генерирует элементы IMPUT[type=radio]
Phalcon\Forms\Element\Select Генерирует элементы тега SELECT (комбинированные списки) на основе выбора
Phalcon\Forms\Element\Submit Генерирует элементы INPUT[type=submit]
Phalcon\Forms\Element\Text Генерирует элементы INPUT[type=text]
Phalcon\Forms\Element\TextArea Генерирует элементы TEXTAREA

Обратные вызовы событий

Всякий раз, когда формы реализуются как классы, обратные вызовы: beforeValidation() и afterValidation() могут быть реализованы в классе формы для выполнения предварительных валидаций и пост-валидации:

<?php

use Phalcon\Forms\Form;

class ContactForm extends Form
{
    public function beforeValidation()
    {

    }
}

Рендеринг форм

Вы можете отобразить форму с полной гибкостью, в следующем примере показано, как визуализировать каждый элемент с помощью стандартной процедуры:

<form method='post'>
    <?php

        // Перейти в форму
        foreach ($form as $element) {
            // Получить любые сгенерированные сообщения для текущего элемента
            $messages = $form->getMessagesFor(
                $element->getName()
            );

            if (count($messages)) {
                // Вывод каждого элемента
                echo '<div class='$messages'>';

                foreach ($messages as $message) {
                    echo $message;
                }

                echo '</div>';
            }

            echo '<p>';

            echo '<label for='', $element->getName(), ''>', $element->getLabel(), '</label>';

            echo $element;

            echo '</p>';
        }

    ?>

    <input type='submit' value='Send' >
</form>

Или повторите использование логики в своем классе формы:

<?php

use Phalcon\Forms\Form;

class ContactForm extends Form
{
    public function initialize()
    {
        // ...
    }

    public function renderDecorated($name)
    {
        $element  = $this->get($name);

        // Получить любые сгенерированные сообщения для текущего элемента
        $messages = $this->getMessagesFor(
            $element->getName()
        );

        if (count($messages)) {
            // Печать каждого элемента
            echo "<div class='messages'>";

            foreach ($messages as $message) {
                echo $this->flash->error($message);
            }

            echo '</div>';
        }

        echo '<p>';

        echo '<label for="', $element->getName(), '">', $element->getLabel(), '</label>';

        echo $element;

        echo '</p>';
    }
}

В представлении:

<?php

echo $element->renderDecorated('name');

echo $element->renderDecorated('telephone');

Создание элементов формы

В дополнение к элементам формы, предоставленным Phalcon, вы можете создавать свои собственные элементы:

<?php

use Phalcon\Forms\Element;

class MyElement extends Element
{
    public function render($attributes = null)
    {
        $html = // ... Произведите некоторый HTML

        return $html;
    }
}

Менеджер форм

Этот компонент предоставляет менеджер форм, который может быть использован разработчиком для регистрации форм и доступа к ним через локатор службы:

<?php

use Phalcon\Forms\Manager as FormsManager;

$di['forms'] = function () {
    return new FormsManager();
};

Формы добавляются в менеджер форм и ссылаются на уникальное имя:

<?php

$this->forms->set(
    'login',
    new LoginForm()
);

Используя уникальное имя, формы могут быть доступны в любой части приложения:

<?php

$loginForm = $this->forms->get('login');

echo $loginForm->render();

Внешние ресурсы

  • Vökuró, это пример приложения, которое использует построитель форм для создания и управления формами, [Github]