<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>JEKA.RU &#187; forms</title>
	<atom:link href="http://jeka.ru/tag/forms/feed/" rel="self" type="application/rss+xml" />
	<link>http://jeka.ru</link>
	<description>Жизнь в мире IT</description>
	<lastBuildDate>Thu, 17 Nov 2011 13:27:15 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Symfony: Фильтры формы &#8211; выпадающий список для текстового поля</title>
		<link>http://jeka.ru/2010/03/29/filtry-formy-vypadayushhij-spisok-dlya-tekstovogo-polya/</link>
		<comments>http://jeka.ru/2010/03/29/filtry-formy-vypadayushhij-spisok-dlya-tekstovogo-polya/#comments</comments>
		<pubDate>Mon, 29 Mar 2010 17:53:18 +0000</pubDate>
		<dc:creator>Jeka</dc:creator>
				<category><![CDATA[Программирование]]></category>
		<category><![CDATA[filter]]></category>
		<category><![CDATA[forms]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://jeka.ru/?p=428</guid>
		<description><![CDATA[Так получилось, что у одной модели имеется текстовое поле с не очень большим количеством вариантов значения. По идее можно сделать по правильному и вывести все в отдельную таблицу, но по некоторым причинам этого не делается.
Следовательно в админке при фильтрации, не очень охота писать значения этого поля ручками, легко можно сделать выпадающий список со всеми вариантами.
Сначала [...]]]></description>
			<content:encoded><![CDATA[<p>Так получилось, что у одной модели имеется текстовое поле с не очень большим количеством вариантов значения. По идее можно сделать по правильному и вывести все в отдельную таблицу, но по некоторым причинам этого не делается.<br />
Следовательно в админке при фильтрации, не очень охота писать значения этого поля ручками, легко можно сделать выпадающий список со всеми вариантами.<br />
Сначала сделал так:</p>
<pre class="brush: php;">

// SomeModelFormFilter.class.php
// ...
  public function configure()
  {
    $this-&gt;setWidget('status', new sfWidgetFormChoice(
      array('choices'=&gt;self::getStatuses())
    ));

    $this-&gt;setValidator('status', new sfValidatorChoice(array(
      'choices'=&gt;array_keys(self::getStatuses()),
      'required'=&gt;false
    )));
  }

  public static function getStatuses()
  {
     return array(
         '' =&gt; '',
         'one'=&gt;'Один',
         'two'=&gt;'Два',
         'three'=&gt;'Три'
     );
  }
//...
</pre>
<p>Оказалось, что хоть выпадающий список появляется, фильтрация не происходит.<br />
Немного покопавшись, нашел такое решение: надо для нашего поля status, указать тип &laquo;ForeignKey&raquo;.<br />
Делаем это перекрываем родительский метод &laquo;getFields()&raquo;.</p>
<pre class="brush: php;">

// SomeModelFormFilter.class.php
// ...
  public function getFields()
  {
    $fields = parent::getFields();
    $fields['status']='ForeignKey';

    return $fields;
  }
// ...
</pre>
<p>Все, теперь работает.</p>
]]></content:encoded>
			<wfw:commentRss>http://jeka.ru/2010/03/29/filtry-formy-vypadayushhij-spisok-dlya-tekstovogo-polya/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Некоторые особенности CSRF Protection в symfony</title>
		<link>http://jeka.ru/2010/01/18/csrf-protection/</link>
		<comments>http://jeka.ru/2010/01/18/csrf-protection/#comments</comments>
		<pubDate>Mon, 18 Jan 2010 09:53:40 +0000</pubDate>
		<dc:creator>Jeka</dc:creator>
				<category><![CDATA[Программирование]]></category>
		<category><![CDATA[CSRF Protection]]></category>
		<category><![CDATA[forms]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://jeka.ru/?p=410</guid>
		<description><![CDATA[В данной заметке я привожу некоторую ситуацию, с которой я столкнулся при работе с формами в замечательном PHP фреймворке Symfony. В частности, проблема возникала при включенной защите от межсайтовых запросов (CSRF Protection), что это такое вы можете прочитать в википедии (http://ru.wikipedia.org/wiki/CSRF, http://www.inattack.ru/article/552.html).]]></description>
			<content:encoded><![CDATA[<p>В данной заметке я привожу некоторую ситуацию, с которой я столкнулся при работе с формами в замечательном PHP фреймворке Symfony. В частности, проблема возникала при включенной защите от межсайтовых запросов (<strong><abbr title="Cross-Site Request Forgery">CSRF</abbr> Protection</strong>), что это за защита вы можете прочитать в википедии (<a href="http://ru.wikipedia.org/wiki/CSRF" target="_blank">http://ru.wikipedia.org/wiki/CSRF</a>, <a href="http://www.inattack.ru/article/552.html" target="_blank">http://www.inattack.ru/article/552.html</a>).</p>
<p>В симфонии при включенной CSRF защите в форму подставляется скрытое поле с именем _csrf_token, его значение формируется как md5 хеш от секретной строки, имени класса и <strong>идентификатора сессии</strong> (session_id).<br />
Пример формирования значения токена в Symfony:</p>
<pre class="brush: php;">
  // sfForm.class.php
  public function getCSRFToken($secret = null)
  {
    ....
    return md5($secret.session_id().get_class($this));
  }
</pre>
<p>Следовательно, если после некоторого действия, значение возвращаемое session_id() меняется, то дальнейшая валидация созданных до этого момента форм, не будет корректно обрабатываться.<br />
Такие случаи могут возникать, например, при авторизации пользователя (sfGuardPlugin) и дальнейшей обработке форм в одном запросе.<br />
Пример, у нас есть две формы c полями:<br />
1. sfGuardFormSignin: signin[username], signin[password]<br />
2. AddressForm: address[phone],address[city],&#8230; -</p>
<p>Мы хотим в одном запросе авторизовать пользователя с помощью логина пароля и сохранить обязательные поля из формы address<br />
Делаем примерно так:</p>
<pre class="brush: php;">
$this-&gt;auth_form = !$this-&gt;getUser()-&gt;isAuthenticated() ? new sfGuardFormSignin() : null;
$this-&gt;address_form = new AddressForm();
if ($request-&gt;isMethod('post'))
{
  // авторизуемся
  if (!$this-&gt;getUser()-&gt;isAuthenticated())
  {
    $this-&gt;auth_form-&gt;bind($request-&gt;getParameter('signin'));
    if ($this-&gt;auth_form-&gt;isValid())
    {
      $values = $this-&gt;auth_form-&gt;getValues();

      $this-&gt;getUser()-&gt;signin($values['user'], array_key_exists('remember', $values) ? $values['remember'] : false);
      $this-&gt;auth_form=null;
    }
  }

  // обрабатываем форму адреса
  $this-&gt;address_form-&gt;bind($request-&gt;getParameter('address'));
  if ($this-&gt;address_form-&gt;isValid())
  {
    // что-то делаем с формой, например сохраняем
    $this-&gt;address_form-&gt;save();
    //...

    $this-&gt;redirect('@somepath');
  }

}
</pre>
<p>Допустим, авторизация прошла успешно, но валидация формы адреса не прошла. Тогда нам покажется форма адреса с ошибками, но исправив ошибки мы все равно получим не валидную форму так как session_id изменился, а форма адреса создавалась с учетом старого его значения и<br />
нам будет в любом случае выдавать ошибку &laquo;csrf token: Required.&raquo;.<br />
Как избежать подобного?<br />
Способ который я применил (на мой взгляд не очень красивый) заключается в следующем: нужно после авторизации поставить в сессию атрибут<br />
о временном отключении &laquo;CSRF Protetion&raquo;  перед обработкой форм проверять данный атрибут и отключать защиту CSRFT.<br />
Пример:</p>
<pre class="brush: php;">
$this-&gt;auth_form = !$this-&gt;getUser()-&gt;isAuthenticated() ? new sfGuardFormSignin() : null;
$this-&gt;address_form = new AddressForm();
if ($request-&gt;isMethod('post'))
{

  // Авторизация
  if (!$this-&gt;getUser()-&gt;isAuthenticated())
  {
    $this-&gt;auth_form-&gt;bind($request-&gt;getParameter('signin'));
    if ($this-&gt;auth_form-&gt;isValid())
    {
      $values = $this-&gt;auth_form-&gt;getValues();

      $this-&gt;getUser()-&gt;signin($values['user'], array_key_exists('remember', $values) ? $values['remember'] : false); // &lt;&lt;&lt; здесь меняется session_id
      $this-&gt;getUser()-&gt;setAttribute('disable_csrf',true); // &lt;&lt;&lt; снимаем защиту CSRF
      $this-&gt;auth_form=null;
    }
  }

  // Отключаем защиту если требуется
  if ($this-&gt;getUser()-&gt;getAttribute('disable_csrf',false))
  {
    sfForm::disableCSRFProtection();
    unset ($this-&gt;address_form[sfForm::getCSRFFieldName()]);
  }

  // обработка формы адреса
  $this-&gt;address_form-&gt;bind($request-&gt;getParameter('address'));

  if ($this-&gt;address_form-&gt;isValid())
  {

    // что-то делаем с формой, например сохраняем
    $this-&gt;address_form-&gt;save();
    //...

    $this-&gt;getUser()-&gt;setAttribute('disable_csrf',null); // если все хорошо включаем защиту CSRF обратно
    $this-&gt;redirect('@somepath');
  }

}
</pre>
<p>Все вышеприведенное тестировалось на версии symfony 1.2, в этой версии CSRF защиту можно отключить только глобально. В более новых версиях фреймворка (1.3, 1.4), появилась возможность отключать защиту локально для конкретной формы по отдельности, что более правильно.<br />
З.Ы. Если кто-то скажет, как подобное можно более красиво решить, буду очень благодарен <img src='http://jeka.ru/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://jeka.ru/2010/01/18/csrf-protection/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Symfony Forms I18n изменение поведения</title>
		<link>http://jeka.ru/2009/02/06/symfony-forms-i18n-izmeneniya-povedeniya/</link>
		<comments>http://jeka.ru/2009/02/06/symfony-forms-i18n-izmeneniya-povedeniya/#comments</comments>
		<pubDate>Fri, 06 Feb 2009 10:40:54 +0000</pubDate>
		<dc:creator>Jeka</dc:creator>
				<category><![CDATA[Программирование]]></category>
		<category><![CDATA[forms]]></category>
		<category><![CDATA[i18n]]></category>
		<category><![CDATA[propel]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://jeka.ru/?p=164</guid>
		<description><![CDATA[Появилась задача унифицировать поведение всех форм, конкретней, чтобы в многоязычной форме автоматически устанавливалась текущая культура пользователя. Для красоты еще добавил иконку флага как идентификатор культуры.
Все формы у нас наследуются от BaseFormPropel, следовательно открываем файл в нашем проекте $project/lib/form/BaseFormPropel.class.php и в методе класса setup(), пишем нужный нам код.

abstract class BaseFormPropel extends sfFormPropel
{
  public function setup()
 [...]]]></description>
			<content:encoded><![CDATA[<p>Появилась задача унифицировать поведение всех форм, конкретней, чтобы в многоязычной форме автоматически устанавливалась текущая культура пользователя. Для красоты еще добавил иконку флага как идентификатор культуры.</p>
<p>Все формы у нас наследуются от BaseFormPropel, следовательно открываем файл в нашем проекте $project/lib/form/BaseFormPropel.class.php и в методе класса setup(), пишем нужный нам код.</p>
<pre class="brush: php;">
abstract class BaseFormPropel extends sfFormPropel
{
  public function setup()
  {
    if ($this-&gt;isI18n())
    {
      $culture = sfContext::getInstance()-&gt;getUser()-&gt;getCulture();
      $this-&gt;embedI18n(array($culture));

      $icons = sfConfig::get('app_site_language_icons'); // get icon array
      $this-&gt;widgetSchema-&gt;setLabel($culture, '&lt;img src=&quot;'.$icons[$culture].'&quot; width=&quot;24&quot; height=&quot;24&quot; alt=&quot;&quot; /&gt;');
    }
  }
}
</pre>
<p>В файле app.yml  у меня хранятся соответствия названий культур и иконок флажков.</p>
<pre class="brush: css;">
all:
  site:
    language_icons:
        ru: /images/flags/24/ru.png
        en: /images/flags/24/en.png
        de: /images/flags/24/de.png
</pre>
<p>
В итоге получаем вот такой вид формы:<br/><br />
<img src="http://jeka.ru/wp-content/uploads/2009/02/form-i18n.gif" alt="form-i18n" title="form-i18n" width="399" height="174" class="alignnone size-full wp-image-171" /></p>
]]></content:encoded>
			<wfw:commentRss>http://jeka.ru/2009/02/06/symfony-forms-i18n-izmeneniya-povedeniya/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Перевод &#171;Symfony forms in action&#187;</title>
		<link>http://jeka.ru/2008/08/18/perevod-symfony-forms-in-action/</link>
		<comments>http://jeka.ru/2008/08/18/perevod-symfony-forms-in-action/#comments</comments>
		<pubDate>Mon, 18 Aug 2008 10:45:40 +0000</pubDate>
		<dc:creator>Jeka</dc:creator>
				<category><![CDATA[Программирование]]></category>
		<category><![CDATA[forms]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[перевод]]></category>

		<guid isPermaLink="false">http://jeka.ru/?p=55</guid>
		<description><![CDATA[Читаем здесь&#8230;
]]></description>
			<content:encoded><![CDATA[<p><a href="http://devilmaydie.name/symfony_doc/form/form-1.html" target="_blank">Читаем здесь&#8230;</a></p>
]]></content:encoded>
			<wfw:commentRss>http://jeka.ru/2008/08/18/perevod-symfony-forms-in-action/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

