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

Last change on this file since 17350 was 17350, checked in by mistic100, 8 years ago

remove useless Quoted-Printable-Encode for mails

File size: 20.5 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-d-m 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 !is_valid_email($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 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(null) != 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(null) != 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(null) != 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($id))
288  {
289    trigger_error('un_subscribe_to_comment: missing id', E_USER_WARNING);
290    return false;
291  }
292 
293  global $template, $user;
294 
295  // check email
296  if ( ( is_a_guest() or empty($user['email']) ) and empty($email) )
297  {
298    return false;
299  }
300  else if ( !is_a_guest() and empty($email) )
301  {
302    $email = $user['email'];
303  }
304 
305  // delete subscription
306  $query = '
307DELETE FROM '.SUBSCRIBE_TO_TABLE.'
308  WHERE
309    email = "'.pwg_db_real_escape_string($email).'"
310    AND id = "'.pwg_db_real_escape_string($id).'"
311;';
312  pwg_query($query);
313     
314  if (pwg_db_changes(null) != 0) return true;
315  return false;
316}
317
318
319/**
320 * validate a subscription
321 * @param: string email
322 * @param: int subscription id
323 * @return: bool
324 */
325function validate_subscriptions($email, $id)
326{
327  if (empty($email))
328  {
329    trigger_error('validate_subscriptions: missing email', E_USER_WARNING);
330    return false;
331  }
332 
333  if (empty($id))
334  {
335    trigger_error('validate_subscriptions: missing id', E_USER_WARNING);
336    return false;
337  }
338 
339  $query = '
340UPDATE '.SUBSCRIBE_TO_TABLE.'
341  SET validated = "true"
342  WHERE
343    email = "'.pwg_db_real_escape_string($email).'"
344    AND id = '.pwg_db_real_escape_string($id).'
345;';
346  pwg_query($query);
347     
348  if (pwg_db_changes(null) != 0) return true;
349  return false;
350}
351
352
353/**
354 * send notification to admins
355 * @param: string email
356 * @param: string type (image|album-images|all-images|album|all-albums)
357 * @param: int element_id
358 * @param: int subscription id
359 */
360function stc_mail_notification_admins($email, $type, $element_id, $inserted_id)
361{
362  global $user, $conf, $template;
363 
364  $admins = get_admins_email();
365  if (empty($admins)) return;
366 
367  set_make_full_url();
368  switch_lang_to(get_default_language());
369  load_language('plugin.lang', SUBSCRIBE_TO_PATH);
370 
371  $template->set_filename('stc_mail', dirname(__FILE__).'/../template/mail/admin.tpl');
372   
373  $subject = '['.strip_tags($conf['gallery_title']).'] '.sprintf(l10n('%s has subscribed to comments on'), is_a_guest()?$email:$user['username']);
374   
375  switch ($type)
376  {
377    case 'image':
378      $element = get_picture_infos($element_id, false);
379      $element['on'] = sprintf(l10n('the picture <a href="%s">%s</a>'), $element['url'], $element['name']);
380      break;
381    case 'album-images':
382      $element = get_category_infos($element_id, false);
383      $element['on'] = sprintf(l10n('all pictures of the album <a href="%s">%s</a>'), $element['url'], $element['name']);
384      break;
385    case 'all-images':
386      $element['on'] = l10n('all pictures of the gallery');
387      break;
388    case 'album':
389      $element = get_category_infos($element_id, false);
390      $element['on'] = sprintf(l10n('the album <a href="%s">%s</a>'), $element['url'], $element['name']);
391      break;
392    case 'all-albums':
393      $element['on'] = l10n('all albums of the gallery');
394      break;
395  }
396 
397  $technical_infos[] = sprintf(l10n('Connected user: %s'), stripslashes($user['username']));
398  $technical_infos[] = sprintf(l10n('IP: %s'), $_SERVER['REMOTE_ADDR']);
399  $technical_infos[] = sprintf(l10n('Browser: %s'), $_SERVER['HTTP_USER_AGENT']);
400 
401  $template->assign('STC', array(
402    'ELEMENT' => $element['on'],
403    'USER' => sprintf(l10n('%s has subscribed to comments on'), is_a_guest() ? '<b>'.$email.'</b>' : '<b>'.$user['username'].'</b> ('.$email.')'), 
404    'GALLERY_TITLE' => $conf['gallery_title'],
405    'TECHNICAL' => implode('<br>', $technical_infos),
406    ));
407 
408  $content = $template->parse('stc_mail', true);
409
410  stc_send_mail($admins, $content, $subject);
411 
412  unset_make_full_url();
413  switch_lang_back();
414  load_language('plugin.lang', SUBSCRIBE_TO_PATH);
415}
416
417
418/**
419 * create absolute url to subscriptions section
420 * @param: string action
421 * @param: string email
422 * @param: int optional
423 * @return: string
424 */
425function make_stc_url($action, $email, $id=null)
426{
427  if ( empty($action) or empty($email) )
428  {
429    trigger_error('make_stc_url: missing action and/or mail', E_USER_WARNING);
430    return null;
431  }
432 
433  global $conf;
434  set_make_full_url();
435 
436  $url_params = array(
437    'action' => $action,
438    'email' => $email,
439    );
440 
441  if (!empty($id))
442  {
443    $url_params['id'] = $id;
444  }
445 
446  $url_params['key'] = crypt_value(
447    $action.$email.(isset($url_params['id'])?$url_params['id']:null), 
448    $conf['secret_key']
449    );
450 
451  $url = add_url_params(
452    make_index_url( array('section' => 'subscriptions') ),
453    $url_params
454    );
455   
456  unset_make_full_url();
457  return $url;
458}
459
460
461/**
462 * send mail with STC style
463 * @param: string to
464 * @param: string content
465 * @param: string subject
466 * @return: bool
467 */
468function stc_send_mail($to, $content, $subject)
469{
470  global $conf, $conf_mail, $page, $template;
471 
472  // inputs
473  if (empty($to))
474  {
475    return false;
476  }
477
478  if (empty($content))
479  {
480    return false;
481  }
482 
483  if (empty($subject))
484  {
485    $subject = 'Piwigo';
486  }
487  else
488  {
489    $subject = trim(preg_replace('#[\n\r]+#s', '', $subject));
490    $subject = encode_mime_header($subject);
491  }
492 
493  if (!isset($conf_mail))
494  {
495    $conf_mail = get_mail_configuration();
496  }
497
498  $args['from'] = $conf_mail['formated_email_webmaster'];
499 
500  set_make_full_url();
501 
502  // hearders
503  $headers = 'From: '.$args['from']."\n"; 
504  $headers.= 'MIME-Version: 1.0'."\n";
505  $headers.= 'X-Mailer: Piwigo Mailer'."\n";
506  // $headers.= 'Content-Transfer-Encoding: Quoted-Printable'."\n";
507  $headers.= 'Content-Transfer-Encoding: 8bit'."\n";
508  $headers.= 'Content-Type: text/html; charset="'.get_pwg_charset().'";'."\n";
509 
510  // template
511  $template->set_filenames(array(
512    'stc_mail_header' => dirname(__FILE__).'/../template/mail/header.tpl',
513    'stc_mail_footer' => dirname(__FILE__).'/../template/mail/footer.tpl',
514    ));
515  $stc_mail_css = file_get_contents(dirname(__FILE__).'/../template/mail/style.css');
516   
517  $template->assign(array(
518    'GALLERY_URL' => get_gallery_home_url(),
519    'PHPWG_URL' => PHPWG_URL,
520    'STC_MAIL_CSS' => str_replace("\n", null, $stc_mail_css),
521    ));
522 
523  $content = $template->parse('stc_mail_header', true) . $content . $template->parse('stc_mail_footer', true);
524 
525  // $content = quoted_printable_encode($content);
526  $content = wordwrap($content, 70, "\n", true);
527
528  unset_make_full_url();
529 
530  // send mail
531  return
532    trigger_event('send_mail',
533      false, /* Result */
534      trigger_event('send_mail_to', get_strict_email_list($to)),
535      trigger_event('send_mail_subject', $subject),
536      trigger_event('send_mail_content', $content),
537      trigger_event('send_mail_headers', $headers),
538      $args
539    );
540}
541
542
543/**
544 * get name, url and thumbnail of a picture
545 * @param: int image_id
546 * @param: bool return thumbnail
547 * @return: array (id, name, url, thumbnail)
548 */
549function get_picture_infos($image_id, $with_thumb=true)
550{
551  $query = '
552SELECT
553    id,
554    file,
555    name,
556    path
557  FROM '.IMAGES_TABLE.'
558  WHERE id = '.$image_id.'
559;';
560  $element = pwg_db_fetch_assoc(pwg_query($query));
561   
562  if (empty($element['name']))
563  {
564    $element['name'] = get_name_from_file($element['file']);
565  }
566 
567  $url_params = array('image_id' => $element['id']);
568  $element['url'] = make_picture_url($url_params);
569 
570  if ($with_thumb)
571  {
572    $element['thumbnail'] = DerivativeImage::thumb_url($element);
573  }
574 
575  return $element;
576}
577
578/**
579 * get name, url and thumbnail of a category
580 * @param: int cat_id
581 * @param: int return thumbnail
582 * @return: array (id, name, url, thumbnail)
583 */
584function get_category_infos($cat_id, $with_thumb=true)
585{
586  global $conf;
587 
588  $query = '
589SELECT
590    cat.id,
591    cat.name,
592    cat.permalink,
593    img.id AS image_id,
594    img.path
595  FROM '.CATEGORIES_TABLE.' AS cat
596    LEFT JOIN '.USER_CACHE_CATEGORIES_TABLE.' AS ucc
597      ON ucc.cat_id = cat.id AND ucc.user_id = '.$conf['guest_id'].'
598    LEFT JOIN '.IMAGES_TABLE.' AS img
599      ON img.id = ucc.user_representative_picture_id
600  WHERE cat.id = '.$cat_id.'
601;';
602  $element = pwg_db_fetch_assoc(pwg_query($query));
603  // we use guest_id for user_cache because we don't know the status of recipient
604 
605  $element['url'] = make_index_url(array(
606    'section'=>'categories',
607    'category'=>$element,
608    ));
609 
610  if ($with_thumb)
611  {
612    $element['thumbnail'] = DerivativeImage::thumb_url(array(
613      'id'=>$element['image_id'],
614      'path'=>$element['path'],
615      ));
616  }
617 
618  return $element;
619}
620
621/**
622 * get list of admins email
623 * @return: string
624 */
625function get_admins_email()
626{
627  global $conf, $user;
628 
629  $admins = array();
630 
631  $query = '
632SELECT
633    u.'.$conf['user_fields']['username'].' AS username,
634    u.'.$conf['user_fields']['email'].' AS email
635  FROM '.USERS_TABLE.' AS u
636    JOIN '.USER_INFOS_TABLE.' AS i
637      ON i.user_id =  u.'.$conf['user_fields']['id'].'
638  WHERE i.status IN ("webmaster", "admin")
639    AND '.$conf['user_fields']['email'].' IS NOT NULL
640    AND i.user_id != '.$user['id'].'
641  ORDER BY username
642;';
643
644  $datas = pwg_query($query);
645  if (!empty($datas))
646  {
647    while ($admin = pwg_db_fetch_assoc($datas))
648    {
649      array_push($admins, format_email($admin['username'], $admin['email']));
650    }
651  }
652
653  return implode(',', $admins);
654}
655
656
657/**
658 * check if the given user can view the category/image
659 * @param: int user_id
660 * @param: int element_id
661 * @param: string type (image|category)
662 * @return: bool
663 */
664function user_can_view_element($user_id, $element_id, $type)
665{
666  global $conf;
667 
668  $old_conf = $conf['external_authentification'];
669  $conf['external_authentification'] = false;
670  $user = getuserdata($user_id, true);
671  $conf['external_authentification'] = $old_conf;
672 
673  if ($type == 'image')
674  {
675    return !in_array($element_id, explode(',', $user['image_access_list']));
676  }
677  else if ($type == 'category')
678  {
679    return !in_array($element_id, explode(',', $user['forbidden_categories']));
680  }
681  else
682  {
683    return false;
684  }
685}
686
687
688/**
689 * check if mail adress is valid
690 * @param: string email
691 * @return: bool
692 */
693if (!function_exists('is_valid_email'))
694{
695  function is_valid_email($mail_address)
696  {
697    if (version_compare(PHP_VERSION, '5.2.0') >= 0)
698    {
699      return filter_var($mail_address, FILTER_VALIDATE_EMAIL)!==false;
700    }
701    else
702    {
703      $atom   = '[-a-z0-9!#$%&\'*+\\/=?^_`{|}~]';   // before  arobase
704      $domain = '([a-z0-9]([-a-z0-9]*[a-z0-9]+)?)'; // domain name
705      $regex = '/^' . $atom . '+' . '(\.' . $atom . '+)*' . '@' . '(' . $domain . '{1,63}\.)+' . $domain . '{2,63}$/i';
706
707      if (!preg_match($regex, $mail_address)) return false;
708      return true;
709    }
710  }
711}
712
713
714/**
715 * crypt a string using mcrypt extension or
716 * http://stackoverflow.com/questions/800922/how-to-encrypt-string-without-mcrypt-library-in-php/802957#802957
717 * @param: string value to crypt
718 * @param: string key
719 * @return: string
720 */
721function crypt_value($value, $key)
722{ 
723  if (extension_loaded('mcrypt'))
724  {
725    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
726    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
727    $result = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $value, MCRYPT_MODE_ECB, $iv);
728  }
729  else
730  {
731    $result = null;
732    for($i = 0; $i < strlen($value); $i++)
733    {
734      $char = substr($value, $i, 1);
735      $keychar = substr($key, ($i % strlen($key))-1, 1);
736      $char = chr(ord($char) + ord($keychar));
737      $result .= $char;
738    }
739  }
740 
741  $result = base64url_encode($result);
742  return trim($result); 
743}
744
745/**
746 * decrypt a string crypted with previous function
747 * @param: string value to decrypt
748 * @param: string key
749 * @return: string
750 */
751function decrypt_value($value, $key)
752{
753  $value = base64url_decode($value); 
754 
755  if (extension_loaded('mcrypt'))
756  {
757    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
758    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
759    $result = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $value, MCRYPT_MODE_ECB, $iv);
760  }
761  else
762  {
763    $result = null;
764    for($i = 0; $i < strlen($value); $i++)
765    {
766      $char = substr($value, $i, 1);
767      $keychar = substr($key, ($i % strlen($key))-1, 1);
768      $char = chr(ord($char) - ord($keychar));
769      $result .= $char;
770    }
771  }
772 
773  return trim($result);
774}
775
776/**
777 * variant of base64 functions usable into url
778 * http://php.net/manual/en/function.base64-encode.php#103849
779 */
780function base64url_encode($data)
781{
782  return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
783}
784function base64url_decode($data)
785{
786  return base64_decode(str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT));
787} 
788
789?>
Note: See TracBrowser for help on using the repository browser.