Материалы из категории - Новые материалы

Catface
Санкт-Петербург

Решение для старой версии модуля RSForm!Pro для Joomla!, в котором не было предусмотрено никаких ограничений по отправки пользователями данных. Боты этим активно пользуются.

Чтобы поставить ограничение на повторную отправку формы можно проверять выполнялась ли отправка данных с текущего IP пользователя ранее за определенный промежуток времени

Для этого в разделе редактирования формы во вкладке "PHP Scripts"

В первую область ввода текста (скрипт исполняемый при выводе формы), с заголовком "The $formLayout string contains the HTML code of the form..." следует прописать следующий код

 

Код php:

$modForm = '';

$ip = $_SERVER['REMOTE_ADDR'];

$db = JFactory::getDbo();

$db->setQuery("SELECT COUNT(`UserIp`) FROM `#__rsform_submissions` WHERE `FormId` = 'ИД_ФОРМЫ' AND `UserIp`='".$db->escape($ip)."' AND `DateSubmitted` > NOW()-INTERVAL 1 HOUR");

 

if ($db->loadResult() > 0){ 

$modForm .= '<p style="color:red;">Превышен интервал запросов (не более одного запроса в час)</p>';

}

 

if ($modForm) $formLayout =  $modForm  . $formLayout ;

 
Где ИД_ФОРМЫ - идентификатор формы, его слудет указать если требуется привязать проверку к конкретной форме (идентификатор формы виден в поле ввода адреса при редактировании соответствующей формы)
 
Это добавит соотвтетсвующее предупреждение при выводе формы
 
Если время базы данных не совпадает с временем заданым для скриптов php следует сделать на это поправку в строке "INTERVAL 1 HOUR"
 
И во вторую область ввода с заголовком "$_POST form data..." (скрипт который выполняется при отправке данных методом POST)
 

Код php:

$ip = $_SERVER['REMOTE_ADDR'];

$db = JFactory::getDbo();

$db->setQuery("SELECT COUNT(`UserIp`) FROM `#__rsform_submissions` WHERE  `FormId` = 'ИД_ФОРМЫ' AND `UserIp`='".$db->escape($ip)."' AND `DateSubmitted` > NOW()-INTERVAL 1 HOUR");

 

if ($db->loadResult() > 0){ 

  $invalid[] = RSFormProHelper::getComponentId("ИД_ПОЛЯ_ФОРМЫ");

}

 

Где так же следует указать идентификатор формы и дополнительно ИД_ПОЛЯ_ФОРМЫ - какое либо существующее поле формы, чтобы форма отработала корректно ошибку подачи запроса и указало что какое либо из полей указано не верно. Можно подвизать под это поле какое либо соответствующее описание ошибки непосредственно в настройках поля.

 

rsform, joomla,
Catface
Санкт-Петербург

 

На момент написания было актуально для версии 2.7

Когда-то требовалось реализовать подобную функцию. К сожалению K2 не особо для этого предназначен, нужно вносить некоторые правки, но это вполне реализуемо. Так что если кому надо, вот один из относительно простых способов.

Найти файл шаблона item_comments_form.php в папке компонента com_k2 (components\com_k2\templates\default\) и перенести  в templates/TEMPLATE/html/com_k2/default/item_comments_form.php

 
где TEMPLATE - текущий шаблон
 
Изменить файл шаблона - добавить поле добавления изображения в форму отправки комментария 
 

Код HTML:

<label class="commentImg" for="commentImg">Прикрепить изображение</label>

