вторник, 16 сентября 2008 г.

Symfony: Создаем форму обратной связи 2/3

Приступим к генерации формы.

Начиная с версии 1.1 в Symfony для генерации форм используется система виджетов. Это означает что Вам надо будет в основном заниматься описанием полей и их свойств, и не заботиться о пользовательском вводе и проверке.

Теперь к практике.
В прошлой статье мы сгенерировали базовые классы форм командой >symfony propel:build-forms
Небольшое объяснение, Symfony генерирует базовые классы, в каталоге например
/lib/forms/base/BaseFeedbackLogForm.class.php
мы их не трогаем, мы в них будем "подглядывать", т.к. в следующий раз при выполнении
>symfony propel:build-forms
все классы в каталоге /lib/forms/base/ будут регенерированы заново, в соответствии в моделью, описанной в schema.yml, и все изменения внесенные в них будут уничтожены.

Для всех опытов и модернизаций нам предоставлены классы в каталоге /lib/forms/
Открываем класс /lib/forms/FeedbackLogForm.class.php, видим пустой класс, отложим его на время.

Открываем actions.class.php, и меняем метод executeIndex

public function executeIndex($request){
$this->form = new FeedbackLogForm(FeedbackLogPeer::retrieveByPk($request->getParameter('id')));
}

Запускаем http://minisite/frontend_dev.php/feedback
ops, error

Class "FeedbackUsers" must implement a "__toString" method to be rendered in a "sfWidgetFormPropelSelect" widget

Что произошло?
Symfony попыталась создать листбокс со списком получателей, для него используется "магический метод" __toString, но он не определен в модели, исправим это.

class FeedbackUsers extends BaseFeedbackUsers
{
public function __toString(){
return $this->getName();
}
}


Пробуем еще, и получаем такой экран:


Для начала неплохо, немного наведем красоту, открываем файл /lib/form/FeedbackLogForm.class.php и вносим следующие изменения:

class FeedbackLogForm extends BaseFeedbackLogForm
{
public function configure()
{
$this->setWidgets(array(
'id' => new sfWidgetFormInputHidden(),
'feedback_user_id' => new sfWidgetFormPropelSelect(array('model' => 'FeedbackUsers', 'add_empty' => true)),
'name' => new sfWidgetFormInput(),
'email' => new sfWidgetFormInput(),
'subject' => new sfWidgetFormInput(),
'content' => new sfWidgetFormTextarea(),
'get_answer' => new sfWidgetFormInputCheckbox(),
));

$this->widgetSchema->setLabels(array(
'feedback_user_id' => 'Кому',
'name' => 'Ваше Ф.И.О.',
'content' => 'Вопрос',
'email' => 'Ваш Email',
'subject' => 'Заголовок письма',
'get_answer' => 'Получить ответ на Email',
));
}//configure
}//class

Обратите внимание на $this->widgetSchema->setLabels тут мы меняем подписи к полям.

Что бы листбокс не пустовал, добавим пару записей.
ПО большому счету сайт начинается с админки.
Но мы пока не будем ей уделять много времени.
symfony propel:init-admin backend feedback_users FeedbackUsers
symfony propel:init-admin backend feedback_log FeedbackLog
Открываем http://minisite/backend_dev.php/feedback_users и вносим пару получателей.

Обновляем страницу http://minisite/frontend_dev.php/feedback и видим



Форма обрела более понятый вид, но нас не устраивает вид подписей к полям, мы хотим их выровнять по левому краю, также мы хотим поля снабдить коментариями, для обязательных полей поставим "*", и рядом с флажком напишем "да"
Для этого мы напишем воспользуемся директивой $this->widgetSchema->setHelps

$this->widgetSchema->setHelps(array(
'feedback_user_id' => ' * ',
'name' => ' * ',
'content' => ' * ',
'email' => ' * ',
'subject' => ' * ',
'get_answer' => ' да ',
));
$myDecorator = new sfFeedbackFormDecorator($this->getWidgetSchema());
$this->getWidgetSchema()->addFormFormatter('custom', $myDecorator);
$this->widgetSchema->setFormFormatterName('custom');

и напишем свой декоратор для строчек формы.

/*
* CUSTOM DECORATOR
*/
class sfFeedbackFormDecorator extends sfWidgetFormSchemaFormatter {
protected
$rowFormat = "
%hidden_fields%

%label%
%field% %help%
\n",
$helpFormat = '%help%',
$errorRowFormat = "
\n%errors%
\n",
$errorListFormatInARow = " \n%errors% \n",
$errorRowFormatInARow = " %error%\n",
$namedErrorRowFormatInARow = "
  • %name%: %error%
  • \n",
    $decoratorFormat = "";
    }// decorator class


    Обновляем страницу и видим:


    На сегодня хватит.
    Что мы пока имеем? Никаких очевидных преимуществ ;)
    Такую формочку с использованием классического HTML мы бы сделали гораздо быстрее, но не будем торопиться, завтра попробуем проверять введенные данные и сохранять их в БД.

    понедельник, 15 сентября 2008 г.

    Symfony: Создаем форму обратной связи 1/3

    Начнем делать маленький сайт-визитку с использованием Symfony(версия 1.1.1 на момент написания статьи).

    Первым модулем сделаем обратную связь.

    Обратная связь необходимый компонент практически для любого сайта, на ее примере мы опробуем многие интересные моменты.

    Приступим.

    1. Создаем проект

    >symfony init-project minisite

    2. Создаем 2 приложения

    >symfony init-app frontend
    >symfony init-app backend

    3. Разворачиваем базу
    ссылка на дамп

    4. Пишем схему

    propel:

    sf_feedback_users:
    _attributes: { phpName: FeedbackUsers }
    id: { type: integer, required: true,primaryKey: true, autoIncrement: true }
    name: { type: varchar(255) }
    email: { type: varchar(255) }
    subject: { type: varchar(255) }

    sf_feedback_log:
    _attributes: { phpName: FeedbackLog }
    id: { type: integer, required: true, primaryKey: true, autoIncrement: true }
    feedback_user_id: { phpName: FeedbackUserId, type: integer, foreignTable: sf_feedback_users, foreignReference: id }
    name: { type: varchar(255) }
    email: { type: varchar(255) }
    subject: { type: varchar(255) }
    content: { type: longvarchar }
    is_published: { type: boolean, default: 0 }
    get_answer: { type: boolean, default: 0 }
    created_at: ~
    updated_at: ~


    Проверим propel.ini, вписываем свои настройки для MySQL
    propel.targetPackage = lib.model
    propel.packageObjectModel = true
    propel.project = minisite
    propel.database = mysql
    propel.database.createUrl = mysql://root@localhost/
    propel.database.url = mysql://root@localhost/minisite

    5. Создаем модель
    >symfony propel:build-model

    6. Сгенерируем формы
    >symfony propel:build-forms

    7. Вносим поправки в C:\WINDOWS\system32\drivers\etc\hosts
    127.0.0.1 minisite

    8. Вносим изменения в httpd.conf
    ServerName minisite
    DocumentRoot "C:\www\sfprojects\minisite\web"
    DirectoryIndex index.php
    Alias /sf c:\php\data\symfony\web\sf

    AllowOverride All
    Allow from All


    AllowOverride All
    Allow from All



    Перезапускаем Апач.

    7. Проверяем
    http://minisite/index.php



    Если Вы видите такое изображение, значит все идет по плану :)

    8. Создаем модуль обр.связи
    >symfony init-module frontend feedback

    Проверяем:
    http://minisite/index.php/feedback


    Если все сделано правильно, видим ту же картинку, только надпись по центру изменилась. Все идет хорошо, в следующей статье займемся непосредственной генерацией формы.