Skip to content

Instantly share code, notes, and snippets.

@sergant210
Last active November 10, 2015 13:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save sergant210/d35fa6cacf3e7340e733 to your computer and use it in GitHub Desktop.
Save sergant210/d35fa6cacf3e7340e733 to your computer and use it in GitHub Desktop.
Сниппет TicketCommentsAjax
<?php
/** @var array $scriptProperties */
/** Get the children ID
* @param string $class
* @param int $id
* @param array $config
* @return array
*/
function getChildIds( $class = '', $id = NULL, $config = array()) {
if (!$modx instanceof MODX) global $modx;
$ids= array ();
$where = isset($config['where']) ? $config['where'] : array();
$depth = isset($config['depth']) ? $config['depth'] : NULL;
// Specify the parent field of class
if ($id !== null && ($depth >= 1 || $depth === NULL)) {
$id= is_int($id) ? $id : intval($id);
$where['parent'] = $id;
$config['return'] = 'ids';
$children = $modx->pdoFetch->getCollection($class,$where,$config);
foreach ($children as $child) {
$ids[] = $child['id'];
if (isset($depth)) $config['depth'] = $depth - 1;
$tmp = getChildIds($class,$child['id'],$config);
$ids = array_merge($ids,$tmp);
}
}
return $ids;
}
if (empty($thread)) {$scriptProperties['thread'] = $modx->getOption('thread', $scriptProperties, 'resource-'.$modx->resource->id, true);}
$scriptProperties['resource'] = $modx->resource->id;
$scriptProperties['snippetPrepareComment'] = $modx->getOption('tickets.snippet_prepare_comment');
$scriptProperties['commentEditTime'] = $modx->getOption('tickets.comment_edit_time', null, 180);
/*******************************/
if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') {$ajax = TRUE;} else {$ajax = FALSE;}
/*********************************/
if (!isset($depth)) {$depth = 0;}
if (empty($tplComments)) {$tplComments = 'tpl.Tickets.comment.wrapper';}
if (empty($tplCommentForm)) {$tplCommentForm = 'tpl.Tickets.comment.form';}
if (empty($tplCommentFormGuest)) {$tplCommentFormGuest = 'tpl.Tickets.comment.form.guest';}
if (empty($tplCommentAuth)) {$tplCommentAuth = 'tpl.Tickets.comment.one.auth';}
if (empty($tplCommentGuest)) {$tplCommentGuest = 'tpl.Tickets.comment.one.guest';}
if (empty($tplLoginToComment)) {$tplLoginToComment = 'tpl.Tickets.comment.login';}
if (empty($outputSeparator)) {$outputSeparator = "\n";}
/** @var Tickets $Tickets */
$Tickets = $modx->getService('tickets','Tickets',$modx->getOption('tickets.core_path',null,$modx->getOption('core_path').'components/tickets/').'model/tickets/',$scriptProperties);
$Tickets->initialize($modx->context->key, $scriptProperties);
/** @var pdoFetch $pdoFetch */
$fqn = $modx->getOption('pdoFetch.class', null, 'pdotools.pdofetch', true);
if (!$pdoClass = $modx->loadClass($fqn, '', false, true)) {return false;}
$pdoFetch = new $pdoClass($modx, $scriptProperties);
$pdoFetch->addTime('pdoTools loaded');
// Prepare Ticket Thread
/** @var TicketThread $thread */
if (!$thread = $modx->getObject('TicketThread', array('name' => $scriptProperties['thread']))) {
$thread = $modx->newObject('TicketThread');
$thread->fromArray(array(
'name' => $scriptProperties['thread'],
'resource' => $modx->resource->id,
'createdby' => $modx->user->id,
'createdon' => date('Y-m-d H:i:s'),
'subscribers' => array($modx->resource->get('createdby')),
));
}
elseif ($thread->get('deleted')) {
return $modx->lexicon('ticket_thread_err_deleted');
}
// Prepare session for guests
if (!empty($allowGuest) && !isset($_SESSION['TicketComments'])) {
$_SESSION['TicketComments'] = array('name' => '', 'email' => '', 'ids' => array());
}
// Migrate authors to subscription system
if (!is_array($thread->get('subscribers'))) {
$thread->set('subscribers', array($modx->resource->get('createdby')));
}
$thread->set('properties', $scriptProperties);
$thread->save();
// Prepare query to db
$class = 'TicketComment';
if (!empty($limit) ) {
// Limit the comments
$pdoFetch->addTime('Prepare the query for AJAX');
$where = array();
if (empty($showUnpublished)) {$where['published'] = 1;}
if (empty($showDeleted)) {$where['deleted'] = 0;}
if (!empty($thread->id)) {$where['thread'] = $thread->id;}
$config['limit'] = intval($limit);
if (!empty($formBefore)) $config['sortdir'] = 'DESC';
if ($ajax) {
$config['offset'] = $_SESSION['TicketComments']['offset'] + intval($limit);
$_SESSION['TicketComments']['offset'] = $config['offset'];
}
else {
$config['offset'] = $_SESSION['TicketComments']['offset'] = 0;
}
$sp_where = array();
if (!empty($scriptProperties['where'])) $sp_where = $modx->fromJSON($scriptProperties['where']);
if (is_array($sp_where)) $where = array_merge($sp_where,$where);
$total_where = $where;
$where['parent'] = 0;
$config['return'] = 'ids';
$parents = $pdoFetch->getCollection($class, $where, $config);
if (empty($parents)) {
$output = '';
if ($ajax) {
$pdoFetch->addTime('The query for AJAX is completed.');
die($modx->toJSON(array('error'=>true,'comments'=>$output)));
}
} else {
unset($where['parent']);
$ids = array();
if (!empty($depth)) $_depth=intval($depth)-1; else $_depth=NULL;
$modx->pdoFetch = $pdoFetch;
foreach ($parents as $parent) {
$ids[] = $parent['id'];
$childIds = getChildIds($class, $parent['id'], array('where' => $where,'return' => 'ids'));
$ids = array_merge($ids,$childIds);
}
unset($modx->pdoFetch,$scriptProperties['limit'],$scriptProperties['where']);
$pdoFetch->addTime('The query for AJAX is completed');
}
}
$where = array();
if (!empty($limit) && !empty($ids)) {
$where['id:IN'] = $ids;
}
if (empty($showUnpublished)) {$where['published'] = 1;}
// Joining tables
$innerJoin = array(
'Thread' => array(
'class' => 'TicketThread',
'on' => '`Thread`.`id` = `TicketComment`.`thread` AND `Thread`.`name` = "'.$thread->get('name').'"'
)
);
$leftJoin = array(
'User' => array('class' => 'modUser', 'on' => '`User`.`id` = `TicketComment`.`createdby`'),
'Profile' => array('class' => 'modUserProfile', 'on' => '`Profile`.`internalKey` = `TicketComment`.`createdby`'),
);
if ($Tickets->authenticated) {
$leftJoin['Vote'] = array(
'class' => 'TicketVote',
'on' => '`Vote`.`id` = `TicketComment`.`id` AND `Vote`.`class` = "TicketComment" AND `Vote`.`createdby` = '.$modx->user->id
);
$leftJoin['Star'] = array(
'class' => 'TicketStar',
'on' => '`Star`.`id` = `TicketComment`.`id` AND `Star`.`class` = "TicketComment" AND `Star`.`createdby` = '.$modx->user->id
);
}
// Fields to select
$select = array(
'TicketComment' => $modx->getSelectColumns('TicketComment', 'TicketComment', '', array('raw'), true) . ', `parent` as `new_parent`, `rating` as `rating_total`',
'Thread' => '`Thread`.`resource`',
'User' => '`User`.`username`',
'Profile' => $modx->getSelectColumns('modUserProfile', 'Profile', '', array('id','email'), true) . ',`Profile`.`email` as `user_email`',
);
if ($Tickets->authenticated) {
$select['Vote'] = '`Vote`.`value` as `vote`';
$select['Star'] = 'COUNT(`Star`.`id`) as `star`';
}
// Add custom parameters
foreach (array('where','select','leftJoin','innerJoin') as $v) {
if (!empty($scriptProperties[$v])) {
$tmp = $modx->fromJSON($scriptProperties[$v]);
if (is_array($tmp)) {
$$v = array_merge($$v, $tmp);
}
}
unset($scriptProperties[$v]);
}
$pdoFetch->addTime('Conditions prepared');
$default = array(
'class' => $class,
'where' => $modx->toJSON($where),
'innerJoin' => $modx->toJSON($innerJoin),
'leftJoin' => $modx->toJSON($leftJoin),
'select' => $modx->toJSON($select),
'sortby' => $class.'.id',
'sortdir' => 'ASC',
'groupby' => $class.'.id',
'limit' => 0,
'fastMode' => true,
'return' => 'data',
'nestedChunkPrefix' => 'tickets_',
);
// Merge all properties and run!
$pdoFetch->setConfig(array_merge($default, $scriptProperties), false);
$pdoFetch->addTime('Query parameters prepared.');
$rows = $pdoFetch->run();
// Processing rows
$output = $commentsThread = null;
if (!empty($rows) && is_array($rows)) {
$tmp = array();
$i = 1;
foreach ($rows as $row) {
$row['idx'] = $i ++;
$tmp[$row['id']] = $row;
}
$rows = $thread->buildTree($tmp, $depth);
unset($tmp, $i);
if (!empty($formBefore)) {
$rows = array_reverse($rows);
}
$tpl = !$thread->get('closed') && ($Tickets->authenticated || !empty($allowGuest))
? $tplCommentAuth
: $tplCommentGuest;
foreach ($rows as $row) {
$output[] = $Tickets->templateNode($row, $tpl);
}
$pdoFetch->addTime('Returning processed chunks');
$output = implode($outputSeparator, $output);
}
// For Ajax
if ($ajax) {
@session_write_close();
$maxIterations= (integer) $modx->getOption('parser_max_iterations', null, 5);
$modx->getParser()->processElementTags('', $output, false, false, '[[', ']]', array(), $maxIterations);
$modx->getParser()->processElementTags('', $output, true, true, '[[', ']]', array(), $maxIterations);
$output = $modx->toJSON(array('error'=>false,'comments' =>$output));
die($output);
} else {
if (!empty($limit)) $total = $modx->getCount($class,$total_where); else $total = $modx->getPlaceholder($pdoFetch->config['totalVar']);
$commentsThread = $pdoFetch->getChunk($tplComments, array(
'total' => $total,
'comments' => $output,
'subscribed' => $thread->isSubscribed(),
// For Ajax
'more_comments' => !empty($limit) && intval($limit) > 0
));
$pls = array('thread' => $scriptProperties['thread']);
if (!$Tickets->authenticated && empty($allowGuest)) {
$form = $pdoFetch->getChunk($tplLoginToComment);
}
elseif (!$Tickets->authenticated) {
$pls['name'] = $_SESSION['TicketComments']['name'];
$pls['email'] = $_SESSION['TicketComments']['email'];
if (!empty($enableCaptcha)) {
$tmp = $Tickets->getCaptcha();
$pls['captcha'] = $modx->lexicon('ticket_comment_captcha', $tmp);
}
$form = $pdoFetch->getChunk($tplCommentFormGuest, $pls);
}
else {
$form = $pdoFetch->getChunk($tplCommentForm, $pls);
}
$commentForm = $thread->get('closed')
? $modx->lexicon('ticket_thread_err_closed')
: $form;
$output = !empty($formBefore)
? $commentForm . $commentsThread
: $commentsThread . $commentForm;
if ($modx->user->hasSessionContext('mgr') && !empty($showLog)) {
$output .= '<pre class="CommentsLog">' . print_r($pdoFetch->getTime(), 1) . '</pre>';
}
$modx->regClientStartupScript('<script type="text/javascript">TicketsConfig.formBefore = ' . (integer)!empty($formBefore) . ';TicketsConfig.thread_depth = ' . (integer)$depth . ';</script>', TRUE);
// Return output
if (!empty($toPlaceholder)) {
$modx->setPlaceholder($toPlaceholder, $output);
}
else {
return $output;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment