Schneimi’s Dev Weblog


Star rating plugin for CakePHP

Posted in Ajax,CakePHP by schneimi on May 25, 2009
Tags: , , , , , ,

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.5 for CakePHP 1.3 to download. Older versions for CakePHP 1.2 can be found here.

This article can also be found in the Bakery.

Features

  • Multi user, multi model rating
  • Guest 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, 1.3
  • Prototype or jQuery javascript framework
  • User id stored in session for secure rating

Demonstration
A demo can be tested at
http://ratingdemo.schneimi.hostingsociety.com/

    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. There is also the possibility to overload the config file settings on 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'));
              
                // overload default settings
                echo $this->element('rating', array('plugin' => 'rating',
                                                    'model' => [name_of_model],
                                                    'id' => [id_of_model],
                                                    'config' => array('Rating.[setting_1]' => true,
                                                                     'Rating.[setting_2]' => false)));
                                                  
                // overload individual settings
                echo $this->element('rating', array('plugin' => 'rating',
                                                    'model' => [name_of_model],
                                                    'id' => [id_of_model],
                                                    'config' => array('plugin_rating_style1', array(
                                                        'Rating.[setting_1]' => true,
                                                        'Rating.[setting_2]' => false));