Переносим вопрос-ответ из файлов в Tickets
Имеем сайт, на котором система вопрос-ответ была разложена по отдельным htm/php файлам.
Для разборки данных использовался тупо парсинг файлов. До simple_html_dom.php руки не дошли.
Исходный сайт был в CP1251. Новый в UTF-8.
Процесс такой:
Получаем из файлов исходные данные,
создаём уникального юзера (без мыла, хотя можно и своё уникальное мыло заделать) для каждого тикета,
создаём тикет с придуманной датой,
апдейтим тикету intro текст,
создаём тред,
создаём коммент с придуманной датой ответа,
обновляем тред с количеством ответов 1 (по условиям задачи).
POSTUPD. А это правильно, что при постинге кода в сообщении тэг
(меньше br больше) таки превращается в перенос строки, а не экранируется?!
Перед строкой
И так два раза в тексте.
Там должно быть (меньше br больше)
а на следующей строке (меньше br дробь больше)
UPD2 Также в коде потерялся nbsp, поставил метки в двух местах, где он должен быть
Сниппет importOtzivi будем вызывать с любой (специально созданной) страницы
создаём основной сниппет importOtzivi
создаём сниппет otzyvyCreateTicket
создаём сниппет otzyvyCreateTicketComment
создаём сниппет otzyvyCreateTicketPatch
создаём сниппет класса otzyvyCreateTicketPatchClass
Для разборки данных использовался тупо парсинг файлов. До simple_html_dom.php руки не дошли.
Исходный сайт был в CP1251. Новый в UTF-8.
Процесс такой:
Получаем из файлов исходные данные,
создаём уникального юзера (без мыла, хотя можно и своё уникальное мыло заделать) для каждого тикета,
создаём тикет с придуманной датой,
апдейтим тикету intro текст,
создаём тред,
создаём коммент с придуманной датой ответа,
обновляем тред с количеством ответов 1 (по условиям задачи).
POSTUPD. А это правильно, что при постинге кода в сообщении тэг
(меньше br больше) таки превращается в перенос строки, а не экранируется?!
Перед строкой
$strQ=str_replace('<br />',"\n",$strQ);
ещё две строки испортились при постинге текста сюда.И так два раза в тексте.
Там должно быть (меньше br больше)
а на следующей строке (меньше br дробь больше)
UPD2 Также в коде потерялся nbsp, поставил метки в двух местах, где он должен быть
Если кому-то будет полезно, я буду рад donate
яндекс.деньги: 410011014866448
сбербанк: 4276838074015787
paypal: kmd@kmd.ru
Благодарю.
Сниппет importOtzivi будем вызывать с любой (специально созданной) страницы
[[!importOtzivi?
]]
создаём основной сниппет importOtzivi
<?php
//придумываем стартовую дату, с которой будут создаваться комменты
$kmdTicketDate=array(
'startUDate' => strtotime("2010/01/01"),
'addDays' => 0,
);
//имя отвечатора на вопросы. Можно конечно добывать это из modX, но...
$kmdAAN='Владимир Владимирович';
//в коде можно включить уникальность почты для отвечатора, теперь уже не знаю зачем так было сделал, но на gmail.com можно указывать ящик vasya+comment@gmail.com, чтобы ящики были как бы разными, а приходилось всё на один ящик на gmail.com
$kmdAemail='vasya@g.mail';
/*
//обнуляем таблицы базы данных, чтобы повторить импорт
//вызов для phpMyAdmin
DELETE FROM `modx_users` WHERE `id`>8;
DELETE FROM `modx_user_attributes` WHERE `id`>8;
DELETE FROM `modx_site_content` WHERE `id`>8;
DELETE FROM `modx_tickets_threads` WHERE `id`>8;
DELETE FROM `modx_tickets_comments` WHERE `id`>8;
*/
//подгружаем "свои" классы
$modx->runSnippet('otzyvyCreateTicketPatchClass');
$modx->runSnippet('otzyvyCreateTicketCommentClass');
//С помощью этой штуки уже не стал переписывать (нашёл её позже, чем всё дописал, оставался только один неотлавливающийся глючок)
//include_once('/usr/home/site/www/simple_html_dom.php');
//разбираем файл по таким метко-блокам: [<h1>]Название[</h1>][Автор:]Имя автора[Вопрос:]Текст вопроса[Ответ:]Текст ответа[</td>]
//ясное дело, что тут всё сугубо индивидуальное
//директория, где лежат файлы с вопрос-ответами
$dir='/usr/home/site/www/old/otzivi';
//куда будем переносить отработанные файлы (вложенная директория)
$dirdone='done';
//сканируем директорию для получения файлов
$scanned_directory = array_diff(scandir($dir), array('..', '.'));
natsort($scanned_directory);
foreach($scanned_directory as $fn) {
//выбираем *.htm файлы
if(trim(substr($fn,strrpos($fn,'.')))=='.htm'){
//получаем имя файла
$filen=substr($fn,0,strrpos($fn,'.'));
//полное имя файла
$fname="$dir/$fn";
//echo "<p><h2>$fname</h2>";
$str=file_get_contents($fname);
//исправляем глюк разметки, когда : стоит не с той стороны тэга
$str=str_replace('</strong>:',':</strong>',$str);
//echo strlen($str);
//ищем первую отсечку
$srch='<h1>';
$str1=explode($srch,$str);
//echo '<br />'.count($str1);
switch(count($str1)){
case '1': //echo '<br />WARNING! Строка '.$srch.' не найдена!';
break;
case '2':
$srch='</h1>';
unset($str);
//ищем вторую отсечку, чтобы найти Имя вопрос-ответа
list($strName,$str)=explode($srch,$str1[1]);
//конвертим в UTF-8
$strName=iconv('CP1251','UTF-8',trim($strName));
//для дебага получаемой информации в браузере
//echo '<br />`'.htmlspecialchars($strName).'`';
//начинаем искать автора
$srchU='Автор:';
$srch=iconv('UTF-8','CP1251',$srchU);
unset($str1);
//разбиваем остаток строки по следующей метке
$str1=explode($srch,$str);
unset($str);
$cs=count($str1);
switch($cs){
case '1':
//если слова "Автор:" не нашлось, то будем обрезать до предыдущего тэга </h1>
$str=$str1[0];
break;
case '2':
//если "Автор:" всё-таки нашлось
$str=$str1[1];
break;
default:
echo '<br />WARNING! Больше одного '.$srchU;
break;
}
if(($cs==1)|($cs==2)){
$srchU='Вопрос:';
$srch=iconv('UTF-8','CP1251',$srchU);
unset($str1);
//Теперь обрезаем имя автора по тегу "Вопрос:"
$str1=explode($srch,$str,2);
unset($str);
switch(count($str1)){
case '1': //echo "<br />WARNING! Строка `$srchU` не найдена!";
break;
case '2':
$strAutor=$str1[0];
//убиваем лишние пробелы. у спец.функции php с nbsp есть какие-то проблемы - оно кодируется в какой-то левый символ, поэтому не пользуемся
//WARN здесь должен быть nbsp, который при постинге потерялся
$strAutor=trim(str_replace('nbsp',' ',$strAutor));
$strAutor=preg_replace('/ {2,}/',' ',$strAutor);
$strAutor=iconv('CP1251','UTF-8',trim(strip_tags($strAutor)));
//$strAutor=htmlspecialchars($strAutor);
//создаём нового автора, причём из каждого файла создаётся новый автор. Для уникальности добавляем название файла до точки, у нас они были числовыми.
if (!$strAutor) $strAutor='Аноним'.$filen;
echo '<br /><b>Автор:</b> `'.$strAutor.'`';
$srchU='Ответ:';
$srch=iconv('UTF-8','CP1251',$srchU);
unset($str);
$str=$str1[1];
unset($str1);
//обрезаем остаток строки по "Ответ:", чтобы найти текст "Вопрос:"
$str1=explode($srch,$str);
$cs=count($str1);
switch($cs){
case '1':
//В данном файле нет "Ответ:"а, поэтому находим текст "Вопрос:"а по завершающему тэгу </td>
echo "<br />WARNING! Строка `$srchU` не найдена!";
$srch='</td>';
$str=$str1[0];
$str1=explode($srch,$str,2);
$strQ=$str1[0];
break;
case '2':
//Стандартный файл - будет "Ответ:".
$strQ=$str1[0];
break;
default:
echo '<br />WARNING! Больше одного '.$srchU;
break;
}
if(($cs==1)|($cs==2)){
//Нашли текст Вопроса
//будем убивать лишние пробелы
//WARN здесь должен быть nbsp, который при постинге потерялся
$strQ=str_replace('nbsp',' ',$strQ);
//меняем на <b>, потому что <strong> для чего-то реально важного нужно пользовать
$strQ=str_replace('<strong>','<b>',$strQ);
$strQ=str_replace('</strong>','</b>',$strQ);
//убиваем переносы строк, чтобы потом они не всплыли в ненужных местах
$strQ=str_replace("\n",' ',$strQ);
$strQ=str_replace("\r",' ',$strQ);
//убиваем двойные пробелы
$strQ=preg_replace('/ {2,}/',' ',$strQ);
//так как разметка у нас была не очень, тэги могли быть ацки напутаны, переносы, короче вот это вот всё мы конвертируем в переносы строк
$strQ=str_replace('<p>',"\n",$strQ);
$strQ=str_replace('</p>',"\n",$strQ);
$strQ=str_replace('
',"\n",$strQ);
$strQ=str_replace('
',"\n",$strQ);
$strQ=str_replace('<br />',"\n",$strQ);
//убиваем все тэги, кроме выделяторных
$strQ=trim(strip_tags($strQ,'<a></a><u></u><i></i><b></b>'));
//конвертируем строку в архив
$strQa=explode("\n",$strQ);
foreach($strQa as $val){
//тэг жирности <b> оказывался до слова "Вопрос:" или "Ответ:", поэтому он оказывался один на строке
$val=trim($val);
//а завершающий тэг </b> был в начале строки, поэтому мы его обрезаем.
//имеется в виду <b>Ответ:</b>, в итоге <b>попадало в текст вопроса, а </b> в текст ответа.
if(substr($val,0,4)=='</b>'){$val=trim(substr($val,4));}
if($val=='<b>'){$val='';}
if($val){
//записываем в новый массив только непустые строки
$strQn[]=$val;
}
}
//превращаем массив в строку, правильно разбитые по абзацам.
$strQ='<p>'.implode('</p><p>',$strQn).'</p>';
//очищаем отработанные массивы
unset($strQa);
unset($strQn);
$strQ=iconv('CP1251','UTF-8',$strQ);
//$strQ=htmlspecialchars($strQ);
$strQsave=$strQ;
if(mb_strlen($strQ)>600){
$strQ=mb_substr($strQ,0,600).''.mb_substr($strQ,600);
}
echo '<br /><b>Вопрос:'.mb_strlen($strQ).'</b> `'.$strQ.'`';
$srchU='</td>';
$srch=$srchU;
unset($str);
$str=$str1[1];
unset($str1);
//обрезаем текст "Ответ:"а
$str1=explode($srch,$str,2);
switch(count($str1)){
case '1': echo '<br />WARNING! Строка '.$srchU.' не найдена!'; break;
case '2':
//работаем со строкой так же, как и выше
$strA=$str1[0];
$strA=str_replace(' ',' ',$strA);
$strA=str_replace('<strong>','<b>',$strA);
$strA=str_replace('</strong>','</b>',$strA);
$strA=str_replace("\n",' ',$strA);
$strA=str_replace("\r",' ',$strA);
$strA=preg_replace('/ {2,}/',' ',$strA);
$strA=str_replace('<p>',"\n",$strA);
$strA=str_replace('</p>',"\n",$strA);
$strA=str_replace('
',"\n",$strA);
$strA=str_replace('
',"\n",$strA);
$strA=str_replace('<br />',"\n",$strA);
$strA=trim(strip_tags($strA,'<a></a><u></u><i></i><b></b>'));
$strAa=explode("\n",$strA);
foreach($strAa as $val){
$val=trim($val);
if(substr($val,0,4)=='</b>'){$val=trim(substr($val,4));}
if($val){
$strAn[]=$val;
}
}
if(count($strAn)){
$strA='<p>'.implode('</p><p>',$strAn).'</p>';
$strA=iconv('CP1251','UTF-8',$strA);
//$strA=htmlspecialchars($strA);
echo '<br /><b>Ответ:</b> `'.$strA.'`';
}
unset($strAa);
unset($strAn);
//Если такой вопрошатель уже есть в базе, то в имени мы дописываем уникальный хвост (название файла)
if($modx->getObject('modUser', array('username' => $strAutor))){
$strAutor.=$filen;
}
//создаём юзера
$kmdUser = $modx->newObject('modUser', array('username' => $strAutor, 'password' => md5($strAutor)));
$kmdUser->save();
//записываем ему полное имя для отобращения в тикетах
if($kmdUserID=$kmdUser->get('id')){
$kmdUserProfile = $modx->newObject('modUserProfile');
$kmdUserProfile->fromArray(array(
'internalKey' => $kmdUserID,
'fullname' => $strAutor,
//сюда можно добавлять уникальный email по типу vasya+userid$kmdUserID@g.mail
));
$kmdUserProfile->save();
}
//создаём тикет штатными средствами
if($kmdResourceID = $modx->runSnippet('otzyvyCreateTicket', array(
'kmdTicketName' => $strName,
'kmdTicketContent' => $strQ,
//безмазовая попытка
//'kmdTicketIntro' => trim(strip_tags(mb_substr($strQ,0,1000),'')),
)))
{
//придумываем дату нового сообщения большую на сколько-то дней
$kmdTicketDate['addDays']+=rand(2,7);
//добавляем часы и минуты для задающего вопросы. Предполагаем, что это может случиться 24h
$kmdTicketDateAddTimeQ=rand(60*60,24*60*60);
$kmdCurrentTicketDate=$kmdTicketDate['startUDate']+$kmdTicketDate['addDays']*24*60*60+$kmdTicketDateAddTimeQ;
//предполагаем, что отвечают на вопросы только в рабочее время
$kmdTicketDateAddTimeA=rand(8*60*60,20*60*60);
$kmdCurrentAnswerDate=$kmdTicketDate['startUDate']+$kmdTicketDate['addDays']*24*60*60+$kmdTicketDateAddTimeA;
//если время ответа не больше чем на час времени вопроса, то добавляем сутки. Не знаю как сформулировать точнее =]]
if(($kmdTicketDateAddTimeA-$kmdTicketDateAddTimeQ)<60*60){
$kmdCurrentAnswerDate+=24*60*60;
}
echo $kmdResourceID.'`'.$kmdTicketDateAddTimeQ.'`'.$kmdCurrentTicketDate.'`'.$kmdUserID;
//патчим текст вопроса (тикета) с помощью "своего" класса
$output = $modx->runSnippet('otzyvyCreateTicketPatch', array(
'id' => $kmdResourceID,
'createdby' => $kmdUserID,
'createdon' => $kmdCurrentTicketDate,
'publishedby' => $kmdUserID,
'publishedon' => $kmdCurrentTicketDate,
//в свой патчер тикетов запихиваем текст Вопроса без
'content' => $strQsave,
));
echo $output;
echo '*'.$fname.'*';
//уносим обработанный файл в другую директорию, чтобы второй раз не импортировать
exec("/bin/mv $fname $dir/$dirdone/");
//есть нет ответа, то отваливаем
if(!$strA){ continue;}
echo '=';
//ответ размещаем через "свой" класс
if($output = $modx->runSnippet('otzyvyCreateTicketComment', array(
'kmdResourceID' => $kmdResourceID,
'kmdAuthorName' => $kmdAAN,
//'kmdAuthorEmail' => 'vasya+id.'.$kmdResourceID.'@g.mail',
'kmdAuthorEmail' => $kmdAemail,
'kmdComment' => $strA,
'kmdThreadTime' => date('Y-m-d H:i:s',$kmdCurrentTicketDate),
'kmdCommentTime' => date('Y-m-d H:i:s',$kmdCurrentAnswerDate),
)))
{
echo $output;
}
} else {
echo 'ОБЛОМ. Так не может быть. Правь исходный файл.';
$modx->log(modX::LOG_LEVEL_ERROR, 'my error:' .$kmdResourceID->getMessage());
//exit;
}
//exit;
break;
default:
echo '<br />WARNING! Больше одного '.$srchU;
break;
}
}
break;
default:
echo '<br />WARNING! Больше одного '.$srchU;
break;
}
} else {
echo 'kooko';
}
break;
default: echo '<br />WARNING! Больше одного '.$srchU; break;
}
//echo '<br /><b>';
//echo $fname;
//echo '</b>';
} else {
//echo '<br /><i>';
//echo $fn;
//echo '</i>';
//echo implode($scanned_directory,'<br />');
}
}
создаём сниппет otzyvyCreateTicket
<?php
//создаём тикет стандартными средствами MODX
$kmdTicketName=$scriptProperties['kmdTicketName'];
$kmdTicketContent=$scriptProperties['kmdTicketContent'];
//когда постил сообщение на modx.pro нашёл тут баг, наверное из-за него были косяки с интро
//было так написано:
//$$kmdTicketIntro=$scriptProperties['$kmdTicketIntro'];
//проверять уже не стал
$kmdTicketIntro=$scriptProperties['$kmdTicketIntro'];
$processorProps = array(
'class_key' => 'Ticket',
'parent' => 4,
'richtext' => 1,
'pagetitle' => $kmdTicketName,
'content' => $kmdTicketContent,
'introtext' => $kmdTicketIntro,
'published' => 1,
//'template' => 3, //здесь template не установится, можно не пытаться. )) Смотри ниже как сделать.
);
$otherProps = array();
$response = $modx->runProcessor('resource/create', $processorProps, $otherProps);
if ($response->isError()) {
$modx->log(modX::LOG_LEVEL_ERROR, 'my error:' .$response->getMessage());
} else {
$TicketArray = $response->getObject();
$kmdResourceID=$TicketArray['id'];
//если нужно по каким-то причинам прописать свой template id, а не который устанавливается по умолчанию
//$TicketArrayO=$modx->getObject('modResource',array('id' => $kmdResourceID));
//$TicketArrayO->set('template',3);
//$TicketArrayO->save();
return $kmdResourceID;
}
return false;
создаём сниппет otzyvyCreateTicketComment
<?php
$kmdResourceID=$scriptProperties['kmdResourceID'];
//здесь указываем id отвечатора, у меня он один на весь сайт
$kmdCreatedbyID=2;
$kmdThreadName='resource-'.$kmdResourceID;
$kmdComment=$scriptProperties['kmdComment'];
$kmdAuthorName=$scriptProperties['kmdAuthorName'];
$kmdAuthorEmail=$scriptProperties['kmdAuthorEmail'];
$kmdThreadTime=$scriptProperties['kmdThreadTime'];
$kmdCommentTime=$scriptProperties['kmdCommentTime'];
if($kmdComment){
if($kmdThread=$modx->getObject('kmdTicketThread', array('name' => $kmdThreadName))){
if($kmdThreadID=$kmdThread->get('id')){
echo " id=".$kmdThreadID;
} else {
$modx->log(modX::LOG_LEVEL_ERROR, 'my error: Can`t get Ticket Thread ID');
}
} else {
//создаём трэд
$kmdThread=$modx->newObject('kmdTicketThread',array(
'resource' => $kmdResourceID,
'name' => $kmdThreadName,
//в подписчики добавляем отвечатора
'subscribers' => '['.$kmdCreatedbyID.']',
'createdon' => $kmdThreadTime,
'createdby' => $kmdCreatedbyID,
'comment_last' => 0,
'comment_time' => '',
'comments' => 0,
'properties' => '{"thread":"resource-'.$kmdResourceID.'","fastMode":true,"gravatarIcon":"mm","gravatarSize":"24","gravatarUrl":"https:\/\/www.gravatar.com\/avatar\/","tplCommentForm":"tpl.Tickets.comment.form","tplCommentFormGuest":"tpl.Tickets.comment.form.guest","tplCommentAuth":"tpl.Tickets.comment.one.auth","tplCommentGuest":"tpl.Tickets.comment.one.guest","tplCommentDeleted":"tpl.Tickets.comment.one.deleted","tplComments":"tpl.Tickets.comment.wrapper","tplLoginToComment":"tpl.Tickets.comment.login","tplCommentEmailOwner":"tpl.Tickets.comment.email.owner","tplCommentEmailReply":"tpl.Tickets.comment.email.reply","tplCommentEmailSubscription":"tpl.Tickets.comment.email.subscription","tplCommentEmailBcc":"tpl.Tickets.comment.email.bcc","tplCommentEmailUnpublished":"tpl.Tickets.comment.email.unpublished","autoPublish":true,"autoPublishGuest":true,"formBefore":false,"depth":0,"allowGuest":false,"allowGuestEdit":true,"allowGuestEmails":false,"enableCaptcha":true,"minCaptcha":1,"maxCaptcha":10,"requiredFields":"name,email","threadUrl":"","resource":'.$kmdResourceID.',"snippetPrepareComment":"","commentEditTime":"600"}',
));
$kmdThread->save();
$kmdThreadID=$kmdThread->get('id');
}
if($kmdThreadID){
//создаём коммент
$newComment=$modx->newObject('kmdTicketComment',array(
'thread' => $kmdThreadID,
'text' => $kmdComment,
'raw' => $kmdComment,
'name' => $kmdAuthorName,
'email' => $kmdAuthorEmail,
'createdon' => $kmdCommentTime,
'createdby' => $kmdCreatedbyID,
'published' => 1,
'properties' => '{"requiredFields":"name,email"}',
));
$newComment->save();
if($newCommentID=$newComment->get('id')){
//echo '`'.$newCommentID.'`';
//обновляем данные трэда по последнему комменту
$kmdThread->set('comment_last',$newCommentID);
$kmdThread->set('comment_time',$kmdCommentTime);
//по условиям задачи у нас только один коммент, то есть 1 ответ
$kmdComments=1;
$kmdThread->set('comments',$kmdComments);
$kmdThread->save();
}
}
}
//return $kmdThreadTime;
создаём сниппет otzyvyCreateTicketPatch
<?php
//я не понял, почему при создании тикета штатными стредствами на некоторых тикетах introtext получается пустой
//поэтому обновляем introtext и content уже своим способом
$id=$scriptProperties['id'];
//echo $id;
//if($kmdSiteContentO=$modx->getObject('kmdSiteContent',array('id' => $scriptProperties['id']))){
if($kmdSiteContentO=$modx->getObject('kmdSiteContent',$id)){
$debug='est object '.$id;
$kmdSiteContentO->set('createdby',$scriptProperties['createdby']);
$kmdSiteContentO->set('createdon',$scriptProperties['createdon']);
$kmdSiteContentO->set('publishedby',$scriptProperties['publishedby']);
$kmdSiteContentO->set('publishedon',$scriptProperties['publishedon']);
} else {
$debug='NO object '.$id;
}
$strQ=$scriptProperties['content'];
//echo $strQ;
//следующая строка уже неактуальна, потому что стали передавать сюда строку без ,
//потому что с ней были какие-то глюки, может из-за кэша, может ещё из-за чего, но не на всех тикетах отсвечивали три точки
//$strQ = str_replace('','',$scriptProperties['content']);
//обрезаем по 800 символов
if(mb_strlen($strQ)>800){
$introtext = mb_substr($strQ,0,800).'...';
} else {
$introtext = $strQ;
}
$kmdSiteContentO->set('introtext',$introtext);
$kmdSiteContentO->set('content',$strQ);
if($kmdSiteContentO->save()){
return 'save ok. '.$debug;
} else {
return 'save error. '.$debug;
}
<u>создаём сниппет класса <b>otzyvyCreateTicketCommentClass</b></u>
<code><?php
$modx->map['kmdTicketThread'] = array (
'table' => 'tickets_threads',
'fields' =>
array (
'id' => '',
'resource' => '',
'name' => '',
'subscribers' => '',
'createdon' => null,
'createdby' => '',
'comment_last' => '',
'comment_time' => null,
'comments' => '',
'properties' => '',
),
'fieldMeta' =>
array (
'id' =>
array(
'dbtype' => 'integer',
'phptype' => 'integer',
'null' => false,
'index' => 'pk',
'generated' => 'native',
'attributes' => 'unsigned',
),
'resource' =>
array (
'dbtype' => 'int',
'precision' => '10',
'phptype' => 'integer',
'attributes' => 'unsigned',
'null' => false,
'default' => 0,
),
'name' =>
array (
'dbtype' => 'varchar',
'precision' => '255',
'phptype' => 'string',
'null' => false,
'default' => '',
),
'subscribers' =>
array (
'dbtype' => 'text',
'phptype' => 'json',
'null' => false,
'default' => '',
),
'createdon' =>
array (
'dbtype' => 'datetime',
'phptype' => 'datetime',
'null' => true,
),
'createdby' =>
array (
'dbtype' => 'integer',
'precision' => '10',
'phptype' => 'integer',
'attributes' => 'unsigned',
'null' => false,
'default' => 0,
),
'comment_last' =>
array (
'dbtype' => 'int',
'precision' => '10',
'phptype' => 'integer',
'attributes' => 'unsigned',
'null' => false,
'default' => 0,
),
'comment_time' =>
array (
'dbtype' => 'datetime',
'phptype' => 'datetime',
'null' => true,
'index' => 'index',
),
'comments' =>
array (
'dbtype' => 'int',
'precision' => '10',
'phptype' => 'integer',
'attributes' => 'unsigned',
'null' => true,
'default' => 0,
),
'properties' =>
array (
'dbtype' => 'text',
'phptype' => 'json',
'null' => true,
),
),
);
class kmdTicketThread extends xPDOObject{}
class kmdTicketThread_mysql extends kmdTicketThread{}
$modx->map['kmdTicketComment'] = array (
'table' => 'tickets_comments',
'fields' =>
array (
'id' => '',
'thread' => '',
'text' => '',
'raw' => '',
'name' => '',
'email' => '',
'createdon' => null,
'createdby' => '',
'published' => '',
'properties' => '',
),
'fieldMeta' =>
array (
'id' =>
array(
'dbtype' => 'integer',
'phptype' => 'integer',
'null' => false,
'index' => 'pk',
'generated' => 'native',
'attributes' => 'unsigned',
),
'thread' =>
array (
'dbtype' => 'int',
'precision' => '10',
'phptype' => 'integer',
'attributes' => 'unsigned',
'null' => false,
'default' => 0,
),
'text' =>
array (
'dbtype' => 'text',
'phptype' => 'text',
'null' => false,
'default' => '',
),
'raw' =>
array (
'dbtype' => 'text',
'phptype' => 'text',
'null' => false,
'default' => '',
),
'name' =>
array (
'dbtype' => 'varchar',
'precision' => '255',
'phptype' => 'string',
'null' => false,
'default' => '',
),
'email' =>
array (
'dbtype' => 'varchar',
'precision' => '255',
'phptype' => 'string',
'null' => false,
'default' => '',
),
'createdon' =>
array (
'dbtype' => 'datetime',
'phptype' => 'datetime',
'null' => true,
),
'createdby' =>
array (
'dbtype' => 'integer',
'precision' => '10',
'phptype' => 'integer',
'attributes' => 'unsigned',
'null' => false,
'default' => 0,
),
'published' =>
array (
'dbtype' => 'tinyint',
'precision' => '1',
'phptype' => 'boolean',
'attributes' => 'unsigned',
'null' => false,
'default' => 1,
),
'properties' =>
array (
'dbtype' => 'text',
'phptype' => 'json',
'null' => true,
),
),
);
class kmdTicketComment extends xPDOObject{}
class kmdTicketComment_mysql extends kmdTicketComment{}
создаём сниппет класса otzyvyCreateTicketPatchClass
<?php
$modx->map['kmdSiteContent'] = array (
'table' => 'site_content',
'fields' =>
array (
'id' => '',
'createdby' => '',
'createdon' => '',
'publishedon' => '',
'publishedby' => '',
'introtext' => '',
'content' => '',
),
'fieldMeta' =>
array (
'id' =>
array(
'dbtype' => 'integer',
'phptype' => 'integer',
'null' => false,
'index' => 'pk',
'generated' => 'native',
'attributes' => 'unsigned',
),
'createdby' =>
array (
'dbtype' => 'integer',
'precision' => '10',
'phptype' => 'integer',
'attributes' => 'unsigned',
'null' => false,
'default' => 0,
),
'createdon' =>
array (
'dbtype' => 'integer',
'precision' => '20',
'phptype' => 'integer',
'attributes' => 'unsigned',
'null' => false,
'default' => 0,
),
'publishedon' =>
array (
'dbtype' => 'integer',
'precision' => '20',
'phptype' => 'integer',
'attributes' => 'unsigned',
'null' => false,
'default' => 0,
),
'publishedby' =>
array (
'dbtype' => 'integer',
'precision' => '10',
'phptype' => 'integer',
'attributes' => 'unsigned',
'null' => false,
'default' => 0,
),
'introtext' =>
array (
'dbtype' => 'text',
'phptype' => 'string',
'index' => 'fulltext',
'indexgrp' => 'content_ft_idx',
),
'content' =>
array (
'dbtype' => 'mediumtext',
'phptype' => 'string',
'index' => 'fulltext',
'indexgrp' => 'content_ft_idx',
),
),
);
class kmdSiteContent extends xPDOObject{}
class kmdSiteContent_mysql extends kmdSiteContent{}