Star rating plugin for CakePHP
Tags: Ajax, CakePHP, models, plugin, prototype, rating, star
In the google groups I recently noticed the lack of a star rating helper/plugin for CakePHP.
As I just implemented an AJAX rating system for my current project and always wanted to learn the CakePHP plugin system, I thought this was a good opportunity to make my code into a plugin and contribute to the community.
My rating system supports multiple users and multiple models, so you can let people rate any model you want.
I tried to keep it simple and flexible, but I am sure there is still much room for improvements. So let me know what you think about it, any suggestions and comments are welcome.
Here is the plugin v2.2 to download.
This article can also be found in the Bakery now.
Features
- Multi user, multi model rating
- Just one element to place in your views
- Seamless integration with AJAX
- Prototype and jQuery support
- Cross browser compatibility
- Fallback for disabled javascript
- Various configurations
Requirements
- CakePHP 1.2
- Prototype or jQuery javascript framework
- User id stored in session for secure rating
Demonstration
A demo can be tested and downloaded at
http://ratingdemo.schneimi.spacequadrat.de/
Installation and Use
- Make sure you meet the requirements above. Make sure you meet the requirements above. For the download and integration of a javascript framework, please visit the Prototype or jQuery website.
- Extract the plugin, including the subfolder ‘rating’, to your app plugins folder ‘app/plugins‘.
- Copy the ‘rating/config/plugin.rating.php’ to your app configs folder ‘app/config’ and change the settings to your desire. It is recommended to let ‘Rating.showHelp’ set to true until everything works.
- Apply the ‘install.sql’ to your database to create the ratings table.
CREATE TABLE `ratings` ( `id` int(11) unsigned NOT NULL auto_increment, `user_id` char(36) NOT NULL default '', `model_id` char(36) NOT NULL default '', `model` varchar(100) NOT NULL default '', `rating` tinyint(2) unsigned NOT NULL default '0', `name` varchar(100) default '', `created` datetime default NULL, `modified` datetime default NULL, PRIMARY KEY (`id`), KEY `rating` (`model_id`,`model`,`rating`,`name`) );
- Load the plugin javascript and css files in your layout file. Replace [your_framework] with prototype_min or jquery_min depending on the framework you use.
<?php echo $javascript->link('/rating/js/[your_framework]'); ?> <?php echo $html->css('/rating/css/rating'); ?> - For full model integration in your app, apply the following relation to your models. (replace [name_of_your_model])
var $hasMany = array('Rating' => array('className' => 'Rating', 'foreignKey' => 'model_id', 'conditions' => array('model' => '[name_of_your_model]'), 'dependent' => true, 'exclusive' => true ) ); - If you set ‘Rating.saveToModel’ to true, then add the defined ‘Rating.modelAverageField’ and ‘Rating.modelVotesField’ to all models you want to rate. To do that you can use the following SQL statements (replace [your_table] and [Rating.modelAverageField]).
ALTER TABLE [your_table] ADD (`[Rating.modelAverageField]` decimal(3,1) unsigned default '0.0'); ALTER TABLE [your_table] ADD (`[Rating.modelVotesField]` int(11) unsigned default '0');
If the plugin shows the fields are still missing, try to clear the model cache of your app at ‘app/tmp/cache/models’.
- You can change the styles of the rating element in the css file ‘rating/vendors/css/rating.css’.
- Finally you can place the rating element in your views as follows. (replace [name_of_your_model] and [id_of_your_model])
Default rating element for one model id
echo $this->element('rating', array('plugin' => 'rating', 'model' => '[name_of_your_model]', 'id' => [id_of_your_model]));More ratings for one model id
If you want to have different ratings for one model id like sound and picture of a movie, you can use the additional name parameter.echo $this->element('rating', array('plugin' => 'rating', 'model' => '[name_of_your_model]', 'id' => [id_of_your_model], 'name' => 'sound')); echo $this->element('rating', array('plugin' => 'rating', 'model' => '[name_of_your_model]', 'id' => [id_of_your_model], 'name' => 'picture'));Individual configuration of a rating element
Sometimes you want to use more than one style of rating elements in your app. That can be reached with the ‘config’ parameter and different config files in ‘app/config’. Just clone the original ‘plugin.rating.php’ and give it a different name, which you then pass to the element.// Uses 'plugin.rating.php' in 'app/config' echo $this->element('rating', array('plugin' => 'rating', 'model' => '[name_of_your_model]', 'id' => [id_of_your_model])); // Uses 'plugin.rating.style1.php' in 'app/config' echo $this->element('rating', array('plugin' => 'rating', 'model' => '[name_of_your_model]', 'id' => [id_of_your_model], 'config' => 'plugin.rating.style1')); // Uses 'plugin.rating.style2.php' in 'app/config' echo $this->element('rating', array('plugin' => 'rating', 'model' => '[name_of_your_model]', 'id' => [id_of_your_model], 'config' => 'plugin.rating.style2'));
41 Responses to 'Star rating plugin for CakePHP'
Subscribe to comments with RSS or TrackBack to 'Star rating plugin for CakePHP'.
on May 25, 2009 on 8:21 pm
Very cool!
Thank you
on May 27, 2009 on 1:55 pm
You can now choose between jQuery and prototype for ajax in the configs.
on June 2, 2009 on 5:03 pm
hey man
looks great… having a problem thoug
have followed instructions step by step but where do you store the rating_app_controller + model.php?
i get
Fatal error: Class ‘RatingAppModel’ not found in /var/www/localhost/htdocs/app/models/rating.php on line 2
thanks!
on June 2, 2009 on 5:45 pm
Hi bryan,
the controller as well as the model should rest inside the plugin structure, you don’t need and have to copy any files to your app.
If all is at it’s place, I can’t tell why you get this error. Do you use the latest cake? Maybe there is a problem with a older CakePHP version.
Btw I just released v1.4 with some other improvements.
on June 2, 2009 on 5:07 pm
Thank you for the plugin it works great
on June 13, 2009 on 9:28 pm
v1.5
- configurable mouseover messages
- cakephp conform config handling
- cakephp conform model loading
- changed sql createdate and changedate
- reworked js events
- separated framework js code
- minified js files
- tested on IE, FF, safari, chrome, opera
Enjoy!
on June 15, 2009 on 4:43 pm
Not working for me!
on June 15, 2009 on 4:52 pm
Hi Peter,
could you be a little more specific what exactly doesn’t work? Do you at least see the rating element in your views? If not, are there shown any errors in debug mode?
on June 15, 2009 on 5:14 pm
I am new with ajax, maybe thats the problem, i do see the stars but nothing happens when i place my mouse over them, neither when i click them, i do have the user model and the user id session.
PD: Thans a lot for quick your response.
on June 15, 2009 on 5:40 pm
Thx for the info, it looks like you didn’t load jQuery or Prototype properly in your layout, that’s one of the requirements.
If you don’t know how to load it, or get other problems, please write me a mail for further help.
on June 15, 2009 on 6:05 pm
I do have jquery working with other javascripts, but thanks for the help i will check it more carefully.
PD: I didt not found a contact or mail
on June 15, 2009 on 6:41 pm
Then it must be the plugin javascript that is not properly loaded, maybe there is a problem with the ‘/rating/js/rating_jquery’ path. Let me know if you can work it out.
Thx for the missing contact info, I just added a page.
on June 15, 2009 on 10:45 pm
I managed to make the javascript run, I bealive it was because i had both the prototype and the jquery javascript declared…
But now i dont see the stars (I doo see the really good , bad, etc.. messages)… when i click the place where the star shoul be i see this error :
“Object not found!
The requested URL was not found on this server. The link on the referring page seems to be wrong or outdated. Please inform the author of that page about the error.
If you think this is a server error, please contact the webmaster.
Error 404
localhost
06/15/09 16:37:57
Apache/2.2.11 (Win32) DAV/2 mod_ssl/2.2.11 OpenSSL/0.9.8i mod_autoindex_color PHP/5.2.8 ”
What am I doing wrong?
Thanks again for your time
on June 16, 2009 on 2:17 pm
Ok yes, both frameworks bite each other.
About the images, I need to know the full link of the stars not showing. Settings concerning this are appRoot and the image locations (starFullImageLocation,…), maybe you can play around with them and work it out.
If not, please write me the details to michael.schneidt@arcor.de, thx.
on June 24, 2009 on 9:51 am
I am having the same problem. I am using Jquery, but have not declared both prototype and Jq. I am using other JQ scripts on the site..
I can see empty stars, but nothing happens when i click on them / mouseover. :S
Help is appreciated
on June 15, 2009 on 4:45 pm
Any working examples?
on June 15, 2009 on 4:58 pm
No site online yet, but I will see if I can set up a demo somewhere.
on June 19, 2009 on 3:40 pm
A demo is up now, you can also download it. http://ratingdemo.schneimi.spacequadrat.de/
on June 16, 2009 on 11:26 pm
works great!!!

