source: trunk/include/functions_comment.inc.php @ 20887

Last change on this file since 20887 was 19703, checked in by plg, 12 years ago

update Piwigo headers to 2013 (the end of the world didn't occur as expected on r12922)

  • Property svn:eol-style set to LF
File size: 13.7 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//returns string action to perform on a new comment: validate, moderate, reject
25function user_comment_check($action, $comment)
26{
27  global $conf,$user;
28
29  if ($action=='reject')
30    return $action;
31
32  $my_action = $conf['comment_spam_reject'] ? 'reject':'moderate';
33
34  if ($action==$my_action)
35    return $action;
36
37  // we do here only BASIC spam check (plugins can do more)
38  if ( !is_a_guest() )
39    return $action;
40
41  $link_count = preg_match_all( '/https?:\/\//',
42    $comment['content'], $matches);
43
44  if ( strpos($comment['author'], 'http://')!==false )
45  {
46    $link_count++;
47  }
48
49  if ( $link_count>$conf['comment_spam_max_links'] )
50  {
51    $_POST['cr'][] = 'links';
52    return $my_action;
53  }
54  return $action;
55}
56
57
58add_event_handler('user_comment_check', 'user_comment_check',
59  EVENT_HANDLER_PRIORITY_NEUTRAL, 2);
60
61/**
62 * Tries to insert a user comment in the database and returns one of :
63 * validate, moderate, reject
64 * @param array comm contains author, content, image_id
65 * @param string key secret key sent back to the browser
66 * @param array infos out array of messages
67 */
68function insert_user_comment( &$comm, $key, &$infos )
69{
70  global $conf, $user;
71
72  $comm = array_merge( $comm,
73    array(
74      'ip' => $_SERVER['REMOTE_ADDR'],
75      'agent' => $_SERVER['HTTP_USER_AGENT']
76    )
77   );
78
79  $infos = array();
80  if (!$conf['comments_validation'] or is_admin())
81  {
82    $comment_action='validate'; //one of validate, moderate, reject
83  }
84  else
85  {
86    $comment_action='moderate'; //one of validate, moderate, reject
87  }
88
89  // display author field if the user status is guest or generic
90  if (!is_classic_user())
91  {
92    if ( empty($comm['author']) )
93    {
94      if ($conf['comments_author_mandatory'])
95      {
96        array_push($infos, l10n('Username is mandatory') );
97        $comment_action='reject';
98      }
99      $comm['author'] = 'guest';
100    }
101    $comm['author_id'] = $conf['guest_id'];
102    // if a guest try to use the name of an already existing user, he must be
103    // rejected
104    if ( $comm['author'] != 'guest' )
105    {
106      $query = '
107SELECT COUNT(*) AS user_exists
108  FROM '.USERS_TABLE.'
109  WHERE '.$conf['user_fields']['username']." = '".addslashes($comm['author'])."'";
110      $row = pwg_db_fetch_assoc( pwg_query( $query ) );
111      if ( $row['user_exists'] == 1 )
112      {
113        array_push($infos, l10n('This login is already used by another user') );
114        $comment_action='reject';
115      }
116    }
117  }
118  else
119  {
120    $comm['author'] = addslashes($user['username']);
121    $comm['author_id'] = $user['id'];
122  }
123
124  if ( empty($comm['content']) )
125  { // empty comment content
126    $comment_action='reject';
127  }
128
129  if ( !verify_ephemeral_key(@$key, $comm['image_id']) )
130  {
131    $comment_action='reject';
132    $_POST['cr'][] = 'key'; // rvelices: I use this outside to see how spam robots work
133  }
134 
135  // website
136  if (!empty($comm['website_url']))
137  {
138    if (!preg_match('/^https?/i', $comm['website_url']))
139    {
140      $comm['website_url'] = 'http://'.$comm['website_url'];
141    }
142    if (!url_check_format($comm['website_url']))
143    {
144      array_push($infos, l10n('Your website URL is invalid'));
145      $comment_action='reject';
146    }
147  }
148 
149  // email
150  if (empty($comm['email']))
151  {
152    if (!empty($user['email']))
153    {
154      $comm['email'] = $user['email'];
155    }
156    else if ($conf['comments_email_mandatory'])
157    {
158      array_push($infos, l10n('Email address is missing. Please specify an email address.') );
159      $comment_action='reject';
160    }
161  }
162  else if (!email_check_format($comm['email']))
163  {
164    array_push($infos, l10n('mail address must be like xxx@yyy.eee (example : jack@altern.org)'));
165    $comment_action='reject';
166  }
167 
168  // anonymous id = ip address
169  $ip_components = explode('.', $comm['ip']);
170  if (count($ip_components) > 3)
171  {
172    array_pop($ip_components);
173  }
174  $comm['anonymous_id'] = implode('.', $ip_components);
175
176  if ($comment_action!='reject' and $conf['anti-flood_time']>0 and !is_admin())
177  { // anti-flood system
178    $reference_date = pwg_db_get_flood_period_expression($conf['anti-flood_time']);
179
180    $query = '
181SELECT count(1) FROM '.COMMENTS_TABLE.'
182  WHERE date > '.$reference_date.'
183    AND author_id = '.$comm['author_id'];
184    if (!is_classic_user())
185    {
186      $query.= '
187      AND anonymous_id = "'.$comm['anonymous_id'].'"';
188    }
189    $query.= '
190;';
191
192    list($counter) = pwg_db_fetch_row(pwg_query($query));
193    if ( $counter > 0 )
194    {
195      array_push( $infos, l10n('Anti-flood system : please wait for a moment before trying to post another comment') );
196      $comment_action='reject';
197    }
198  }
199
200  // perform more spam check
201  $comment_action = trigger_event('user_comment_check',
202      $comment_action, $comm
203    );
204
205  if ( $comment_action!='reject' )
206  {
207    $query = '
208INSERT INTO '.COMMENTS_TABLE.'
209  (author, author_id, anonymous_id, content, date, validated, validation_date, image_id, website_url, email)
210  VALUES (
211    \''.$comm['author'].'\',
212    '.$comm['author_id'].',
213    \''.$comm['anonymous_id'].'\',
214    \''.$comm['content'].'\',
215    NOW(),
216    \''.($comment_action=='validate' ? 'true':'false').'\',
217    '.($comment_action=='validate' ? 'NOW()':'NULL').',
218    '.$comm['image_id'].',
219    '.(!empty($comm['website_url']) ? '\''.$comm['website_url'].'\'' : 'NULL').',
220    '.(!empty($comm['email']) ? '\''.$comm['email'].'\'' : 'NULL').'
221  )
222';
223
224    pwg_query($query);
225
226    $comm['id'] = pwg_db_insert_id(COMMENTS_TABLE);
227
228    if ( ($conf['email_admin_on_comment'] && 'validate' == $comment_action)
229        or ($conf['email_admin_on_comment_validation'] and 'moderate' == $comment_action))
230    {
231      include_once(PHPWG_ROOT_PATH.'include/functions_mail.inc.php');
232
233      $comment_url = get_absolute_root_url().'comments.php?comment_id='.$comm['id'];
234
235      $keyargs_content = array
236      (
237        get_l10n_args('Author: %s', stripslashes($comm['author']) ),
238        get_l10n_args('Email: %s', stripslashes($comm['email']) ),
239        get_l10n_args('Comment: %s', stripslashes($comm['content']) ),
240        get_l10n_args('', ''),
241        get_l10n_args('Manage this user comment: %s', $comment_url)
242      );
243
244      if ('moderate' == $comment_action)
245      {
246        $keyargs_content[] = get_l10n_args('', '');
247        $keyargs_content[] = get_l10n_args('(!) This comment requires validation', '');
248      }
249
250      pwg_mail_notification_admins
251      (
252        get_l10n_args('Comment by %s', stripslashes($comm['author']) ),
253        $keyargs_content
254      );
255    }
256  }
257  return $comment_action;
258}
259
260/**
261 * Tries to delete a user comment in the database
262 * only admin can delete all comments
263 * other users can delete their own comments
264 * so to avoid a new sql request we add author in where clause
265 *
266 * @param int or array of int comment_id
267 */
268function delete_user_comment($comment_id)
269{
270  $user_where_clause = '';
271  if (!is_admin())
272  {
273    $user_where_clause = '   AND author_id = \''.$GLOBALS['user']['id'].'\'';
274  }
275 
276  if (is_array($comment_id))
277    $where_clause = 'id IN('.implode(',', $comment_id).')';
278  else
279    $where_clause = 'id = '.$comment_id;
280   
281  $query = '
282DELETE FROM '.COMMENTS_TABLE.'
283  WHERE '.$where_clause.
284$user_where_clause.'
285;';
286  $result = pwg_query($query);
287 
288  if ($result) 
289  {
290    email_admin('delete', 
291                array('author' => $GLOBALS['user']['username'],
292                      'comment_id' => $comment_id
293                  ));
294  }
295 
296  trigger_action('user_comment_deletion', $comment_id);
297}
298
299/**
300 * Tries to update a user comment in the database
301 * only admin can update all comments
302 * users can edit their own comments if admin allow them
303 * so to avoid a new sql request we add author in where clause
304 *
305 * @param comment_id
306 * @param post_key
307 * @param content
308 */
309
310function update_user_comment($comment, $post_key)
311{
312  global $conf, $page;
313
314  $comment_action = 'validate';
315
316  if ( !verify_ephemeral_key($post_key, $comment['image_id']) )
317  {
318    $comment_action='reject';
319  }
320  elseif (!$conf['comments_validation'] or is_admin()) // should the updated comment must be validated
321  {
322    $comment_action='validate'; //one of validate, moderate, reject
323  }
324  else
325  {
326    $comment_action='moderate'; //one of validate, moderate, reject
327  }
328
329  // perform more spam check
330  $comment_action =
331    trigger_event('user_comment_check',
332                  $comment_action,
333                  array_merge($comment,
334                              array('author' => $GLOBALS['user']['username'])
335                              )
336                  );
337
338  // website
339  if (!empty($comment['website_url']))
340  {
341    if (!preg_match('/^https?/i', $comment['website_url']))
342    {
343      $comment['website_url'] = 'http://'.$comment['website_url'];
344    }
345    if (!url_check_format($comment['website_url']))
346    {
347      array_push($page['errors'], l10n('Your website URL is invalid'));
348      $comment_action='reject';
349    }
350  }
351
352  if ( $comment_action!='reject' )
353  {
354    $user_where_clause = '';
355    if (!is_admin())
356    {
357      $user_where_clause = '   AND author_id = \''.
358        $GLOBALS['user']['id'].'\'';
359    }
360
361    $query = '
362UPDATE '.COMMENTS_TABLE.'
363  SET content = \''.$comment['content'].'\',
364      website_url = '.(!empty($comment['website_url']) ? '\''.$comment['website_url'].'\'' : 'NULL').',
365      validated = \''.($comment_action=='validate' ? 'true':'false').'\',
366      validation_date = '.($comment_action=='validate' ? 'NOW()':'NULL').'
367  WHERE id = '.$comment['comment_id'].
368$user_where_clause.'
369;';
370    $result = pwg_query($query);
371   
372    // mail admin and ask to validate the comment
373    if ($result and $conf['email_admin_on_comment_validation'] and 'moderate' == $comment_action) 
374    {
375      include_once(PHPWG_ROOT_PATH.'include/functions_mail.inc.php');
376
377      $comment_url = get_absolute_root_url().'comments.php?comment_id='.$comment['comment_id'];
378
379      $keyargs_content = array
380      (
381        get_l10n_args('Author: %s', stripslashes($GLOBALS['user']['username']) ),
382        get_l10n_args('Comment: %s', stripslashes($comment['content']) ),
383        get_l10n_args('', ''),
384        get_l10n_args('Manage this user comment: %s', $comment_url),
385        get_l10n_args('', ''),
386        get_l10n_args('(!) This comment requires validation', ''),
387      );
388
389      pwg_mail_notification_admins
390      (
391        get_l10n_args('Comment by %s', stripslashes($GLOBALS['user']['username']) ),
392        $keyargs_content
393      );
394    }
395    // just mail admin
396    else if ($result)
397    {
398      email_admin('edit', array('author' => $GLOBALS['user']['username'],
399                                'content' => stripslashes($comment['content'])) );
400    }
401  }
402 
403  return $comment_action;
404}
405
406function email_admin($action, $comment)
407{
408  global $conf;
409
410  if (!in_array($action, array('edit', 'delete'))
411      or (($action=='edit') and !$conf['email_admin_on_comment_edition'])
412      or (($action=='delete') and !$conf['email_admin_on_comment_deletion']))
413  {
414    return;
415  }
416
417  include_once(PHPWG_ROOT_PATH.'include/functions_mail.inc.php');
418
419  $keyargs_content = array();
420  $keyargs_content[] = get_l10n_args('Author: %s', $comment['author']);
421  if ($action=='delete')
422  {
423    $keyargs_content[] = get_l10n_args('This author removed the comment with id %d',
424                                       $comment['comment_id']
425                                       );
426  }
427  else
428  {
429    $keyargs_content[] = get_l10n_args('This author modified following comment:', '');
430    $keyargs_content[] = get_l10n_args('Comment: %s', $comment['content']);
431  }
432
433  pwg_mail_notification_admins(get_l10n_args('Comment by %s',
434                                             $comment['author']),
435                               $keyargs_content
436                               );
437}
438
439function get_comment_author_id($comment_id, $die_on_error=true)
440{
441  $query = '
442SELECT
443    author_id
444  FROM '.COMMENTS_TABLE.'
445  WHERE id = '.$comment_id.'
446;';
447  $result = pwg_query($query);
448  if (pwg_db_num_rows($result) == 0)
449  {
450    if ($die_on_error)
451    {
452      fatal_error('Unknown comment identifier');
453    }
454    else
455    {
456      return false;
457    }
458  }
459 
460  list($author_id) = pwg_db_fetch_row($result);
461
462  return $author_id;
463}
464
465/**
466 * Tries to validate a user comment in the database
467 * @param int or array of int comment_id
468 */
469function validate_user_comment($comment_id)
470{
471  if (is_array($comment_id))
472    $where_clause = 'id IN('.implode(',', $comment_id).')';
473  else
474    $where_clause = 'id = '.$comment_id;
475   
476  $query = '
477UPDATE '.COMMENTS_TABLE.'
478  SET validated = \'true\'
479    , validation_date = NOW()
480  WHERE '.$where_clause.'
481;';
482  pwg_query($query);
483 
484  trigger_action('user_comment_validation', $comment_id);
485}
486?>
Note: See TracBrowser for help on using the repository browser.