source: extensions/Subscribe_to_comments/include/functions.inc.php @ 21340

Last change on this file since 21340 was 21340, checked in by mistic100, 11 years ago

too many changes

File size: 19.7 KB
Line 
1<?php
2if (!defined('PHPWG_ROOT_PATH')) die('Hacking attempt!');
3
4include_once(PHPWG_ROOT_PATH.'include/functions_mail.inc.php');
5
6/**
7 * Send comment to subscribers
8 * @param: array comment (author, content, image_id|category_id)
9 */
10function send_comment_to_subscribers($comm)
11{
12  if ( empty($comm) or !is_array($comm) )
13  {
14    trigger_error('send_comment_to_subscribers: undefineded comm', E_USER_WARNING);
15    return false;
16  }
17 
18  global $conf, $page, $user, $template;
19 
20  // create search clauses
21  $where_clauses = array();
22  if (isset($comm['image_id']))
23  {
24    $element_id = $comm['image_id'];
25    $element_type = 'image';
26   
27    array_push($where_clauses, 'type = "image" AND element_id = '.$element_id.'');
28    if (!empty($page['category']['id'])) array_push($where_clauses, 'type = "album-images" AND element_id = '.$page['category']['id'].'');
29    array_push($where_clauses, 'type = "all-images"');
30  }
31  else if (isset($comm['category_id']))
32  {
33    $element_id = $comm['category_id'];
34    $element_type = 'category';
35   
36    array_push($where_clauses, 'type = "album" AND element_id = '.$element_id.'');
37    array_push($where_clauses, 'type = "all-albums"');
38  }
39  else
40  {
41    return;
42  }
43 
44  // exclude current user
45  $exclude = null;
46  if (!empty($_POST['stc_mail']))
47  {
48    $exclude = pwg_db_real_escape_string($_POST['stc_mail']);
49  }
50  else if (!is_a_guest())
51  {
52    $exclude = $user['email'];
53  }
54 
55  // get subscribers datas
56  $query = '
57SELECT
58    id,
59    email,
60    language
61  FROM '.SUBSCRIBE_TO_TABLE.'
62  WHERE (
63      ('.implode(")\n      OR (", $where_clauses).')
64    )
65    AND validated = true
66    AND email != "'.$exclude.'"
67';
68  $subscriptions = hash_from_query($query, 'email');
69 
70  set_make_full_url();
71 
72  // get element infos
73  if ($element_type == 'image')
74  {
75    $element = get_picture_infos($comm['image_id']);
76  }
77  else
78  {
79    $element = get_category_infos($comm['category_id']);
80  }
81 
82  // format comment
83  if ($comm['author'] == 'guest') $comm['author'] = l10n('guest');
84  $comm['author'] = trigger_event('render_comment_author', $comm['author']);
85  $comm['content'] = trigger_event('render_comment_content', $comm['content']);
86 
87  // mail content
88  $subject = '['.strip_tags($conf['gallery_title']).'] Re:'.$element['name'];
89   
90  $template->set_filename('stc_mail', dirname(__FILE__).'/../template/mail/notification.tpl');
91
92  foreach ($subscriptions as $row)
93  {
94    // get subscriber id
95    if ( ($uid = get_userid_by_email($row['email'])) !== false )
96    {
97      $row['user_id'] = $uid;
98    }
99    else
100    {
101      $row['user_id'] = $conf['guest_id'];
102    }
103   
104    // check permissions
105    if (!user_can_view_element($row['user_id'], $element_id, $element_type))
106    {
107      continue;
108    }
109   
110    // send mail
111    switch_lang_to($row['language']);
112    load_language('plugin.lang', SUBSCRIBE_TO_PATH);
113   
114    $comm['caption'] = sprintf('<b>%s</b> wrote on <i>%s</i>', $comm['author'], format_date(date('Y-m-d H:i:s')));
115   
116    $template->assign('STC', array(
117      'element' => $element,
118      'comment' => $comm,
119      'UNSUB_URL' => make_stc_url('unsubscribe', $row['email'], $row['id']),
120      'MANAGE_URL' => make_stc_url('manage', $row['email']),
121      'GALLERY_TITLE' => $conf['gallery_title'],
122      ));
123   
124    $content = $template->parse('stc_mail', true);
125
126    stc_send_mail($row['email'], $content, $subject);
127    switch_lang_back();
128  }
129 
130  load_language('plugin.lang', SUBSCRIBE_TO_PATH);
131  unset_make_full_url();
132}
133
134
135/**
136 * add an email to subscribers list
137 * @param: string email
138 * @param: string type (image|album-images|all-images|album|all-albums)
139 * @param: int element_id
140 * @return: bool
141 */
142function subscribe_to_comments($email, $type, $element_id='NULL')
143{
144  if (empty($type))
145  {
146    trigger_error('subscribe_to_comment: missing type', E_USER_WARNING);
147    return false;
148  }
149 
150  if ( !in_array($type, array('all-images','all-albums')) and $element_id == 'NULL' )
151  {
152    trigger_error('subscribe_to_comment: missing element_id', E_USER_WARNING);
153    return false;
154  }
155 
156  global $page, $conf, $user, $template, $picture;
157 
158  // check email
159  if ( !empty($email) and !email_check_format($email) )
160  {
161    array_push($page['errors'], l10n('mail address must be like xxx@yyy.eee (example : jack@altern.org)'));
162    return false;
163  }
164  if ( ( is_a_guest() or empty($user['email']) ) and empty($email) )
165  {
166    array_push($page['errors'], l10n('Invalid email adress, your are not subscribed to comments.'));
167    return false;
168  }
169  else if ( !is_a_guest() and empty($email) )
170  {
171    $email = $user['email'];
172  }
173 
174  // search if already registered (can't use ODKU because we want to get the id of inserted OR updated row)
175  $query = '
176SELECT id
177  FROM '.SUBSCRIBE_TO_TABLE.'
178  WHERE
179    type = "'.$type.'"
180    AND element_id = '.$element_id.'
181    AND email = "'.pwg_db_real_escape_string($email).'"
182;';
183  $result = pwg_query($query);
184 
185  if (pwg_db_num_rows($result))
186  {
187    list($inserted_id) = pwg_db_fetch_row($result);
188  }
189  else
190  {
191    $query = '
192INSERT INTO '.SUBSCRIBE_TO_TABLE.'(
193    type,
194    element_id,
195    language,
196    email,
197    registration_date,
198    validated
199  )
200  VALUES(
201    "'.$type.'",
202    '.$element_id.',
203    "'.$user['language'].'",
204    "'.pwg_db_real_escape_string($email).'",
205    NOW(),
206    "'.(is_a_guest() ? "false" : "true").'"
207  )
208;';
209    pwg_query($query);
210   
211    $inserted_id = pwg_db_insert_id();
212  }
213 
214  // notify admins
215  if ( pwg_db_changes() != 0 and $conf['Subscribe_to_Comments']['notify_admin_on_subscribe'] )
216  {
217    stc_mail_notification_admins($email, $type, $element_id, $inserted_id);
218  }
219 
220  // send validation mail
221  if ( is_a_guest() and pwg_db_changes() != 0 )
222  {
223    set_make_full_url();
224   
225    $template->set_filename('stc_mail', dirname(__FILE__).'/../template/mail/confirm.tpl');
226   
227    $subject = '['.strip_tags($conf['gallery_title']).'] '.l10n('Confirm your subscribtion to comments');
228     
229    switch ($type)
230    {
231      case 'image':
232        $element = get_picture_infos($element_id);
233        $element['on'] = sprintf(l10n('the picture <a href="%s">%s</a>'), $element['url'], $element['name']);
234        break;
235      case 'album-images':
236        $element = get_category_infos($element_id);
237        $element['on'] = sprintf(l10n('all pictures of the album <a href="%s">%s</a>'), $element['url'], $element['name']);
238        break;
239      case 'all-images':
240        $element['thumbnail'] = null;
241        $element['on'] = l10n('all pictures of the gallery');
242        break;
243      case 'album':
244        $element = get_category_infos($element_id);
245        $element['on'] = sprintf(l10n('the album <a href="%s">%s</a>'), $element['url'], $element['name']);
246        break;
247      case 'all-albums':
248        $element['thumbnail'] = null;
249        $element['on'] = l10n('all albums of the gallery');
250        break;
251    }
252   
253    $template->assign('STC', array(
254      'element' => $element,
255      'VALIDATE_URL' => make_stc_url('validate', $email, $inserted_id),
256      'MANAGE_URL' => make_stc_url('manage', $email),
257      'GALLERY_TITLE' => $conf['gallery_title'],
258      ));
259   
260    $content = $template->parse('stc_mail', true);
261
262    stc_send_mail($email, $content, $subject);
263    unset_make_full_url();
264   
265    array_push($page['infos'], l10n('Please check your email inbox to confirm your subscription.'));
266    return true;
267  }
268  // just display confirmation message
269  else if (pwg_db_changes() != 0)
270  {
271    array_push($page['infos'], l10n('You have been added to the list of subscribers.'));
272    return true;
273  }
274 
275  return false;
276}
277
278
279/**
280 * remove an email from subscribers list
281 * @param: string email
282 * @param: int subscription id
283 * @return: bool
284 */
285function un_subscribe_to_comments($email, $id)
286{ 
287  if ( !empty($email) and !email_check_format($email) )
288  {
289    trigger_error('un_subscribe_to_comment: bad email', E_USER_WARNING);
290    return false;
291  }
292 
293  if (!preg_match('#^[0-9]+$#', $id))
294  {
295    trigger_error('un_subscribe_to_comment: bad id', E_USER_WARNING);
296    return false;
297  }
298 
299  global $template, $user;
300 
301  // check email
302  if ( ( is_a_guest() or empty($user['email']) ) and empty($email) )
303  {
304    return false;
305  }
306  else if ( !is_a_guest() and empty($email) )
307  {
308    $email = $user['email'];
309  }
310 
311  // delete subscription
312  $query = '
313DELETE FROM '.SUBSCRIBE_TO_TABLE.'
314  WHERE
315    email = "'.pwg_db_real_escape_string($email).'"
316    AND id = '.$id.'
317;';
318  pwg_query($query);
319 
320  return (pwg_db_changes() != 0);
321}
322
323
324/**
325 * validate a subscription
326 * @param: string email
327 * @param: int subscription id
328 * @return: bool
329 */
330function validate_subscriptions($email, $id)
331{
332  if (!email_check_format($email))
333  {
334    trigger_error('validate_subscriptions: bad email', E_USER_WARNING);
335    return false;
336  }
337 
338  if (!preg_match('#^[0-9]+$#', $id))
339  {
340    trigger_error('validate_subscriptions: bad id', E_USER_WARNING);
341    return false;
342  }
343 
344  $query = '
345UPDATE '.SUBSCRIBE_TO_TABLE.'
346  SET validated = "true"
347  WHERE
348    email = "'.pwg_db_real_escape_string($email).'"
349    AND id = '.$id.'
350;';
351  pwg_query($query);
352 
353  return (pwg_db_changes() != 0);
354}
355
356
357/**
358 * send notification to admins
359 * @param: string email
360 * @param: string type (image|album-images|all-images|album|all-albums)
361 * @param: int element_id
362 * @param: int subscription id
363 */
364function stc_mail_notification_admins($email, $type, $element_id, $inserted_id)
365{
366  global $user, $conf, $template;
367 
368  $admins = get_admins_email();
369  if (empty($admins)) return;
370 
371  set_make_full_url();
372  switch_lang_to(get_default_language());
373  load_language('plugin.lang', SUBSCRIBE_TO_PATH);
374 
375  $template->set_filename('stc_mail', dirname(__FILE__).'/../template/mail/admin.tpl');
376   
377  $subject = '['.strip_tags($conf['gallery_title']).'] '.sprintf(l10n('%s has subscribed to comments on %s.'), is_a_guest()?$email:$user['username'], null);
378   
379  switch ($type)
380  {
381    case 'image':
382      $element = get_picture_infos($element_id, false);
383      $element['on'] = sprintf(l10n('the picture <a href="%s">%s</a>'), $element['url'], $element['name']);
384      break;
385    case 'album-images':
386      $element = get_category_infos($element_id, false);
387      $element['on'] = sprintf(l10n('all pictures of the album <a href="%s">%s</a>'), $element['url'], $element['name']);
388      break;
389    case 'all-images':
390      $element['on'] = l10n('all pictures of the gallery');
391      break;
392    case 'album':
393      $element = get_category_infos($element_id, false);
394      $element['on'] = sprintf(l10n('the album <a href="%s">%s</a>'), $element['url'], $element['name']);
395      break;
396    case 'all-albums':
397      $element['on'] = l10n('all albums of the gallery');
398      break;
399  }
400 
401  $technical_infos[] = sprintf(l10n('Connected user: %s'), stripslashes($user['username']));
402  $technical_infos[] = sprintf(l10n('IP: %s'), $_SERVER['REMOTE_ADDR']);
403  $technical_infos[] = sprintf(l10n('Browser: %s'), $_SERVER['HTTP_USER_AGENT']);
404 
405  $template->assign('STC', array(
406    'ELEMENT' => $element['on'],
407    'USER' => is_a_guest() ? '<b>'.$email.'</b>' : '<b>'.$user['username'].'</b> ('.$email.')', 
408    'GALLERY_TITLE' => $conf['gallery_title'],
409    'TECHNICAL' => implode('<br>', $technical_infos),
410    ));
411 
412  $content = $template->parse('stc_mail', true);
413
414  stc_send_mail($admins, $content, $subject);
415 
416  unset_make_full_url();
417  switch_lang_back();
418  load_language('plugin.lang', SUBSCRIBE_TO_PATH);
419}
420
421
422/**
423 * create absolute url to subscriptions section
424 * @param: string action
425 * @param: string email
426 * @param: int optional
427 * @return: string
428 */
429function make_stc_url($action, $email, $id=null)
430{
431  if ( empty($action) or empty($email) )
432  {
433    trigger_error('make_stc_url: missing action and/or mail', E_USER_WARNING);
434    return null;
435  }
436 
437  global $conf;
438  set_make_full_url();
439 
440  $url_params = array(
441    'action' => $action,
442    'email' => $email,
443    );
444 
445  if (!empty($id))
446  {
447    $url_params['id'] = $id;
448  }
449 
450  $url_params['key'] = crypt_value(
451    $action.$email.(isset($url_params['id'])?$url_params['id']:null), 
452    $conf['secret_key']
453    );
454 
455  $url = add_url_params(
456    make_index_url( array('section' => 'subscriptions') ),
457    $url_params
458    );
459   
460  unset_make_full_url();
461  return $url;
462}
463
464
465/**
466 * send mail with STC style
467 * @param: string to
468 * @param: string content
469 * @param: string subject
470 * @return: bool
471 */
472function stc_send_mail($to, $content, $subject)
473{
474  global $conf, $conf_mail, $page, $template;
475 
476  // inputs
477  if (empty($to))
478  {
479    return false;
480  }
481
482  if (empty($content))
483  {
484    return false;
485  }
486 
487  if (empty($subject))
488  {
489    $subject = 'Piwigo';
490  }
491  else
492  {
493    $subject = trim(preg_replace('#[\n\r]+#s', '', $subject));
494    $subject = encode_mime_header($subject);
495  }
496 
497  if (!isset($conf_mail))
498  {
499    $conf_mail = get_mail_configuration();
500  }
501
502  $args['from'] = $conf_mail['formated_email_webmaster'];
503 
504  set_make_full_url();
505 
506  // hearders
507  $headers = 'From: '.$args['from']."\n"; 
508  $headers.= 'MIME-Version: 1.0'."\n";
509  $headers.= 'X-Mailer: Piwigo Mailer'."\n";
510  $headers.= 'Content-Transfer-Encoding: 8bit'."\n";
511  $headers.= 'Content-Type: text/html; charset="'.get_pwg_charset().'";'."\n";
512 
513  // template
514  $template->set_filenames(array(
515    'stc_mail_header' => dirname(__FILE__).'/../template/mail/header.tpl',
516    'stc_mail_footer' => dirname(__FILE__).'/../template/mail/footer.tpl',
517    ));
518  $stc_mail_css = file_get_contents(dirname(__FILE__).'/../template/mail/style.css');
519   
520  $template->assign(array(
521    'GALLERY_URL' => get_gallery_home_url(),
522    'PHPWG_URL' => PHPWG_URL,
523    'STC_MAIL_CSS' => str_replace("\n", null, $stc_mail_css),
524    ));
525 
526  $content = $template->parse('stc_mail_header', true) . $content . $template->parse('stc_mail_footer', true);
527 
528  $content = wordwrap($content, 70, "\n", false);
529
530  unset_make_full_url();
531 
532  // send mail
533  return
534    trigger_event('send_mail',
535      false, /* Result */
536      trigger_event('send_mail_to', get_strict_email_list($to)),
537      trigger_event('send_mail_subject', $subject),
538      trigger_event('send_mail_content', $content),
539      trigger_event('send_mail_headers', $headers),
540      $args
541    );
542}
543
544
545/**
546 * get name, url and thumbnail of a picture
547 * @param: int image_id
548 * @param: bool return thumbnail
549 * @return: array (id, name, url, thumbnail)
550 */
551function get_picture_infos($image_id, $with_thumb=true)
552{
553  $query = '
554SELECT
555    id,
556    file,
557    name,
558    path
559  FROM '.IMAGES_TABLE.'
560  WHERE id = '.$image_id.'
561;';
562  $element = pwg_db_fetch_assoc(pwg_query($query));
563   
564  if (empty($element['name']))
565  {
566    $element['name'] = get_name_from_file($element['file']);
567  }
568 
569  $url_params = array('image_id' => $element['id']);
570  $element['url'] = make_picture_url($url_params);
571 
572  if ($with_thumb)
573  {
574    $element['thumbnail'] = DerivativeImage::thumb_url($element);
575  }
576 
577  return $element;
578}
579
580/**
581 * get name, url and thumbnail of a category
582 * @param: int cat_id
583 * @param: int return thumbnail
584 * @return: array (id, name, url, thumbnail)
585 */
586function get_category_infos($cat_id, $with_thumb=true)
587{
588  global $conf;
589 
590  $query = '
591SELECT
592    cat.id,
593    cat.name,
594    cat.permalink,
595    img.id AS image_id,
596    img.path
597  FROM '.CATEGORIES_TABLE.' AS cat
598    LEFT JOIN '.USER_CACHE_CATEGORIES_TABLE.' AS ucc
599      ON ucc.cat_id = cat.id AND ucc.user_id = '.$conf['guest_id'].'
600    LEFT JOIN '.IMAGES_TABLE.' AS img
601      ON img.id = ucc.user_representative_picture_id
602  WHERE cat.id = '.$cat_id.'
603;';
604  $element = pwg_db_fetch_assoc(pwg_query($query));
605  // we use guest_id for user_cache because we don't know the status of recipient
606 
607  $element['url'] = make_index_url(array(
608    'section'=>'categories',
609    'category'=>$element,
610    ));
611 
612  if ($with_thumb)
613  {
614    $element['thumbnail'] = DerivativeImage::thumb_url(array(
615      'id'=>$element['image_id'],
616      'path'=>$element['path'],
617      ));
618  }
619 
620  return $element;
621}
622
623/**
624 * get list of admins email
625 * @return: string
626 */
627function get_admins_email()
628{
629  global $conf, $user;
630 
631  $admins = array();
632 
633  $query = '
634SELECT
635    u.'.$conf['user_fields']['username'].' AS username,
636    u.'.$conf['user_fields']['email'].' AS email
637  FROM '.USERS_TABLE.' AS u
638    JOIN '.USER_INFOS_TABLE.' AS i
639      ON i.user_id =  u.'.$conf['user_fields']['id'].'
640  WHERE i.status IN ("webmaster", "admin")
641    AND '.$conf['user_fields']['email'].' IS NOT NULL
642    AND i.user_id != '.$user['id'].'
643  ORDER BY username
644;';
645
646  $datas = pwg_query($query);
647  if (!empty($datas))
648  {
649    while ($admin = pwg_db_fetch_assoc($datas))
650    {
651      array_push($admins, format_email($admin['username'], $admin['email']));
652    }
653  }
654
655  return implode(',', $admins);
656}
657
658
659/**
660 * check if the given user can view the category/image
661 * @param: int user_id
662 * @param: int element_id
663 * @param: string type (image|category)
664 * @return: bool
665 */
666function user_can_view_element($user_id, $element_id, $type)
667{
668  global $conf;
669 
670  $old_conf = $conf['external_authentification'];
671  $conf['external_authentification'] = false;
672  $user = getuserdata($user_id, true);
673  $conf['external_authentification'] = $old_conf;
674 
675  if ($type == 'image')
676  {
677    return !in_array($element_id, explode(',', $user['image_access_list']));
678  }
679  else if ($type == 'category')
680  {
681    return !in_array($element_id, explode(',', $user['forbidden_categories']));
682  }
683  else
684  {
685    return false;
686  }
687}
688
689
690/**
691 * crypt a string using mcrypt extension or
692 * http://stackoverflow.com/questions/800922/how-to-encrypt-string-without-mcrypt-library-in-php/802957#802957
693 * @param: string value to crypt
694 * @param: string key
695 * @return: string
696 */
697function crypt_value($value, $key)
698{ 
699  if (extension_loaded('mcrypt'))
700  {
701    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
702    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
703    $result = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $value, MCRYPT_MODE_ECB, $iv);
704  }
705  else
706  {
707    $result = null;
708    for($i = 0; $i < strlen($value); $i++)
709    {
710      $char = substr($value, $i, 1);
711      $keychar = substr($key, ($i % strlen($key))-1, 1);
712      $char = chr(ord($char) + ord($keychar));
713      $result .= $char;
714    }
715  }
716 
717  $result = base64url_encode($result);
718  return trim($result); 
719}
720
721/**
722 * decrypt a string crypted with previous function
723 * @param: string value to decrypt
724 * @param: string key
725 * @return: string
726 */
727function decrypt_value($value, $key)
728{
729  $value = base64url_decode($value); 
730 
731  if (extension_loaded('mcrypt'))
732  {
733    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
734    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
735    $result = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $value, MCRYPT_MODE_ECB, $iv);
736  }
737  else
738  {
739    $result = null;
740    for($i = 0; $i < strlen($value); $i++)
741    {
742      $char = substr($value, $i, 1);
743      $keychar = substr($key, ($i % strlen($key))-1, 1);
744      $char = chr(ord($char) - ord($keychar));
745      $result .= $char;
746    }
747  }
748 
749  return trim($result);
750}
751
752/**
753 * variant of base64 functions usable into url
754 * http://php.net/manual/en/function.base64-encode.php#103849
755 */
756function base64url_encode($data)
757{
758  return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
759}
760function base64url_decode($data)
761{
762  return base64_decode(str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT));
763} 
764
765?>
Note: See TracBrowser for help on using the repository browser.