Thanks a lot!!
Congrats for you job, is very flexible and easy to use
on June 17, 2009 on 12:27 am
Could it be possible to add more than one voting for the same element?… for example at the begining and at the end of a new…
on June 17, 2009 on 10:07 am
Good idea, thx! I think about giving the elements an additional user defined name to separate them.
on June 17, 2009 on 12:28 pm
v1.6 supports this now, enjoy.
on June 17, 2009 on 3:23 pm
How can I allow unlogued users to vote? can the User id be stored in a cookie instead of a session???
on June 17, 2009 on 4:58 pm
Both points are not possible because of security issues. Anonymous ratings can be easily manipulated and cookies are client side, so you could edit them and become any user you want.
on June 19, 2009 on 4:02 pm
v1.7
- individual configuration of single elements
- fixed stars update on user id not found
- helper class for the view
- changed appRoot format
on July 28, 2009 on 8:01 pm
Is there a way to disable the voting and to show only the average voting? i wish to have previews of articles showing the average voting and to allow people to vote only when they see the complete view of the article…
Any sugestion?
on July 28, 2009 on 8:37 pm
Hi,
this is not possible by default, but you just have to do two quick changes to reach that behavior.
1) add a new setting in app/config/plugin.rating.php
2) use it in the condition in the rating/views/view.ctp
// decision to enable or disable the rating $enable = $session->check(Configure::read('Rating.userIdInSession')) && !Configure::read('Rating.disable') && (Configure::read('Rating.allowChange') || (!Configure::read('Rating.allowChange') && $data['userRating'] == 0));on July 29, 2009 on 11:08 pm
Thanks
on August 19, 2009 on 6:12 pm
I dont know hoy to make an user not logged in not to vote!
If i dont write the User.id in the Session I get the error The User id was not found at “User.id” in the session
And if I set the user.id session to an id that does not exist like 0 for example, then it takes it as valid and let it votes and saves it on the ratings with user_id 0
Should I just left the session blank and place the show errors to false? how does the ‘Please login to rate’ message activates?
Hope i explained myself rigth, i apologize for my english
on August 20, 2009 on 8:22 am
Yes, you should set showErrors to false, this is just for installation to check if it works when the user is logged in. I will think about how to make this less confusing.
The User.id 0 should not be used as a valid user, thx for that information I will fix it.
The “Please login to rate” message appears on mouse over if showMouseOverMessages is set true and no User.id is found in session.
on August 20, 2009 on 3:29 pm
Thanks
Maybe if it shows as warning and not an error will be less confusing.
on November 2, 2009 on 9:02 am
Hi schneimi,
Thanx for this great plugin. It works fine for me.. Everything looks great except it throws a Notice
Notice (8): Undefined index: fallback [APP\plugins\rating\controllers\ratings_controller.php, line 189]
on November 2, 2009 on 7:07 pm
Hi Robin,
the notice is catched in the latest version 2.2, I just forgot to update the blog, you can download it now.
on November 2, 2009 on 9:12 am
Schneimi,
In my application, the rating is displayed vertically. Should I change any configuration to display it vertically ?
on November 2, 2009 on 10:30 am
“In my application, the rating is displayed vertically.”
-> This problem occurred because of the default style of Cake PHP.
I commented ‘display: block; ‘ for label class in cake.generic.css and its working fine now.
label {
/*display: block; */
}
on November 2, 2009 on 7:11 pm
Thx for showing the css problem, with two small changes on the plugin the problem can also be solved.
rating\views\helpers\rating.php: line 58
$output .= $this->Form->label($model.'.rating', $htmlImage, array('for' => $model.'Rating'.ucfirst($options['name']).$id.$i, 'class' => 'rating'));rating\vendors\css\rating.css
div.rating label { display: inline; }on June 24, 2009 on 10:38 am
If jQuery works for your other scripts then the plugin javascript is most likely not loaded.
How does your layout look like? You need the link(‘/rating/js/rating_jquery_min’); ?> in it, the first slash in the path is necessary.
on June 24, 2009 on 3:41 pm
Yep, thats how i done it… i can look at the JS when i check the source code… :S
Do i have to change to Jquery manually somewhere in the plugin?
on June 24, 2009 on 3:49 pm
Update:
I used firebug and found out that this is ht eline causing the error:
$(‘#’ + element + ‘_’ + i).bind(‘mouseenter’, {i: i}, function(e) {
2 errors:
$ is not a function
and doc.body is undefined
any thoughts?
on June 24, 2009 on 3:51 pm
Sorry for so many posts. Fixed it with “var $j = jQuery.noConflict();” in the beginning of the js file.
Hope this helps somebody else
on June 24, 2009 on 4:06 pm
Great you found a solution, could you also figure out the script(s) causing the conflict?