В Symfony для Propel есть такая замечательная функциональность как Behaviors. Благодаря Behavior можно расширять существующие модели без необходимости изменять код самой модели. Фактически получает имитация “множественного” наследования. Зачем это надо? К примеру есть вот такой интересный плагин sfPropelActAsTaggableBehaviorPlugin – задумка прекрасная, сделать возможность добавлять теги для любых моделей. Чтобы активировать Behaviors нужно в propel.ini включить их.
propel.builder.addBehaviors = true
А в самой модели в самом конце прописать следующее
<?php
class Post extends BasePost
{
}
sfPropelBehavior::add('Post', array('sfPropelActAsTaggableBehavior'));
[/sourcecode]
Далее незабываем пересобирать модели и очистить кеш
[sourcecode lang="php"]
symfony propel:build-model
symfony cc
[/sourcecode]
Теперь в нашей модели можно воспользоваться новыми методами, например вот так.
[sourcecode lang="php"]
<?php
$post = new Post();
$post->addTag('toto');
$post->addTag('tata, tutu');
$post->addTag(array('Titi', 'Gros Minet'));
$post->save();
Чтобы более подробнее ознакомиться с Behaviors советую почитать:
• How to write a Propel behavior
• Symfony 1.1: Chapter 17 – Extending Symfon – Propel Behaviors
• Symfony 1.0: Chapter 17 – Extending Symfony – Mixins
• Symfony 1.0: Глава 8 – Внутри слоя Модели – Использование поведения модели
В репозитории плагинов можно ознакомиться с 14 плагинами использующими Behavior.
А теперь о минусах:
• Многие из плагинов давно не обновлялись, в частности sfPropelActAsTaggableBehaviorPlugin. Он не работает с Propel 1.3.
• На страничке плагина sfPropelActAsTaggableBehaviorPlugin Readme проблема с описанием использования плагина, верстка “хромает”, если посмотреть Show Markdown, то можно увидеть много интересного, :). Искать строчку “edit the classes that you want to make taggable” и читать ниже.
И особенности:
Т.к. в базовый класс, например: BasePost.php добавляется метод __call через который собственно и работает Behaviors у меня возник один казус. Я воспользовался рекомендацией How To Handle i18n Db Fields With the Admin Generator Method 2, чтобы в админке была поддержка мультиязычного контента. Идея отличная, но там тоже используется метод __call, который перекрывал метод родителя.
Работающий кусок кода для мультиязычности с поддержкой Behaviors
// Файл Post.php
public function __call($method, $arguments)
{
$data = split('I18n', $method, 2);
if( count($data) != 2 )
{
// Вместо вывода ошибки перенаправляем на метод родителя
return parent::__call($method, $arguments);
// throw new Exception('Tried to call unknown method ' . get_class($this) . '::' . $method);
}
list( $method, $culture ) = $data;
if (4 == strlen($culture))
{
$culture = strtolower(substr($culture, 0, 2)) . '_' . strtoupper(substr($culture, 2, 2));
}
else
{
$culture = strtolower($culture);
}
$this->setCulture( $culture );
return call_user_func_array(array($this, $method), $arguments);
}


