source: trunk/include/functions_rate.inc.php @ 30887

Last change on this file since 30887 was 30563, checked in by plg, 10 years ago

bug 3178 fixed, in_array check is not reliable when you compare string (user input) and numeric values

  • Property svn:eol-style set to LF
File size: 6.0 KB
RevLine 
[1084]1<?php
2// +-----------------------------------------------------------------------+
[8728]3// | Piwigo - a PHP based photo gallery                                    |
[2297]4// +-----------------------------------------------------------------------+
[26461]5// | Copyright(C) 2008-2014 Piwigo Team                  http://piwigo.org |
[2297]6// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
7// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
8// +-----------------------------------------------------------------------+
9// | This program is free software; you can redistribute it and/or modify  |
10// | it under the terms of the GNU General Public License as published by  |
11// | the Free Software Foundation                                          |
12// |                                                                       |
13// | This program is distributed in the hope that it will be useful, but   |
14// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
15// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
16// | General Public License for more details.                              |
17// |                                                                       |
18// | You should have received a copy of the GNU General Public License     |
19// | along with this program; if not, write to the Free Software           |
20// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
21// | USA.                                                                  |
22// +-----------------------------------------------------------------------+
[1084]23
24/**
[25614]25 * @package functions\rate
26 */
27
28
29/**
30 * Rate a picture by the current user.
[1084]31 *
[25614]32 * @param int $image_id
33 * @param float $rate
34 * @return array as return by update_rating_score()
[1084]35 */
[1092]36function rate_picture($image_id, $rate)
[1084]37{
[1092]38  global $conf, $user;
[1084]39
[1092]40  if (!isset($rate)
41      or !$conf['rate']
[30563]42      or !preg_match('/^[0-9]+$/', $rate)
[1092]43      or !in_array($rate, $conf['rate_items']))
[1084]44  {
[2435]45    return false;
[1084]46  }
[1092]47
48  $user_anonymous = is_autorize_status(ACCESS_CLASSIC) ? false : true;
49
50  if ($user_anonymous and !$conf['rate_anonymous'])
[1084]51  {
[2435]52    return false;
[1084]53  }
[1092]54
[2100]55  $ip_components = explode('.', $_SERVER["REMOTE_ADDR"]);
56  if (count($ip_components) > 3)
57  {
58    array_pop($ip_components);
59  }
60  $anonymous_id = implode ('.', $ip_components);
61
[1092]62  if ($user_anonymous)
[1084]63  {
[1992]64    $save_anonymous_id = pwg_get_cookie_var('anonymous_rater', $anonymous_id);
65
66    if ($anonymous_id != $save_anonymous_id)
67    { // client has changed his IP adress or he's trying to fool us
68      $query = '
[1084]69SELECT element_id
[2100]70  FROM '.RATE_TABLE.'
71  WHERE user_id = '.$user['id'].'
72    AND anonymous_id = \''.$anonymous_id.'\'
[1084]73;';
[1992]74      $already_there = array_from_query($query, 'element_id');
[1092]75
[1992]76      if (count($already_there) > 0)
77      {
78        $query = '
[1084]79DELETE
[2100]80  FROM '.RATE_TABLE.'
81  WHERE user_id = '.$user['id'].'
82    AND anonymous_id = \''.$save_anonymous_id.'\'
83    AND element_id IN ('.implode(',', $already_there).')
[1084]84;';
[1992]85         pwg_query($query);
86       }
[1084]87
[1992]88       $query = '
[2100]89UPDATE '.RATE_TABLE.'
90  SET anonymous_id = \'' .$anonymous_id.'\'
91  WHERE user_id = '.$user['id'].'
92    AND anonymous_id = \'' . $save_anonymous_id.'\'
[1084]93;';
[1992]94       pwg_query($query);
95    } // end client changed ip
[1084]96
[2100]97    pwg_set_cookie_var('anonymous_rater', $anonymous_id);
[1092]98  } // end anonymous user
[1992]99
[1092]100  $query = '
[1084]101DELETE
102  FROM '.RATE_TABLE.'
103  WHERE element_id = '.$image_id.'
[2100]104    AND user_id = '.$user['id'].'
[1084]105';
[2471]106  if ($user_anonymous)
[1092]107  {
108    $query.= ' AND anonymous_id = \''.$anonymous_id.'\'';
109  }
110  pwg_query($query);
111  $query = '
[1084]112INSERT
113  INTO '.RATE_TABLE.'
114  (user_id,anonymous_id,element_id,rate,date)
115  VALUES
116  ('
[1092]117    .$user['id'].','
[2100]118    .'\''.$anonymous_id.'\','
[1092]119    .$image_id.','
120    .$rate
121    .',NOW())
[1084]122;';
[1092]123  pwg_query($query);
124
[11827]125  return update_rating_score($image_id);
126}
127
128
[25614]129/**
130 * Update images.rating_score field.
131 * We use a bayesian average (http://en.wikipedia.org/wiki/Bayesian_average) with
132 *  C = average number of rates per item
133 *  m = global average rate (all rates)
134 *
135 * @param int|false $element_id if false applies to all
136 * @return array (score, average, count) values are null if $element_id is false
[11827]137*/
138function update_rating_score($element_id = false)
139{
[28587]140  if ( ($alt_result = trigger_change('update_rating_score', false, $element_id)) !== false)
[27294]141  {
142    return $alt_result;
143  }
144
[1092]145  $query = '
[11827]146SELECT element_id,
147    COUNT(rate) AS rcount,
148    SUM(rate) AS rsum
[1084]149  FROM '.RATE_TABLE.'
[11827]150  GROUP by element_id';
151
152  $all_rates_count = 0;
153  $all_rates_avg = 0;
154  $item_ratecount_avg = 0;
155  $by_item = array();
156
157  $result = pwg_query($query);
158  while ($row = pwg_db_fetch_assoc($result))
159  {
160    $all_rates_count += $row['rcount'];
161    $all_rates_avg += $row['rsum'];
162    $by_item[$row['element_id']] = $row;
163  }
164
[12412]165  if ($all_rates_count>0)
166  {
167    $all_rates_avg /= $all_rates_count;
168    $item_ratecount_avg = $all_rates_count / count($by_item);
169  }
[11827]170
171  $updates = array();
172  foreach ($by_item as $id => $rate_summary )
173  {
174    $score = ( $item_ratecount_avg * $all_rates_avg + $rate_summary['rsum'] ) / ($item_ratecount_avg + $rate_summary['rcount']);
175    $score = round($score,2);
176    if ($id==$element_id)
177    {
178      $return = array(
179        'score' => $score,
180        'average' => round($rate_summary['rsum'] / $rate_summary['rcount'], 2),
181        'count' => $rate_summary['rcount'],
182        );
183    }
[11893]184    $updates[] = array( 'id'=>$id, 'rating_score'=>$score );
[11827]185  }
186  mass_updates(
187    IMAGES_TABLE,
188    array(
189      'primary' => array('id'),
[11893]190      'update' => array('rating_score')
[11827]191      ),
192    $updates
193    );
194
195  //set to null all items with no rate
196  if ( !isset($by_item[$element_id]) )
197  {
198    $query='
199SELECT id FROM '.IMAGES_TABLE .'
200  LEFT JOIN '.RATE_TABLE.' ON id=element_id
[11893]201  WHERE element_id IS NULL AND rating_score IS NOT NULL';
[11827]202
203    $to_update = array_from_query( $query, 'id');
204
205    if ( !empty($to_update) )
206    {
207      $query='
208UPDATE '.IMAGES_TABLE .'
[11893]209  SET rating_score=NULL
[11827]210  WHERE id IN (' . implode(',',$to_update) . ')';
211    pwg_query($query);
212    }
213  }
214
215  return isset($return) ? $return : array('score'=>null, 'average'=>null, 'count'=>0 );
[1084]216}
217
[2100]218?>
Note: See TracBrowser for help on using the repository browser.