<input name="commentImg" type="file" id="commentImg">

 
В файле шаблона item.php отвечающего за вывод материала K2 (по аналогии скопируйте его в папку templates/TEMPLATE/html/com_k2/default/item.php) области вывода листинга комментариев (можно найти по строке "
$comment->commentText")
 
 
Дописать предварительную обработку строки с комментарием
 

Код php:

$comment->commentText = preg_replace("/\[img\](.*)\[\/img\]/Usi", "<img class=\"img-comment\" src=\"\\1\">", $comment->commentText);

 
Скачать мою библиотеку (класс с набором статичных методов) с набором некоторых базовых функций для работы с файлами и дирректориями. Разархивировать и разместить файл Tool.class.php в папке additions корневой директории сайта
 
 
В данном случае она используется для безопасной проверки и переноса принятого файла и организации дирректории для сохранения файлов (см. методы isFileRecieved и fileSafeMove, возможно просто скопируйте требуемый функционал из них без копирования всей библиотеки если это принципиально). Если вы знаете какие-либо стандартные методы Joomla для работы с входящими файлами и генерации путей с последующей расстановкой корректных прав то дайте знать.
 
В объекте K2ModelItem изменить метод  comment() 

Добавить следующий код сразу перед строкой  "if (!$row->store())"

Код php:

require_once(JPATH_SITE . '/additions/Tool.class.php');

$response->fileRec = KellyTool::isFileRecieved('commentImg', array('jpg', 'jpeg', 'gif', 'png'));

$imgFile = false;

if ($response->fileRec) {

 

$mediaDir = '/media/k2/comments/';

$baseDir = JPATH_SITE . $mediaDir;

 

$imgFile = KellyTool::fileSafeMove('commentImg', $baseDir, 'comment_tmp', 'tmp');

if ($imgFile) {

 

$imageInfo = @getimagesize($imgFile['path']);

 

$imageTypeArray = array

(

1 => 'gif',

2 => 'jpg',

3 => 'png',

6 => 'bmp',

);

 

if (!$imageInfo or empty($imageTypeArray[$imageInfo[2]])) {

 

if (file_exists($imgFile['path'])) unlink($imgFile['path']);

 

$response->message = 'Недопустимый формат файла';

$response->cssClass = 'k2FormLogError';

echo $this->commentExit(json_encode($response));

$mainframe->close(); 

}

 

$imgExt = $imageTypeArray[$imageInfo[2]];

$imgName = KellyTool::uniName($baseDir, 'cimg', $imgExt);

 

if (!rename($imgFile['path'], $baseDir . $imgName)) {

 

if (file_exists($imgFile['path'])) unlink($imgFile['path']);

 

$response->message = 'Ошибка сохранения вложения';

$response->cssClass = 'k2FormLogError';

echo $this->commentExit(json_encode($response));

$mainframe->close();

}

 

$row->commentText .= '[img]' . JURI::root() . $mediaDir . $imgName . '[/img]';

}

}

Как видим изображения будут сохраняться в дирректорию со случайно сгенерированым уникальным именем (замечу возможно лучше следовало просто привязать изображения к идентификатору комментария т.к. оно всего одно) 

На случай неудачного сохранения комментария (if (!$row->store()) { ... }) можно добавить в тело условия неудачного сохранения следующий код чтобы удалять изображение к неудачно сохраненному комментарию. 

 

 

 

 

Код php:

if (!$row->store())

{

    if ($imgFile and file_exists($imgFile['path'])) unlink($imgFile['path']);

    ...

}

 

 
 
 
 
Заменить все строки "echo json_encode($response);" в методе на "echo $this->commentExit(json_encode($response));" 
 
и добавить этот метод в Объект K2ModelItem 
 
 
 

 

Код php:

function commentExit($jsontxt) {

 

$escapers =     array("\\",     "/",   "\"",  "\n",  "\r",  "\t", "\x08", "\x0c");

$replacements = array("\\\\", "\\/", "\\\"", "\\n", "\\r", "\\t",  "\\f",  "\\b");

 

$result = str_replace($escapers, $replacements, $jsontxt);

 

$result = '<html><head><title>jnone</title><script type="text/javascript"> var json_response = "' . $result . '"</script></head><body></body></html>';

 

return $result;

}

 

 
 
 
 
С клиентской части потребуется модифицировать функцию подачи AJAX запроса т.к. по умолчанию она не расчитана на отправку файлов

В файле /media/k2/assets/js/k2.frontend.js заменить обработчик кнопки отправки формы комментария

 

 

 

 

 

Код php:

$K2('#comment-form').submit(function(event){

event.preventDefault();

$K2('#formLog').empty().addClass('formLogLoading');

 

var bEvent = function(response) {

$K2('#formLog').removeClass('formLogLoading').html(response.message).addClass(response.cssClass);

 

console.log(response)

 

if(typeof(Recaptcha) != "undefined"){

Recaptcha.reload();

}

if (response.refresh) {

window.location.reload();

}

}

 

K2sendFormByIFrame('comment-form', bEvent)

});

 

 
 
 

и наконец добавить функции отправки AJAX запроса через ifarme  

 

 

 

Код JavaScript:

function K2getBody() {

    return document.getElementsByTagName('body')[0]

}

 

function K2getIframeDocument(iframeNode) {

 

    if (iframeNode.contentDocument)

        return iframeNode.contentDocument

    if (iframeNode.contentWindow)

        return iframeNode.contentWindow.document

    return iframeNode.document

}

 

function K2iFrameOnLoadEvent(iframeNode, event) {

 

    if (iframeNode.attachEvent)

        iframeNode.attachEvent('onload', event)

    else if (iframeNode.addEventListener)

        iframeNode.addEventListener('load', event, false)

    else

        iframeNode.onload = event

}

 

function K2sendFormByIFrame(formname, onload){

 

    var iframe = document.createElement('iframe')

        iframe.name = 'ajax-frame-' + Math.random(1000000)

        iframe.style.display = 'none'

 

    K2getBody().appendChild(iframe)

 

    var form = document.getElementById(formname)

 

    if (form == null) {

        console.log('Form ' + formname + 'not found')

        return false

    }

 

    form.target = iframe.name

 

    var event = function() {

 

        if (K2getIframeDocument(iframe).location.href == 'about:blank') return

 

        if (!iframe.contentWindow.json_response) {

 

console.log ('json_response is not set [' + formname + ']')

return;

        }

 

        var response = K2getJSvalue(iframe.contentWindow.json_response)

 

        K2getBody().removeChild(iframe)

 

        onload(response)

    }

 

    K2iFrameOnLoadEvent(iframe,event)

    form.submit()

}

 

function K2getJSvalue(value) {

 

    var result = false

 

    //alert(value)

 

    if (typeof value != "string") { 

 

            alert('[K2getJSvalue] Value is not string : '+value)

            return result

    }

 

    try {

 

    result = window.JSON && window.JSON.parse ? JSON.parse(value) : eval('(' + value + ')')

 

    } catch (E) {

 

    alert('[K2getJSvalue] Incorect server response : ' + value)

 

    }

 

    return result

}

так же в CSS текущего шаблона добавить 

Код CSS:

div.itemComments ul.itemCommentsList li .img-comment {

    float: none;

display : block;

}

 
 
Все готово. Единственное забыл посмотреть метод удаления комментария в administrator\components\com_k2\models\comments.php, судя по всему это remove() и туда следует добавить удаление изображения если оно есть в комментарии. Проверить есть файл или нет можно тем же методом что и при выводе только через callback вариант что то вроде preg_replace_callback("/\[img\](.*)\[\/img\]/Usi", function($matches) {parse_url($matches[1]); ... } ,$row->commentText); как понадобится необходимость, проверю и добавлю сюда в публикацию.
 
 

 

 

 

k2, joomla,