set_filename('stc_mail', realpath(SUBSCRIBE_TO_PATH . 'template/mail/notification.tpl')); foreach ($subscriptions as $row) { // get subscriber id if ( ($uid = get_userid_by_email($row['email'])) !== false ) { $row['user_id'] = $uid; } else { $row['user_id'] = $conf['guest_id']; } // check permissions if (!user_can_view_element($row['user_id'], $element_id, $element_type)) { continue; } // send mail switch_lang_to($row['language']); load_language('plugin.lang', SUBSCRIBE_TO_PATH); $comm['caption'] = sprintf('%s wrote on %s', $comm['author'], format_date(date('Y-m-d H:i:s'))); $template->assign('STC', array( 'element' => $element, 'comment' => $comm, 'UNSUB_URL' => make_stc_url('unsubscribe', $row['email'], $row['id']), 'MANAGE_URL' => make_stc_url('manage', $row['email']), 'GALLERY_TITLE' => $conf['gallery_title'], )); $content = $template->parse('stc_mail', true); stc_send_mail($row['email'], $content, $subject); switch_lang_back(); } load_language('plugin.lang', SUBSCRIBE_TO_PATH); unset_make_full_url(); } /** * add an email to subscribers list * @param: string email * @param: string type (image|album-images|all-images|album|all-albums) * @param: int element_id * @return: bool */ function subscribe_to_comments($email, $type, $element_id='NULL') { if (empty($type)) { trigger_error('subscribe_to_comment: missing type', E_USER_WARNING); return false; } if ( !in_array($type, array('all-images','all-albums')) and $element_id == 'NULL' ) { trigger_error('subscribe_to_comment: missing element_id', E_USER_WARNING); return false; } global $page, $conf, $user, $template, $picture; // check email if ( !empty($email) and !email_check_format($email) ) { array_push($page['errors'], l10n('mail address must be like xxx@yyy.eee (example : jack@altern.org)')); return false; } if ( ( is_a_guest() or empty($user['email']) ) and empty($email) ) { array_push($page['errors'], l10n('Invalid email adress, your are not subscribed to comments.')); return false; } else if ( !is_a_guest() and empty($email) ) { $email = $user['email']; } // search if already registered (can't use ODKU because we want to get the id of inserted OR updated row) $query = ' SELECT id FROM '.SUBSCRIBE_TO_TABLE.' WHERE type = "'.$type.'" AND element_id = '.$element_id.' AND email = "'.pwg_db_real_escape_string($email).'" ;'; $result = pwg_query($query); if (pwg_db_num_rows($result)) { list($inserted_id) = pwg_db_fetch_row($result); } else { $query = ' INSERT INTO '.SUBSCRIBE_TO_TABLE.'( type, element_id, language, email, registration_date, validated ) VALUES( "'.$type.'", '.$element_id.', "'.$user['language'].'", "'.pwg_db_real_escape_string($email).'", NOW(), "'.(is_a_guest() ? "false" : "true").'" ) ;'; pwg_query($query); $inserted_id = pwg_db_insert_id(); } // notify admins if ( pwg_db_changes() != 0 and $conf['Subscribe_to_Comments']['notify_admin_on_subscribe'] ) { stc_mail_notification_admins($email, $type, $element_id, $inserted_id); } // send validation mail if ( is_a_guest() and pwg_db_changes() != 0 ) { set_make_full_url(); $template->set_filename('stc_mail', realpath(SUBSCRIBE_TO_PATH . 'template/mail/confirm.tpl')); $subject = '['.strip_tags($conf['gallery_title']).'] '.l10n('Confirm your subscribtion to comments'); switch ($type) { case 'image': $element = get_picture_infos($element_id); $element['on'] = sprintf(l10n('the picture %s'), $element['url'], $element['name']); break; case 'album-images': $element = get_category_infos($element_id); $element['on'] = sprintf(l10n('all pictures of the album %s'), $element['url'], $element['name']); break; case 'all-images': $element['thumbnail'] = null; $element['on'] = l10n('all pictures of the gallery'); break; case 'album': $element = get_category_infos($element_id); $element['on'] = sprintf(l10n('the album %s'), $element['url'], $element['name']); break; case 'all-albums': $element['thumbnail'] = null; $element['on'] = l10n('all albums of the gallery'); break; } $template->assign('STC', array( 'element' => $element, 'VALIDATE_URL' => make_stc_url('validate', $email, $inserted_id), 'MANAGE_URL' => make_stc_url('manage', $email), 'GALLERY_TITLE' => $conf['gallery_title'], )); $content = $template->parse('stc_mail', true); stc_send_mail($email, $content, $subject); unset_make_full_url(); array_push($page['infos'], l10n('Please check your email inbox to confirm your subscription.')); return true; } // just display confirmation message else if (pwg_db_changes() != 0) { array_push($page['infos'], l10n('You have been added to the list of subscribers.')); return true; } return false; } /** * remove an email from subscribers list * @param: string email * @param: int subscription id * @return: bool */ function un_subscribe_to_comments($email, $id) { if ( !empty($email) and !email_check_format($email) ) { trigger_error('un_subscribe_to_comment: bad email', E_USER_WARNING); return false; } if (!preg_match('#^[0-9]+$#', $id)) { trigger_error('un_subscribe_to_comment: bad id', E_USER_WARNING); return false; } global $template, $user; // check email if ( ( is_a_guest() or empty($user['email']) ) and empty($email) ) { return false; } else if ( !is_a_guest() and empty($email) ) { $email = $user['email']; } // delete subscription $query = ' DELETE FROM '.SUBSCRIBE_TO_TABLE.' WHERE email = "'.pwg_db_real_escape_string($email).'" AND id = '.$id.' ;'; pwg_query($query); return (pwg_db_changes() != 0); } /** * validate a subscription * @param: string email * @param: int subscription id * @return: bool */ function validate_subscriptions($email, $id) { if (!email_check_format($email)) { trigger_error('validate_subscriptions: bad email', E_USER_WARNING); return false; } if (!preg_match('#^[0-9]+$#', $id)) { trigger_error('validate_subscriptions: bad id', E_USER_WARNING); return false; } $query = ' UPDATE '.SUBSCRIBE_TO_TABLE.' SET validated = "true" WHERE email = "'.pwg_db_real_escape_string($email).'" AND id = '.$id.' ;'; pwg_query($query); return (pwg_db_changes() != 0); } /** * send notification to admins * @param: string email * @param: string type (image|album-images|all-images|album|all-albums) * @param: int element_id * @param: int subscription id */ function stc_mail_notification_admins($email, $type, $element_id, $inserted_id) { global $user, $conf, $template; $admins = get_admins_email(); if (empty($admins)) return; set_make_full_url(); switch_lang_to(get_default_language()); load_language('plugin.lang', SUBSCRIBE_TO_PATH); $template->set_filename('stc_mail', realpath(SUBSCRIBE_TO_PATH . 'template/mail/admin.tpl')); $subject = '['.strip_tags($conf['gallery_title']).'] '.sprintf(l10n('%s has subscribed to comments on %s.'), is_a_guest()?$email:$user['username'], null); switch ($type) { case 'image': $element = get_picture_infos($element_id, false); $element['on'] = sprintf(l10n('the picture %s'), $element['url'], $element['name']); break; case 'album-images': $element = get_category_infos($element_id, false); $element['on'] = sprintf(l10n('all pictures of the album %s'), $element['url'], $element['name']); break; case 'all-images': $element['on'] = l10n('all pictures of the gallery'); break; case 'album': $element = get_category_infos($element_id, false); $element['on'] = sprintf(l10n('the album %s'), $element['url'], $element['name']); break; case 'all-albums': $element['on'] = l10n('all albums of the gallery'); break; } $technical_infos[] = sprintf(l10n('Connected user: %s'), stripslashes($user['username'])); $technical_infos[] = sprintf(l10n('IP: %s'), $_SERVER['REMOTE_ADDR']); $technical_infos[] = sprintf(l10n('Browser: %s'), $_SERVER['HTTP_USER_AGENT']); $template->assign('STC', array( 'ELEMENT' => $element['on'], 'USER' => is_a_guest() ? ''.$email.'' : ''.$user['username'].' ('.$email.')', 'GALLERY_TITLE' => $conf['gallery_title'], 'TECHNICAL' => implode('
', $technical_infos), )); $content = $template->parse('stc_mail', true); stc_send_mail($admins, $content, $subject); unset_make_full_url(); switch_lang_back(); load_language('plugin.lang', SUBSCRIBE_TO_PATH); } /** * create absolute url to subscriptions section * @param: string action * @param: string email * @param: int optional * @return: string */ function make_stc_url($action, $email, $id=null) { if ( empty($action) or empty($email) ) { trigger_error('make_stc_url: missing action and/or mail', E_USER_WARNING); return null; } global $conf; set_make_full_url(); $url_params = array( 'action' => $action, 'email' => $email, ); if (!empty($id)) { $url_params['id'] = $id; } $url_params['key'] = crypt_value( $action.$email.(isset($url_params['id'])?$url_params['id']:null), $conf['secret_key'] ); $url = add_url_params( make_index_url( array('section' => 'subscriptions') ), $url_params ); unset_make_full_url(); return $url; } /** * send mail with STC style * @param: string to * @param: string content * @param: string subject * @return: bool */ function stc_send_mail($to, $content, $subject) { global $conf, $conf_mail, $page, $template; // inputs if (empty($to)) { return false; } if (empty($content)) { return false; } if (empty($subject)) { $subject = 'Piwigo'; } else { $subject = trim(preg_replace('#[\n\r]+#s', '', $subject)); $subject = encode_mime_header($subject); } if (!isset($conf_mail)) { $conf_mail = get_mail_configuration(); } $args['from'] = $conf_mail['formated_email_webmaster']; set_make_full_url(); // hearders $headers = 'From: '.$args['from']."\n"; $headers.= 'MIME-Version: 1.0'."\n"; $headers.= 'X-Mailer: Piwigo Mailer'."\n"; $headers.= 'Content-Transfer-Encoding: 8bit'."\n"; $headers.= 'Content-Type: text/html; charset="'.get_pwg_charset().'";'."\n"; // template $template->set_filenames(array( 'stc_mail_header' => realpath(SUBSCRIBE_TO_PATH . 'template/mail/header.tpl'), 'stc_mail_footer' => realpath(SUBSCRIBE_TO_PATH . 'template/mail/footer.tpl'), )); $stc_mail_css = file_get_contents(realpath(SUBSCRIBE_TO_PATH . 'template/mail/style.css')); $template->assign(array( 'GALLERY_URL' => get_gallery_home_url(), 'PHPWG_URL' => PHPWG_URL, 'STC_MAIL_CSS' => str_replace("\n", null, $stc_mail_css), )); $content = $template->parse('stc_mail_header', true) . $content . $template->parse('stc_mail_footer', true); $content = wordwrap($content, 70, "\n", false); unset_make_full_url(); // send mail return trigger_event('send_mail', false, /* Result */ trigger_event('send_mail_to', get_strict_email_list($to)), trigger_event('send_mail_subject', $subject), trigger_event('send_mail_content', $content), trigger_event('send_mail_headers', $headers), $args ); } /** * get name, url and thumbnail of a picture * @param: int image_id * @param: bool return thumbnail * @return: array (id, name, url, thumbnail) */ function get_picture_infos($image_id, $with_thumb=true) { if (empty($image_id)) return array(); $query = ' SELECT id, file, name, path FROM '.IMAGES_TABLE.' WHERE id = '.$image_id.' ;'; $element = pwg_db_fetch_assoc(pwg_query($query)); if (empty($element['name'])) { $element['name'] = get_name_from_file($element['file']); } $element['name'] = trigger_event('render_element_name', $element['name']); $element['url'] = make_picture_url(array( 'image_id'=>$element['id'] )); if ($with_thumb) { $element['thumbnail'] = DerivativeImage::thumb_url($element); } return $element; } /** * get name, url and thumbnail of a category * @param: int cat_id * @param: int return thumbnail * @return: array (id, name, url, thumbnail) */ function get_category_infos($cat_id, $with_thumb=true, $user_id=null) { global $conf; if ($user_id===null) $user_id = $conf['guest_id']; $query = ' SELECT cat.id, cat.name, cat.permalink, ucc.count_images, cat.uppercats, img.id AS image_id, img.path FROM '.CATEGORIES_TABLE.' AS cat LEFT JOIN '.USER_CACHE_CATEGORIES_TABLE.' AS ucc ON ucc.cat_id = cat.id AND ucc.user_id = '.$user_id.' LEFT JOIN '.IMAGES_TABLE.' AS img ON img.id = ucc.user_representative_picture_id WHERE cat.id = '.$cat_id.' ;'; $element = pwg_db_fetch_assoc(pwg_query($query)); $element['url'] = make_index_url(array( 'section'=>'categories', 'category'=>$element, )); $element['name'] = trigger_event('render_category_name', $element['name']); if ($with_thumb) { if (empty($element['image_id']) and $conf['allow_random_representative']) { $image = get_picture_infos(get_random_image_in_category($element)); $element['thumbnail'] = $image['thumbnail']; } else { $element['thumbnail'] = DerivativeImage::thumb_url(array( 'id'=>$element['image_id'], 'path'=>$element['path'], )); } } return $element; } /** * get list of admins email * @return: string */ function get_admins_email() { global $conf, $user; $admins = array(); $query = ' SELECT u.'.$conf['user_fields']['username'].' AS username, u.'.$conf['user_fields']['email'].' AS email FROM '.USERS_TABLE.' AS u JOIN '.USER_INFOS_TABLE.' AS i ON i.user_id = u.'.$conf['user_fields']['id'].' WHERE i.status IN ("webmaster", "admin") AND '.$conf['user_fields']['email'].' IS NOT NULL AND i.user_id != '.$user['id'].' ORDER BY username ;'; $datas = pwg_query($query); if (!empty($datas)) { while ($admin = pwg_db_fetch_assoc($datas)) { array_push($admins, format_email($admin['username'], $admin['email'])); } } return implode(',', $admins); } /** * check if the given user can view the category/image * @param: int user_id * @param: int element_id * @param: string type (image|category) * @return: bool */ function user_can_view_element($user_id, $element_id, $type) { global $conf; $old_conf = $conf['external_authentification']; $conf['external_authentification'] = false; $user = getuserdata($user_id, true); $conf['external_authentification'] = $old_conf; if ($type == 'image') { return !in_array($element_id, explode(',', $user['image_access_list'])); } else if ($type == 'category') { return !in_array($element_id, explode(',', $user['forbidden_categories'])); } else { return false; } } /** * crypt a string using mcrypt extension or * http://stackoverflow.com/questions/800922/how-to-encrypt-string-without-mcrypt-library-in-php/802957#802957 * @param: string value to crypt * @param: string key * @return: string */ function crypt_value($value, $key) { if (extension_loaded('mcrypt')) { $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB); $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); $result = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $value, MCRYPT_MODE_ECB, $iv); } else { $result = null; for($i = 0; $i < strlen($value); $i++) { $char = substr($value, $i, 1); $keychar = substr($key, ($i % strlen($key))-1, 1); $char = chr(ord($char) + ord($keychar)); $result .= $char; } } $result = base64url_encode($result); return trim($result); } /** * decrypt a string crypted with previous function * @param: string value to decrypt * @param: string key * @return: string */ function decrypt_value($value, $key) { $value = base64url_decode($value); if (extension_loaded('mcrypt')) { $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB); $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); $result = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $value, MCRYPT_MODE_ECB, $iv); } else { $result = null; for($i = 0; $i < strlen($value); $i++) { $char = substr($value, $i, 1); $keychar = substr($key, ($i % strlen($key))-1, 1); $char = chr(ord($char) - ord($keychar)); $result .= $char; } } return trim($result); } /** * variant of base64 functions usable into url * http://php.net/manual/en/function.base64-encode.php#103849 */ function base64url_encode($data) { return rtrim(strtr(base64_encode($data), '+/', '-_'), '='); } function base64url_decode($data) { return base64_decode(str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT)); } ?>