Skip to content


Basic Controller Edits in Yii

This entry is part 8 of 8 in the series Learning the Yii Framework

After using Yii‘s command-line and Gii tools to build an application’s base structure, and then to create its Models and crud functionality, there’s still quite a bit of customizing to do (although Yii really does perform the bulk of the work). Previous posts discuss some of the common changes one makes to Models and Views at this point in the development stage; here I’ll discuss Controllers. I have personally found that I don’t make nearly the level of alterations to my auto-generated Controllers as I do to my Models and Views. This makes sense, as the Model should have the bulk of the code, the View is the interface the end user sees, and the Controller is largely an agent between the two (see my series on the MVC architecture for more on this).

(Note: In October 2010, I’ve updated this entire series to reflect changes in Yii since this series was written, and to take into account feedback provided through the comments. Some outdated material will be crossed out, but left in to reflect how things have changed since the series was begun in June 2009.)


Edit for Yii 1.1: The $defaultAction line is no longer present. Also, the names of some of two of the action methods have changed to match the new names of the corresponding View files: actionView() and actionIndex().


The Controller represents the actions a user takes with a site: views a specific record, updates a record, lists all the records, etc. A user request (i.e., the loading of a URL) is handled by the Yii application, then passed off to the corresponding Controller. It’s the Controller’s duty to perform any necessary work, likely involving the loading or manipulation of some Models, then pass data off to the View. As with any class definition, all of the tasks are performed within methods.

The first thing you’ll encounter within a Controller class is a variable called $layout:

public $layout='//layouts/column2';

As explained in the post on Views, this variable dictates which of the two built-in layouts—one column or two column—the Controller uses. You can change this value to change the layout for the entire Controller, or you can change $this->layout within any of the methods.

Another class variable, which used to be written into the class but now has to be added is:

public $defaultAction='admin';

As just stated, Controllers are the actions one takes, listing information, showing particular records, handling form submissions, and so forth. For each action there is a corresponding method in the Controller class: actionIndex(), actionView(), actionCreate(), etc. The above line dictates which method is called if not otherwise specified. So with that line, the URL www.example.com/index.php/employee calls the actionAdmin() method whereas www.example.com/index.php/employee/create calls actionCreate(). The default value, if you don’t use that line, is to call actionIndex().

Your Controllers should also have several non-action methods, including accessRules(). This method is a key part of the security picture, dictating who can do what. For the “what” options, you have your actions: list, show, create, update, and delete. Your “who” depends upon the situation, but to start there’s at least logged-in and not logged-in users, represented by * (anyone) and @ (logged-in users), accordingly. Depending upon the login system in place, you may also have levels of users, like admins. So the accessRules() method uses all this information and returns an array of values. The values are also arrays, indicating permissions (allow or deny), actions, and users:

public function accessRules()
{
    return array(
        array('allow',  // allow all users to perform 'index' and 'view' actions
            'actions'=>array('index','view'),
            'users'=>array('*'),
        ),
        array('allow', // allow authenticated user to perform 'create' and 'update' actions
            'actions'=>array('create','update'),
            'users'=>array('@'),
        ),
        array('allow', // allow admin user to perform 'admin' and 'delete' actions
            'actions'=>array('admin','delete'),
            'users'=>array('admin'),
        ),
        array('deny',  // deny all users
            'users'=>array('*'),
        ),
    );
}

That’s the default setting, where anyone can perform index and view actions, meaning that anyone can list all records or view individual records in the associated Model. The next section allows any logged-in user to perform create and update actions. Next, only administrators can perform admin and delete actions. Finally, a global deny for all users is added, to cover any situation that wasn’t explicitly defined. This is just a good security practice. Note that these rules just apply to this Controller; each Controller needs its own rules.

You’ll want to customize the rules to each Controller and situation. For example, I did a site with a subscription system, represented by a Contact Model. In that case, anyone had to be allowed to create new Contact records but only the admin was allowed to list or show Contact records. Generally, though, I think most Controllers would allow everyone to perform show and list actions.

You can also create more sophisticated conditionals to create permissions, but that will be a subject for another post. For example, on one project I did, any logged-in user could create certain types of content but they could only update and delete records that they themselves created. Or you could allow users show permission only on their own Contact record.

Finally, you may need to change your Controllers so that the retrieval of Model records is handled differently. There are a few methods that load records to be used in a View. Some of the methods, like actionView() and actionUpdate(), call a loadModel() method whose job it is to retrieve a single record. Other methods, like actionIndex() and actionAdmin() retrieve every Model record (using a different approach). In these methods, there are a couple of changes you may want to make. For starters, if the Model in question is related to another Model, as defined in the Model class’s relations() method (see my post on Models), you can invoke that relation when you retrieve the record(s). For example, this code will retrieve an employee, plus the department for that employee:

$model=Employee::model()->with('department')->findByPk((int)$id);

You only want to do this if you’ll use the related records, of course.

You might also tweak the criteria applied to these methods, but that is a big topic. It basically involves adding WHERE SQL conditions to a query. I’ll address it in another post but you can also see the Yii documentation, of course.

So this makes the eighth post in a series on using the Yii framework, from start to kinda-finish. I’ve got a bunch of miscellaneous topics on the subject to post about, but I won’t write those up formally as part of this series. To find those, or any other posting on Yii, use the tags at right.

As always, thanks for reading and let me know if you have any comments or questions.

Larry

Series NavigationBasic View Edits in Yii

Posted in MySQL, PHP, Web Development.

Tagged with , , .


221 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

  1. Chamal says

    I was able to finish my first YII web application within a short time thanks to this tutorial.

    Thanks Larry.

    • Larry says

      I’m glad to hear that. Congrats! Let me know if there’s anything in particular you’d like me to write about (I have a few Yii-specific topics lined up for December).

  2. Vic says

    Very nice tutorial! Thank you!

    • Larry says

      You’re quite welcome. Thanks for the nice words and let me know if there’s anything specific you’d like me to write about.

  3. Jimmy Armand says

    Your tutorial is great and simple. Put me up and running with the basics of yii in no time. I would like to know if you plan to do a I18N tut?

    Thanks!

    • Larry says

      Thanks for the nice words. I appreciate it! As for l18N, I’ll consider that. I’m writing one on FCKEditor and Yii now, and will be doing one on Zend_Lucene (search engine) and Yii soon.

  4. Dave says

    Very well put together tutorial, thanks for the hard work.

    A co-developer and I are just starting to explore Yii for an upcoming project, and this series was a great lead in for me :)

    • Larry says

      Thanks for the nice words. I’m glad it’s been helpful. Let me know if there’s anything specific you’d like me to write about.

  5. Vic says

    Larry, I think it’d be usefull for me and probably others to see an example of creating a search form with all it’s controllers, safe sql queries to db and probably something else related to search in your future tutorials (not Lucene, but some kind of a simple search). Thanks again for your articles!

    • Larry says

      Thanks for your suggestions, Vic. I’ll see what I can do!

  6. Yii newbie says

    I’m new to yii and where this code $models=Department::model()->with(‘employees’)->findAll();

    could be placed to show department name when listing employees?

    • Larry says

      Well, that’s the code for retrieving every department and employee, and it would go in the Controller, like in the actionList() method. The code for actually showing the department name would be in the View. In the list View, you would have a foreach loop going through the $models array, assigning each to $model. Then you could print out $model->name, which would be the department name.

  7. Sunny Chevli says

    Thanks this blog really help me lot to understand framework basics. Will move for next tutorial now… thank you…

    • Larry says

      Thanks for the nice words. Much appreciated!

  8. Sherri says

    Thanks for taking the time to write up this quality series. You’ve helped to get me up to speed very quickly, and Yii is now my favourite PHP framework too.

    • Larry says

      Thanks for the nice words. I’m glad the posts have been helpful and that you now like Yii, too!

  9. queej says

    Excellent tutorial. Thank you! I was up and limping within a couple of hours.

    • Larry says

      You’re quite welcome. Thanks for the nice words.

  10. lin says

    这个教程确实很新,看来要好好学习一下yii,谢了
    (Roughly translates to “This course is truly very new, looks like must study well yii, thanked” according to Yahoo! Babel Fish).

  11. Sebastian Breit says

    Larry is there a screencast or video-tutorial about yii? I liked this one very much, and I understand everything but if I wanted to do a totally different webpage I wouldn’t know how to do it. What do you recommend me in order to enlarge my knowledge about this framework? Thank you!

    • Larry says

      Thanks for the nice words. On the Yii framework’s docs page, there’s a link to a screencast. Other than that, I would recommend the blog tutorial (also part of the Yii documentation), which walks through creating a reasonably-sophisticated application using Yii.

  12. Rejeesh says

    Dear Larry,

    Thanks.. thank you very much….
    Its an excellent tutorial on Yii…

    Regards,
    Rejeesh

    • Larry says

      Thank you for the nice words. Much appreciated.

  13. Mihai says

    Great tutorial.
    Thank you very much.

  14. chris says

    Here is my problem. I got code, theme, the works. It works! Why and how would I integrate that into yii? What do I get, that I don’t have now?

    OK, simpler question. I got a bunch of classes. Where do I put them in yii?

    Most people I talked to about this said I don’t need a framework. If so, who does?

    In other words, what’s it in it for me?

    I never understood agility.

    • Larry says

      I’m not into convincing people of things, especially those that don’t want to be convinced. From what it sounds like, you’ve got a system that works for you, so you’ve got no need to use a framework. Who does? Well, people that don’t have an established system already, for one. And people interested in learning new things and seeing if there’s not a better way out there, for two. When we stop learning, we shut down progress.

  15. Blacloud says

    Thank you very much for writing this tutorial. It has been a great introduction to yii programming.

    • Larry says

      You’re quite welcome. Thanks for the feedback!

  16. Taner Ozdas says

    I have a plan to use yii framework for one of my project.

    Thanks for this great informations.

    • Larry says

      You’re quite welcome. Thanks for the nice words and good luck with your project.

  17. André Luiz Müller says

    Thanks for the this great tutorial!

    I’m starting in the PHP and Yii development and your posts guided me through the first steps.

    • Larry says

      Thanks for the nice words and for the feedback. I’m glad it was useful. Good luck with your Yii projects!

  18. Garry Freemyer says

    You have made a fine tutorial. The one thing that I don’t see is how I should add links to the main page, that might appear if an admin logs in that I could have appear where I could edit the employees and department table. Oh my first guess is it would be simple for me to drop in some links in the first page and some function like isAdmin to tell the page to display these links, but like so many other times I end up guessing I usually guess wrong. This MVC is too new for me to trust my guesses. Could I get a hint or two about how I should go about this. Sign me, need to be hit by a clue by four. thanks!

    • Larry says

      Thanks, Garry. Two ways of handling this: first, show or don’t show a login link. I normally don’t if only an admin would login (don’t want to confuse others); instead I just have the admin bookmark the login URL. Then this is something I put in my views/layouts/main.php script:
      widget('UserMenu',array('visible'=>(!Yii::app()->user->isGuest))); ?>
      That says to show the UserMenu widget should the user not be a guest (i.e., be logged in). The UserMenu widget would then show admin-specific links. That’s pre-Yii 1.1 code, so I forget offhand if it’d be slightly different in Yii 1.1 or later.

  19. Winston says

    Larry, thank you :-)

  20. Cynthia says

    It’s a dear experience to learn Yii from your tutorials [and comments!]. ..
    Didn’t make it with the ‘foreach’ you suggested to show department’s name instead of its id. Should I try it in which View? index, view or _view? (I’m using Yii 1.1)

    Again, thank you very much for this.

    [I wish I could properly translate(pt-BR) a few lines from this Yii series and share it with my peps, you mind?]

    • Larry says

      Thank you very much for the nice words and do feel free to translate this so long as you give me credit, of course. You could also reference my books, if you’d like (I’ve written several on PHP, Web development, et al.) I’m glad you feel the content is worth sharing.

      The foreach you’re referring to, I think, is on the basic View edits page. It goes in the Departments.php Model file.

  21. Senguttuvan G says

    Superb article on Yii startup. Good tutorial for beginners and ZCEs(myself) alike.

    • Larry says

      Thanks for the nice words! You’re a Zend Certified Engineer? What are your initial thoughts on Yii compared with the Zend Framework?

  22. Richard Viets says

    Very useful tutorials to understand the basics of this framework, which we are just starting to use. But here’s the thing, I am not doing the YII and php and database stuff, I am just responsible for tweaking the css that controls the look and feel.

    I see that there are several copies of styles.css (in our case for detailview, listview and gridview. There are single copies of form.css, main.css, pager.css.

    I’d love a tutorial (or pointer to one) that explains how to manage the css for a YII project. Thanks.

    • Larry says

      Thanks for your post. I don’t know of any tutorial on this particular subject but I find the CSS files pretty apparent to use (they’re well documented). Also, in my experience, normally designers use a new HTML design with its own CSS files, making those Yii-created CSS files irrelevant.

  23. Bhavik Chauhan says

    Sir…
    i am beginner with YII.
    i want to display record with different two tables.
    display employee..
    CHtml::encode($data->departmentId);
    insted of departmentid i want to write name(from table department)
    -BhavikChauhan

    • Larry says

      No problem. You just need to identify the relationship between the two in the two Model definitions, then select the employees with the departments in your Controller.

  24. Bhavik Chauhan says

    thanks for reply,,
    your language is so easy..
    really useful blog..
    plz give me some more hint abt “identify the relationship”and “select the employees with the departments”..

    • Larry says

      Thanks for the nice words. Could you please clarify what your questions are?

  25. Bhavik Chauhan says

    I Have done…
    thank you very much.

  26. Pastia says

    Hi,

    Thanks for the nice tutorial! It really helped me in starting with Yii!

  27. Sudip says

    Dear Larry,
    I have been following all ur 8 posts.

    & a big thank u.
    After reading some documentation(Yii definitive guide), I was trying to understand how all the pieces work together. But, it seemed to me as complex.

    But, ur tutorial was a big help for me.

    once again, thank u.

    • Larry says

      Thank you very much. Very nice of you to say. Good luck with your Yii work!

  28. Bhavik Chauhan says

    hi Larry,
    i am your fan..
    i need help..
    i have 3 models(staff,clients,user)
    mysite.com/staff/admin
    mysite.com/clients/admin
    mysite.com/user/admin
    But, i want only one “admin-page” which manage all models.
    e.g.mysite.com/admin
    a panel having menu(or,link)with we can manage all models.

    Regards,
    Bhavik Chauhan

    • Larry says

      I’m not sure what you mean by manage, but if you just want to put all those admin pages onto one page, I’d create an actionAdmin() method in another Controller, load all three Models into three different variables and pass them to an admin page. On that admin page create three CGridViews, one for each Model.

  29. Bhavik Chauhan says

    hi,
    thanks for reply,
    i have created admin controller and its works..
    thank u very much..
    love yii and u also..
    -Bhavik Chauhan

    • Larry says

      You’re welcome. Glad it’s working and thanks for the nice words.

  30. Litto says

    Brilliant tutorial, looking forward to learning more about Yii.

    Thnx!

  31. Bhima Raju says

    This post really helped me in understanding each file in detail. Thanks sooo much for your time in explaining things to starters like me.

    Thnx!

    • Larry says

      You’re quite welcome. Thanks for the feedback.

  32. квартири says

    Tutorial about Zend Lucene and Yii sounds like a very good idea :) I hope it will see light some day

    • Larry says

      I’m actually working on a more complicated use of Zend_Search_Lucene and Yii right now, so I should be doing a follow-up post on that subject. Thanks for the interest!

  33. uwebrasil says

    Hi Larry,

    I’m new to PHP Frameworks. After doing some tutorials
    in Zend, Symfony, Prado and some others, I only can say:
    Yii is great and your tutorial is even better.
    Thanks a lot for this nice work.

    greetings uwe

    • Larry says

      Thanks. Very nice of you to say. I hope you continue to appreciate Yii!

  34. Satyesh says

    Hi Larry,

    Thanks a lot for this tutorial !!

    I liked it a lot and it is the best tutorial on Yii I have
    read so far.

    Tons of thanks and best wishes, Keep writing.

    Regards
    Satyesh

    • Larry says

      You’re quite welcome. Thank you for the nice words and good luck with Yii!

  35. Spike_DE says

    Hi,

    as mentioned above: great tutorial, thx!!!

    I’ve got still one question…

    I put the “$model=Employee::model()->with(‘department’)->findByPk((int)$id);” in my loadModel from EmployeeController, replacing “$model=Employee::model()->findByPk((int)$id);” with it.

    But still the id of the department is shown. I would like to see the name of the department.

    I’ve also tried to change the employee-view and _view to show “departmentName” (also tried “department”) in place of “departmentId”… won’t work.

    In actionIndex and actionAdmin the code $model=Employee::… seems not to fit.

    Because no other readers asked that before i assume some kind of blindness for me :)

    • John says

      I had the same confusion until I realized the last 2 articles in this series are the wrong way around. This is actually meant to be part 8 of 8 (Basic Controller Edits in Yii) not part 7. If you run through the last article (Basic View Edits in Yii) THEN this one it’s all in the tutorial and the $model=Employee::model()->with(‘department’)->findByPk((int)$id); now makes sense and not totally out of context.

      • Larry says

        Sorry about that. I must have messed up the order when I made my major site overhaul. Thanks for pointing it out and I’ve corrected the order.

  36. Spike_DE says

    got the entry for views/employee/_view.php
    $data->department->name
    in place of $data->departmendId

    still searching how to pass the departmentName do the widget zii.widgets.CDetailView inside view.php…

  37. Spike_DE says

    ‘department.name’ does it in view.php…

    • Larry says

      Thanks for your comments and kudos for figuring out your solution (and thanks for sharing). Let me know if you have any other questions. Larry

  38. Chakaphan says

    Larry, refer to item# 70, where do I put ‘department.name’ in view.php.

    • Larry says

      Wherever you want the department name to appear?

  39. Spike_DE says

    hi, thanks for your answer.

    indeed, i have one question open.

    i would like to search in the “manage employe” view for the department-name, not the id.

    to display the name of the department i put department.name in the right place, but the colum is disabled for searching.

    therefore i’ve tried to modify the model-search to get extra compares

    $criteria->compare(‘department.name’,$this->department->name);

    but the error :Trying to get property of non-object
    appears.

    what’s wrong?

    • Larry says

      Sorry for the delayed reply; I was busy transitioning the site over the weekend. I think I know what you’re trying to do and I believe I’ve done it before myself, but I don’t recall that code off the top of my head. I’ll see if I can find it.

  40. Chakaphan says

    In view detail page.

    • Larry says

      Yeah, that wasn’t really a question (I was asking). Just put the reference to department.name where ever in your view.php script you want the department name to appear.

  41. Spike_DE says

    i want to always show the department-name to the user, rather then the department-id (which is of no interest for the user).
    i can “display” the department-name in every view.

    my problem is that in “manage employees” i cannot search for the department-name.

    below the column of the department-name, there is no search-form-field!

    or does the widget not support relations like that?

    if so, how can i modify the widget like that?

  42. Spike_DE says

    Hi Larry,

    sorry for posting my question again. I thought the answer to Chakaphan would be adressed to me…

    I’m wondering that my question is so rarely beeing discussed. I think it’s the normal way to present related table-entrys to the master-entry in form of its value rather than its ID.

    i hope you find the code (in your head or archive :) )

    by the way, the new threaded-layout for the post’s (missing the # of the entry) is a bit of confusing.

    • Larry says

      Well, let me just get this straight: if you’re looking at the manage employee page, there’s a table of employees with a dynamic search at the top. And you’ve replaced the employee’s department ID with the department name but are trying to figure out how to search using that value? If that’s the case, it’s not surprising that you’re not seeing other discussions of it. That’s all accomplished using the GridView widget, which is relatively new to Yii (at least as a formal extension). So you’re talking about customizing the behavior of this widget, which uses an Ajax search, which is tied to a Model scenario. That’s not the most common or easy thing to implement. But I think I’ve done it before.

      Funny you should mention the threaded comments. I actually thought it was more confusing previously, where threads were not indicated. I’ll see if I can get these to be numbered and threaded as I know others have referenced comment numbers in their comments.

  43. Bob says

    Thanks for this very helpful introduction to the Yii framework. You make this stuff more accessible and thus it is a great place to start!

    • Larry says

      You’re welcome, Bob. Thanks for the nice words.

  44. Phillip says

    Great tutorial, but I think that post about relations in model and creating dropDown in post about View were a little complicated.

  45. David says

    It is an excellent tutorial, and I read the one of MVC too. Very enlightening. I only regret that you could have been a little bit less lazy, and in such way you could have done a larger tutorial. No, I’m kidding, many, many thanks for these useful small course.

    • Larry says

      Thanks! And for a minute there, I thought you were being serious about me being lazy!

  46. Humbal says

    Hi!
    Yii tutorial is great. I appreciate overall tutorial.
    I want to make 2 separate module, one for front end and another for backend (adminpanel) so that it can be reuse easily.
    Can you give me idea how to manage it?

    • Larry says

      Thanks. I’d recommend you start with the manual’s section on modules.

  47. Alin says

    This is very good stuff. I have read a lot about frameworks, about choosing the right one, but this framework developers have a big problem in creating start up documentation. I have read a lot about yii and now when i decided to read more and get familiar with it i did not know from where to start. This post show me a lot of stuff and a very good starting point. Congratulations for Larry for putting all together in such a clear manner . Thanks a lot !

    • Larry says

      Thank you very much for the nice and detailed feedback! Good luck with your projects!

  48. Prashant says

    Hi Larry,

    You have written the best tutorial and helped me a lot in creating my first web app using yii.
    Thnak a lot.

    • Larry says

      Thanks for saying so! Good luck with Yii!

  49. articfox says

    Excellent tutorial . Thanks Larry 谢谢

  50. Sid says

    Great stuff Larry!

    Is it possible to write something about RBAC. This is one topic which has resources but some how lacks eloquence.

    • Larry says

      Thanks for the suggestion. I’ll see what I can do.

1 2 3

If you need quick assistance with a question or problem related to one of my books, please use the support forums instead.

Some HTML is OK

or, reply to this post via trackback.