Простые отзывы на сайте AjaxForm (Formit) + MIGX

Создание отзывов на сайте без использования платных дополнений или громоздких, таких как Tickets.
Нам понадобятся следующие дополнения: Formit, AjaxForm и если хочется защитить форму — recaptchav3.

Данная статья будет полезна новичкам в modx и ни на что не претендует.
1) Создание ресурса «Отзывы», Конфигурация MIGX и создание TV поля.
1.1) Создайте ресурс «Отзывы» желательно с отдельным шаблоном «Отзывы».
1.2) Теперь создайте конфигурацию MIGX. Для этого Нужно зайти в «Пакеты» — «MIGX» и добавить конфигурацию. Например, назовите ее reviews. (!!! запомните название, оно понадобится на шаге 1.3)


На вкладке Formtabs нажмите «Добавить элемент» и далее добавьте 4 поля:
name — Имя, text — Текст отзыва, phone — Телефон, published — Публиковать отзыв.
При добавлении поля published в поле Input TV Type нужно вписать checkbox, а на вкладке Input Options в поле Input Option Values написать Да==1. Тем самым поле получится в виде галочки.



На вкладке Columns так же добавьте эти поля, но у поля published на вкладке Render, в поле Render выберете this.renderCrossTick, что бы это поле отображалось в виде галочки.

1.3 Теперь создайте ТВ поле с названием «reviews» и подписью «Список отзывов». На вкладке «Параметры ввода» выберите «migx», а в поле «Конфигурация» введите название конфигурации, созданной в пункте 1.2), в нашем случае reviews. На вкладке «Доступно для шаблонов» выберите наш шаблон «Отзывы».

Теперь если у вас оставят отзыв они будут храниться в данном ТВ-поле у этого ресурса.


2) Форма для добавления отзывов.
В шаблоне «Отзывы» в нужном вам месте добавьте вызов AjaxForm:
Обычный синтаксис modx
[[!AjaxForm?
&rcv3Action=`reviews-action`
&snippet=`FormIt`
&hooks=`rcv3,addReview,email`
&form=`form.review`
&emailFrom=`[[++emailsender]]`
&emailSubject=`Новый отзыв на сайте [[++site_name]]`
&emailTo=`ВАШ ЕМЕЙЛ`
&emailTpl=`tpl.review`
&successMessage=`<h5>Ваш отзыв добавлен</h5><p>После проверки администратором он будет опубликован.</p>`
&validate=`name:required:russian,text:required`
&validationErrorMessage=`В форме содержатся ошибки!`
&customValidators=`russian`
]]
Fenom
{'!AjaxForm' | snippet : [
    'rcv3Action' => 'reviews-action',
    'snippet' => 'FormIt',
    'hooks' => 'rcv3,addReview,email',
    'form' => 'form.review',
    'emailFrom' => $_modx->config.emailsender,
    'emailSubject' => 'Новый отзыв на сайте ' ~ $_modx->config.site_name,
    'emailTo' => 'ВАШ ЕМЕЙЛ',
    'emailTpl' => 'tpl.review',
    'successMessage' => '<h5>Ваш отзыв добавлен</h5><p>После проверки администратором он будет опубликован.</p>',
    'validate' => 'name:required:russian,text:required',
    'validationErrorMessage' => 'В форме содержатся ошибки!',
    
    'customValidators' => 'russian',
]}

Разберем некоторые параметры:
rcv3Action — Уникальное значение на всем сайте. Необходим при использовании Рекапчи.

hooks
rcv3 — проверка на робота
addReview — наш сниппет, который добавляет отзыв в ТВ-поле «Список отзывов». О нем ниже
email — отправляет Администратору письмо о новом отзыве.

form — чанк, который содержит код формы. Пример:
<form action="{$_modx->resource.id | url}" method="post" novalidate>
    <div class="form-group">
        <input type="text" name="name" class="form-control" placeholder="Ваше имя">
        <span class="error_name"></span>
    </div>
        	
    <div class="form-group">
        <input type="tel" name="phone" class="form-control" placeholder="Ваш телефон (не публикуется)" pattern="\d*" novalidate>
        <span class="error_phone"></span>
    </div>
    
    <div class="form-group">
        <textarea name="text" placeholder="Текст отзыва" class="form-control"></textarea>
        <span class="error_text"></span>
    </div>

    <button type="submit" class="btn btn-primary btn-red">Отправить</button>
    
    {'!rcv3_html' | snippet : [
        'action' => $rcv3Action,
        'error' => $_modx->getPlaceholder('fi.error.g-recaptcha-response'),
    ]}
