My question is: How can I change this example, so that I don’t need to change the Controller and get the same functionality.
Background: I have many from implemented as Widgets and they clutter the controller with code needed to process the $_POST data. Is there any solution to get rid of any code in the controller or can’t Yii provide such a feature?
To process the form, you have to add code to the Controller. If you have many Forms as Widgets, because you reuse them on multiple places, your controller gets cluttered with the processing for every form.
The following code, from the example, resides in the controller.
if (isset($_POST['_lang']))
{
$app->language = $_POST['_lang'];
$app->session['_lang'] = $app->language;
}
else if (isset($app->session['_lang']))
{
$app->language = $app->session['_lang'];
}
That may be find for one form. But if you add another, the controller get’s filled up with code for the form processing.
So if you want to reuse such a widget in another application, you need to copy also the code for the controller.
I’d like to have just the widget (plus the view) and nothing else make the code more modular.
I have the only one question: what will be the difference between a controller and a "self-contained" widget? Both will have actions, access rules, etc.
It’s not about the actions/rules, it’s about the ability to reuse the widget without cluttering the controller action with code to process the $_REQUEST.
I think of an widget which process it’s request and then hands the request handling to the actual controller which was called.
It’s more a question if it’s possible or not.
The typical problem is, if the request is processed in the run() method of the widget, the controller has no chance to react on the input from the request.
The controller mentioned in the wiki should be a parent/base controller, so you only need to implement this once per app. IMO, if you allow widgets to handle GET/POST data, you blur the line between a controller and widget. Let’s say you have a widget that displays a login/signup form for a guest and a logout link for a logged in user. If the widget is to handle all the scenarios for logins (active, inactive, suspended users etc.) it’s going to become bloated and not a whole lot different from a controller - not to mention handling access rules etc. This leads to embedding a conget (controller + widget) in a view i.e. MVCC
Don’t be afraid to get your controllers dirty, that’s what they’re there for. If you do want to separate your widget handling, look at andy_s’s link.