5
Май
Doctrine 1.2: сортировка связей
Запостил Jeka, в раздел Новости, Программирование
Чтобы связанные объекты выводились в определенном нами порядке, при описании модели можно указать поле по которому будет вестись сортировка.
Пример:
Image:
columns:
# .... необходимые поля
pos: { type: integer, notnull: true, default: 0} # поле по которому будет вестись сортировка
product_id: {type: integer}
Product:
# .... необходимые поля
relations:
Images:
type: many
class: Image
local: id
foreign: product_id
onDelete: 'SET NULL'
orderBy: 'pos ASC' # <- указываем по какому полю сортировать
Данная заметка касается версии Doctrine 1.2. Как я знаю в более старых версиях, подобное приходилось решать самостоятельно правкой классов в дистрибутиве Doctrine.
27
Апр
Вышла стабильная версия Propel 1.5
Запостил Jeka, в раздел Новости, Программирование

Хорошая новость для разработчиков использующих Propel, вышла стабильная версия Propel 1.5!!!
Кто не знает – это ORM для PHP (http://www.propelorm.org/).
Изменений в данной версии очень много, но как обещают разработчики, не надо этого пугаться, так как остается совместимость с версиями 1.4, 1.3.
Для апгрейда надо всего лишь перегенерировать модель и начать использовать новые возможности Propel.
Что нового, смотрим здесь http://www.propelorm.org/wiki/Documentation/1.5/WhatsNew.
Удачи!
29
Мар
Symfony: Фильтры формы – выпадающий список для текстового поля
Запостил Jeka, в раздел Программирование
Так получилось, что у одной модели имеется текстовое поле с не очень большим количеством вариантов значения. По идее можно сделать по правильному и вывести все в отдельную таблицу, но по некоторым причинам этого не делается.
Следовательно в админке при фильтрации, не очень охота писать значения этого поля ручками, легко можно сделать выпадающий список со всеми вариантами.
Сначала сделал так:
// SomeModelFormFilter.class.php
// ...
public function configure()
{
$this->setWidget('status', new sfWidgetFormChoice(
array('choices'=>self::getStatuses())
));
$this->setValidator('status', new sfValidatorChoice(array(
'choices'=>array_keys(self::getStatuses()),
'required'=>false
)));
}
public static function getStatuses()
{
return array(
'' => '',
'one'=>'Один',
'two'=>'Два',
'three'=>'Три'
);
}
//...
Оказалось, что хоть выпадающий список появляется, фильтрация не происходит.
Немного покопавшись, нашел такое решение: надо для нашего поля status, указать тип «ForeignKey».
Делаем это перекрываем родительский метод «getFields()».
// SomeModelFormFilter.class.php
// ...
public function getFields()
{
$fields = parent::getFields();
$fields['status']='ForeignKey';
return $fields;
}
// ...
Все, теперь работает.
17
Фев
phpBB 4.0 & Symfony 2.0
Запостил Jeka, в раздел Новости
Отличная новость прилетела! Говорят, что phpBB 4.0 будет написана с использованием Symfony 2.0
18
Янв
Некоторые особенности CSRF Protection в symfony
Запостил Jeka, в раздел Программирование
В данной заметке я привожу некоторую ситуацию, с которой я столкнулся при работе с формами в замечательном PHP фреймворке Symfony. В частности, проблема возникала при включенной защите от межсайтовых запросов (CSRF Protection), что это за защита вы можете прочитать в википедии (http://ru.wikipedia.org/wiki/CSRF, http://www.inattack.ru/article/552.html).
В симфонии при включенной CSRF защите в форму подставляется скрытое поле с именем _csrf_token, его значение формируется как md5 хеш от секретной строки, имени класса и идентификатора сессии (session_id).
Пример формирования значения токена в Symfony:
// sfForm.class.php
public function getCSRFToken($secret = null)
{
....
return md5($secret.session_id().get_class($this));
}
Следовательно, если после некоторого действия, значение возвращаемое session_id() меняется, то дальнейшая валидация созданных до этого момента форм, не будет корректно обрабатываться.
Такие случаи могут возникать, например, при авторизации пользователя (sfGuardPlugin) и дальнейшей обработке форм в одном запросе.
Пример, у нас есть две формы c полями:
1. sfGuardFormSignin: signin[username], signin[password]
2. AddressForm: address[phone],address[city],… -
Мы хотим в одном запросе авторизовать пользователя с помощью логина пароля и сохранить обязательные поля из формы address
Делаем примерно так:
$this->auth_form = !$this->getUser()->isAuthenticated() ? new sfGuardFormSignin() : null;
$this->address_form = new AddressForm();
if ($request->isMethod('post'))
{
// авторизуемся
if (!$this->getUser()->isAuthenticated())
{
$this->auth_form->bind($request->getParameter('signin'));
if ($this->auth_form->isValid())
{
$values = $this->auth_form->getValues();
$this->getUser()->signin($values['user'], array_key_exists('remember', $values) ? $values['remember'] : false);
$this->auth_form=null;
}
}
// обрабатываем форму адреса
$this->address_form->bind($request->getParameter('address'));
if ($this->address_form->isValid())
{
// что-то делаем с формой, например сохраняем
$this->address_form->save();
//...
$this->redirect('@somepath');
}
}
Допустим, авторизация прошла успешно, но валидация формы адреса не прошла. Тогда нам покажется форма адреса с ошибками, но исправив ошибки мы все равно получим не валидную форму так как session_id изменился, а форма адреса создавалась с учетом старого его значения и
нам будет в любом случае выдавать ошибку «csrf token: Required.».
Как избежать подобного?
Способ который я применил (на мой взгляд не очень красивый) заключается в следующем: нужно после авторизации поставить в сессию атрибут
о временном отключении «CSRF Protetion» перед обработкой форм проверять данный атрибут и отключать защиту CSRFT.
Пример:
$this->auth_form = !$this->getUser()->isAuthenticated() ? new sfGuardFormSignin() : null;
$this->address_form = new AddressForm();
if ($request->isMethod('post'))
{
// Авторизация
if (!$this->getUser()->isAuthenticated())
{
$this->auth_form->bind($request->getParameter('signin'));
if ($this->auth_form->isValid())
{
$values = $this->auth_form->getValues();
$this->getUser()->signin($values['user'], array_key_exists('remember', $values) ? $values['remember'] : false); // <<< здесь меняется session_id
$this->getUser()->setAttribute('disable_csrf',true); // <<< снимаем защиту CSRF
$this->auth_form=null;
}
}
// Отключаем защиту если требуется
if ($this->getUser()->getAttribute('disable_csrf',false))
{
sfForm::disableCSRFProtection();
unset ($this->address_form[sfForm::getCSRFFieldName()]);
}
// обработка формы адреса
$this->address_form->bind($request->getParameter('address'));
if ($this->address_form->isValid())
{
// что-то делаем с формой, например сохраняем
$this->address_form->save();
//...
$this->getUser()->setAttribute('disable_csrf',null); // если все хорошо включаем защиту CSRF обратно
$this->redirect('@somepath');
}
}
Все вышеприведенное тестировалось на версии symfony 1.2, в этой версии CSRF защиту можно отключить только глобально. В более новых версиях фреймворка (1.3, 1.4), появилась возможность отключать защиту локально для конкретной формы по отдельности, что более правильно.
З.Ы. Если кто-то скажет, как подобное можно более красиво решить, буду очень благодарен
2
Дек
sfYandexYMLPlugin – генерация YML для Яндекс.Маркета
Запостил Jeka, в раздел Новости, Программирование

Выложил еще один плагин, который позволяет упростить генерацию XML для сервиса Яндекс.Маркет.
В плагин входят несколько классов, которые предоставляют объектный интерфейс для генерации YML файла.
Описание формата YML можно посмотреть здесь http://partner.market.yandex.ru/legal/tt/
В данный момент, не все еще возможности реализованы.
Например, по товарным предложениям, реализовано только самое простое предложение (offer).
Классы не привязаны к фреймворку symfony, так что думаю использовать их можно в любом проекте на PHP.
Взять плагин сейчас возможно только из SVN.
Страница плагина: http://www.symfony-project.org/plugins/sfYandexYMLPlugin
SVN: http://svn.symfony-project.com/plugins/sfYandexYMLPlugin/trunk/
25
Ноя
Интернет-магазин на symfony
Запостил Jeka, в раздел Новости, Программирование
Некоторое время назад, создал очень интересный проект – Интернет-магазин оригинальных подарков Expetro.Ru.
Магазин делался с нуля, написан на PHP с использованием фреймворка Symfony, Propel, JQuery.
Есть интеграция с 1С, экспорт в Yandex YML.
Для сжатия Javascript скриптов, используется плагин sfGoogleClosureCompilerPlugin.
Сам магазин очень интересный, он существует как дочерний проект компании «Экспедиция» и в нем можно купить различные удивительные подарки.
Советую посмотреть подарки судьбы и обязательно остальные товары.
PS Сайт магазина еще в разработке, но функции свои выполняет.
12
Ноя
sfGoogleClosureCompilerPlugin – Мой первый плагин для Symfony
Запостил Jeka, в раздел Новости, Программирование
Первый плагин который я выложил в паблик доступ.
Сильно не пинать! ![]()
С английским у меня проблемы.
Если кто-то хочет помочь, буду очень рад.
Суть такая:
Подключается фильтр, который ищет на странице подключаемые js-скрипты, потом передает их через rest-api на сервер гугла, после чего сохраняет резултат и вставляет на него линк, старые ссылки из html удаляет.
http://www.symfony-project.org/plugins/sfGoogleClosureCompilerPlugin
9
Сен
Презентация: «30 Symfony Best Practices» (30 лучших советов для разработчиков на symfony)
Запостил Jeka, в раздел Программирование
28
Авг
Развертывание проектов используя Capistrano
Запостил Jeka, в раздел Новости
Давно хотел попробовать для деплоймента своих symfony проектов, систему Capistrano.
На хабре есть пара статей про него:
Последние записи:
- 03 Ноя Что я использую в работе...
- 09 Сен Анонс: Конференция Symfony Camp ...
- 24 Авг Особенности whereIn в Doctrine...
- 16 Авг PHP, получение контекста в $this...
- 30 Июн Поездочка в Казань, Чистополь и ...
- 10 мая Вакансия: Разыскиваются талантли...
- 20 Апр WideImage – манипуляция из...
- 08 Апр prettyPhoto – отличная зам...
- 06 Апр Предпринимательство в России...
- 13 Янв Apostrophe CMS: Получить значени...
Разделы:
- Администрирование (2)
- Новости (45)
- Программирование (29)
- Управление проектами (1)
Архивы:
- Ноябрь 2011
- Сентябрь 2011
- Август 2011
- Июнь 2011
- Май 2011
- Апрель 2011
- Январь 2011
- Ноябрь 2010
- Октябрь 2010
- Сентябрь 2010
- Август 2010
- Июль 2010
- Май 2010
- Апрель 2010
- Март 2010
- Февраль 2010
- Январь 2010
- Декабрь 2009
- Ноябрь 2009
- Сентябрь 2009
- Август 2009
- Июль 2009
- Июнь 2009
- Май 2009
- Апрель 2009
- Март 2009
- Февраль 2009
- Январь 2009
- Ноябрь 2008
- Октябрь 2008
- Сентябрь 2008
- Август 2008