Простая генерация форм при помощи FuelPHP
http://2web-master.ru/prostaya-generaciya-form-pri-pomoshhi-fuelphp.html
Благодаря FuelPHP классу fieldset, работа с формами может быть очень простой.
Используя несколько строк кода, вы можете легко сгенерировать и проверить форму. Сегодня мы узнаем, как это сделать. Здесь вы можете посетить бесплатный интернет магазин
Включите пакет ORM через
И наконец, вот SQL код для таблицы, которую мы используем в этом уроке.
Давайте узнаем, какие опции мы можем использовать.
ORM обрабатывает столбец под названием
Пользователи смогут видеть список
постов, добавлять новые или редактировать существующие. Поскольку мы
используем шаблонный контроллер, мы можем использовать для работы
основной файл шаблона. Шаблоны находятся в
Это просто стандартная HTML разметка. Переменная
Используя метод
Наконец, мы передаём
Запустите свой браузер и введите в адресную строку
Нет кнопки подтверждения? Давайте исправим это. Нам нужно добавить новое поле нашему объекту формы.
Используя метод
После добавления, наш
А наша форма...
Если вы попытаетесь подтвердить какие-либо недопустимые данные, вы получите подобный результат:
Всё, кажется, прекрасно, за исключением одной проблемы: данные, которые мы подтвердили не появляются после перезагрузки страницы. Не волнуйтесь, один запрос метода и всё готово.
Круто? Добавьте какие-то допустимые данные, и вы будете переадресованы к методу
С некоторыми небольшими модификациями нашего метода
В этом случае мы получаем пост из нашей базы данных, используя параметр
Список будет обработан методом
В просмотре мы выполняем цикл в
Если у вас есть несколько постов в базе данных, то это должно выглядеть так.
Вы можете передать все типы полей:
Используя несколько строк кода, вы можете легко сгенерировать и проверить форму. Сегодня мы узнаем, как это сделать. Здесь вы можете посетить бесплатный интернет магазин
КлассFieldset
используется для создания формы и управления её проверкой объектно-ориентированным способом. Он использует классыForm
иValidation
. Сам класс непосредственно предназначен только для того, чтобы смоделировать набор полей формы, в то время, как два других класса выполняют основную работу.
Установка Fuel
Нам нужно установить FuelPHP с подключённым пакетом RM. Мы собираемся использовать базу данных MySQL со стандартной таблицей. В то время, как классFieldset
может быть сконфигурирован с использованием обычной модели, использование ORM сэкономит нам немного времени.Если вы не читали два урока, посвящённые FuelPHP, на сайте Nettuts+, сейчас самое время прочитать первую (eng.) и вторую (eng.) статьи от Phil Sturgeon.Настройте соединение базы данных в
fuel/app/config/development/db.php
.
return array(
'default' => array(
'connection' => array(
'dsn' => 'mysql:host=localhost;dbname=blog',
'username' => 'root',
'password' => 'root',
),
),
);
|
fuel/app/config.php
'packages' => array(
'orm',
),
|
CREATE TABLE `blog`.`posts` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`post_title` VARCHAR( 100 ) NOT NULL ,
`post_content` TEXT NOT NULL ,
`author_name` VARCHAR( 65 ) NOT NULL ,
`author_email` VARCHAR( 80 ) NOT NULL ,
`author_website` VARCHAR( 60 ) NULL,
`post_status` TINYINT NULL
) ENGINE = INNODB;
|
Модель
Нам нужна модель для нашего контроллера, чтобы работать с таблицей постов. Создайтеpost.php
в app/classes/model/
. Затем создайте класс Model_Post
и убедитесь, что он расширяет \Orm\Model
. ORM автоматически будет использовать таблицу posts
в нашей базе данных, т.к. мы использовали только её. Если вы хотите установить другую таблицу, настройте статическое свойство $_table_name
.
class Model_Post extends \Orm\Model
{
protected static $_table_name = 'posts'; //установка названия таблицы вручную
}
|
Настройка свойств
Мы должны определить столбцы нашей таблицы постов в пределах нашей модели. В то же время, мы можем также установить метки, правила проверки формы для использования с нашим классом fieldset, чтобы сгенерировать форму. Всё это вместе входит в связанный массив$_properties
. Если собрать всё воедино, наша конечная модель должна выглядеть так:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
class Model_Post extends \Orm\Model
{
protected static $_table_name = 'posts';
protected static $_properties = array(
'id',
'post_title' => array( //column name
'data_type' => 'string',
'label' => 'Post Title', //label for the input field
'validation' => array('required', 'max_length'=>array(100), 'min_length'=>array(10)) //правила валидации
),
'post_content' => array(
'data_type' => 'string',
'label' => 'Post Content',
'validation' => array('required')
),
'author_name' => array(
'data_type' => 'string',
'label' => 'Author Name',
'validation' => array('required', 'max_length'=>array(65), 'min_length'=>array(2))
),
'author_email' => array(
'data_type' => 'string',
'label' => 'Author Email',
'validation' => array('required', 'valid_email')
),
'author_website' => array(
'data_type' => 'string',
'label' => 'Author Website',
'validation' => array('required', 'valid_url', 'max_length'=>array(60))
),
'post_status' => array(
'data_type' => 'string',
'label' => 'Post Status',
'validation' => array('required'),
'form' => array('type' => 'select', 'options' => array(1=>'Published', 2=>'Draft')),
)
);
}
|
data_type
просто определяет тип поля. Это может быть string (строка), integer (целое число) или mysql_date. Значение свойства label
будет показано, как метка поля, когда форма будет сформирована. validation
вводит массив правил проверки. По умолчанию, эти поля являются текстовыми. Но используя form
, вы можете изменить их тип на select
или texarea
.ORM обрабатывает столбец под названием
id
,
как первичный, и он не будет показан во время генерации формы. Если у
вас другой первичный столбец таблицы, используйте свойство $_primary_key
, чтобы определить его.
/**
* Post Model
*/
class Model_Post extends \Orm\Model
{
protected static $_table_name = 'posts';
protected static $_primary_key = array('id'); //вы может установить несколько столбцов, .. $_primary_key => array('id', 'user_id')
}
|
Контроллер
Теперь, когда модель готова, давайте создадим контроллер. Контроллеры должны быть размещены вfuel/app/classes/controller/
. Мы создали контроллер, под названием Controller_Posts (posts.php)
и расширили его из Controller_Template
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
/**
* Post Controller fuel/app/classes/controller/posts.php
*/
class Controller_Posts extends \Controller_Template
{
//list posts
function action_index()
{
}
//add new one
function action_add()
{
}
//edit
function action_edit($id)
{
}
}
|
fuel/app/views/template.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<?php echo Asset::css('bootstrap.css'); ?>
</head>
<body>
<div id="content">
<p>
<?php
echo \Html::anchor('posts/index', 'Listing'), ' ', \Html::anchor('posts/add', 'Add');
?>
</p>
<?php if(isset($messages) and count($messages)>0): ?>
<div class="message">
<ul>
<?php
foreach($messages as $message)
{
echo '<li>', $message,'</li>';
}
?>
</ul>
</div>
<?php endif; ?>
<?php echo $content; ?>
</div>
</body>
</html>
|
$content
будет содержать контент. Мы можем установить массив переменных, и если
мы так сделаем, то этот массив будет отображён в виде неупорядоченного
списка.Добавление новых постов
Вот теперь начинаются развлечения. Мы собираемся создать форму для добавления новых постов. Как вы, возможно, предположили, мы будем работать с методомaction_add()
. Давайте сгенерируем форму и передадим её нашему шаблону.
//добавить
function action_add()
{
$fieldset = Fieldset::forge()->add_model('Model_Post');
$form = $fieldset->form();
$this->template->set('content', $form->build(), false); //false говорит fuel не преобразовывать html теги в безопасную строку.
}
|
Fieldset::forge()
возвращает новый экземпляр класса поля. Это идентично выполнению new Fieldset
. Однако, использование здесь метода forge
позволяет нам указать название нового экземпляра класса. Если мы
назовём свой класс второй раз одинаковым именем, существующий экземпляр
класса будет возвращён, если это доступно [the Factory pattern]. Чтобы
назвать свой класс, передайте название методу forge
. Fieldset::forge('new_post')
Используя метод
add_model
, мы передаём модель, из которой должны генерироваться формы. Fieldset возмет информацию из $_properties
, чтобы сгенерировать форму. Вызов метода form()
из объекта fieldset
возвратит экземпляр класса Form
, а вызывая метод build()
, мы можем получить html (строковый) вывод формы.
$this->template->set('content', $form, false);
|
$form
шаблону, как контент. Другой метод передачи переменных шаблону это $this->template->content = $form
.Запустите свой браузер и введите в адресную строку
http://path_to_site/index.php/posts/add
. Вы должны увидеть форму, идентичную этой.Нет кнопки подтверждения? Давайте исправим это. Нам нужно добавить новое поле нашему объекту формы.
$form->add('submit', '', array('type' => 'submit', 'value' => 'Add', 'class' => 'btn medium primary'));
|
add
, мы
можем добавлять дополнительные поля в нашу форму. Первый параметр это
новое название поля, второй — его метка, а третьим параметром мы
передаём массив атрибутов.После добавления, наш
action_add()
будет выглядеть так.
function action_add()
{
$fieldset = Fieldset::forge()->add_model('Model_Post');
$form = $fieldset->form();
$form->add('submit', '', array('type' => 'submit', 'value' => 'Add', 'class' => 'btn medium primary'));
$this->template->set('content', $form->build(), false);
}
|
Проверка и сохранение
Теперь, когда у нас есть форма, давайте проверим её правильность и сохраним в базе данных. Объектfieldset
включает экземпляр класса валидации FuelPHP. Все правила применены и готовы к работе.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
function action_add()
{
$fieldset = Fieldset::forge()->add_model('Model_Post');
$form = $fieldset->form();
$form->add('submit', '', array('type' => 'submit', 'value' => 'Add', 'class' => 'btn medium primary'));
if($fieldset->validation()->run() == true)
{
$fields = $fieldset->validated();
$post = new Model_Post;
$post->post_title = $fields['post_title'];
$post->post_content = $fields['post_content'];
$post->author_name = $fields['author_name'];
$post->author_email = $fields['author_email'];
$post->author_website = $fields['author_website'];
$post->post_status = $fields['post_status'];
if($post->save())
{
\Response::redirect('posts/edit/'.$post->id);
}
}
else
{
$this->template->messages = $fieldset->validation()->errors();
}
$this->template->set('content', $form->build(), false);
}
|
$fieldset->validation()
передаёт экземпляр класса валидации, и обратившись к его методу run()
, мы можем проверить, пройдена ли валидация. Если так, мы добавляем новый пост в нашу базу данных. $fieldset->validated()
возвращает массив проверенных полей. Если проверка пройдена, и пост
сохранён, пользователь будет переадресован на страницу редактирования, в
противном случае ошибки проверки будут переданы нашему шаблону, как
переменная сообщения.Если вы попытаетесь подтвердить какие-либо недопустимые данные, вы получите подобный результат:
Всё, кажется, прекрасно, за исключением одной проблемы: данные, которые мы подтвердили не появляются после перезагрузки страницы. Не волнуйтесь, один запрос метода и всё готово.
$fieldset = Fieldset::forge()->add_model('Model_Post')->repopulate(); //метод repopulate заполнит форму сохранённой информацией
|
action_edit()
, который ещё не готов.Редактирование поста
Редактирование очень похоже на добавление поста. За исключением того, что мы должны заполнить секцию данными из существующего поста. Мы собираемся дублировать кодaction_add
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
function action_edit($id)
{
$post = \Model_Post::find($id);
$fieldset = Fieldset::forge()->add_model('Model_Post')->populate($post); //объект поста передан методу populate
$form = $fieldset->form();
$form->add('submit', '', array('type' => 'submit', 'value' => 'Save', 'class' => 'btn medium primary'));
if($fieldset->validation()->run() == true)
{
$fields = $fieldset->validated();
//$post = new Model_Post;
$post->post_title = $fields['post_title'];
$post->post_content = $fields['post_content'];
$post->author_name = $fields['author_name'];
$post->author_email = $fields['author_email'];
$post->author_website = $fields['author_website'];
$post->post_status = $fields['post_status'];
if($post->save())
{
\Response::redirect('posts/edit/'.$id);
}
}
else
{
$this->template->messages = $fieldset->validation()->errors();
}
$this->template->set('content', $form->build(), false);
}
|
action_add()
, у нас есть свой метод редактирования. Метод repopulate()
был заменён на метод populate()
. Используя метод populate
, мы можем заполнить форму существующими данными поста.В этом случае мы получаем пост из нашей базы данных, используя параметр
$id
, а затем передаём его необходимому методу. Мы больше не нуждаемся в $post = new Model_Post;
, поскольку мы ничего не добавили в базу данных. Объект $post
,
который мы создаём в начале, используется, чтобы назначить новые
значения. Как только пост отредактирован, вы будете переадресованы назад
к экрану редактирования. Всё готово! Добавьте несколько постов и
попытайтесь их отредактировать.Страницы списка
Давайте создадим раздел списка постов, так пользователи смогут увидеть все посты в одном месте.Список будет обработан методом
action_index()
.
//список
function action_index()
{
$posts = \Model_Post::find('all');
$view = \View::forge('listing');
$view->set('posts', $posts, false);
$this->template->content = $view; //In config file View objects are whitelisted so Fuelphp will not escape the html.
}
|
Model_Post::find('all')
возвратит массив объектов всех наших постов. Используя View::forge()
, мы создаём новый объект просмотра. Параметр для View::forge()
— это название нашего определённого просмотра. Они располагаются в app/views/listing.php
. Затем массив объектов постов ($posts
) передаётся нашему «view». «Listing» позаботится о списке, и наконец, мы назначаем просмотр на $this->template->content
.В просмотре мы выполняем цикл в
$posts
и генерируем список.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<?php
/**
* Listing view, views/listing.php
*/
if($posts):
foreach($posts as $post):
?>
<div class="post">
<h2><?php echo $post->post_title; ?> <small><?php echo \Html::anchor('posts/edit/'.$post->id, '[Edit]');?></small></h2>
<p><?php echo $post->post_content; ?></p>
<p>
<small>By <?php echo $post->author_name; ?></small><br />
<small><?php echo $post->author_email; ?></small><br />
<small><?php echo $post->author_website; ?></small><br />
</p>
</div>
<?php
endforeach;
endif;
?>
|
Некоторые конечные доработки
Кажется всё работает правильно; однако, есть некоторые незначительные проблемы. У сгенерированной формы есть текстовое поле для контента поста, которое будет лучше выглядеть, какtextarea
.
//Model_Post
'post_content' => array(
'data_type' => 'string',
'label' => 'Post Content',
'validation' => array('required'),
'form' => array('type' => 'textarea') //даст нам поле textarea
),
|
text
, textarea
, select
, radio
и т.д. Для элементов select
или radio
вы можете установить опции. Установка опций для select
, используя другую таблицу также возможна. Если вы хотите изменить стандартную разметку, поместите файл конфигурации формы в fuel/app/config/form.php
. Если вы не уверены, что ставить туда, скопируйте материал из fuel/core/config/form.php
. Fuel использует этот файл для генерации форм.
Комментарии
Отправить комментарий