Plugin Directory

Changeset 539746


Ignore:
Timestamp:
05/04/2012 12:54:30 AM (14 years ago)
Author:
digitalnature
Message:
 
Location:
post-ratings
Files:
17 added
2 edited

Legend:

Unmodified
Added
Removed
  • post-ratings/trunk/post-ratings.php

    r535411 r539746  
    22/*
    33Plugin Name: Post Ratings
    4 Version: 1.9
     4Version: 2.0
    55Plugin URI: http://digitalnature.eu/forum/plugins/post-ratings/
    66Description: Simple, developer-friendly, straightforward post rating plugin. Relies on post meta to store avg. rating / vote count.
     
    2626
    2727
    28 
    2928/*
    3029 * PostRatings Class
     
    3736
    3837  const
    39     VERSION   = '1.9',                                      // plugin version
     38    VERSION   = '2.0',                                      // plugin version
    4039    ID        = 'post_ratings',                             // internally used for text domain, theme option group name etc.
    4140    MIN_VOTES = 1,                                          // minimum vote count (MV)
    42     BR1       = '(v / (v + MV)) * r + (MV / (v + MV)) * R', // bayesian rating formula (the IMDB version)
    43     BR2       = '((AV * R) + (v * r)) / (AV + v)';          // bayesian rating formula (thebroth.com version)
     41    BR1       = '(v / (v + MV)) * r + (MV / (v + MV)) * R', // bayesian rating formula: the IMDB version
     42    BR2       = '((AV * R) + (v * r)) / (AV + v)';          // bayesian rating formula: thebroth.com version
    4443
    4544  protected static $instance;
     45
     46  protected
     47    $options  = null,
     48
     49    // default option values
     50    $defaults = array(
     51                  'version'     => self::VERSION,
     52                  'anonymous_vote'   => true,
     53                  'max_rating'       => 5,
     54                  'bayesian_formula' => self::BR1,
     55                  'user_formula'     => '',
     56                  'custom_filter'    => '',
     57                  'before_post'      => false,
     58                  'after_post'       => true,
     59                  'post_types'       => array('post'),
     60                  'visibility'       => array('home', 'singular'),  // same as WP conditional "tags", but with "is_" omitted
     61
     62                  // internal, global stats
     63                  'avg_rating'       => 0,
     64                  'num_votes'        => 0,
     65                  'num_rated_posts'  => 0,
     66                );
    4667
    4768
     
    94115  * @since 1.0
    95116  */
    96   final protected function __construct(){}
     117  final protected function __construct(){
     118
     119    // initialize early, to avoid endless loop within update_option() + settings validation callback.
     120    // stupid settings API...
     121    $this->getOptions();
     122  }
    97123
    98124
     
    107133
    108134
    109  /*
    110   * Plugin options.
    111   * If an option doesn't exist in the db, the default value will be returned instead
    112   *
    113   * @since    1.0
    114   * @param    string $single_option_req    Optional, if passed the function will return the value of this option
    115   * @return   array|string
    116   */
    117   public function Options($single_option_req = ''){
    118 
    119     $options = wp_parse_args((array)get_option(self::ID), array(
    120       'anonymous_vote'   => true,
    121       'max_rating'       => 5,
    122       'bayesian_formula' => self::BR1,
    123       'user_formula'     => '',
    124       'custom_filter'    => '',
    125       'before_post'      => false,
    126       'after_post'       => true,
    127       'post_types'       => array('post'),
    128       'visibility'       => array('home', 'singular'),  // same as WP conditional "tags", but with "is_" omitted
    129 
    130       // internal, global stats
    131       'avg_rating'       => 0,
    132       'num_votes'        => 0,
    133       'num_rated_posts'  => 0,
    134     ));
    135 
    136     return $single_option_req ? $options[$single_option_req] : $options;
    137   }
     135
     136  /*
     137   * Returns one or all plugin options.
     138   *
     139   * @since   1.0
     140   * @param   string $key   Option to get; if not given all options are returned
     141   * @return  mixed         Option(s)
     142   */
     143  public function getOptions($key = false){
     144
     145      // first call, initialize the options
     146    if(!isset($this->options)){
     147
     148      $options = get_option(self::ID);
     149
     150      // options exist
     151      if($options !== false){
     152
     153        if(!isset($options['version']))
     154          $options['version'] = '1.0';
     155
     156        $new_version = version_compare($options['version'], self::VERSION, '!=');
     157        $desync = array_diff_key($this->defaults, $options) !== array_diff_key($options, $this->defaults);
     158
     159        // update options if version changed, or we have missing/extra (out of sync) option entries
     160        if($new_version || $desync){
     161
     162          $new_options = array();
     163
     164          // check for new options and set defaults if necessary
     165          foreach($this->defaults as $option => $value)
     166            $new_options[$option] = isset($options[$option]) ? $options[$option] : $value;
     167
     168          // update version info
     169          $new_options['version'] = self::VERSION;
     170
     171          update_option(self::ID, $new_options);
     172          $this->options = $new_options;
     173
     174        // no update was required
     175        }else{
     176          $this->options = $options;
     177        }
     178
     179
     180      // new install (plugin was just activated)
     181      }else{
     182        update_option(self::ID, $this->defaults);
     183        $this->options = $this->defaults;
     184      }
     185    }
     186
     187    return $key ? $this->options[$key] : $this->options;
     188  }
     189
     190
     191
     192  /*
     193   * Loads a template file from the theme or child theme directory.
     194   *
     195   * @since   1.0
     196   * @param   string $_name   Template name, without the '.php' suffix
     197   * @param   array $_vars    Variables to expose in the template. Note that unlike WP, we're not exposing all the global variable mess inside it...
     198   */
     199  final public function loadTemplate($_name, $_vars = array()){
     200
     201    // you cannot let locate_template to load your template
     202    // because WP devs made sure you can't pass
     203    // variables to your template :(
     204    $_located = locate_template($_name, false, false);
     205
     206    // use the default one if the (child) theme doesn't have it
     207    if(!$_located)
     208      $_located = dirname(plugin_basename(__FILE__)).'/templates/'.$_name.'.php';
     209
     210    unset($_name);
     211
     212    // create variables
     213    if($_vars)
     214      extract($_vars);
     215
     216    // load it
     217    require $_located;
     218  }
     219
    138220
    139221
     
    198280
    199281      // only allow super admins to change this, because it's a little sensitive (part of this string is used inside the top rated db query)
    200       'user_formula'     => current_user_can('edit_plugins') ? wp_filter_nohtml_kses($user_formula) : $this->options('user_formula'),
     282      'user_formula'     => current_user_can('edit_plugins') ? wp_filter_nohtml_kses($user_formula) : $this->getOptions('user_formula'),
    201283
    202284      'before_post'      => isset($before_post) ? true : false,
     
    207289
    208290      // internal, global stats
    209       'avg_rating'       => $this->options('avg_rating'),
    210       'num_votes'        => $this->options('num_votes'),
    211       'num_rated_posts'  => $this->options('num_rated_posts'),
     291      'avg_rating'       => $this->getOptions('avg_rating'),
     292      'num_votes'        => $this->getOptions('num_votes'),
     293      'num_rated_posts'  => $this->getOptions('num_rated_posts'),
     294
     295      'version'          => self::VERSION,
    212296    );
    213297
    214     if(isset($remove_ratings) || ($options['max_rating'] !== $this->options('max_rating'))){
     298    if(isset($remove_ratings) || ($options['max_rating'] !== $this->getOptions('max_rating'))){
    215299      $options['avg_rating'] = $options['num_votes'] = $options['num_rated_posts'] = 0;
    216300      $this->DeleteRatingRecords();
     
    229313  public function SettingsPage(){
    230314
    231     $options = $this->Options();
     315    $options = $this->getOptions();
    232316    extract($options);
    233317
     
    429513      wp_localize_script(self::ID, 'post_ratings', array('blog_url' => home_url('/')));
    430514
    431     // css
    432     wp_enqueue_style(self::ID, plugins_url('post-ratings.css', __FILE__));
     515    // allow themes to override css
     516    $style = is_readable(get_stylesheet_directory().'/post-ratings.css') ? get_stylesheet_directory_uri().'/post-ratings.css' : plugins_url('post-ratings.css', __FILE__);
     517
     518    wp_enqueue_style(self::ID, $style);
    433519  }
    434520
     
    461547
    462548 /*
     549  * Adjust user meta key name, or cookie key name for multisite blogs (except primary blog)
     550  *
     551  * @since    2.0
     552  * @param    string
     553  * @return   string
     554  */
     555  private function getRecordsKey($key){
     556    if(is_multisite() && !is_main_site())
     557      $key .= '_'.get_current_blog_id();
     558
     559    return $key;
     560  }
     561
     562
     563
     564 /*
    463565  * Process rating, or set up plugin hooks if this is not a rate request
    464566  *
     
    467569  public function Run(){
    468570
    469     $options = $this->Options();
     571    $options = $this->getOptions();
    470572    extract($options);
    471573
     
    530632            $ip_cache = array();
    531633
    532           $posts_rated = isset($_COOKIE['posts_rated']) ? explode('-', $_COOKIE['posts_rated']) : array();
     634          $posts_rated = isset($_COOKIE[$this->getRecordsKey('posts_rated')]) ? explode('-', $_COOKIE[$this->getRecordsKey('posts_rated')]) : array();
    533635          $posts_rated = array_map('intval', array_filter($posts_rated));
    534636
     
    551653            $user = wp_get_current_user();
    552654
    553             $current_user_ratings = get_user_meta($user->ID, 'posts_rated', true);
     655            $current_user_ratings = get_user_meta($user->ID, $this->getRecordsKey('posts_rated'), true);
    554656
    555657            if(!$current_user_ratings)
     
    558660            $posts_rated = array_unique(array_merge($posts_rated, array_filter($current_user_ratings)));
    559661
    560             update_user_meta($user->ID, 'posts_rated', $posts_rated);
     662            update_user_meta($user->ID, $this->getRecordsKey('posts_rated'), $posts_rated);
    561663          }
    562664
     
    564666          $posts_rated = array_slice($posts_rated, -20); // keep it under 20 entries
    565667          $posts_rated[] = $post_id;
    566           setcookie('posts_rated', implode('-', $posts_rated),  time() + 60 * 60 * 24 * 90, '/'); // expires in 90 days
     668          setcookie($this->getRecordsKey('posts_rated'), implode('-', $posts_rated),  time() + 60 * 60 * 24 * 90, '/'); // expires in 90 days
    567669
    568670          do_action('rated_post', $post_id);
     
    608710    delete_metadata('post', 0, 'rating', '', $delete_all = true);
    609711    delete_metadata('post', 0, 'votes', '', $delete_all = true);
    610     delete_metadata('user', 0, 'posts_rated', '', $delete_all = true);
     712    delete_metadata('user', 0, $this->getRecordsKey('posts_rated'), '', $delete_all = true);
    611713
    612714    // delete the current user's cookie too; this is probably useless because it only handles the current user;
    613715    // we should store a unique ID on both the server and client computer
    614716    // and if this ID doesn't match with the one on the user's computer then expire his cookie
    615     if(isset($_COOKIE['posts_rated']))
    616       setcookie('posts_rated', null, -1, '/');
     717    if(isset($_COOKIE[$this->getRecordsKey('posts_rated')]))
     718      setcookie($this->getRecordsKey('posts_rated'), null, -1, '/');
    617719  }
    618720
     
    629731  public function FormatRatingMeta($rating, $votes){
    630732
    631     $options = $this->options();
     733    $options = $this->getOptions();
    632734    extract($options);
    633735
     
    682784    if($control){
    683785
    684       $options = $this->Options();
     786      $options = $this->getOptions();
    685787
    686788      extract($options);
     
    728830
    729831
    730 
    731 
    732 
    733832 /*
    734833  * The rate links
     
    743842
    744843    $control = array();
    745     $options = $this->options();
     844    $options = $this->getOptions();
    746845    $post_id = $post_id ? $post_id : $post->ID;
    747846
     
    818917
    819918    // check if ratings are enabled for this post type
    820     if(in_array(get_post_type($post_id), $this->Options('post_types')))
     919    if(in_array(get_post_type($post_id), $this->getOptions('post_types')))
    821920
    822921      // check if the user is logged in; if not, only continue if anonymouse voting is allowed
    823       if($this->Options('anonymous_vote') || is_user_logged_in()){
     922      if($this->getOptions('anonymous_vote') || is_user_logged_in()){
    824923
    825924        // last 100 IPs
     
    829928
    830929        // client cookie
    831         $posts_rated = isset($_COOKIE['posts_rated']) ? explode('-', $_COOKIE['posts_rated']) : array();
     930        $posts_rated = isset($_COOKIE[$this->getRecordsKey('posts_rated')]) ? explode('-', $_COOKIE[$this->getRecordsKey('posts_rated')]) : array();
    832931
    833932        // current user IP
     
    837936        if(is_user_logged_in()){
    838937          $user = wp_get_current_user();
    839           $posts_rated = array_merge($posts_rated, (array)get_user_meta($user->ID, 'posts_rated', true));
     938          $posts_rated = array_merge($posts_rated, (array)get_user_meta($user->ID, $this->getRecordsKey('posts_rated'), true));
    840939        }
    841940
     
    868967      'date_limit'       => 0,                    // date limit in days
    869968      'where'            => '',
    870       'bayesian_formula' => $this->options('bayesian_formula'),
     969      'bayesian_formula' => $this->getOptions('bayesian_formula'),
    871970    ));
    872971
    873     $options = $this->options();
     972    $options = $this->getOptions();
    874973    extract($options);
    875974    extract($args);
     
    9821081    register_widget('PostRatingsWidget');
    9831082  }
    984 
    985 
    9861083}
    9871084
  • post-ratings/trunk/readme.txt

    r535411 r539746  
    7575== Changelog ==
    7676
     77= 2.0 =
     78* Fixed buggy rating records on multisite
     79* Themes can now override default CSS, if post-ratings.css is present in the theme dir
     80
    7781= 1.9 =
    7882* Added cache flush triggers
Note: See TracChangeset for help on using the changeset viewer.