Валидация данных в виджете без создания дополнительных классов в Yii

В прошлый раз мне понадобилось выполнить виджет (CWidget) как экшен (CAction) без создания дополнительных классов, а теперь требуется использовать в нем валидацию данных. В этом случае за основу уже берется класс CFormModel, и к нему добавляется функциональность CAction и CWidget. Чтобы быть доступным из контроллера, класс реализует интерфейс IAction. В нем появляются методы getId и getController, для их реализации переопределяется конструктор класса (по примеру CAction).

CWidget по принципу работы похож на CAction, поэтому дополнительных модификаций для вызова класса через метод контроллера widget() не требуется, за исключением рендеринга отображений. Класс формы от которого мы наследуемся не имеет метода render(), релизовать который требуется с тем учетом, что при работе класса в режиме CAction требуется рендрить всю страницу целиком (например, с layout), а в случае рендеринга в режиме CWidget только её часть. Определить работу в режиме виджета можно по отсутствию передаваемого в конструктор параметра id.

С учетом всего вышесказанного, получается следующий класс:


class Test extends CFormModel implements IAction { private $_id; private $_controller; public function __construct($controller = NULL, $id = NULL) { parent::__construct(); $this->_controller = $controller; $this->_id = $id; } public function getId() { return $this->_id; } public function getController() { return $this->_controller; } public function render($name, $params = array()) { if (($this->id != FALSE) && ($this->controller != FALSE)) { $this->controller->render($name, $params); } else { Yii::app()->controller->renderPartial($name, $params); } } public function runWithParams($params) { $this->run(); } public function run() { if (isset($_POST['Test']) != FALSE) { $this->attributes = $_POST['Test']; if ($this->validate() != FALSE) { } } $this->render( '/public/test', array( 'model' => $this ) ); } }

30.11.2012