</form>
emailTpl — чанк, который содержит текст письма. Пример:
<p>Добавлен новый отзыв на сайте {$_modx->config.site_url}</p>

<p><strong>Контакты</strong></p>
<p>Имя: {$name}</p>
<p>Телефон: {$phone}</p>

<p><strong>Отзыв</strong></p>
<p>{$text | nl2br}</p>
validate
name:required — Поле является обязательным
:russian — Поле обязательно на русском языке (дополнительная защита от ботов. об этом ниже)
text:required — поле текст отзыва — обязательное

customValidators — мы указываем что подключаем кастомный валидатор russian. Если вы хотите так же, что бы была проверка на русский текст имени, то можете создать сниппет russian со следующим содержимым:
<?php
if (preg_match("/[a-zA-Z0-9]+/ui", $value)) {
    $validator->addError($key, 'Имя должно быть на русском языке!');
    return false;
}
return false;
Так же самое главное — это создать сниппет addReview и в переменную $review_resource_id прописать ID ресурса «Отзывы»
<?php
$review_resource_id = 17;

$name = $hook->getValue('name');
$text = $hook->getValue('text');
$phone = $hook->getValue('phone');

if (empty($name) || empty($review)) {
    return false;
}

$doc = $modx->getObject('modResource', ['id' => $review_resource_id]);
$reviews = $doc->getTVValue('reviews');
$reviews_array = $modx->fromJSON($reviews);

$next_id = 1;
//get the next MIGX_id
if (is_array($reviews_array)) {
    foreach ($reviews_array as $item){
        $id = $modx->getOption('MIGX_id', $item, 0) + 1;
        if ($id > $next_id) {
            $next_id = $id;
        }
    }
} else {
    $reviews_array = array();
}

$item = array(
    'MIGX_id' => $next_id,
    'name' => $name,
    'text' => $text,
    'phone' => $phone,
);

$reviews_array[] = $item;
 
if (!$doc->setTVValue('reviews', $modx->toJson($reviews_array))) {
    $modx->log(modX::LOG_LEVEL_ERROR,'Проблемы при добавлении отзыва в сниппете addReview');
//   return false;
}

return true;

Ну и теперь можно вывести только опубликованные отзывы.
Обычный синтаксис modx
[[getImageList?
&tvname=`reviews`
&where=`{ "published:=":"1" }`
&tpl=`one.review.tpl`
]]

Fenom
{var $reviews = json_decode($_modx->resource.reviews, true)}
{if $reviews}
    <div class="row">
        {foreach $reviews as $one}
            {if !$one.published} {continue} {/if}
            <div class="col-lg-4">
                <div class="card mb-2">
                    <div class="card-body">
                        <h5 class="card-title">{$one.name}</h5>
                        <p class="card-text">
                            {$one.text}
                        </p>
                    </div>
                </div>
            </div>
        {/foreach}
    </div>
{/if}
P.S. Для работы recaptchav3 в системных настройках, на вкладке Formit необходимо указать публичный и секретный ключи выданные гуглом.
Ivan
06 августа 2022, 22:41
modx.pro
3
336
+7

Комментарии: 7

Ivan
06 августа 2022, 22:44
0
Администрация, если я что-то нарушаю или делаю не правильно, то сообщите в комментариях и я все поправлю.
Игорь
07 августа 2022, 12:06
+1
Супер спасибо! Как раз вот искал самодельный способ без модулей на днях. Надо будет попробовать! Круто))
    Эдуард
    07 августа 2022, 22:51
    +3
    Я обычно подобные штуки делаю на migxdb с созданием отдельной таблицы в БД. (создаю пакет при помощи CMP Generator)
    Потом выношу ссылку на эти migx таблицы в верхнее меню.
    Плюсы: не нужно создавать отдельный ресурс с ТВ и отдельным шаблоном. Ну и прямая запись в эти таблицы очень удобно, если нужно туда что то писать через сниппеты.

    С migxdb можно даже еще дальше пойти и расширить базовые migxdb процессоры, тогда можно еще кастомизировать вывод и редактирование стандартных migx строк на свою логику. Там есть конечно ограничения, но для большинства задач хватает что бы, что-то накрутить свое )) Например добавить кнопку в строку с каким-то событием при клике по ней, или показывать кнопку Активировать, если строка не активна и наоборот.
    Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
    7