Иногда посетители сайта оставляют такие комментарии к статьям, публиковать которые по каким-либо причинам не нужно. В то же время необходимо написать ответ посетителю. В компоненте JСomments нет возможности ответить на комментарий без его публикации на сайте. В связи с этим, необходимо предоставить возможность администратору сайта отвечать на комментарии посетителей прямо из админки компонента JComments (со страницы редактирования комментария в компоненте).
В этой небольшой статье я расскажу о том, как можно кастомизировать JComments для предоставления возможности отвечать на комментарии посетителей, отправляя ответ им на электронную почту.
Задача эта несложная, тем не менее ее можно разделить на 2 этапа:
- Показ формы для ответа на комментарий при клике по ссылке «Ответить на e-mail», которую мы добавим в форму редактирования комментария;
- Отправка данных из формы на сервер (будет создана отдельная задача в контроллере комментария), формирование электронного сообщения и отправка его на электронную почту посетителя сайта с помощью AJAX;
Итак, давайте приступать к решению задачи.
Для начала необходимо добавить в структуру компонента JComments скрипты сторонних инструментов. Мы будем использовать Fancybox для показа всплывающих окон, поэтому скопируем файлы в следующие папки:
- Файл jquery.fancybox.css в /administrator/components/com_jcomments/assets/css/
- Файл jquery.fancybox.pack.js в /administrator/components/com_jcomments/assets/js/
- Изображения из папки img в папку /administrator/components/com_jcomments/assets/img/
В любом компоненте CMS Joomla используются языковые сообщения. Jcomments не исключение. В процессе наших изменений нам необходимо будет добавить новые языковые сообщения. Мы не будем вносить изменения в языковой файл компонента /administrator/language/ru-RU/ru-RU.com_jcomments.ini, вместо этого разместим все сообщения в файл /administrator/language/overrides/ru-RU.override.ini.
У меня получился следующий список сообщений:
INI
COM_JCOMMENTS_LETTER_NOT_ACCEPTED_TO_SEND="<b>Письмо не принято для отправки</b>"
COM_JCOMMENTS_LETTER_ACCEPTED_TO_SEND="<b>Письмо принято для отправки</b>"
COM_JCOMMENTS_RESPOND_TO_EMAIL="Ответить на e-mail"
COM_JCOMMENTS_RESPOND_SUBJECT_LABEL="Тема:"
COM_JCOMMENTS_RESPOND_SUBJECT_TXT="Ответ на ваш комментарий с сайта site.ru"
COM_JCOMMENTS_RESPOND_BODY_LABEL="Ответ:"
COM_JCOMMENTS_RESPOND_BODY_TXT="<h2>Добрый день, %s</h2> <p>Ваш комментарий:<br />%s</p> <p>Ответ:<br />"
COM_JCOMMENTS_RESPOND_SUBMIT_LABEL="Ответить"
COM_JCOMMENTS_RESPOND_SIGNATURE="</p><p>С уважением,<br /> Иван Иванов</p>"
Далее нужно разместить в файле /administrator/components/com_jcomments/views/comment/tmpl/edit.php форму для ответа на комментарий. Форма будет скрытой, а показываться она будет при клике по ссылке «Ответить на e-mail» (которую также размещаем в указанном шаблоне) во всплывающем Fancybox-окне.
Код для показа ссылки вы можете разместить в удобном для вас месте - среди полей формы. Например, я разместил ее после поля «E-mail автора».
PHP
<?php
$email = $this->item->email;
if(!empty($email) && strpos($email, '@') !== false):?>
<div class="control-group">
<a href="#" id="email_comment_answer">
<?php echo Jtext::_('COM_JCOMMENTS_RESPOND_TO_EMAIL')?>
</a>
</div>
<?endif;?>
Код формы нужно разместить в самом конце файла /administrator/components/com_jcomments/views/comment/tmpl/edit.php.
PHP
<div class="answ_wrap" id="answ_wrap" style="display: none;">
<form action="<?php echo JRoute::_('index.php?option=com_jcomments&task=comment.sendanswer'); ?>" id="comm_answ_form">
<input type="hidden" name="auth_email" id="auth_email" value="<?=$email?>"/>
<div>
<label for="comm_answ_subject"><?php echo JText::_('COM_JCOMMENTS_RESPOND_SUBJECT_LABEL')?> </label>
<input type="text" id="comm_answ_subject" name="answ_subject" value="<?php echo JText::_('COM_JCOMMENTS_RESPOND_SUBJECT_TXT')?>" style="width:90%" />
</div>
<div>
<label for="comm_answ_text"><?php echo JText::_('COM_JCOMMENTS_RESPOND_BODY_LABEL')?> </label>
<textarea id="comm_answ_text" name="answ_text" style="width:90%" rows="8"><?php echo sprintf(JText::_('COM_JCOMMENTS_RESPOND_BODY_TXT'), $this->item->name, htmlspecialchars($this->item->comment));?></textarea>
</div>
<div style="margin-top:20px;">
<input type="submit" name="comm_answ_send" value="<?php echo JText::_('COM_JCOMMENTS_RESPOND_SUBMIT_LABEL');?>"/>
</div>
</form>
</div>
Для того, чтобы все работало корректно на стороне клиента мы подключаем jQuery Fancybox и добавляем в тот же файл JavaScript-код, который будет показывать нам всплывающее окно с формой для ввода ответа на комментарий.
Код для подключения jQuery Fancybox нужно разместить в начале файла после строки defined('_JEXEC') or die;
PHP
$document = JFactory::getDocument();
$document->addStylesheet(JURI::root(true).'/administrator/components/com_jcomments/assets/css/jquery.fancybox.css');
$document->addScript(JURI::root(true).'/administrator/components/com_jcomments/assets/js/jquery.fancybox.pack.js', 'text/javascript', true);
Следующий блок кода размещаем также в начале файла после подключения jQuery Fancybox.
JavaScript
<script type="text/javascript">
(function ($) {
$(document).ready(function(){
// всплывающее окно с формой
$('#email_comment_answer').on('click', function(evt){
$.fancybox.open($('#answ_wrap'),{
minWidth: '400px',
minHeight: '400px',
});
$('#comm_answ_text').focus();
evt.preventDefault();
});
// отправка формы с помощью AJAX
$('#comm_answ_form').on('submit', function(evt){
$.ajax({
method: 'POST',
url: $(this).attr('action'),
data: $(this).serialize(),
success: function(data){
$('#answ_wrap').html(data);
}
});
evt.preventDefault();
});
});
})(jQuery);
</script>
На стороне сервера необходимо добавить в контроллер JcommentsControllerComment, расположенный в файле /administrator/components/com_jcomments/controllers/comment.php метод sendanswer, который будет получать данные из формы, создавать письмо и отправлять его на электронную почту посетителя.
PHP
public function sendanswer()
{
$to = JFactory::getApplication()->input->get('auth_email','','string');
$subject = JFactory::getApplication()->input->get('answ_subject', '', 'string');
$body = JFactory::getApplication()->input->get('answ_text', '', 'raw');
$body .= JText::_('COM_JCOMMENTS_RESPOND_SIGNATURE');
$headers = "MIME-Version: 1.0\r\n";
$headers .= "Content-type: text/html; charset=utf-8\r\n";
$headers .= "From: info@mattweb.ru\r\n";
$mess = JText::_('COM_JCOMMENTS_LETTER_NOT_ACCEPTED_TO_SEND');
if(mail($to, $subject, $body, $headers)){
$mess = JText::_('COM_JCOMMENTS_LETTER_ACCEPTED_TO_SEND');
}
die($mess);
}
По результатам отправки, метод sendanswer будет возвращать сообщение, которое будет отображаться вместо формы во всплывающем окне. Вот и все решение нашей задачи.
Для ознакомления с примерами кода, я подготовил архив с измененными файлами, который вы можете скачать.