<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
* Основные функции MaxSite CMS
* (c) https://max-3000.com/
* Функции для комментариев
*/
// функция получения комментариев
function mso_get_comments($page_id = 0, $r = [])
{
global /*$MSO,*/ $page;
$r = mso_hook('mso_get_comments_args', $r);
if (!isset($r['limit'])) $r['limit'] = false;
if (!isset($r['order'])) $r['order'] = 'asc';
if (!isset($r['tags'])) $r['tags'] = '<p><img><strong><em><i><b><u><s><pre><code><blockquote>';
if (!isset($r['tags_users'])) $r['tags_users'] = '<a><p><img><strong><em><i><b><u><s><pre><code><blockquote>';
if (!isset($r['tags_comusers'])) $r['tags_comusers'] = '<a><p><img><strong><em><i><b><u><s><pre><code><blockquote>';
if (!isset($r['anonim_comments'])) $r['anonim_comments'] = [];
if (!isset($r['anonim_title'])) $r['anonim_title'] = ''; // ' ('. t('анонимно'). ')'; // дописка к имени для анонимов
if (!isset($r['anonim_no_name'])) $r['anonim_no_name'] = tf('Аноним'); // Если не указано имя анонима
// если аноним указывает имя с @, то это страница в твиттере - делаем ссылку
if (!isset($r['anonim_twitter'])) $r['anonim_twitter'] = true;
// дописка к имени для комментаторов без ника
if (!isset($r['add_author_name'])) $r['add_author_name'] = tf('Комментатор');
$CI = &get_instance();
// получим список всех комюзеров, где посдчитается количество их комментариев
$all_comusers = mso_comuser_update_count_comment();
$CI->db->select('page.page_id, page.page_slug, page.page_title, comments.*,
users.users_id,
users.users_nik,
users.users_count_comments,
users.users_url,
users.users_email,
users.users_avatar_url,
comusers.comusers_id,
comusers.comusers_nik,
comusers.comusers_count_comments,
comusers.comusers_allow_publish,
comusers.comusers_email,
comusers.comusers_avatar_url,
comusers.comusers_url
');
if ($page_id) $CI->db->where('page.page_id', $page_id);
// если нет анономого коммента, то вводим условие на comments_approved=1 - только разрешенные
if (!$r['anonim_comments']) {
$CI->db->where('comments.comments_approved', '1');
} else {
// есть массив с указанными комментариям - они выводятся отдельно
$CI->db->where('comments.comments_approved', '0');
$CI->db->where_in('comments.comments_id', $r['anonim_comments']);
}
// вот эти два join жутко валят мускуль...
// пока решение не найдено, все запросы к комментам следует кэшировать на уровне плагина
$CI->db->join('users', 'users.users_id = comments.comments_users_id', 'left');
$CI->db->join('comusers', 'comusers.comusers_id = comments.comments_comusers_id', 'left');
// вручную делаем этот where, потому что CodeIgniter его неверно экранирует
$CI->db->where($CI->db->dbprefix . 'page.page_id', $CI->db->dbprefix . 'comments.comments_page_id', false);
// для private-записей комментарии разрешаем
if (isset($page['page_status']) and $page['page_status'] === 'private')
$CI->db->where('page.page_status', 'private');
else
$CI->db->where('page.page_status', 'publish');
$CI->db->order_by('comments.comments_date', $r['order']);
if ($r['limit']) $CI->db->limit($r['limit']);
$CI->db->from('comments, page');
$query = $CI->db->get();
if ($query->num_rows() > 0) {
$comments = $query->result_array();
foreach ($comments as $key => $comment) {
$commentator = 3; // комментатор: 1-комюзер 2-автор 3-аноним
if ($comment['comusers_id']) {
// это комюзер
if ($comment['comusers_nik'])
$comment['comments_author_name'] = $comment['comusers_nik'];
else
$comment['comments_author_name'] = $r['add_author_name'] . ' ' . $comment['comusers_id'];
$comment['comments_url'] = '<a href="' . getinfo('siteurl') . 'users/' . $comment['comusers_id'] . '">' . $comment['comments_author_name'] . '</a>';
// есть адрес страницы
if ($comment['comusers_url']) {
// зачистка XSS
$comments[$key]['comusers_url'] = mso_xss_clean($comment['comusers_url'], '');
}
// зачистка XSS комюзер имя
if ($comment['comusers_nik']) {
$comments[$key]['comusers_nik'] = mso_xss_clean($comment['comusers_nik']);
}
$commentator = 1;
if (isset($all_comusers[$comment['comusers_id']]))
$comments[$key]['comusers_count_comments'] = $all_comusers[$comment['comusers_id']];
} elseif ($comment['users_id']) // это автор
{
if ($comment['users_url'])
$comment['comments_url'] = '<a href="' . $comment['users_url'] . '">' . $comment['users_nik'] . '</a>';
else
$comment['comments_url'] = $comment['users_nik'];
$commentator = 2;
} else // просто аноним
{
if (!$comment['comments_author_name']) $comment['comments_author_name'] = $r['anonim_no_name'];
if ($r['anonim_twitter']) {
// разрешено проверять это твиттер-логин?
if (strpos($comment['comments_author_name'], '@') === 0) {
// первый символ @
$lt = mso_slug(substr($comment['comments_author_name'], 1)); // вычленим @
$lt = mso_xss_clean($lt, 'Error', $lt, true); // зачистка XSS
$comment['comments_url'] = '<a href="https://twitter.com/' . $lt . '" rel="nofollow">@' . $lt . '</a>';
} else {
$comment['comments_url'] = $comment['comments_author_name'] . $r['anonim_title'];
}
} else {
$comment['comments_url'] = $comment['comments_author_name'] . $r['anonim_title'];
}
}
$comments_content = $comment['comments_content'];
if (mso_hook_present('comments_content_custom'))
$comments_content = mso_hook('comments_content_custom', $comments_content);
else
$comments_content = mso_comments_autotag($comments_content, $commentator, $r);
$comments_content = mso_hook('comments_content_out', $comments_content);
$comments[$key]['comments_content'] = $comments_content;
$comments[$key]['comments_url'] = $comment['comments_url'];
}
} else
$comments = [];
return $comments;
}
// парсер текста для комментариев
function mso_comments_autotag($text, $commentator = 3, $r = ['tags' => '<p><img><strong><em><i><b><u><s><pre><code><blockquote>', 'tags_comusers' => '<p><img><strong><em><i><b><u><s><pre><code><blockquote>', 'tags_users' => '<p><img><strong><em><i><b><u><s><pre><code><blockquote>'])
{
// раньше использовался mso_auto_tag теперь свой вариант
if ($commentator == 1)
$text = strip_tags($text, $r['tags_comusers']);
elseif ($commentator == 2)
$text = strip_tags($text, $r['tags_users']);
else
$text = strip_tags($text, $r['tags']);
$text = mso_comments_content($text);
$text = mso_hook('comments_content', $text);
return $text;
}
// обработка через парсер parser_default
function mso_comments_content($text = '')
{
// текст комментария прогоняется через стандартный парсер
if (!function_exists('parser_default_content')) {
require_once getinfo('plugins_dir') . 'parser_default/index.php';
}
$text = str_replace("\n", "<br>", $text); // обязательная замена
$text = parser_default_content($text);
$text = mso_hook('comments_content_out', $text);
return $text;
}
// функция отправляет админу уведомление о новом комментарии
// первый парметр id, второй данные текст и т.д.
function mso_email_message_new_comment($id = 0, $data = [], $page_title = '')
{
$data['page_title'] = $page_title; // заголовок страницы
$data['id'] = $id; // номер комментария
$data['comments_content'] = mso_xss_clean($data['comments_content']);
// хук на который можно повесить подписку на новые комментарии
mso_hook('mso_email_message_new_comment', $data);
// рассылаем комментарий всем, кто на него подписан
mso_email_message_new_comment_subscribe($data);
// После рассылки смотрим, какие уведомления мы хотим получать.
$level = mso_get_option('email_comments_level', 'general', 1);
$return = false; //А это потому, что пых не понимает return false; внутри кейсов.
switch ($level) {
case 6:
$return = true;
break; // Ни от кого.
case 5:
if ($data['comments_approved']) $return = true;
break; // Требующий модерации
case 4:
if ((array_key_exists('comments_users_id', $data) or array_key_exists('comments_comusers_id', $data))) $return = true;
break;
case 3:
if (!array_key_exists('comments_comusers_id', $data)) $return = true;
break; // От комментаторов
case 2:
if (array_key_exists('comments_users_id', $data)) $return = true;
break; // От всех кроме юзеров
case 1:
break; // От всех
}
if ($return) return false;
$email = mso_get_option('comments_email', 'general', false); // email куда приходят уведомления
// если не задан, отдельный email, то берём email администратора.
if (!$email) $email = mso_get_option('admin_email', 'general', false);
if (!$email) return false;
$CI = &get_instance();
if (!$data['comments_approved']) // нужно промодерировать
$subject = '[' . getinfo('name_site') . '] ' . '(-) ' . tf('Новый комментарий') . ' (' . $id . ') "' . $page_title . '"';
else
$subject = '[' . getinfo('name_site') . '] ' . tf('Новый комментарий') . ' (' . $id . ') "' . $page_title . '"';
// не посылаем уведомление о своём комментарии если нет специальной опции
if (!mso_get_option('subscribe_message_my_comment', 'general', true) && isset($data['comments_users_id']) && $data['comments_users_id'] == getinfo('users_id')) return false;
// шаблон уведомления
$def_option = 'Новый комментарий на "{{ $page_title }}"
{{ $comment_url }}
{% if (!$comments_approved) : %}
Комментарий требует модерации: {{ $edit_link }}
{% endif %}
Автор IP: {{ $comment_ip }}
Referer: {{ $comment_referer }}
Дата: {{ $comment_date }}
{% if ($user) : %}
Пользователь: {{ $user_id }}
{% endif %}
{% if ($comuser) : %}
Комюзер: id={{ $comuser_id }}, ник: {{ $comuser_nik }}, email: {{ $comuser_email }}
Профиль: {{ $comuser_url }}
{% endif %}
{% if ($anonim) : %}
Аноним: {{ $anonim }}
{% endif %}
Текст:
{{ $comment_content }}
Администрировать комментарий вы можете по ссылке:
{{ $edit_link }}
';
$template = mso_get_option('template_email_message_new_comment', 'general', $def_option);
$comment_url = mso_get_permalink_page($data['comments_page_id']) . '#comment-' . $id;
$comments_approved = $data['comments_approved'];
$comment_ip = $data['comments_author_ip'];
$comment_referer = mso_clean_str($_SERVER['HTTP_REFERER'], 'xss');
$comment_date = $data['comments_date'];
$user = $comuser = $anonim = false;
if (isset($data['comments_users_id'])) {
$user = true;
$user_id = $data['comments_users_id'];
}
if (isset($data['comments_comusers_id'])) {
$comuser = true;
$comuser_id = $data['comments_comusers_id'];
$CI->db->select('comusers_nik, comusers_email');
$CI->db->from('comusers');
$CI->db->where('comusers_id', $data['comments_comusers_id']);
$query = $CI->db->get();
if ($query->num_rows() > 0) {
$comusers = $query->row();
$comuser_nik = $comusers->comusers_nik;
$comuser_email = $comusers->comusers_email;
$comuser_url = getinfo('siteurl') . 'users/' . $data['comments_comusers_id'];
}
}
if (isset($data['comments_author_name'])) {
$anonim = $data['comments_author_name'];
}
$comment_content = $data['comments_content'];
$edit_link = getinfo('site_admin_url') . 'comments/edit/' . $id;
$template = mso_tmpl_prepare($template, false);
ob_start();
eval($template);
$text = ob_get_contents();
ob_end_clean();
// Чтобы плагин smtp_mail точно знал, что ему подсунули коммент, а не вычислял это по subject
$data = array_merge($data, ['comment' => true]);
// А зная о комментарии, он сможет сотворить некоторые бонусы.
return mso_mail($email, $subject, $text, false, $data);
}
// функция отправляет новому комюзеру уведомление о новой регистрации
// первый параметр id, второй данные
// третий - если это автоматическая активация и подтверждение не требуется
function mso_email_message_new_comuser($comusers_id = 0, $ins_data = [], $comusers_activate_auto = false)
{
$email = $ins_data['comusers_email']; // email куда приходят уведомления
if (!$email) return false;
// comusers_password
// comusers_activate_key
$subject = tf('Регистрация на ') . getinfo('title');
// шаблон уведомления
$def_option = '{% if ($activate_auto) : %}
Спасибо за регистрацию на сайте "{{ $name_site }}" — {{ $site_url }}
Ваша страница:
{{ $comuser_url }}
Ваш код активации:
{{ $activate_key }}
Сохраните это письмо, поскольку код активации может понадобиться для смены пароля.
{% else: %}
Вы или кто-то еще зарегистрировал ваш адрес на сайте "{{ $name_site }}" — {{ $site_url }}
Если это действительно сделали вы, то вам нужно подтвердить эту регистрацию. Для этого следует пройти по ссылке:
{{ $comuser_url }}
И ввести следующий код для активации:
{{ $activate_key }}
(Сохраните это письмо, поскольку код активации может понадобиться для смены пароля.)
Если же регистрацию выполнили не вы, то просто удалите это письмо.
{% endif %}
';
$template = mso_get_option('template_email_message_new_comuser', 'general', $def_option);
$activate_auto = $comusers_activate_auto;
$name_site = getinfo('name_site');
$site_url = getinfo('siteurl');
$comuser_url = getinfo('siteurl') . 'users/' . $comusers_id;
$activate_key = $ins_data['comusers_activate_key'];
$template = mso_tmpl_prepare($template, false);
ob_start();
eval($template);
$text = ob_get_contents();
ob_end_clean();
return mso_mail($email, $subject, $text, $email); // поскольку это регистрация, то отправитель - тот же email
}
// функция добавляет новый коммент и выводит сообщение о результате
function mso_get_new_comment($args = [])
{
global $MSO;
$args = mso_hook('mso_get_new_comment_args', $args);
if ($post = mso_check_post(array('comments_session', 'comments_submit', 'comments_page_id', 'comments_content'))) {
// mso_checkreferer(); // если нужно проверять на реферер
$CI = &get_instance();
// заголовок страницы
if (!isset($args['page_title'])) $args['page_title'] = '';
// стили
if (!isset($args['css_ok'])) $args['css_ok'] = 'comment-ok';
if (!isset($args['css_error'])) $args['css_error'] = 'comment-error';
// разрешенные тэги
if (!isset($args['tags'])) $args['tags'] = '<p><blockquote><br><span><strong><strong><em><i><b><u><s><pre><code>';
// обрабатывать текст на xss-атаку
if (!isset($args['xss_clean'])) $args['xss_clean'] = true;
// если найдена xss-атака, то не публиковать комментарий
if (!isset($args['xss_clean_die'])) $args['xss_clean_die'] = false;
// запрещенные слова как имя автора
if (!isset($args['noword']))
$args['noword'] = [
'.com', '.ru', '.net', '.org', '.info', '.ua',
'.su', '.name', '/', 'www.', 'http', ':', '-', '"',
'«', '»', '%', '<', '>', '&', '*', '+', '\''
];
mso_hook('add_new_comment');
if (!mso_checksession($post['comments_session']))
return '<div class="' . $args['css_error'] . '">' . tf('Ошибка сессии! Обновите страницу') . '</div>';
if (!$post['comments_page_id'])
return '<div class="' . $args['css_error'] . '">' . tf('Ошибка!') . '</div>';
$comments_page_id = $post['comments_page_id'];
$id = (int) $comments_page_id;
if ((string) $comments_page_id != (string) $id) $id = false; // $comments_page_id не число
if (!$id) return '<div class="' . $args['css_error'] . '">' . tf('Ошибка!') . '</div>';
// капчу проверим
// если этот хук возвращает false, значит капча неверная
if (!mso_hook('comments_new_captcha', true)) {
// если определен хук на неверную капчу, отдаем его
if (mso_hook_present('comments_new_captcha_error')) {
return mso_hook('comments_new_captcha_error');
} else {
return '<div class="' . $args['css_error'] . '">' . tf('Ошибка! Неверно введены нижние символы!') . '</div>';
}
}
// вычищаем от запрещенных тэгов
if ($args['tags']) {
$t = $post['comments_content'];
$t = strip_tags($t, $args['tags']); // оставим только разрешенные тэги
$post['comments_content'] = $t; // сохраним как текст комментария
}
// если указано рубить коммент при обнаруженной xss-атаке
if ($args['xss_clean_die'] and mso_xss_clean($post['comments_content'], true, false) === true) {
return '<div class="' . $args['css_error'] . '">' . tf('Обнаружена XSS-атака!') . '</div>';
}
if (!trim($post['comments_content']))
return '<div class="' . $args['css_error'] . '">' . tf('Ошибка, нет текста!') . '</div>';
// возможно есть текст, но только из одних html - не пускаем
if (!trim(strip_tags(trim($post['comments_content']))))
return '<div class="' . $args['css_error'] . '">' . tf('Ошибка, нет полезного текста!') . '</div>';
// вычищаем текст от xss
if ($args['xss_clean']) {
$post['comments_content'] = mso_xss_clean($post['comments_content']);
// проставим pre исправление ошибки CodeIgniter
$post['comments_content'] = str_replace('</pre>', '</pre>', $post['comments_content']);
}
$comments_author_ip = $_SERVER['REMOTE_ADDR'];
$comments_date = date('Y-m-d H:i:s');
$comments_content = mso_hook('new_comments_content', $post['comments_content']);
// есть дли родитель у комментария
$comments_parent_id = $post['comments_parent_id'] ?? '0';
// провека на спам - проверим через хук new_comments_check_spam
$comments_check_spam = mso_hook(
'new_comments_check_spam',
[
'comments_content' => $comments_content,
'comments_date' => $comments_date,
'comments_author_ip' => $comments_author_ip,
'comments_page_id' => $comments_page_id,
'comments_server' => $_SERVER,
'comments_parent_id' => $comments_parent_id,
'comments_author' => $post['comments_author'] ?? false,
'comments_email' => $post['comments_email'] ?? false,
'comusers_email' => $post['comusers_email'] ?? false,
'comments_user_id' => $post['comments_user_id'] ?? false,
'comments_comusers_nik' => $post['comments_comusers_nik'] ?? false,
'comments_comusers_url' => $post['comments_comusers_url'] ?? false,
],
false
);
// если есть спам, то возвращается что-то отличное от comments_content
// если спама нет, то должно вернуться false
// если есть подозрения, то возвращается массив с moderation (comments_approved)
// если есть параметр check_spam=true, значит определен спам и он вообще не пускается
// сообщение для вывода в парметре 'message'
// разрешение антиспама moderation
// -1 - не определено, 0 - можно разрешить, 1 - отдать на модерацию
$moderation = -1;
if ($comments_check_spam) {
if (isset($comments_check_spam['check_spam']) and $comments_check_spam['check_spam'] == true) {
if (isset($comments_check_spam['message']) and $comments_check_spam['message'])
return '<div class="' . $args['css_error'] . '">' . $comments_check_spam['message'] . '</div>';
else
return '<div class="' . $args['css_error'] . '">' . tf('Ваш комментарий определен как спам и удален.') . '</div>';
} else {
// спам не определен, но возможно стоит moderation - принудительная модерация
if (isset($comments_check_spam['moderation'])) $moderation = $comments_check_spam['moderation'];
}
}
// проверим есть ли уже такой комментарий
// проверка по ip и тексту
$CI->db->select('comments_id');
$CI->db->where([
'comments_page_id' => $comments_page_id,
'comments_author_ip' => $comments_author_ip,
'comments_content' => $comments_content,
]);
$query = $CI->db->get('comments');
if ($query->num_rows()) {
return '<div class="' . $args['css_error'] . '">' . tf('Похоже, вы уже отправили этот комментарий...') . '</div>';
}
if (is_login()) {
// коммент от автора
$comments_users_id = $MSO->data['session']['users_id'];
$ins_data = array(
'comments_users_id' => $comments_users_id,
'comments_page_id' => $comments_page_id,
'comments_author_ip' => $comments_author_ip,
'comments_date' => $comments_date,
'comments_content' => $comments_content,
'comments_parent_id' => $comments_parent_id,
'comments_approved' => 1, // авторы могут сразу публиковать комменты без модерации
'comments_author_name' => '',
);
$res = ($CI->db->insert('comments', $ins_data)) ? '1' : '0';
if ($res) {
$id_comment_new = $CI->db->insert_id();
mso_email_message_new_comment($id_comment_new, $ins_data, $args['page_title']);
mso_flush_cache();
$CI->db->cache_delete_all();
mso_hook('new_comment');
mso_redirect(mso_current_url() . '#comment-' . $id_comment_new);
} else {
return '<div class="' . $args['css_error'] . '">' . tf('Ошибка добавления комментария') . '</div>';
}
} else {
if (isset($post['comments_reg'])) {
// комюзер или аноном
if ($post['comments_reg'] == 'reg') {
// нужно зарегистрировать или уже есть регистрация
// проверим есть ли разршение на комментарии от комюзеров
// для случаев подделки post-запроса
if (!mso_get_option('allow_comment_comusers', 'general', '1'))
return '<div class="' . $args['css_error'] . '">' . tf('Error allow_comment_comusers') . '</div>';
if (!isset($post['comments_email']) or !$post['comments_email'])
return '<div class="' . $args['css_error'] . '">' . tf('Нужно указать Email') . '</div>';
if (!isset($post['comments_password']) or !$post['comments_password'])
return '<div class="' . $args['css_error'] . '">' . tf('Нужно указать пароль') . '</div>';
$comments_email = mso_strip($post['comments_email']);
$comments_password = mso_strip($post['comments_password']);
if (!mso_valid_email($comments_email))
return '<div class="' . $args['css_error'] . '">' . tf('Ошибочный Email') . '</div>';
// проверим время последнего комментария чтобы не очень часто
if (!mso_last_activity_comment())
return '<div class="' . $args['css_error'] . '">' . tf('Слишком частые комментарии. Попробуйте позже.') . '</div>';
// вначале нужно зарегистрировать comюзера - получить его id и только после этого добавить сам коммент
// но вначале есть смысл проверить есть ли такой ком-пользователь
$comusers_id = false;
$CI->db->select('comusers_id, comusers_password');
$CI->db->where('comusers_email', $comments_email);
$query = $CI->db->get('comusers');
if ($query->num_rows()) {
// есть такой комюзер
$row = $query->row_array(1);
// пароль не нужно шифровать mso_md5
if (isset($post['comments_password_md']) and $post['comments_password_md']) {
if ($row['comusers_password'] != $comments_password) // пароль неверный
return '<div class="' . $args['css_error'] . '">' . tf('Неверный пароль') . '</div>';
} else {
if ($row['comusers_password'] != mso_md5($comments_password)) // пароль неверный
return '<div class="' . $args['css_error'] . '">' . tf('Неверный пароль') . '</div>';
}
$comusers_id = $row['comusers_id']; // получаем номер комюзера
} else {
// такого комюзера нет
$ins_data = array(
'comusers_email' => $comments_email,
'comusers_password' => mso_md5($comments_password)
);
// генерируем случайный ключ активации
$ins_data['comusers_activate_key'] = mso_md5(rand());
$ins_data['comusers_date_registr'] = date('Y-m-d H:i:s');
$ins_data['comusers_last_visit'] = date('Y-m-d H:i:s');
$ins_data['comusers_ip_register'] = $_SERVER['REMOTE_ADDR'];
$ins_data['comusers_notify'] = '1'; // сразу включаем подписку на уведомления
// если сразу отправлен адрес ссайта
if (isset($post['comments_comusers_url']) and $post['comments_comusers_url']) {
$comusers_url = htmlspecialchars(mso_xss_clean(strip_tags($post['comments_comusers_url'])));
// if (strpos($comusers_url, 'http://') === false) $comusers_url = 'http://' . $comusers_url;
if ($comusers_url) $ins_data['comusers_url'] = $comusers_url;
}
// если сразу отправлен ник
if (isset($post['comments_comusers_nik']) and $post['comments_comusers_nik']) {
$ins_data['comusers_nik'] = htmlspecialchars(mso_xss_clean(strip_tags($post['comments_comusers_nik'])));
}
// Автоматическая активация новых комюзеров
// если активация стоит автоматом, то сразу её и прописываем
if (mso_get_option('comusers_activate_auto', 'general', '0'))
$ins_data['comusers_activate_string'] = $ins_data['comusers_activate_key'];
$res = ($CI->db->insert('comusers', $ins_data)) ? '1' : '0';
if ($res) {
// сохраним в сессии время отправления комментария - используется в mso_last_activity_comment
$CI->session->set_userdata('last_activity_comment', time());
$comusers_id = $CI->db->insert_id(); // номер добавленной записи
// нужно добавить опцию в мета «новые комментарии, где я участвую» subscribe_my_comments
// вначале грохаем если есть такой ключ
$CI->db->where('meta_table', 'comusers');
$CI->db->where('meta_id_obj', $comusers_id);
$CI->db->where('meta_key', 'subscribe_my_comments');
$CI->db->delete('meta');
// теперь добавляем как новый
$ins_data2 = array(
'meta_table' => 'comusers',
'meta_id_obj' => $comusers_id,
'meta_key' => 'subscribe_my_comments',
'meta_value' => '1'
);
$CI->db->insert('meta', $ins_data2);
// почему CodeIgniter не может так?
// INSERT INTO table SET column = 1, id=1 ON DUPLICATE KEY UPDATE column = 2
// отправляем ему уведомление с кодом активации
mso_email_message_new_comuser($comusers_id, $ins_data, mso_get_option('comusers_activate_auto', 'general', '0'));
mso_flush_cache();
$CI->db->cache_delete_all();
} else {
return '<div class="' . $args['css_error'] . '">' . tf('Ошибка регистрации') . '</div>';
}
}
if ($comusers_id) {
// Модерация комюзеров 1 - модерировать
$comments_com_approved = mso_get_option('new_comment_comuser_moderate', 'general', 1);
// если включена модерация комюзеров
// и включена опция только первого комментария
// то получаем кол-во комментариев комюзера
if ($comments_com_approved and mso_get_option('new_comment_comuser_moderate_first_comment', 'general', 0)) {
$all_comusers = mso_comuser_update_count_comment(); // список комюзер => колво комментов
// есть такой комюзер и у него более 1 комментария
if (isset($all_comusers[$comusers_id]) and $all_comusers[$comusers_id] > 0)
$comments_com_approved = 0; // разрешаем публикацию
}
// но у нас в базе хранится значение наоборот - 1 разрешить 0 - запретить
$comments_com_approved = !$comments_com_approved;
if ($moderation == 1) $comments_com_approved = 0; // антиспам определил, что нужно премодерировать
if ($comments_com_approved == 1) {
// если разрешено
$comments_com_approved = mso_hook(
'new_comments_check_spam_comusers',
[
'comments_page_id' => $comments_page_id,
'comments_comusers_id' => $comusers_id,
'comments_com_approved' => $comments_com_approved,
],
1
);
}
// комюзер добавлен или есть
// теперь сам коммент
$ins_data = [
'comments_page_id' => $comments_page_id,
'comments_comusers_id' => $comusers_id,
'comments_author_ip' => $comments_author_ip,
'comments_date' => $comments_date,
'comments_content' => $comments_content,
'comments_approved' => $comments_com_approved,
'comments_parent_id' => $comments_parent_id,
'comments_author_name' => '',
];
// проверим время последнего комментария чтобы не очень часто
if (!mso_last_activity_comment())
return '<div class="' . $args['css_error'] . '">' . tf('Слишком частые комментарии. Попробуйте позже.') . '</div>';
$res = ($CI->db->insert('comments', $ins_data)) ? '1' : '0';
if ($res) {
// сохраним в сессии время отправления комментария - используется в mso_last_activity_comment
$CI->session->set_userdata('last_activity_comment', time());
$id_comment_new = $CI->db->insert_id();
// посколько у нас идет редирект, то данные об отправленном комменте
// сохраняем в сессии номер комментария
if (isset($MSO->data['session'])) {
$CI->session->set_userdata(array('comments' =>
array(
// $CI->db->insert_id()=>$comments_page_id
$id_comment_new
)));
}
mso_email_message_new_comment($id_comment_new, $ins_data, $args['page_title']);
mso_flush_cache();
$CI->db->cache_delete_all();
mso_hook('new_comment');
// если комюзер не залогинен, то сразу логиним его
$CI->db->select('comusers_id, comusers_password, comusers_email,
comusers_nik, comusers_url, comusers_avatar_url, comusers_last_visit');
$CI->db->where('comusers_email', $comments_email);
$CI->db->where('comusers_password', mso_md5($comments_password));
$query = $CI->db->get('comusers');
if ($query->num_rows()) {
// есть такой комюзер
$comuser_info = $query->row_array(1); // вся инфа о комюзере
// сразу же обновим поле последнего входа
$CI->db->where('comusers_id', $comuser_info['comusers_id']);
$CI->db->update('comusers', array('comusers_last_visit' => date('Y-m-d H:i:s')));
$expire = time() + 60 * 60 * 24 * 30; // 30 дней = 2592000 секунд
$name_cookies = 'maxsite_comuser';
$value = serialize($comuser_info);
$value = mso_de_code($value, 'encode'); // кодируем данные
// ставим куку и редиректимся автоматом
mso_add_to_cookie(
$name_cookies,
$value,
$expire,
mso_current_url(true) . '#comment-' . $id_comment_new
);
exit;
}
mso_redirect(mso_current_url() . '#comment-' . $id_comment_new);
} else {
return '<div class="' . $args['css_error'] . '">' . tf('Ошибка добавления комментария') . '</div>';
}
}
} elseif ($post['comments_reg'] == 'noreg') {
// комментарий от анонима
// проверим есть ли разрешение на комментарии от анонимов
// для случаев подделки post-запроса
if (!mso_get_option('allow_comment_anonim', 'general', '1'))
return '<div class="' . $args['css_error'] . '">' . tf('Error allow_comment_anonim') . '</div>';
// проверим время последнего комментария чтобы не очень часто
if (!mso_last_activity_comment())
return '<div class="' . $args['css_error'] . '">' . tf('Слишком частые комментарии. Попробуйте позже.') . '</div>';
if (isset($post['comments_author'])) {
$comments_author_name = mso_strip($post['comments_author']);
$comments_author_name = str_replace($args['noword'], '', $comments_author_name);
$comments_author_name = htmlspecialchars(trim($comments_author_name));
if (!$comments_author_name) $comments_author_name = tf('Аноним');
} else {
$comments_author_name = 'Аноним';
}
// можно ли публиковать без модерации?
$comments_approved = mso_get_option('new_comment_anonim_moderate', 'general', 1);
// но у нас в базе хранится значение наоборот - 1 разрешить 0 - запретить
$comments_approved = !$comments_approved;
if ($moderation == 1) $comments_approved = 0; // антиспам определил, что нужно премодерировать
$ins_data = array(
'comments_page_id' => $comments_page_id,
'comments_author_name' => $comments_author_name,
'comments_author_ip' => $comments_author_ip,
'comments_date' => $comments_date,
'comments_content' => $comments_content,
'comments_approved' => $comments_approved,
'comments_parent_id' => $comments_parent_id,
);
$res = ($CI->db->insert('comments', $ins_data)) ? '1' : '0';
if ($res) {
$id_comment_new = $CI->db->insert_id();
// сохраним в сессии время отправления комментария - используется в mso_last_activity_comment
$CI->session->set_userdata('last_activity_comment', time());
// посколько у нас идет редирект, то данные об отправленном комменте
// сохраняем в сессии номер комментария
if (isset($MSO->data['session'])) {
$CI->session->set_userdata(array('comments' =>
array(
// $CI->db->insert_id()=>$comments_page_id
$id_comment_new
)));
}
mso_email_message_new_comment($id_comment_new, $ins_data, $args['page_title']);
mso_flush_cache();
$CI->db->cache_delete_all();
mso_hook('new_comment');
mso_redirect(mso_current_url() . '#comment-' . $id_comment_new);
} else {
return '<div class="' . $args['css_error'] . '">' . tf('Ошибка добавления комментария') . '</div>';
}
}
}
}
}
}
// получаем данные комюзера.
// если id = 0, то номер получаем из сессии или текущего сегмента (2)
function mso_get_comuser($id = 0, $args = [])
{
global $MSO;
if (!$id) {
// не указан id, получаем его из сессии
if (isset($MSO->data['session']['comuser']) and $MSO->data['session']['comuser'])
$id = $MSO->data['session']['comuser']['comusers_id'];
else
$id = mso_segment(2); // или сегмент в url
}
if (!$id) return []; // нет номера, выходим
if (!is_numeric($id)) return []; // если id указан не номером, выходим
if (!isset($args['limit'])) $args['limit'] = 20;
if (!isset($args['tags'])) $args['tags'] = '<p><img><strong><em><i><b><u><s><font><pre><code><blockquote>';
if (!isset($args['order'])) $args['order'] = 'comments_date';
if (!isset($args['asc'])) $args['asc'] = 'desc';
$CI = &get_instance();
$CI->db->select('comusers.*, COUNT(comments_comusers_id) as comusers_count_comment_real');
$CI->db->from('comusers');
$CI->db->where('comusers_id', $id);
$CI->db->limit(1);
// отдавать все комменты, включая и неотмодерированные
//$CI->db->where('comments.comments_approved', '1');
$CI->db->join('comments', 'comusers.comusers_id = comments.comments_comusers_id', 'left');
$CI->db->group_by('comments_comusers_id');
$query = $CI->db->get();
if ($query->num_rows() > 0) {
$comuser = $query->result_array(); // данные комюзера
$comuser_count_comment_first = $comuser[0]['comusers_count_comments']; // первоначальное значание колво комментариев
// подсоединим к нему [comments] - все его комментарии
$CI->db->select('comments.*, page.page_id, page.page_title, page.page_slug');
$CI->db->from('comments');
$CI->db->where('comments_comusers_id', $id);
// $CI->db->where('page.page_status', 'publish');
// $CI->db->where('page_date_publish <', date('Y-m-d H:i:s'));
$CI->db->where('comments.comments_approved', '1');
$CI->db->join('page', 'page.page_id = comments.comments_page_id');
$CI->db->order_by('comments_date', $args['asc']);
if ($args['limit']) $CI->db->limit($args['limit']);
$query = $CI->db->get();
$comments = []; // все комменты
if ($query->num_rows() > 0) {
// нужно обработать тексты комментариев на предмет всяких хуков и лишних тэгов
$comments = $query->result_array();
foreach ($comments as $key => $comment) {
$comments[$key]['comments_content'] = mso_comments_content($comment['comments_content']);
}
$comuser[0]['comments'] = $comments;
// $comuser[0]['comments'] = $query->result_array();
$comuser[0]['comusers_count_comments'] = count($comments);
} else {
$comuser[0]['comments'] = [];
}
// колво комментариев не совпадает с реальным - нужно обновить
if ($comuser_count_comment_first != count($comments)) {
mso_comuser_set_count_comment($id, count($comments));
}
// в секцию meta добавим все метаполя данного юзера
$CI->db->select('meta_key, meta_value');
$CI->db->from('meta');
$CI->db->where('meta_table', 'comusers');
$CI->db->where('meta_id_obj', $id);
$query = $CI->db->get();
if ($query->num_rows() > 0) {
// переделаем полученный массив в key = value
foreach ($query->result_array() as $val) {
$comuser[0]['comusers_meta'][$val['meta_key']] = $val['meta_value'];
}
} else {
$comuser[0]['comusers_meta'] = [];
}
// от вских гадостей
$comuser[0]['comusers_url'] = mso_xss_clean($comuser[0]['comusers_url']);
// if ($comuser[0]['comusers_url'] and strpos($comuser[0]['comusers_url'], 'http://') === false)
// $comuser[0]['comusers_url'] = 'http://' . $comuser[0]['comusers_url'];
$comuser[0]['comusers_msn'] = mso_xss_clean($comuser[0]['comusers_msn']); // twitter
$comuser[0]['comusers_msn'] = mso_slug(str_replace('@', '', $comuser[0]['comusers_msn']));
// подчистка
$comuser[0] = mso_clean_post([
'comusers_nik' => 'base',
'comusers_icq' => 'base',
'comusers_jaber' => 'base',
'comusers_skype' => 'base',
'comusers_description' => 'base',
'comusers_msn' => 'base',
'comusers_url' => 'base',
], $comuser[0]);
// pr($comuser);
return $comuser;
} else {
return [];
}
}
// устанавливаем колво комментариев у указаного комюзера
function mso_comuser_set_count_comment($id = 0, $count = -1)
{
if (!$id) return;
$CI = &get_instance();
// не указано количество - нужно его получить
if ($count == -1) {
$CI->db->select('COUNT(comments_comusers_id) as comusers_count_comment_real', false);
$CI->db->from('comusers');
$CI->db->where('comusers_id', $id);
$CI->db->where('comments.comments_approved', '1');
$CI->db->join('comments', 'comusers.comusers_id = comments.comments_comusers_id', 'left');
$CI->db->group_by('comments_comusers_id');
$query = $CI->db->get();
if ($query->num_rows() > 0) {
$comuser = $query->result_array(); // данные комюзера
$count = $comuser[0]['comusers_count_comment_real'];
} else {
$count = 0;
}
}
$CI->db->where('comusers_id', $id);
$CI->db->update('comusers', array('comusers_count_comments' => $count));
$CI->db->cache_delete_all();
}
// функция проверяет в цикле количество реальных комментариев
// с тем, что указано в поле comusers_count_comments
// если данные не совпадают, то выполняется обновление
// с помощью mso_comuser_set_count_comment()
// функция возвращает $all_comusers - массив всех комюзеров
function mso_comuser_update_count_comment()
{
$cache_key = 'all_comusers';
$k = mso_get_cache($cache_key);
if (!$k) {
// нет в кэше
$CI = &get_instance();
$CI->db->select('comusers_id, comusers_count_comments, COUNT(comments_comusers_id) as comusers_count_comment_real');
$CI->db->from('comusers');
$CI->db->where('comments.comments_approved', '1');
$CI->db->join('comments', 'comusers.comusers_id = comments.comments_comusers_id', 'left');
$CI->db->group_by('comments_comusers_id');
$query = $CI->db->get();
$all_comusers = [];
if ($query->num_rows() > 0) {
$comusers = $query->result_array();
foreach ($comusers as $comuser) {
$all_comusers[$comuser['comusers_id']] = $comuser['comusers_count_comment_real'];
// сразу сверим количество кмментариев
if ($comuser['comusers_count_comments'] != $comuser['comusers_count_comment_real']) // не равно
mso_comuser_set_count_comment($comuser['comusers_id'], $comuser['comusers_count_comment_real']);
}
}
mso_add_cache($cache_key, $all_comusers); // в кэш
} else {
$all_comusers = $k;
}
return $all_comusers;
}
// обработка POST из формы комюзера
function mso_comuser_edit($args = [])
{
global $MSO;
if (!isset($args['css_ok'])) $args['css_ok'] = 'comment-ok';
if (!isset($args['css_error'])) $args['css_error'] = 'comment-error';
// id комюзера, который в сессии
if (isset($MSO->data['session']['comuser']) and $MSO->data['session']['comuser'])
$id_session = $MSO->data['session']['comuser']['comusers_id'];
else
$id_session = false;
if ($post = mso_check_post(['f_session_id', 'f_submit', 'f_comusers_activate_key'])) {
// это активация
// защита рефера
mso_checkreferer();
// защита сессии - если не нужно закомментировать строчку!
if ($MSO->data['session']['session_id'] != $post['f_session_id']) mso_redirect();
// получаем номер юзера id из f_submit[]
$id = (int) mso_array_get_key($post['f_submit']);
if (!$id) return '<div class="' . $args['css_error'] . '">' . tf('Ошибочный номер пользователя') . '</div>';
// проверяем id в сессии с сабмитом
// if ($id != $id_session)
// return '<div class="' . $args['css_error']. '">'. t('Ошибочный номер пользователя'). '</div>';
$f_comusers_activate_key = trim($post['f_comusers_activate_key']);
if (!$f_comusers_activate_key) return '<div class="' . $args['css_error'] . '">' . tf('Неверный (пустой) ключ') . '</div>';
// нужно проверить если у указанного комюзера не равные ключи
// если они равны, то ничего не делаем
$CI = &get_instance();
$CI->db->select('comusers_activate_string, comusers_activate_key');
$CI->db->from('comusers');
$CI->db->where('comusers_id', $id);
$CI->db->limit(1);
$query = $CI->db->get();
if ($query->num_rows() > 0) {
$comuser = $query->result_array(); // данные комюзера
if ($comuser[0]['comusers_activate_string'] == $comuser[0]['comusers_activate_key']) {
// уже равны, активация не требуется
return '<div class="' . $args['css_ok'] . '">' . tf('Активация уже выполнена') . '</div>';
} else {
// ключи в базе не равны
// сверяем с переданным ключом из формы
if ($f_comusers_activate_key == $comuser[0]['comusers_activate_key']) {
// верный ключ - обновляем в базе
$CI->db->where('comusers_id', $id);
$res = ($CI->db->update(
'comusers',
array('comusers_activate_string' => $f_comusers_activate_key)
)) ? '1' : '0';
$CI->db->cache_delete_all();
if ($res)
return '<div class="' . $args['css_ok'] . '">' . tf('Активация выполнена!') . '</div>';
else
return '<div class="' . $args['css_error'] . '">' . tf('Ошибка БД при добавления ключа активации') . '</div>';
} else {
return '<div class="' . $args['css_error'] . '">' . tf('Ошибочный ключ активации') . '</div>';
}
}
} else {
// вообще нет такого комюзера
return '<div class="' . $args['css_error'] . '">' . tf('Ошибочный номер пользователя') . '</div>';
}
} elseif ($post = mso_check_post(['flogin_session_id', 'flogin_submit', 'flogin_user', 'flogin_password', 'flogin_redirect'])) {
// логинимся через стандартную _mso_login()
_mso_login();
return;
}
// это форма?
elseif ($post = mso_check_post(['f_session_id', 'f_submit', 'f_comusers_email', 'f_comusers_password', 'f_comusers_nik', 'f_comusers_url', 'f_comusers_icq', 'f_comusers_msn', 'f_comusers_jaber', 'f_comusers_date_birth', 'f_comusers_description', 'f_comusers_avatar_url'])) {
// это обновление формы
if (!is_login_comuser())
return '<div class="' . $args['css_error'] . '">' . tf('Ошибочные данные пользователя') . '</div>';
// защита рефера
mso_checkreferer();
// защита сессии - если не нужно закомментировать строчку!
if ($MSO->data['session']['session_id'] != $post['f_session_id']) mso_redirect();
// получаем номер юзера id из f_submit[]
$id = (int) mso_array_get_key($post['f_submit']);
if (!$id) return '<div class="' . $args['css_error'] . '">' . tf('Ошибочный номер пользователя') . '</div>';
// проверяем id в сессии с сабмитом
if ($id != $id_session)
return '<div class="' . $args['css_error'] . '">' . tf('Ошибочный номер пользователя') . '</div>';
$f_comusers_email = trim($post['f_comusers_email']);
$f_comusers_password = trim($post['f_comusers_password']);
if (!$f_comusers_email or !$f_comusers_password)
return '<div class="' . $args['css_error'] . '">' . tf('Необходимо указать email и пароль') . '</div>';
// проверим есть ли такой комюзер
$CI = &get_instance();
$CI->db->select('*');
$CI->db->from('comusers');
// CodeIgniter экранирует where, даже когда только условия в полях
$CI->db->where('comusers_activate_string=comusers_activate_key', '', false); // активация должна уже быть
$CI->db->where([
'comusers_id' => $id,
'comusers_email' => $f_comusers_email,
'comusers_password' => $f_comusers_password
]);
$CI->db->limit(1);
$query = $CI->db->get();
if ($query->num_rows() > 0) {
// все ок - логин пароль верные
$comuser = $query->result_array(); // данные комюзера
$f_comusers_avatar_url = mso_strip(
$post['f_comusers_avatar_url'],
false,
['\\', '|', '?', '%', '*', '`']
);
$allowed_ext = array('gif', 'jpg', 'jpeg', 'png'); // разрешенные типы
$ext = strtolower(str_replace('.', '', strrchr($f_comusers_avatar_url, '.'))); // расширение файла
if (!in_array($ext, $allowed_ext)) $f_comusers_avatar_url = ''; // запрещенный тип файла
if (!isset($post['f_comusers_notify'])) $post['f_comusers_notify'] = '0';
if (!isset($post['f_comusers_skype'])) $post['f_comusers_skype'] = ''; // скайп
$post = mso_clean_post([
'f_comusers_nik' => 'base',
'f_comusers_url' => 'base',
'f_comusers_icq' => 'base',
'f_comusers_msn' => 'base',
'f_comusers_jaber' => 'base',
'f_comusers_skype' => 'base',
'f_comusers_date_birth' => 'base',
'f_comusers_description' => 'base',
'f_comusers_notify' => 'int',
], $post);
$upd_date = [
'comusers_nik' => strip_tags($post['f_comusers_nik']),
'comusers_url' => strip_tags($post['f_comusers_url']),
'comusers_icq' => strip_tags($post['f_comusers_icq']),
'comusers_msn' => strip_tags($post['f_comusers_msn']),
'comusers_jaber' => strip_tags($post['f_comusers_jaber']),
'comusers_skype' => strip_tags($post['f_comusers_skype']),
'comusers_date_birth' => strip_tags($post['f_comusers_date_birth']),
'comusers_description' => strip_tags($post['f_comusers_description']),
'comusers_avatar_url' => $f_comusers_avatar_url,
'comusers_notify' => $post['f_comusers_notify'],
];
// pr($upd_date );
$CI->db->where('comusers_id', $id);
$res = ($CI->db->update('comusers', $upd_date)) ? '1' : '0';
// если переданы метаполя, то обновляем и их
if (isset($post['f_comusers_meta']) and $post['f_comusers_meta']) {
//pr($post);
foreach ($post['f_comusers_meta'] as $key => $val) {
// вначале грохаем если есть такой ключ
$CI->db->where('meta_table', 'comusers');
$CI->db->where('meta_id_obj', $id);
$CI->db->where('meta_key', $key);
$CI->db->delete('meta');
// теперь добавляем как новый
$ins_data = [
'meta_table' => 'comusers',
'meta_id_obj' => $id,
'meta_key' => $key,
'meta_value' => $val
];
$CI->db->insert('meta', $ins_data);
}
}
$CI->db->cache_delete_all();
// mso_flush_cache(); // сбросим кэш
if ($res)
return '<div class="' . $args['css_ok'] . '">' . tf('Обновление выполнено!') . '</div>';
else
return '<div class="' . $args['css_error'] . '">' . tf('Ошибка БД при обновлении') . '</div>';
} else {
return '<div class="' . $args['css_error'] . '">' . tf('Ошибочный email и пароль') . '</div>';
}
} // обновление формы
}
// восстановление пароля комюзера
function mso_comuser_lost($args = [])
{
global $MSO;
if (!isset($args['css_ok'])) $args['css_ok'] = 'comment-ok';
if (!isset($args['css_error'])) $args['css_error'] = 'comment-error';
// если нет опции password_recovery, значит восстанавливаем с учетом номера комюзера во втором сегмента адреса
// если опция есть, значит восстанавливаем без учета id комюзера
if (!isset($args['password_recovery']))
$password_recovery = false;
else
$password_recovery = true;
// id комюзера, который в сессии - какой комюзер
// если комюзер залогинен, то будет $id_session
// если нет, то залогиненности нет
if (isset($MSO->data['session']['comuser']) and $MSO->data['session']['comuser'])
$id_session = $MSO->data['session']['comuser']['comusers_id'];
else
$id_session = false;
if ($post = mso_check_post(['f_session_id', 'f_submit', 'f_comusers_email'])) {
// это активация
mso_checkreferer(); # защита рефера
// защита сессии - если не нужно закомментировать строчку!
if ($MSO->data['session']['session_id'] != $post['f_session_id']) mso_redirect();
if (!$password_recovery) {
// номер пользователя указан в f_submit - вычленяем его
// получаем номер юзера id из f_submit[]
$id = (int) mso_array_get_key($post['f_submit']);
if (!$id) return '<div class="' . $args['css_error'] . '">' . tf('Ошибочный номер пользователя') . '!</div>';
// проверяем id в сессии с сабмитом
if ($id_session and $id != $id_session)
return '<div class="' . $args['css_error'] . '">' . tf('Ошибочный номер пользователя2') . '</div>';
}
$comusers_email = trim($post['f_comusers_email']);
if (!$comusers_email) return '<div class="' . $args['css_error'] . '">' . tf('Нужно указать email') . '</div>';
if (!mso_valid_email($comusers_email)) return '<div class="' . $args['css_error'] . '">' . tf('Ошибочный email') . '</div>';
$CI = &get_instance();
// проверим есть ли вообще такой юзер
$CI->db->select('comusers_id');
if (!$password_recovery) $CI->db->where('comusers_id', $id); // если явно указан id, то ищем по нему
$CI->db->where('comusers_email', $comusers_email);
$query = $CI->db->get('comusers');
if ($query->num_rows() == 0) // нет такого комментатора
return '<div class="' . $args['css_error'] . '">' . tf('Неверный email или номер пользователя') . '!</div>';
if ($password_recovery) {
// получаем id из последнего запроса
// получим id этого комюзера
$res = $query->result_array();
$id = $res[0]['comusers_id'];
}
$comusers_new_password = trim($post['f_comusers_password']);
$comusers_activate_key = trim($post['f_comusers_activate_key']);
if ($comusers_email and !$comusers_activate_key and !$comusers_new_password) {
// указан email без остального
// проверим есть ли активация
$CI->db->select('comusers_id, comusers_activate_key');
$CI->db->where('comusers_id', $id);
$CI->db->where('comusers_activate_string=comusers_activate_key', '', false);
$CI->db->where('comusers_email', $comusers_email);
$CI->db->limit(1);
$query = $CI->db->get('comusers');
if ($query->num_rows() > 0) {
// все верно, можно установить новый пароль
$comuser = $query->result_array(); // данные комюзера
mso_email_message_new_comuser(
$id,
array('comusers_email' => $comusers_email, 'comusers_activate_key' => $comuser[0]['comusers_activate_key'])
);
return '<div class="' . $args['css_ok'] . '">' . tf('Код активации отправлен на ваш email') . '!</div>';
} else {
return '<div class="' . $args['css_error'] . '">' . tf('Данный email не зарегистрирован или не активирован') . '</div>';
}
} elseif ($comusers_email and $comusers_new_password and !$comusers_activate_key)
// указан email, новый пароля, но не указан код активации
{
return '<div class="' . $args['css_error'] . '">' . tf('Для установки нового пароля нужно заполнить все поля!') . '</div>';
} elseif ($comusers_email and !$comusers_new_password and $comusers_activate_key) {
// указан email и код активации, но не указан новый пароль
return '<div class="' . $args['css_error'] . '">' . tf('Для установки нового пароля нужно заполнить все поля!') . '</div>';
}
// если указано поле активации и новый пароль, то сверяем код активации с базой + email + id и если все верно,
// то обновляем пароль
// если же поле активации не указано, то высылаем его на указанный email
$CI->db->select('comusers_id');
$CI->db->where('comusers_id', $id);
$CI->db->where('comusers_activate_key', $comusers_activate_key);
$CI->db->where('comusers_activate_string', $comusers_activate_key);
$CI->db->where('comusers_email', $comusers_email);
$CI->db->limit(1);
$query = $CI->db->get('comusers');
if ($query->num_rows() > 0) {
// все верно, можно установить новый пароль
$CI->db->where('comusers_id', $id);
$CI->db->where('comusers_email', $comusers_email);
$res = ($CI->db->update('comusers', array('comusers_password' => mso_md5($comusers_new_password)))) ? '1' : '0';
$CI->db->cache_delete_all();
if ($res) {
// все ок
// сразу логиним и редиректим на страницу комюзера
$data = array(
'email' => $comusers_email,
'password' => $comusers_new_password,
'redirect' => getinfo('siteurl') . 'users/' . $id,
'allow_create_new_comuser' => false
);
mso_comuser_auth($data);
exit;
// return '<div class="' . $args['css_ok']. '">'. t('Новый пароль установлен!'). '</div>';
} else
return '<div class="' . $args['css_error'] . '">' . tf('Ошибка БД при смене пароля...') . '</div>';
} else {
return '<div class="' . $args['css_error'] . '">' . tf('Данные указаны неверно!') . '</div>';
}
}
}
// список всех комюзеров
function mso_get_comusers_all()
{
$cache_key = mso_md5('mso_get_comusers_all');
$k = mso_get_cache($cache_key);
if ($k) return $k; // да есть в кэше
$comusers = [];
$CI = &get_instance();
$CI->db->select('*');
$CI->db->from('comusers');
$query = $CI->db->get();
if ($query->num_rows() > 0) {
$comusers = $query->result_array();
mso_add_cache($cache_key, $comusers);
}
// получим все мета одним запросом
$CI->db->select('meta_id_obj, meta_key, meta_value');
$CI->db->where('meta_table', 'comusers');
$CI->db->order_by('meta_id_obj');
$query = $CI->db->get('meta');
if ($query->num_rows() > 0)
$all_meta = $query->result_array();
else
$all_meta = [];
// переделываем формат массива, чтобы индекс был равен номеру комюзера
$r_array = [];
foreach ($all_meta as $val) {
$r_array[$val['meta_id_obj']][$val['meta_key']] = $val['meta_value'];
}
$all_meta = $r_array;
// получить все номера страниц, где оставил комментарий комюзер
$CI->db->select('comments_id, comments_page_id, comments_comusers_id');
$CI->db->where('comments_comusers_id >', '0');
$CI->db->order_by('comments_comusers_id, comments_page_id');
$query = $CI->db->get('comments');
if ($query->num_rows() > 0)
$all_comments = $query->result_array();
else
$all_comments = [];
// переделываем массив под удобный формат
$r_array = [];
$all_comments_page_id = []; // тут массив номеров страниц, где участвовал комюзер
foreach ($all_comments as $val) {
$r_array[$val['comments_comusers_id']][$val['comments_id']] = $val['comments_page_id'];
$all_comments_page_id[$val['comments_comusers_id']][$val['comments_page_id']] = $val['comments_page_id'];
}
$all_comments = $r_array;
// добавляем в каждого комюзера элемент массива meta, comments и comments_pages_id
$r_array = [];
foreach ($comusers as $key => $val) {
$r_array[$key] = $val;
if (isset($all_meta[$val['comusers_id']]))
$r_array[$key]['meta'] = $all_meta[$val['comusers_id']];
else
$r_array[$key]['meta'] = [];
if (isset($all_comments[$val['comusers_id']]))
$r_array[$key]['comments'] = $all_comments[$val['comusers_id']];
else
$r_array[$key]['comments'] = [];
if (isset($all_comments_page_id[$val['comusers_id']]))
$r_array[$key]['comments_pages_id'] = $all_comments_page_id[$val['comusers_id']];
else
$r_array[$key]['comments_pages_id'] = [];
}
$comusers = $r_array;
mso_add_cache($cache_key, $comusers);
return $comusers;
}
// рассылаем по email уведомление о новом комментарии
function mso_email_message_new_comment_subscribe($data)
{
/*
Array
(
[comments_page_id] => 153 - id страницы
[comments_content] => sdafsadfsdaf - текст комментария
[comments_approved] => - если 0, то отправки нет
[page_title] => тест - заголовок страницы
[id] => 607 - id комментария
-- [comments_comusers_id] => 1 - номер комюзера - пока не используется
-- [comments_date] => 2009-12-10 20:45:39 - дата - пока не используется
-- [comments_author_ip] => 127.0.0.1 - ip - пока не используется
)
*/
// Опция не рассылать подписку.
if (!mso_get_option('allow_comments_subscribe', 'general', 1)) return;
// комментарий не одобрен, не отсылаем
if ($data['comments_approved'] == 0) return;
// разослать нужно всем комюзерам у которых стоит получение уведомления о новом комментарии
// $CI = &get_instance();
$comusers_all = mso_get_comusers_all(); // все комюзеры
$from = mso_get_option('admin_email_server', 'general', '');
$subject = '[' . getinfo('name_site') . '] ' . tf('Новый комментарий к') . ' "' . $data['page_title'] . '"';
$message = tf('Новый комментарий к') . ' "' . $data['page_title'] . '"' . NR . NR;
$message .= tf('Текст:') . NR . mso_xss_clean($data['comments_content']);
$message .= NR . NR . tf('Перейти к комментарию на сайте:') . NR . mso_get_permalink_page($data['comments_page_id']) . '#comment-' . $data['id'] . NR;
foreach ($comusers_all as $comuser) {
// отправлять на все комментарии сайта
$subscribe_other_comments = (isset($comuser['meta']['subscribe_other_comments'])
and $comuser['meta']['subscribe_other_comments']) ? true : false;
// отключить subscribe_other_comments, если включена subscribe_other_comments_ban
if (
isset($comuser['meta']['subscribe_other_comments_ban'])
and $comuser['meta']['subscribe_other_comments_ban']
)
$subscribe_other_comments = false;
// только на свой
$subscribe_my_comments = (isset($comuser['meta']['subscribe_my_comments'])
and $comuser['meta']['subscribe_my_comments']) ? true : false;
if (
$subscribe_other_comments // на любой коммент
or ($subscribe_my_comments // только свой
and
isset($comuser['comments_pages_id'][$data['comments_page_id']]))
) {
// можно отправлять
if (mso_valid_email($comuser['comusers_email'])) {
$data = array_merge($data, array('subscription' => true)); //А здесь для smtp_mail важно знать, чтобы запретить сохранять мыло в файл.
$res = mso_mail($comuser['comusers_email'], $subject, $message, $from, $data);
if (!$res) break; // ошибка отправки почты - рубим цикл
}
}
}
}
// авторизация/регистрация комюзеров
// обязательно указывается email
// если не указывать password, то проверка на пароль не осуществляется
function mso_comuser_auth($data)
{
if (!isset($data['email']))
return false;
else
$email = $data['email'];
$pass = $data['password'] ?? false;
$comusers_nik = $data['comusers_nik'] ?? '';
$redirect = $data['redirect'] ?? true;
// если $die = true, то всё рубим через die
// иначе возвращаем результат по return
$die = $data['die'] ?? true;
// разрешить создавать через эту функцию новых комюзеров (если такого email нет в базе)
$allow_create_new_comuser = $data['allow_create_new_comuser'] ?? true;
$CI = &get_instance();
// если указанный email зарегистрирован на user, то отказываем в регистрации
$CI->db->select('users_id');
$CI->db->where('users_email', $email);
$query = $CI->db->get('users');
if ($query->num_rows() > 0) {
if ($die)
die(tf('Данный email уже используется на сайте админом или автором.'));
else
return tf('Данный email уже используется на сайте админом или автором.');
}
// имя email и пароль нужно проверить, чтобы такие были в базе
// вначале нужно проверить наличие такого email
// если есть, то сверяем и пароль
$CI->db->select('comusers_id, comusers_password, comusers_email, comusers_nik, comusers_url, comusers_avatar_url, comusers_last_visit');
$CI->db->where('comusers_email', $email);
$query = $CI->db->get('comusers');
if ($query->num_rows()) {
// есть такой комюзер
$comuser_info = $query->row_array(1); // вся инфа о комюзере
if ($pass !== false) {
// пароль указан
// сверим пароль
if ($comuser_info['comusers_password'] == mso_md5($pass)) {
// пароли равны, можно логинить
// сразу же обновим поле последнего входа
$CI->db->where('comusers_id', $comuser_info['comusers_id']);
$CI->db->update('comusers', array('comusers_last_visit' => date('Y-m-d H:i:s')));
$expire = time() + 60 * 60 * 24 * 365; // 365 дней
$name_cookies = 'maxsite_comuser';
$value = serialize($comuser_info);
$value = mso_de_code($value, 'encode'); // кодируем данные
mso_add_to_cookie($name_cookies, $value, $expire, $redirect); // в куку для всего сайта
} else {
// email есть но пароль ошибочный
if ($die)
die('Данный email уже зарегистрирован <a href="' . getinfo('siteurl') . '">на сайте</a>. Для входа нужно указать верный пароль. Вы можете <a href="' . getinfo('siteurl') . 'password-recovery">восстановить пароль</a>.');
else
return 'Данный email уже зарегистрирован <a href="' . getinfo('siteurl') . '">на сайте</a>. Для входа нужно указать верный пароль. Вы можете <a href="' . getinfo('siteurl') . 'password-recovery">восстановить пароль</a>.';
}
} else {
// пароль сверять не нужно
// сразу же обновим поле последнего входа
$CI->db->where('comusers_id', $comuser_info['comusers_id']);
$CI->db->update('comusers', array('comusers_last_visit' => date('Y-m-d H:i:s')));
$expire = time() + 60 * 60 * 24 * 365; // 365 дней
$name_cookies = 'maxsite_comuser';
$value = serialize($comuser_info);
$value = mso_de_code($value, 'encode'); // кодируем данные
mso_add_to_cookie($name_cookies, $value, $expire, $redirect); // в куку для всего сайта
}
} elseif ($allow_create_new_comuser) {
// только если разрешено создавать новых комюзеров
// нет такого email, нужно регистрировать комюзера
// но если запрещены регистрации, то все рубим
if (!mso_get_option('allow_comment_comusers', 'general', '1')) {
if ($die)
die(t('На сайте запрещена регистрация.'));
else
return t('На сайте запрещена регистрация.');
}
// если пароль не указан, то генерируем его случайным образом
if ($pass === false) $pass = substr(mso_md5($email), 1, 9);
$ins_data = [
'comusers_email' => $email,
'comusers_password' => mso_md5($pass)
];
// генерируем случайный ключ активации
$ins_data['comusers_activate_key'] = mso_md5(rand());
$ins_data['comusers_date_registr'] = date('Y-m-d H:i:s');
$ins_data['comusers_last_visit'] = date('Y-m-d H:i:s');
$ins_data['comusers_ip_register'] = $_SERVER['REMOTE_ADDR'];
$ins_data['comusers_notify'] = '1'; // сразу включаем подписку на уведомления
if (isset($data['comusers_url'])) {
// если указан сайт
if ($comusers_url = mso_clean_str($data['comusers_url']))
$ins_data['comusers_url'] = $comusers_url;
} else {
$comusers_url = '';
}
if ($comusers_nik = mso_clean_str($comusers_nik, 'base|not_url')) {
$ins_data['comusers_nik'] = $comusers_nik;
}
// Автоматическая активация новых комюзеров
// если активация стоит автоматом, то сразу её и прописываем
if (mso_get_option('comusers_activate_auto', 'general', '0'))
$ins_data['comusers_activate_string'] = $ins_data['comusers_activate_key'];
$res = ($CI->db->insert('comusers', $ins_data)) ? '1' : '0';
if ($res) {
$comusers_id = $CI->db->insert_id(); // номер добавленной записи
// нужно добавить опцию в мета «новые комментарии, где я участвую» subscribe_my_comments
// вначале грохаем если есть такой ключ
$CI->db->where('meta_table', 'comusers');
$CI->db->where('meta_id_obj', $comusers_id);
$CI->db->where('meta_key', 'subscribe_my_comments');
$CI->db->delete('meta');
// теперь добавляем как новый
$ins_data2 = [
'meta_table' => 'comusers',
'meta_id_obj' => $comusers_id,
'meta_key' => 'subscribe_my_comments',
'meta_value' => '1'
];
$CI->db->insert('meta', $ins_data2);
// отправляем ему уведомление с кодом активации
mso_email_message_new_comuser($comusers_id, $ins_data, mso_get_option('comusers_activate_auto', 'general', '0'));
// после отправки можно сразу залогинить
$comuser_info = [
'comusers_id' => $comusers_id,
'comusers_password' => mso_md5($pass),
'comusers_email' => $email,
'comusers_nik' => $comusers_nik,
'comusers_url' => $comusers_url,
'comusers_avatar_url' => '',
'comusers_last_visit' => '',
];
$name_cookies = 'maxsite_comuser';
$expire = time() + 60 * 60 * 24 * 365; // 365 дней
$value = serialize($comuser_info);
$value = mso_de_code($value, 'encode'); // кодируем данные
mso_add_to_cookie($name_cookies, $value, $expire, $redirect); // в куку для всего сайта
} else {
if ($die)
die(t('Произошла ошибка регистрации'));
else
return t('Произошла ошибка регистрации');
}
}
return false;
}
// определение времени последнего комментария и сравнение с текущим
// нужно чтобы было не более 15 секунд - защита от частых комментариев
function mso_last_activity_comment()
{
global $MSO;
/*
last_activity - время текущей сессии
last_activity_prev - время предыдущей сесиии
last_activity_comment - время предыдущего успешного комментария
*/
// предыдущего комментария не было - это первый
if (!isset($MSO->data['session']['last_activity_comment'])) return true;
// время в секундах между последним комментарием и текущим в секундах
$delta = time() - $MSO->data['session']['last_activity_comment'];
return ($delta < 15) ? false : true;
}
// вывод аватарки комментатора
// на входе массив комментария из page-comments.php
function mso_avatar($comment, $img_add = 'class="mso-gravatar"', $echo = false, $size = false, $url_only = false)
{
extract($comment);
$avatar_url = '';
// если отмечана опция «Только граватарки», то обнуляем указанный адрес комюзера
if (mso_get_option('gravatar_only', 'templates', 0)) $comusers_avatar_url = '';
if ($comusers_avatar_url) $avatar_url = $comusers_avatar_url;
elseif ($users_avatar_url) $avatar_url = $users_avatar_url;
if ($size === false)
$avatar_size = (int) mso_get_option('gravatar_size', 'templates', 80);
else
$avatar_size = $size;
if ($avatar_size < 1 or $avatar_size > 512) $avatar_size = 80;
if (!$avatar_url) {
// аватарки нет, попробуем получить из gravatara
if ($users_email) $grav_email = $users_email;
elseif ($comusers_email) $grav_email = $comusers_email;
else $grav_email = $comments_author_name ?? ''; // имя комментатора
if ($gravatar_type = mso_get_option('gravatar_type', 'templates', '')) {
$d = '&d=' . urlencode($gravatar_type);
} else {
$d = '';
$def = getinfo('template_dir') . 'assets/images/gravatar-default.png';
if (file_exists($def)) {
$d = '&d=' . urlencode(getinfo('template_url') . 'assets/images/gravatar-default.png');
} else {
$def = getinfo('uploads_dir') . 'gravatar-default.png';
if (file_exists($def))
$d = '&d=' . urlencode(getinfo('uploads_url') . 'gravatar-default.png');
}
}
$avatar_url = "https://www.gravatar.com/avatar/?gravatar_id="
. md5($grav_email)
. "&s=" . $avatar_size
. $d;
// http://ru.gravatar.com/site/implement/images/php/
// $grav_url = "https://www.gravatar.com/avatar/" . md5( strtolower( trim( $email ) ) ) . "?d=" . urlencode( $default ) . "&s=" . $size;
/*
if (!empty($_SERVER['HTTPS']))
{
$avatar_url = "https://secure.gravatar.com/avatar.php?gravatar_id="
. md5($grav_email)
. "&size=" . $avatar_size
. $d;
}
else
{
$avatar_url = "http://www.gravatar.com/avatar.php?gravatar_id="
. md5($grav_email)
. "&size=" . $avatar_size
. $d;
}
*/
}
if (!$url_only) {
if ($avatar_url) $avatar_url = '<img src="' . $avatar_url . '" width="' . $avatar_size . '" height="' . $avatar_size . '" alt="" title="" ' . $img_add . '>';
}
if ($echo)
echo $avatar_url;
else
return $avatar_url;
}
# end of file