source: branches/2.5/include/functions_rate.inc.php @ 30568

Last change on this file since 30568 was 30568, checked in by plg, 9 years ago

merge r30563 from trunk to branch 2.5

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: 5.8 KB
Line 
1<?php
2// +-----------------------------------------------------------------------+
3// | Piwigo - a PHP based photo gallery                                    |
4// +-----------------------------------------------------------------------+
5// | Copyright(C) 2008-2013 Piwigo Team                  http://piwigo.org |
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// +-----------------------------------------------------------------------+
23
24/**
25 * rate a picture by a user
26 *
27 * @param int image identifier
28 * @param int rate
29 * @return void
30 */
31function rate_picture($image_id, $rate)
32{
33  global $conf, $user;
34
35  if (!isset($rate)
36      or !$conf['rate']
37      or !preg_match('/^[0-9]+$/', $rate)
38      or !in_array($rate, $conf['rate_items']))
39  {
40    return false;
41  }
42
43  $user_anonymous = is_autorize_status(ACCESS_CLASSIC) ? false : true;
44
45  if ($user_anonymous and !$conf['rate_anonymous'])
46  {
47    return false;
48  }
49
50  $ip_components = explode('.', $_SERVER["REMOTE_ADDR"]);
51  if (count($ip_components) > 3)
52  {
53    array_pop($ip_components);
54  }
55  $anonymous_id = implode ('.', $ip_components);
56
57  if ($user_anonymous)
58  {
59    $save_anonymous_id = pwg_get_cookie_var('anonymous_rater', $anonymous_id);
60
61    if ($anonymous_id != $save_anonymous_id)
62    { // client has changed his IP adress or he's trying to fool us
63      $query = '
64SELECT element_id
65  FROM '.RATE_TABLE.'
66  WHERE user_id = '.$user['id'].'
67    AND anonymous_id = \''.$anonymous_id.'\'
68;';
69      $already_there = array_from_query($query, 'element_id');
70
71      if (count($already_there) > 0)
72      {
73        $query = '
74DELETE
75  FROM '.RATE_TABLE.'
76  WHERE user_id = '.$user['id'].'
77    AND anonymous_id = \''.$save_anonymous_id.'\'
78    AND element_id IN ('.implode(',', $already_there).')
79;';
80         pwg_query($query);
81       }
82
83       $query = '
84UPDATE '.RATE_TABLE.'
85  SET anonymous_id = \'' .$anonymous_id.'\'
86  WHERE user_id = '.$user['id'].'
87    AND anonymous_id = \'' . $save_anonymous_id.'\'
88;';
89       pwg_query($query);
90    } // end client changed ip
91
92    pwg_set_cookie_var('anonymous_rater', $anonymous_id);
93  } // end anonymous user
94
95  $query = '
96DELETE
97  FROM '.RATE_TABLE.'
98  WHERE element_id = '.$image_id.'
99    AND user_id = '.$user['id'].'
100';
101  if ($user_anonymous)
102  {
103    $query.= ' AND anonymous_id = \''.$anonymous_id.'\'';
104  }
105  pwg_query($query);
106  $query = '
107INSERT
108  INTO '.RATE_TABLE.'
109  (user_id,anonymous_id,element_id,rate,date)
110  VALUES
111  ('
112    .$user['id'].','
113    .'\''.$anonymous_id.'\','
114    .$image_id.','
115    .$rate
116    .',NOW())
117;';
118  pwg_query($query);
119
120  return update_rating_score($image_id);
121}
122
123
124/* update images.rating_score field
125  * we use a bayesian average (http://en.wikipedia.org/wiki/Bayesian_average) with
126C = average number of rates per item
127m = global average rate (all rates)
128
129 * param int $element_id optional, otherwise applies to all
130 * @return array(rating_score, count) if element_id is specified
131*/
132function update_rating_score($element_id = false)
133{
134  $query = '
135SELECT element_id,
136    COUNT(rate) AS rcount,
137    SUM(rate) AS rsum
138  FROM '.RATE_TABLE.'
139  GROUP by element_id';
140
141  $all_rates_count = 0;
142  $all_rates_avg = 0;
143  $item_ratecount_avg = 0;
144  $by_item = array();
145
146  $result = pwg_query($query);
147  while ($row = pwg_db_fetch_assoc($result))
148  {
149    $all_rates_count += $row['rcount'];
150    $all_rates_avg += $row['rsum'];
151    $by_item[$row['element_id']] = $row;
152  }
153
154  if ($all_rates_count>0)
155  {
156    $all_rates_avg /= $all_rates_count;
157    $item_ratecount_avg = $all_rates_count / count($by_item);
158  }
159
160  $updates = array();
161  foreach ($by_item as $id => $rate_summary )
162  {
163    $score = ( $item_ratecount_avg * $all_rates_avg + $rate_summary['rsum'] ) / ($item_ratecount_avg + $rate_summary['rcount']);
164    $score = round($score,2);
165    if ($id==$element_id)
166    {
167      $return = array(
168        'score' => $score,
169        'average' => round($rate_summary['rsum'] / $rate_summary['rcount'], 2),
170        'count' => $rate_summary['rcount'],
171        );
172    }
173    $updates[] = array( 'id'=>$id, 'rating_score'=>$score );
174  }
175  mass_updates(
176    IMAGES_TABLE,
177    array(
178      'primary' => array('id'),
179      'update' => array('rating_score')
180      ),
181    $updates
182    );
183
184  //set to null all items with no rate
185  if ( !isset($by_item[$element_id]) )
186  {
187    $query='
188SELECT id FROM '.IMAGES_TABLE .'
189  LEFT JOIN '.RATE_TABLE.' ON id=element_id
190  WHERE element_id IS NULL AND rating_score IS NOT NULL';
191
192    $to_update = array_from_query( $query, 'id');
193
194    if ( !empty($to_update) )
195    {
196      $query='
197UPDATE '.IMAGES_TABLE .'
198  SET rating_score=NULL
199  WHERE id IN (' . implode(',',$to_update) . ')';
200    pwg_query($query);
201    }
202  }
203
204  return isset($return) ? $return : array('score'=>null, 'average'=>null, 'count'=>0 );
205}
206
207?>
Note: See TracBrowser for help on using the repository browser.