Иногда бывает необходимо добавить новый функционал на сайт. А сайты как известно могут быть собраны на разных движках: Joomla, Drupal, MODX и прочие. Попался мне тут один сайт на Joomla, ещё и версии 1.5. Нужно было прикрутить комментарии к товарам. Писать с нуля не захотелось и было решено воспользоваться моим любимым PHP-фреймворком Yii. Для начала подключаем наше приложение.

$yii = dirname(__FILE__).'/../_distr/yii-1.1.13.e9e4a0/framework/yii.php';
$config = dirname(__FILE__).'/protected/config/main.php';
require_once($yii);
Yii::createWebApplication($config);

Подключение очень похоже на подключение обычного приложения, за исключением метода run(), после создания экземпляра приложения. Такой способ подключения описан в рецептах на сайте Yii.Yii подключили, создали модельку комментариев. И теперь надо вывести их, например, виджетом CListView. В обычном приложении для вызова виджета мы обычно используем такой код:

$this->widget('zii.widgets.CListView', array(
     'dataProvider'=>$dataProvider,
     'itemView'=>'_view',
));

Но тут $this у нас ссылается на контроллер, в контексте которого будет вызван виджет. А у нас то никакой контроллер не вызывается, мы просто создали приложение и хотим использовать его возможности. Вот тут то и начинаются трудности. Хотя сами разработчики говорят нам, что мы можем смело использовать кучу функционала при таком подключении.Попробуем разобраться. Идем в метод widget базового контроллера CBaseController и видим, что он свою очередь передает эстафету методу createWidget, который вызывает виджет так:

$widget=Yii::app()->getWidgetFactory()->createWidget($this,$className,$properties);
$widget->init();

Как видно из метода createWidget, что первым параметром передается $this. Идем дальше. Смотрим код класса CWidget и видим, что он наследуется от базого контроллера CBaseController. Следовательно без контроллера нам виджет никак не запустить.Создаем экземпляр контроллера вручную при помощи метода createController и присваиваем его какой нибудь переменной.Пробуем вызвать наш виджет и вуаля, работает!

$ctl = array_shift(Yii::app()->createController("/"));
$ctl->widget('zii.widgets.CListView', array(
     'dataProvider'=>new CActiveDataProvider('Comment'),
     'itemView'=>'_view',
));

Так как метод createController возвращает 2 элемента массива(экземпляр объекта и параметры урла), то пришлось воспользоваться функцией array_shift, чтобы получить первый элемент массива, т.е. ссылку на наш контроллер.