Вопрос/ответ с редактированием в отдельном модуле
Здравствуйте. Нужно реализовать следующее: неавторизованный пользователь на сайте оставляет отзыв и в админке, в отдельном модуле админ выбирает отправить его на публикацию или нет, а также при желании редактирует. Соответственно на странице отзывов выводятся одобренные отзывы.
Прошу подсказать модуль или решения, на базе которых можно самостоятельно осуществить подобный функционал. Если таковых нет, то сколько стоит решить мою задачу.
Прошу подсказать модуль или решения, на базе которых можно самостоятельно осуществить подобный функционал. Если таковых нет, то сколько стоит решить мою задачу.
Комментарии: 13
Думаю, это можно сделать с помощью Tickets.
Только не спрашивай, как именно — читай сразу историю изменений с первой версии.
Только не спрашивай, как именно — читай сразу историю изменений с первой версии.
Я уже не на первом сайте это делаю через MIGx db, пару сниппетов, формы на Formit и хука к ней.
В админке вопросы появляются в виде таблицы MIGx, как TV поле, там их можно удалять, публиковать, редактировать.
Если интересно — напишу попродробнее.
В админке вопросы появляются в виде таблицы MIGx, как TV поле, там их можно удалять, публиковать, редактировать.
Если интересно — напишу попродробнее.
Напишите, пожалуйста.
Алексей, если не сложно, прошу вас ответить по поводу
MIGx. Спасибо.
MIGx. Спасибо.
Извиняюсь, забыл. Сейчас в общих чертах накидаю код с одного из сайтов.
Пример с MIGx db, в общих чертах, код взят с одного из сайтов кусками, и для вашего сайта его надо будет переработать.
1. Настраиваем MIGx
1.1. Создаем таблицы в БД и объекты
— Ставим MIGx, как написано в документации к нему!
Я назвал этот «полукомпонент» xqa, все имена/префиксы делал с этим названием…
— Открываем MIGx в админке, и на первой вкладке создаем package xqa
— берем эту xml
— теперь создаем таблицы в БД на вкладке create Tables и создаем классы на вкладке parse Schema.
Таким образом мы получаем таблицу в БД и xpdo классы для работы с этой таблицей.
Структура моей таблицы:
1.2 Создаем MIGx настройку.
Идем в MIGx — вкладка MIGx (вторая вкладка с настройками)
Делаем новую xqa и по ней правой кнопкой — Экспорт/Импорт, вставляем следующий код:
2. Делаем стандартную форму на Formit, в которой должны быть поля author, author_email, question. Как вы ее реализуете — ваши заботы.
Что важно для нас, у Formit указываем хук xQaAdd:
&hooks=`email,xQaAdd`
Хук email я тоже использую, что бы пришло администратору сайта уведомление «Добавлен новый вопрос...».
Код хука примерно такой, т.е. мы просто создаем новый объект xQa (вопрос):
У ресурса должна появится таблица:
4. Уведомление пользователя об ответе:
Создаем плагин notifyVisitors на событие OnDocFormSave:
1. Настраиваем MIGx
1.1. Создаем таблицы в БД и объекты
— Ставим MIGx, как написано в документации к нему!
Я назвал этот «полукомпонент» xqa, все имена/префиксы делал с этим названием…
— Открываем MIGx в админке, и на первой вкладке создаем package xqa
— берем эту xml
<?xml version="1.0" encoding="UTF-8"?>
<model package="xqa" baseClass="xPDOObject" platform="mysql" defaultEngine="MyISAM" version="1.1">
<object class="xQa" table="xqa" extends="xPDOSimpleObject" >
<field key="resource_id" dbtype="int" precision="11" phptype="integer" null="false" default="0" />
<field key="author" dbtype="varchar" precision="255" phptype="string" null="false" default="" />
<field key="author_email" dbtype="varchar" precision="255" phptype="string" null="false" default="" />
<field key="question" dbtype="text" phptype="string" />
<field key="answer" dbtype="text" phptype="string" />
<field key="notify" dbtype="tinyint" precision="1" attributes="unsigned" phptype="integer" null="false" default="0" />
<field key="published" dbtype="tinyint" precision="1" attributes="unsigned" phptype="integer" null="false" default="0" />
<field key="createdby" dbtype="int" precision="10" phptype="integer" null="false" default="0" />
<field key="createdon" dbtype="datetime" phptype="datetime" null="false" />
<field key="editedby" dbtype="int" precision="10" phptype="integer" null="false" default="0" />
<field key="editedon" dbtype="datetime" phptype="datetime" null="false" />
<field key="deleted" dbtype="tinyint" precision="1" attributes="unsigned" phptype="integer" null="false" default="0" />
<field key="deletedon" dbtype="datetime" phptype="datetime" null="false" />
<field key="deletedby" dbtype="int" precision="10" phptype="integer" null="false" default="0" />
<field key="publishedon" dbtype="datetime" phptype="datetime" null="false" />
<field key="publishedby" dbtype="int" precision="10" phptype="integer" null="false" default="0" />
<index alias="PRIMARY" name="PRIMARY" primary="true" unique="true">
<column key="id" collation="A" null="false" />
</index>
<aggregate alias="Resource" class="modResource" local="resource_id" foreign="id" cardinality="one" owner="foreign" />
</object>
</model>
и на вкладке xml schema ждем save, сохраняя ее.— теперь создаем таблицы в БД на вкладке create Tables и создаем классы на вкладке parse Schema.
Таким образом мы получаем таблицу в БД и xpdo классы для работы с этой таблицей.
Структура моей таблицы:
resource_id - документ, к которому "привязан" вопрос
author - имя автора
author_email - его email
question - текст вопроса
answer - текст ответа
notify - галочка, символизирующая что нужно отправить уведомление автору о том, что не его вопрос появился ответ
---- с колонками ниже MIGx работает САМ, т.е. мы в коде ничего с ними не делаем, они сами заполняются
published
createdby
createdon
editedby
editedon
deleted
deletedon
deletedby
publishedon
publishedby
1.2 Создаем MIGx настройку.
Идем в MIGx — вкладка MIGx (вторая вкладка с настройками)
Делаем новую xqa и по ней правой кнопкой — Экспорт/Импорт, вставляем следующий код:
{
"formtabs":[
{
"MIGX_id":1,
"caption":"\u0412\u043e\u043f\u0440\u043e\u0441-\u043e\u0442\u0432\u0435\u0442",
"print_before_tabs":"0",
"fields":[
{
"MIGX_id":1,
"field":"author",
"caption":"\u0410\u0432\u0442\u043e\u0440",
"description":"",
"description_is_code":"0",
"inputTV":"",
"inputTVtype":"",
"validation":"",
"configs":"",
"sourceFrom":"config",
"sources":"[]",
"inputOptionValues":"",
"default":""
},
{
"MIGX_id":4,
"field":"author_email",
"caption":"E-mail",
"description":"",
"description_is_code":"0",
"inputTV":"",
"inputTVtype":"",
"validation":"",
"configs":"",
"sourceFrom":"config",
"sources":"[]",
"inputOptionValues":"",
"default":""
},
{
"MIGX_id":2,
"field":"question",
"caption":"\u0412\u043e\u043f\u0440\u043e\u0441",
"description":"",
"description_is_code":"0",
"inputTV":"",
"inputTVtype":"textarea",
"validation":"",
"configs":"",
"sourceFrom":"config",
"sources":"[]",
"inputOptionValues":"",
"default":""
},
{
"MIGX_id":3,
"field":"answer",
"caption":"\u041e\u0442\u0432\u0435\u0442",
"description":"",
"description_is_code":"0",
"inputTV":"",
"inputTVtype":"textarea",
"validation":"",
"configs":"",
"sourceFrom":"config",
"sources":"[]",
"inputOptionValues":"",
"default":""
},
{
"MIGX_id":6,
"field":"notify",
"caption":"\u0423\u0432\u0435\u0434\u043e\u043c\u0438\u0442\u044c \u0430\u0432\u0442\u043e\u0440\u0430 \u043e\u0431 \u043e\u0442\u0432\u0435\u0442\u0435?",
"description":"",
"description_is_code":"0",
"inputTV":"",
"inputTVtype":"listbox",
"validation":"",
"configs":"",
"sourceFrom":"config",
"sources":"[]",
"inputOptionValues":"\u041d\u0435\u0442==||\u0414\u0430==1",
"default":""
},
{
"MIGX_id":5,
"field":"published",
"caption":"\u041e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d",
"description":"",
"description_is_code":"0",
"inputTV":"",
"inputTVtype":"listbox",
"validation":"",
"configs":"",
"sourceFrom":"config",
"sources":"[]",
"inputOptionValues":"\u041d\u0435\u0442==||\u0414\u0430==1",
"default":""
}
]
}
],
"contextmenus":"update||publish||unpublish||recall_remove_delete",
"actionbuttons":"addItem||toggletrash",
"columnbuttons":"",
"filters":"[]",
"extended":{
"migx_add":"\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432\u043e\u043f\u0440\u043e\u0441",
"formcaption":"",
"update_win_title":"\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u043e\u043f\u0440\u043e\u0441",
"win_id":"xqa",
"maxRecords":"",
"addNewItemAt":"top",
"multiple_formtabs":"",
"extrahandlers":"",
"packageName":"xqa",
"classname":"xQa",
"task":"",
"getlistsort":"createdon",
"getlistsortdir":"DESC",
"use_custom_prefix":"0",
"prefix":"",
"grid":"",
"gridload_mode":2,
"check_resid":1,
"check_resid_TV":"",
"join_alias":"",
"has_jointable":"yes",
"getlistwhere":"",
"joins":"",
"cmpmaincaption":"",
"cmptabcaption":"",
"cmptabdescription":"",
"cmptabcontroller":"",
"winbuttons":"",
"onsubmitsuccess":"",
"submitparams":""
},
"columns":[
{
"MIGX_id":7,
"header":"ID",
"dataIndex":"id",
"width":"",
"sortable":"false",
"show_in_grid":"0",
"renderer":"",
"clickaction":"",
"selectorconfig":"",
"renderchunktpl":"",
"renderoptions":"[]"
},
{
"MIGX_id":6,
"header":"\u0414\u0430\u0442\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f",
"dataIndex":"createdon",
"width":"",
"sortable":"false",
"show_in_grid":1,
"renderer":"this.renderDate",
"clickaction":"",
"selectorconfig":"",
"renderchunktpl":"",
"renderoptions":"[]"
},
{
"MIGX_id":1,
"header":"\u0410\u0432\u0442\u043e\u0440",
"dataIndex":"author",
"width":"",
"sortable":"false",
"show_in_grid":1,
"renderer":"",
"clickaction":"",
"selectorconfig":"",
"renderchunktpl":"",
"renderoptions":"[]"
},
{
"MIGX_id":8,
"header":"E-mail",
"dataIndex":"author_email",
"width":"",
"sortable":"false",
"show_in_grid":1,
"renderer":"",
"clickaction":"",
"selectorconfig":"",
"renderchunktpl":"",
"renderoptions":"[]"
},
{
"MIGX_id":2,
"header":"\u0412\u043e\u043f\u0440\u043e\u0441",
"dataIndex":"question",
"width":"",
"sortable":"false",
"show_in_grid":1,
"renderer":"",
"clickaction":"",
"selectorconfig":"",
"renderchunktpl":"",
"renderoptions":"[]"
},
{
"MIGX_id":3,
"header":"\u041e\u0442\u0432\u0435\u0442",
"dataIndex":"answer",
"width":"",
"sortable":"false",
"show_in_grid":1,
"renderer":"",
"clickaction":"",
"selectorconfig":"",
"renderchunktpl":"",
"renderoptions":"[]"
},
{
"MIGX_id":9,
"header":"\u0423\u0432\u0435\u0434\u043e\u043c\u0438\u0442\u044c?",
"dataIndex":"notify",
"width":"",
"sortable":"false",
"show_in_grid":1,
"renderer":"this.renderCrossTick",
"clickaction":"",
"selectorconfig":"",
"renderchunktpl":"",
"renderoptions":"[]"
},
{
"MIGX_id":4,
"header":"\u041e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d",
"dataIndex":"published",
"width":"",
"sortable":true,
"show_in_grid":1,
"renderer":"this.renderCrossTick",
"clickaction":"",
"selectorconfig":"",
"renderchunktpl":"",
"renderoptions":"[]"
},
{
"MIGX_id":5,
"header":"\u0423\u0434\u0430\u043b\u0435\u043d",
"dataIndex":"deleted",
"width":"",
"sortable":"false",
"show_in_grid":"0",
"renderer":"",
"clickaction":"",
"selectorconfig":"",
"renderchunktpl":"",
"renderoptions":"[]"
}
]
}
Сохраняем и ради интереса жмем редактировать, смотрим какие поля и колонки у нас есть.2. Делаем стандартную форму на Formit, в которой должны быть поля author, author_email, question. Как вы ее реализуете — ваши заботы.
Что важно для нас, у Formit указываем хук xQaAdd:
&hooks=`email,xQaAdd`
Хук email я тоже использую, что бы пришло администратору сайта уведомление «Добавлен новый вопрос...».
Код хука примерно такой, т.е. мы просто создаем новый объект xQa (вопрос):
$resource_id = $modx->resource->get('id');
$modx->addPackage('xqa', MODX_CORE_PATH.'components/xqa/model/');
$qa = $modx->newObject('xQa');
$qa->set('author', strip_tags($hook->getValue('author')));
$qa->set('author_email', strip_tags($hook->getValue('author_email')));
$qa->set('question', strip_tags($hook->getValue('question')));
$qa->set('resource_id', $resource_id);
$qa->set('published', 0);
$qa->set('createdby', 1);
$qa->set('createdon', strtotime("now"));
$qa->save();
return true;
3. Делаем TV поле с типом ввода migxdb, указываем Конфигурацию xqa (мы ее выше создавали), назначаем TV нужному шаблону.У ресурса должна появится таблица:
4. Уведомление пользователя об ответе:
Создаем плагин notifyVisitors на событие OnDocFormSave:
<?php
if($modx->event->name != 'OnDocFormSave'){
return false;
}
$template = $resource->get('template');
switch($template){
case 7:
case 15:
// Вопрос-ответ
$modx->addPackage('xqa', MODX_CORE_PATH.'components/xqa/model/');
$qas = $modx->getCollection('xQa', array('deleted' => 0, 'notify' => 1, 'resource_id' => $resource->get('id')));
foreach($qas as $qa){
$to = $qa->get('author_email');
if(!empty($to)){
// ЗДЕСЬ отправляем письмо, объект $qa у нас есть
}
$qa->set('notify', 0);
$qa->save();
}
break;
default:
return false;
}
Что делает плагин: при сохранении ресурса получаем все xQa, у которых стоит галочка «Оповестить автора об ответе», далее, например, отправляем письмо (я НЕ ПРИВОЖУ этот код, напишите его сами), ставим notify в 0.
Спасибо большое!
Подскажите, а как лучше вывести ответы и вопросы?
getImageList почему-то не работает.
getImageList почему-то не работает.
Решено.
Использовал
Использовал
[[!pdoPage?
&elementClass=`modSnippet`
&element=`migxLoopCollection`
&limit=`1`
&packageName=`xqa`
&classname=`xQa`
&tpl=`return-questions`
&where=`{"published":"1","deleted":"0"}`
]]
[[!+page.nav]]
Подскажите, а как выполнять сортировку вопросов при выводе по дате (полю published)?
Можно сделать свой собственный компонент. Либо по урокам Василия Наумкина, либо по этим кратким описаниям: фронтенд, бэкенд.
Спасибо, у вас очень интересный сайт.
Спасибо, я старался)
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.