diff --git a/include/ajax.tasks.php b/include/ajax.tasks.php index 8181b4eaea1646aba8e229a96a6ac8fd9d2755b2..e0330dc98daf11ec850e10a6ac859c4916c67271 100644 --- a/include/ajax.tasks.php +++ b/include/ajax.tasks.php @@ -119,7 +119,7 @@ class TasksAjaxAPI extends AjaxController { Http::response(404, __('Unknown action')); - $errors = $e = array(); + $info = $errors = $e = array(); $inc = null; $i = $count = 0; if ($_POST) { diff --git a/include/ajax.thread.php b/include/ajax.thread.php new file mode 100644 index 0000000000000000000000000000000000000000..33160073030b41c4a2706cc39947b9f7e6b5c932 --- /dev/null +++ b/include/ajax.thread.php @@ -0,0 +1,299 @@ +<?php +/********************************************************************* + ajax.thread.php + + AJAX interface for thread + + Peter Rotich <peter@osticket.com> + Copyright (c) 2015 osTicket + http://www.osticket.com + + Released under the GNU General Public License WITHOUT ANY WARRANTY. + See LICENSE.TXT for details. + + vim: expandtab sw=4 ts=4 sts=4: +**********************************************************************/ + +if(!defined('INCLUDE_DIR')) die('403'); + +include_once(INCLUDE_DIR.'class.ticket.php'); +require_once(INCLUDE_DIR.'class.ajax.php'); +require_once(INCLUDE_DIR.'class.note.php'); +include_once INCLUDE_DIR . 'class.thread_actions.php'; + +class ThreadAjaxAPI extends AjaxController { + + function lookup() { + global $thisstaff; + + if(!is_numeric($_REQUEST['q'])) + return self::lookupByEmail(); + + + $limit = isset($_REQUEST['limit']) ? (int) $_REQUEST['limit']:25; + $tickets=array(); + + $visibility = Q::any(array( + 'staff_id' => $thisstaff->getId(), + 'team_id__in' => $thisstaff->teams->values_flat('team_id'), + )); + if (!$thisstaff->showAssignedOnly() && ($depts=$thisstaff->getDepts())) { + $visibility->add(array('dept_id__in' => $depts)); + } + + + $hits = TicketModel::objects() + ->filter(Q::any(array( + 'number__startswith' => $_REQUEST['q'], + ))) + ->filter($visibility) + ->values('number', 'user__emails__address') + ->annotate(array('tickets' => SqlAggregate::COUNT('ticket_id'))) + ->order_by('-created') + ->limit($limit); + + foreach ($hits as $T) { + $tickets[] = array('id'=>$T['number'], 'value'=>$T['number'], + 'info'=>"{$T['number']} — {$T['user__emails__address']}", + 'matches'=>$_REQUEST['q']); + } + if (!$tickets) + return self::lookupByEmail(); + + return $this->json_encode($tickets); + } + + + function addRemoteCollaborator($tid, $bk, $id) { + global $thisstaff; + + if (!($thread=Thread::lookup($tid)) + || !($object=$thread->getObject()) + || !$object->checkStaffPerm($thisstaff)) + Http::response(404, 'No such thread'); + elseif (!$bk || !$id) + Http::response(422, 'Backend and user id required'); + elseif (!($backend = StaffAuthenticationBackend::getBackend($bk))) + Http::response(404, 'User not found'); + + $user_info = $backend->lookup($id); + $form = UserForm::getUserForm()->getForm($user_info); + $info = array(); + if (!$user_info) + $info['error'] = __('Unable to find user in directory'); + + return self::_addcollaborator($thread, null, $form, $info); + } + + //Collaborators utils + function addCollaborator($tid, $uid=0) { + global $thisstaff; + + if (!($thread=Thread::lookup($tid)) + || !($object=$thread->getObject()) + || !$object->checkStaffPerm($thisstaff)) + Http::response(404, __('No such thread')); + + + $user = $uid? User::lookup($uid) : null; + + //If not a post then assume new collaborator form + if(!$_POST) + return self::_addcollaborator($thread, $user); + + $user = $form = null; + if (isset($_POST['id']) && $_POST['id']) { //Existing user/ + $user = User::lookup($_POST['id']); + } else { //We're creating a new user! + $form = UserForm::getUserForm()->getForm($_POST); + $user = User::fromForm($form); + } + + $errors = $info = array(); + if ($user) { + // FIXME: Refuse to add ticket owner?? + if (($c=$thread->addCollaborator($user, + array('isactive'=>1), $errors))) { + $note = Format::htmlchars(sprintf(__('%s <%s> added as a collaborator'), + Format::htmlchars($c->getName()), $c->getEmail())); + + $thread->getObject()->postThreadEntry('N', + array( + 'title' => __('New Collaborator Added'), + 'note' => $note)); + $info = array('msg' => sprintf(__('%s added as a collaborator'), + Format::htmlchars($c->getName()))); + return self::_collaborators($thread, $info); + } + } + + if($errors && $errors['err']) { + $info +=array('error' => $errors['err']); + } else { + $info +=array('error' =>__('Unable to add collaborator. Internal error')); + } + + return self::_addcollaborator($thread, $user, $form, $info); + } + + function updateCollaborator($tid, $cid) { + global $thisstaff; + + if (!($thread=Thread::lookup($tid)) + || !($object=$thread->getObject()) + || !$object->checkStaffPerm($thisstaff)) + Http::response(405, 'No such thread'); + + + if (!($c=Collaborator::lookup(array( + 'id' => $cid, + 'thread_id' => $thread->getId()))) + || !($user=$c->getUser())) + Http::response(406, 'Unknown collaborator'); + + $errors = array(); + if(!$user->updateInfo($_POST, $errors)) + return self::_collaborator($c ,$user->getForms($_POST), $errors); + + $info = array('msg' => sprintf('%s updated successfully', + Format::htmlchars($c->getName()))); + + return self::_collaborators($thread, $info); + } + + function viewCollaborator($tid, $cid) { + global $thisstaff; + + if (!($thread=Thread::lookup($tid)) + || !($object=$thread->getObject()) + || !$object->checkStaffPerm($thisstaff)) + Http::response(404, 'No such thread'); + + + if (!($collaborator=Collaborator::lookup(array( + 'id' => $cid, + 'thread_id' => $thread->getId())))) + Http::response(404, 'Unknown collaborator'); + + return self::_collaborator($collaborator); + } + + function showCollaborators($tid) { + global $thisstaff; + + if(!($thread=Thread::lookup($tid)) + || !($object=$thread->getObject()) + || !$object->checkStaffPerm($thisstaff)) + Http::response(404, 'No such thread'); + + if ($thread->getCollaborators()) + return self::_collaborators($thread); + + return self::_addcollaborator($thread); + } + + function previewCollaborators($tid) { + global $thisstaff; + + if (!($thread=Thread::lookup($tid)) + || !($object=$thread->getObject()) + || !$object->checkStaffPerm($thisstaff)) + Http::response(404, 'No such thread'); + + ob_start(); + include STAFFINC_DIR . 'templates/collaborators-preview.tmpl.php'; + $resp = ob_get_contents(); + ob_end_clean(); + + return $resp; + } + + function _addcollaborator($thread, $user=null, $form=null, $info=array()) { + global $thisstaff; + + $info += array( + 'title' => __('Add a collaborator'), + 'action' => sprintf('#thread/%d/add-collaborator', + $thread->getId()), + 'onselect' => sprintf('ajax.php/thread/%d/add-collaborator/', + $thread->getId()), + ); + + ob_start(); + include STAFFINC_DIR . 'templates/user-lookup.tmpl.php'; + $resp = ob_get_contents(); + ob_end_clean(); + + return $resp; + } + + function updateCollaborators($tid) { + global $thisstaff; + + if (!($thread=Thread::lookup($tid)) + || !($object=$thread->getObject()) + || !$object->checkStaffPerm($thisstaff)) + Http::response(404, 'No such thread'); + + $errors = $info = array(); + if ($thread->updateCollaborators($_POST, $errors)) + Http::response(201, sprintf('Recipients (%d of %d)', + $thread->getNumActiveCollaborators(), + $thread->getNumCollaborators())); + + if($errors && $errors['err']) + $info +=array('error' => $errors['err']); + + return self::_collaborators($thread, $info); + } + + + + function _collaborator($collaborator, $form=null, $info=array()) { + global $thisstaff; + + $info += array('action' => sprintf('#thread/%d/collaborators/%d', + $collaborator->thread_id, $collaborator->getId())); + + $user = $collaborator->getUser(); + + ob_start(); + include(STAFFINC_DIR . 'templates/user.tmpl.php'); + $resp = ob_get_contents(); + ob_end_clean(); + + return $resp; + } + + function _collaborators($thread, $info=array()) { + + ob_start(); + include(STAFFINC_DIR . 'templates/collaborators.tmpl.php'); + $resp = ob_get_contents(); + ob_end_clean(); + + return $resp; + } + + function triggerThreadAction($ticket_id, $thread_id, $action) { + $thread = ThreadEntry::lookup($thread_id); + if (!$thread) + Http::response(404, 'No such ticket thread entry'); + if ($thread->getThread()->getObjectId() != $ticket_id) + Http::response(404, 'No such ticket thread entry'); + + $valid = false; + foreach ($thread->getActions() as $group=>$list) { + foreach ($list as $name=>$A) { + if ($A->getId() == $action) { + $valid = true; break; + } + } + } + if (!$valid) + Http::response(400, 'Not a valid action for this thread'); + + $thread->triggerAction($action); + } +} +?> diff --git a/include/ajax.tickets.php b/include/ajax.tickets.php index d1ea440c0495351edb894f76acccb13599d670be..1e95dde3ec1c033f51fb70b13456739aafea7cfb 100644 --- a/include/ajax.tickets.php +++ b/include/ajax.tickets.php @@ -192,189 +192,6 @@ class TicketsAjaxAPI extends AjaxController { include STAFFINC_DIR . 'templates/ticket-preview.tmpl.php'; } - function addRemoteCollaborator($tid, $bk, $id) { - global $thisstaff; - - if (!($ticket=Ticket::lookup($tid)) - || !$ticket->checkStaffPerm($thisstaff)) - Http::response(404, 'No such ticket'); - elseif (!$bk || !$id) - Http::response(422, 'Backend and user id required'); - elseif (!($backend = StaffAuthenticationBackend::getBackend($bk))) - Http::response(404, 'User not found'); - - $user_info = $backend->lookup($id); - $form = UserForm::getUserForm()->getForm($user_info); - $info = array(); - if (!$user_info) - $info['error'] = __('Unable to find user in directory'); - - return self::_addcollaborator($ticket, null, $form, $info); - } - - //Collaborators utils - function addCollaborator($tid, $uid=0) { - global $thisstaff; - - if (!($ticket=Ticket::lookup($tid)) - || !$ticket->checkStaffPerm($thisstaff)) - Http::response(404, __('No such ticket')); - - - $user = $uid? User::lookup($uid) : null; - - //If not a post then assume new collaborator form - if(!$_POST) - return self::_addcollaborator($ticket, $user); - - $user = $form = null; - if (isset($_POST['id']) && $_POST['id']) { //Existing user/ - $user = User::lookup($_POST['id']); - } else { //We're creating a new user! - $form = UserForm::getUserForm()->getForm($_POST); - $user = User::fromForm($form); - } - - $errors = $info = array(); - if ($user) { - if ($user->getId() == $ticket->getOwnerId()) - $errors['err'] = sprintf(__('Ticket owner, %s, is a collaborator by default!'), - Format::htmlchars($user->getName())); - elseif (($c=$ticket->addCollaborator($user, - array('isactive'=>1), $errors))) { - $note = Format::htmlchars(sprintf(__('%s <%s> added as a collaborator'), - Format::htmlchars($c->getName()), $c->getEmail())); - $ticket->logNote(__('New Collaborator Added'), $note, - $thisstaff, false); - $info = array('msg' => sprintf(__('%s added as a collaborator'), - Format::htmlchars($c->getName()))); - return self::_collaborators($ticket, $info); - } - } - - if($errors && $errors['err']) { - $info +=array('error' => $errors['err']); - } else { - $info +=array('error' =>__('Unable to add collaborator. Internal error')); - } - - return self::_addcollaborator($ticket, $user, $form, $info); - } - - function updateCollaborator($cid) { - global $thisstaff; - - if(!($c=Collaborator::lookup($cid)) - || !($user=$c->getUser()) - || !($ticket=$c->getTicket()) - || !$ticket->checkStaffPerm($thisstaff) - ) - Http::response(404, 'Unknown collaborator'); - - $errors = array(); - if(!$user->updateInfo($_POST, $errors)) - return self::_collaborator($c ,$user->getForms($_POST), $errors); - - $info = array('msg' => sprintf('%s updated successfully', - Format::htmlchars($c->getName()))); - - return self::_collaborators($ticket, $info); - } - - function viewCollaborator($cid) { - global $thisstaff; - - if(!($collaborator=Collaborator::lookup($cid)) - || !($ticket=$collaborator->getTicket()) - || !$ticket->checkStaffPerm($thisstaff)) - Http::response(404, 'Unknown collaborator'); - - return self::_collaborator($collaborator); - } - - function showCollaborators($tid) { - global $thisstaff; - - if(!($ticket=Ticket::lookup($tid)) - || !$ticket->checkStaffPerm($thisstaff)) - Http::response(404, 'No such ticket'); - - if($ticket->getCollaborators()) - return self::_collaborators($ticket); - - return self::_addcollaborator($ticket); - } - - function previewCollaborators($tid) { - global $thisstaff; - - if (!($ticket=Ticket::lookup($tid)) - || !$ticket->checkStaffPerm($thisstaff)) - Http::response(404, 'No such ticket'); - - ob_start(); - include STAFFINC_DIR . 'templates/collaborators-preview.tmpl.php'; - $resp = ob_get_contents(); - ob_end_clean(); - - return $resp; - } - - function _addcollaborator($ticket, $user=null, $form=null, $info=array()) { - - $info += array( - 'title' => sprintf(__('Ticket #%s: Add a collaborator'), $ticket->getNumber()), - 'action' => sprintf('#tickets/%d/add-collaborator', $ticket->getId()), - 'onselect' => sprintf('ajax.php/tickets/%d/add-collaborator/', $ticket->getId()), - ); - return self::_userlookup($user, $form, $info); - } - - - function updateCollaborators($tid) { - global $thisstaff; - - if(!($ticket=Ticket::lookup($tid)) - || !$ticket->checkStaffPerm($thisstaff)) - Http::response(404, 'No such ticket'); - - $errors = $info = array(); - if ($ticket->updateCollaborators($_POST, $errors)) - Http::response(201, sprintf('Recipients (%d of %d)', - $ticket->getNumActiveCollaborators(), - $ticket->getNumCollaborators())); - - if($errors && $errors['err']) - $info +=array('error' => $errors['err']); - - return self::_collaborators($ticket, $info); - } - - - - function _collaborator($collaborator, $form=null, $info=array()) { - - $info += array('action' => '#collaborators/'.$collaborator->getId()); - - $user = $collaborator->getUser(); - - ob_start(); - include(STAFFINC_DIR . 'templates/user.tmpl.php'); - $resp = ob_get_contents(); - ob_end_clean(); - - return $resp; - } - - function _collaborators($ticket, $info=array()) { - - ob_start(); - include(STAFFINC_DIR . 'templates/collaborators.tmpl.php'); - $resp = ob_get_contents(); - ob_end_clean(); - - return $resp; - } function viewUser($tid) { global $thisstaff; diff --git a/include/class.collaborator.php b/include/class.collaborator.php index c457f1cd3cf4feac927e6076a428bc6a90ca4766..205b5200b151911c757611483fae9560f041bb27 100644 --- a/include/class.collaborator.php +++ b/include/class.collaborator.php @@ -51,6 +51,10 @@ implements EmailContact, ITicketUser { return $this->created; } + function getThreadId() { + return $this->thread_id; + } + function getTicketId() { if ($this->thread->object_type == ObjectModel::OBJECT_TYPE_TICKET) return $this->thread->object_id; @@ -140,18 +144,5 @@ implements EmailContact, ITicketUser { return false; } - static function forThread($tid, $criteria=array()) { - - $collaborators = static::objects() - ->filter(array('thread_id' => $tid)); - - if (isset($criteria['isactive'])) - $collaborators->filter(array('isactive' => $criteria['isactive'])); - - // TODO: sort by name of the user - $collaborators->order_by('user__name'); - - return $collaborators; - } } ?> diff --git a/include/class.task.php b/include/class.task.php index c629379f6e88470408ab6eab9e36467576a38958..5f2f761baa25c8339cd503edfcd60712df1df28c 100644 --- a/include/class.task.php +++ b/include/class.task.php @@ -181,7 +181,7 @@ class TaskModel extends VerySimpleModel { RolePermission::register(/* @trans */ 'Tasks', TaskModel::getPermissions()); -class Task extends TaskModel { +class Task extends TaskModel implements Threadable { var $form; var $entry; @@ -269,6 +269,10 @@ class Task extends TaskModel { return $assignees ? implode($glue, $assignees):''; } + function getThreadId() { + return $this->thread->getId(); + } + function getThread() { return $this->thread; } @@ -284,6 +288,15 @@ class Task extends TaskModel { return $thread; } + function postThreadEntry($type, $vars) { + $errors = array(); + switch ($type) { + case 'N': + default: + return $this->postNote($vars, $errors); + } + } + function getForm() { if (!isset($this->form)) { // Look for the entry first diff --git a/include/class.thread.php b/include/class.thread.php index bd50ecb20c48a8c7e3a2e935cfdf878042c07748..3268c5cc8c31d8cfa7a95cd0b6701c003c404ef7 100644 --- a/include/class.thread.php +++ b/include/class.thread.php @@ -46,6 +46,7 @@ class Thread extends VerySimpleModel { ); var $_object; + var $_collaborators; // Cache for collabs function getId() { return $this->id; @@ -89,6 +90,108 @@ class Thread extends VerySimpleModel { return $base; } + // Collaborators + function getNumCollaborators() { + return $this->collaborators->count(); + } + + function getNumActiveCollaborators() { + + if (!isset($this->ht['active_collaborators'])) + $this->ht['active_collaborators'] = count($this->getActiveCollaborators()); + + return $this->ht['active_collaborators']; + } + + function getActiveCollaborators() { + return $this->getCollaborators(array('isactive'=>1)); + } + + function getCollaborators($criteria=array()) { + + if ($this->_collaborators && !$criteria) + return $this->_collaborators; + + $collaborators = $this->collaborators + ->filter(array('thread_id' => $this->getId())); + + if (isset($criteria['isactive'])) + $collaborators->filter(array('isactive' => $criteria['isactive'])); + + // TODO: sort by name of the user + $collaborators->order_by('user__name'); + + if (!$criteria) + $this->_collaborators = $collaborators; + + return $collaborators; + } + + function addCollaborator($user, $vars, &$errors) { + + if (!$user) + return null; + + $vars = array_merge(array( + 'threadId' => $this->getId(), + 'userId' => $user->getId()), $vars); + if (!($c=Collaborator::add($vars, $errors))) + return null; + + $this->_collaborators = null; + + return $c; + } + + function updateCollaborators($vars, &$errors) { + global $thisstaff; + + if (!$thisstaff) return; + + //Deletes + if($vars['del'] && ($ids=array_filter($vars['del']))) { + $collabs = array(); + foreach ($ids as $k => $cid) { + if (($c=Collaborator::lookup($cid)) + && $c->getThreadId() == $this->getId() + && $c->delete()) + $collabs[] = $c; + } + + $this->getObject()->postThreadEntry('N', + array( + 'title' => _S('Collaborators Removed'), + 'note' => implode("<br>", $collabs))); + } + + //statuses + $cids = null; + if($vars['cid'] && ($cids=array_filter($vars['cid']))) { + $this->collaborators->filter(array( + 'thread_id' => $this->getId(), + 'id__in' => $cids + ))->update(array( + 'updated' => SqlFunction::NOW(), + 'isactive' => 1, + )); + } + + if ($cids) { + $this->collaborators->filter(array( + 'thread_id' => $this->getId(), + Q::not(array('id__in' => $cids)) + ))->update(array( + 'updated' => SqlFunction::NOW(), + 'isactive' => 0, + )); + } + + unset($this->ht['active_collaborators']); + $this->_collaborators = null; + + return true; + } + // Render thread function render($type=false) { $entries = $this->getEntries(); @@ -1878,6 +1981,8 @@ abstract class ThreadEntryAction { } interface Threadable { + function getThreadId(); + function getThread(); function postThreadEntry($type, $vars); } ?> diff --git a/include/class.ticket.php b/include/class.ticket.php index 9198bf4b4cc3fdab010dd3d718316a020554916f..3127c85071c9b6b28d8c652d7abd036642da8af0 100644 --- a/include/class.ticket.php +++ b/include/class.ticket.php @@ -883,35 +883,6 @@ implements RestrictedAccess, Threadable, TemplateVariable { return $entries; } - //Collaborators - function getNumCollaborators() { - return count($this->getCollaborators()); - } - - function getNumActiveCollaborators() { - - if (!isset($this->ht['active_collaborators'])) - $this->ht['active_collaborators'] = count($this->getActiveCollaborators()); - - return $this->ht['active_collaborators']; - } - - function getActiveCollaborators() { - return $this->getCollaborators(array('isactive'=>1)); - } - - - function getCollaborators($criteria=array()) { - - if ($criteria) - return Collaborator::forThread($this->getThreadId(), $criteria); - - if (!isset($this->collaborators)) - $this->collaborators = Collaborator::forThread($this->getThreadId()); - - return $this->collaborators; - } - //UserList of recipients (owner + collaborators) function getRecipients() { diff --git a/include/staff/tasks.inc.php b/include/staff/tasks.inc.php index cd07dfa21bbd3edb44012f34cba80a06ecc9dd37..e74a543994d0823b9cabd010c021e293c36d1769 100644 --- a/include/staff/tasks.inc.php +++ b/include/staff/tasks.inc.php @@ -86,10 +86,19 @@ $tasks->filter(Q::any($visibility)); // Add in annotations $tasks->annotate(array( - //'collab_count' => SqlAggregate::COUNT('collaborators'), - 'attachment_count' => SqlAggregate::COUNT('thread__entries__attachments'), - 'thread_count' => SqlAggregate::COUNT('thread__entries'), - // 'isopen' => new SqlExpr(array('flags__hasbit' => TaskModel::ISOPEN)), + 'collab_count' => SqlAggregate::COUNT('thread__collaborators', true), + 'attachment_count' => SqlAggregate::COUNT(SqlCase::N() + ->when(new SqlField('thread__entries__attachments__inline'), null) + ->otherwise(new SqlField('thread__entries__attachments')), + true + ), + 'thread_count' => SqlAggregate::COUNT(SqlCase::N() + ->when( + new Q(array('thread__entries__flags__hasbit'=>ThreadEntry::FLAG_HIDDEN)), + null) + ->otherwise(new SqlField('thread__entries__id')), + true + ), )); $tasks->values('id', 'number', 'created', 'staff_id', 'team_id', diff --git a/include/staff/templates/collaborators-preview.tmpl.php b/include/staff/templates/collaborators-preview.tmpl.php index 964c225e7db174f8e0a614889104378f14d7e312..e7fb4f5985d6b46472e49e9453081d325c927b44 100644 --- a/include/staff/templates/collaborators-preview.tmpl.php +++ b/include/staff/templates/collaborators-preview.tmpl.php @@ -2,7 +2,7 @@ <table border="0" cellspacing="" cellpadding="1"> <colgroup><col style="min-width: 250px;"></col></colgroup> <?php -if (($users=$ticket->getCollaborators())) {?> +if (($users=$thread->getCollaborators())) {?> <?php foreach($users as $user) { echo sprintf('<tr><td %s><i class="icon-%s"></i> %s <em><%s></em></td></tr>', @@ -12,16 +12,16 @@ if (($users=$ticket->getCollaborators())) {?> $user->getEmail()); } } else { - echo "<strong>".__("Ticket doesn't have any collaborators.")."</strong>"; + echo "<strong>".__("Thread doesn't have any collaborators.")."</strong>"; }?> </table> <?php $options = array(); $options[] = sprintf( - '<a class="collaborators" id="managecollab" href="#tickets/%d/collaborators">%s</a>', - $ticket->getId(), - $ticket->getNumCollaborators() + '<a class="collaborators" id="managecollab" href="#thread/%d/collaborators">%s</a>', + $thread->getId(), + $thread->getNumCollaborators() ? __('Manage Collaborators') : __('Add Collaborator') ); diff --git a/include/staff/templates/collaborators.tmpl.php b/include/staff/templates/collaborators.tmpl.php index cd17a3ca12f9051e5c7c1cc91187d059f0127ef2..c49b1b266edaf1118a5f058ab8cb2f67fa5dc8cb 100644 --- a/include/staff/templates/collaborators.tmpl.php +++ b/include/staff/templates/collaborators.tmpl.php @@ -1,4 +1,4 @@ -<h3 class="drag-handle"><?php echo __('Ticket Collaborators'); ?></h3> +<h3 class="drag-handle"><?php echo __('Collaborators'); ?></h3> <b><a class="close" href="#"><i class="icon-remove-circle"></i></a></b> <?php if($info && $info['msg']) { @@ -6,9 +6,9 @@ if($info && $info['msg']) { } ?> <hr/> <?php -if(($users=$ticket->getCollaborators())) {?> +if(($users=$thread->getCollaborators())) {?> <div id="manage_collaborators"> -<form method="post" class="collaborators" action="#tickets/<?php echo $ticket->getId(); ?>/collaborators"> +<form method="post" class="collaborators" action="#thread/<?php echo $thread->getId(); ?>/collaborators"> <table border="0" cellspacing="1" cellpadding="1" width="100%"> <?php foreach($users as $user) { @@ -16,7 +16,7 @@ if(($users=$ticket->getCollaborators())) {?> echo sprintf('<tr> <td> <input type="checkbox" name="cid[]" id="c%d" value="%d" %s> - <a class="collaborator" href="#collaborators/%d/view">%s</a> + <a class="collaborator" href="#thread/%d/collaborators/%d/view">%s</a> <span class="faded"><em>%s</em></span></td> <td width="10"> <input type="hidden" name="del[]" id="d%d" value=""> @@ -26,6 +26,7 @@ if(($users=$ticket->getCollaborators())) {?> $user->getId(), $user->getId(), $checked, + $thread->getId(), $user->getId(), Format::htmlchars($user->getName()), $user->getEmail(), @@ -36,7 +37,7 @@ if(($users=$ticket->getCollaborators())) {?> </table> <hr style="margin-top:1em"/> <div><a class="collaborator" - href="#tickets/<?php echo $ticket->getId(); ?>/add-collaborator" + href="#thread/<?php echo $thread->getId(); ?>/add-collaborator" ><i class="icon-plus-sign"></i> <?php echo __('Add New Collaborator'); ?></a></div> <div id="savewarning" style="display:none; padding-top:2px;"><p id="msg_warning"><?php echo __('You have made changes that you need to save.'); ?></p></div> @@ -57,15 +58,22 @@ if(($users=$ticket->getCollaborators())) {?> echo __("Bro, not sure how you got here!"); } -if ($_POST && $ticket && $ticket->getNumCollaborators()) { +if ($_POST && $thread && $thread->getNumCollaborators()) { + + $collaborators = sprintf('Participants (%d)', + $thread->getNumCollaborators()); + $recipients = sprintf(__('Recipients (%d of %d)'), - $ticket->getNumActiveCollaborators(), - $ticket->getNumCollaborators()); + $thread->getNumActiveCollaborators(), + $thread->getNumCollaborators()); ?> <script type="text/javascript"> $(function() { $('#emailcollab').show(); - $('#recipients').html('<?php echo $recipients; ?>'); + $('#t<?php echo $thread->getId(); ?>-recipients') + .html('<?php echo $recipients; ?>'); + $('#t<?php echo $thread->getId(); ?>-collaborators') + .html('<?php echo $collaborators; ?>'); }); </script> <?php diff --git a/include/staff/templates/task-preview.tmpl.php b/include/staff/templates/task-preview.tmpl.php index d6968f49a42da80daa6ccc8f730d548edbd519b0..5203956880e919bd708714227f1af258bb5206d5 100644 --- a/include/staff/templates/task-preview.tmpl.php +++ b/include/staff/templates/task-preview.tmpl.php @@ -23,6 +23,13 @@ echo '<ul class="tabs" id="task-preview">'; echo ' <li class="active"><a href="#summary" ><i class="icon-list-alt"></i> '.__('Task Summary').'</a></li>'; +if ($task->getThread()->getNumCollaborators()) { + echo sprintf(' + <li><a id="collab_tab" href="#collab" + ><i class="icon-fixed-width icon-group + faded"></i> '.__('Collaborators (%d)').'</a></li>', + $task->getThread()->getNumCollaborators()); +} echo '</ul>'; echo '<div id="task-preview_container">'; echo '<div class="tab_content" id="summary">'; @@ -72,9 +79,37 @@ echo ' </table>'; echo '</div>'; ?> -</div> <?php //TODO: add link to view if the user has permission - -echo '</div>'; ?> +<div class="hidden tab_content" id="collab"> + <table border="0" cellspacing="" cellpadding="1"> + <colgroup><col style="min-width: 250px;"></col></colgroup> + <?php + if (($collabs=$task->getThread()->getCollaborators())) {?> + <?php + foreach($collabs as $collab) { + echo sprintf('<tr><td %s><i class="icon-%s"></i> + <a href="users.php?id=%d" class="no-pjax">%s</a> <em><%s></em></td></tr>', + ($collab->isActive()? '' : 'class="faded"'), + ($collab->isActive()? 'comments' : 'comment-alt'), + $collab->getUserId(), + $collab->getName(), + $collab->getEmail()); + } + } else { + echo __("Task doesn't have any collaborators."); + }?> + </table> + <br> + <?php + echo sprintf('<span><a class="collaborators" + href="#thread/%d/collaborators">%s</a></span>', + $task->getThreadId(), + $task->getThread()->getNumCollaborators() + ? __('Manage Collaborators') : __('Add Collaborator') + ); + ?> +</div> +</div> +</div> diff --git a/include/staff/templates/task-view.tmpl.php b/include/staff/templates/task-view.tmpl.php index cf9c3897fd76f68591f08fa573cebbd230693906..0e3f509268b1b5dcded6377b5a137af6be80a029 100644 --- a/include/staff/templates/task-view.tmpl.php +++ b/include/staff/templates/task-view.tmpl.php @@ -61,7 +61,7 @@ if ($task->isOverdue()) ?> <table width="940" cellpadding="2" cellspacing="0" border="0"> <tr> - <td width="70%" class="has_bottom_border"> + <td width="<?php echo $ticket ? '70%' : '20%'; ?>" class="has_bottom_border"> <?php if ($ticket) { ?> <strong> @@ -157,6 +157,34 @@ if (!$ticket) { ?> <th width="100"><?php echo __('Status');?>:</th> <td><?php echo $task->getStatus(); ?></td> </tr> + + <tr> + <th><?php echo __('Create Date');?>:</th> + <td><?php echo Format::datetime($task->getCreateDate()); ?></td> + </tr> + <?php + if($task->isOpen()){ ?> + <tr> + <th><?php echo __('Due Date');?>:</th> + <td><?php echo $task->duedate ? + Format::datetime($task->duedate) : '<span + class="faded">— '.__('None').' —</span>'; ?></td> + </tr> + <?php + }else { ?> + <tr> + <th><?php echo __('Close Date');?>:</th> + <td><?php echo 0 ? + Format::datetime($task->getCloseDate()) : ''; ?></td> + </tr> + <?php + } + ?> + </table> + </td> + <td width="50%" style="vertical-align:top"> + <table cellspacing="0" cellpadding="4" width="100%" border="0"> + <tr> <th><?php echo __('Department');?>:</th> <td><?php echo Format::htmlchars($task->dept->getName()); ?></td> @@ -189,36 +217,24 @@ if (!$ticket) { ?> </tr> <?php } ?> - </table> - </td> - <td width="50%" style="vertical-align:top"> - <table cellspacing="0" cellpadding="4" width="100%" border="0"> - <tr> - <th><?php echo __('SLA Plan');?>:</th> - <td><?php echo $sla?Format::htmlchars($sla->getName()):'<span class="faded">— '.__('None').' —</span>'; ?></td> - </tr> <tr> - <th><?php echo __('Create Date');?>:</th> - <td><?php echo Format::datetime($task->getCreateDate()); ?></td> - </tr> - <?php - if($task->isOpen()){ ?> - <tr> - <th><?php echo __('Due Date');?>:</th> - <td><?php echo $task->duedate ? - Format::datetime($task->duedate) : '<span - class="faded">— '.__('None').' —</span>'; ?></td> - </tr> - <?php - }else { ?> - <tr> - <th><?php echo __('Close Date');?>:</th> - <td><?php echo 0 ? - Format::datetime($task->getCloseDate()) : ''; ?></td> + <th><?php echo __('Collaborators');?>:</th> + <td> + <?php + $collaborators = __('Add Participants'); + if ($task->getThread()->getNumCollaborators()) + $collaborators = sprintf(__('Participants (%d)'), + $task->getThread()->getNumCollaborators()); + + echo sprintf('<span><a class="collaborators preview" + href="#thread/%d/collaborators"><span + id="t%d-collaborators">%s</span></a></span>', + $task->getThreadId(), + $task->getThreadId(), + $collaborators); + ?> + </td> </tr> - <?php - } - ?> </table> </td> </tr> diff --git a/include/staff/templates/ticket-preview.tmpl.php b/include/staff/templates/ticket-preview.tmpl.php index 875c9d701bdcd641540b6f1c5d37e76b674ddc4c..f4091921f15fc4f32455e2fdd7aed9f94008f93d 100644 --- a/include/staff/templates/ticket-preview.tmpl.php +++ b/include/staff/templates/ticket-preview.tmpl.php @@ -34,12 +34,12 @@ echo '<ul class="tabs" id="ticket-preview">'; echo ' <li class="active"><a id="preview_tab" href="#preview" ><i class="icon-list-alt"></i> '.__('Ticket Summary').'</a></li>'; -if ($ticket->getNumCollaborators()) { +if ($ticket->getThread()->getNumCollaborators()) { echo sprintf(' <li><a id="collab_tab" href="#collab" ><i class="icon-fixed-width icon-group faded"></i> '.__('Collaborators (%d)').'</a></li>', - $ticket->getNumCollaborators()); + $ticket->getThread()->getNumCollaborators()); } echo '</ul>'; echo '<div id="ticket-preview_container">'; @@ -121,7 +121,7 @@ echo '</div>'; // ticket preview content. <table border="0" cellspacing="" cellpadding="1"> <colgroup><col style="min-width: 250px;"></col></colgroup> <?php - if (($collabs=$ticket->getCollaborators())) {?> + if (($collabs=$ticket->getThread()->getCollaborators())) {?> <?php foreach($collabs as $collab) { echo sprintf('<tr><td %s><i class="icon-%s"></i> @@ -141,7 +141,7 @@ echo '</div>'; // ticket preview content. echo sprintf('<span><a class="collaborators" href="#tickets/%d/collaborators">%s</a></span>', $ticket->getId(), - $ticket->getNumCollaborators() + $ticket->getThread()->getNumCollaborators() ? __('Manage Collaborators') : __('Add Collaborator') ); ?> diff --git a/include/staff/ticket-view.inc.php b/include/staff/ticket-view.inc.php index 83cb718ea1a20acd10e8919f378ffce7aa8d07bc..74407ea1952c951da73f9345baa0dc6fe88ddb5a 100644 --- a/include/staff/ticket-view.inc.php +++ b/include/staff/ticket-view.inc.php @@ -510,18 +510,19 @@ $tcount = $ticket->getThreadEntries($types)->count(); <td> <input type='checkbox' value='1' name="emailcollab" id="emailcollab" <?php echo ((!$info['emailcollab'] && !$errors) || isset($info['emailcollab']))?'checked="checked"':''; ?> - style="display:<?php echo $ticket->getNumCollaborators() ? 'inline-block': 'none'; ?>;" + style="display:<?php echo $ticket->getThread()->getNumCollaborators() ? 'inline-block': 'none'; ?>;" > <?php $recipients = __('Add Recipients'); - if ($ticket->getNumCollaborators()) + if ($ticket->getThread()->getNumCollaborators()) $recipients = sprintf(__('Recipients (%d of %d)'), - $ticket->getNumActiveCollaborators(), - $ticket->getNumCollaborators()); + $ticket->getThread()->getNumActiveCollaborators(), + $ticket->getThread()->getNumCollaborators()); echo sprintf('<span><a class="collaborators preview" - href="#tickets/%d/collaborators"><span id="recipients">%s</span></a></span>', - $ticket->getId(), + href="#thread/%d/collaborators"><span id="t%d-recipients">%s</span></a></span>', + $ticket->getThreadId(), + $ticket->getThreadId(), $recipients); ?> </td> diff --git a/scp/ajax.php b/scp/ajax.php index f6e2f36de5eb6a966eca31a4980cae32ea8406d9..54e2770736488081832ac325a9a345e94bb5081d 100644 --- a/scp/ajax.php +++ b/scp/ajax.php @@ -143,12 +143,6 @@ $dispatcher = patterns('', url_post('^(?P<tid>\d+)/lock$', 'acquireLock'), url_post('^(?P<tid>\d+)/lock/(?P<id>\d+)/renew', 'renewLock'), url_post('^(?P<tid>\d+)/lock/(?P<id>\d+)/release', 'releaseLock'), - url_get('^(?P<tid>\d+)/collaborators/preview$', 'previewCollaborators'), - url_get('^(?P<tid>\d+)/collaborators$', 'showCollaborators'), - url_post('^(?P<tid>\d+)/collaborators$', 'updateCollaborators'), - url_get('^(?P<tid>\d+)/add-collaborator/(?P<uid>\d+)$', 'addCollaborator'), - url_get('^(?P<tid>\d+)/add-collaborator/auth:(?P<bk>\w+):(?P<id>.+)$', 'addRemoteCollaborator'), - url('^(?P<tid>\d+)/add-collaborator$', 'addCollaborator'), url_get('^(?P<tid>\d+)/forms/manage$', 'manageForms'), url_post('^(?P<tid>\d+)/forms/manage$', 'updateForms'), url_get('^(?P<tid>\d+)/canned-resp/(?P<cid>\w+).(?P<format>json|txt)', 'cannedResponse'), @@ -189,9 +183,15 @@ $dispatcher = patterns('', url_get('^mass/(?P<action>[\w.]+)', 'massProcess'), url_post('^mass/(?P<action>[\w.]+)', 'massProcess') )), - url('^/collaborators/', patterns('ajax.tickets.php:TicketsAjaxAPI', - url_get('^(?P<cid>\d+)/view$', 'viewCollaborator'), - url_post('^(?P<cid>\d+)$', 'updateCollaborator') + url('^/thread/', patterns('ajax.thread.php:ThreadAjaxAPI', + url_get('^(?P<tid>\d+)/collaborators/preview$', 'previewCollaborators'), + url_get('^(?P<tid>\d+)/collaborators$', 'showCollaborators'), + url_post('^(?P<tid>\d+)/collaborators$', 'updateCollaborators'), + url_get('^(?P<tid>\d+)/add-collaborator/(?P<uid>\d+)$', 'addCollaborator'), + url_get('^(?P<tid>\d+)/add-collaborator/auth:(?P<bk>\w+):(?P<id>.+)$', 'addRemoteCollaborator'), + url('^(?P<tid>\d+)/add-collaborator$', 'addCollaborator'), + url_get('^(?P<tid>\d+)/collaborators/(?P<cid>\d+)/view$', 'viewCollaborator'), + url_post('^(?P<tid>\d+)/collaborators/(?P<cid>\d+)$', 'updateCollaborator') )), url('^/draft/', patterns('ajax.draft.php:DraftAjaxAPI', url_post('^(?P<id>\d+)$', 'updateDraft'),