/** * Returns ticket custom fields in the form of array: * array( * '<custom field group title>' => array(<custom field object>, ... ), * ... * ) * * @param kyTicket $ticket Ticket. * @param bool $file_custom_field_present Placeholder to indicate if there is file custom field. * @return array */ function get_ticket_custom_fields(kyTicket $ticket, &$file_custom_field_present) { $custom_field_groups = $ticket->getCustomFieldGroups(); if (count($custom_field_groups) === 0) { return array(); } $custom_fields = array(); foreach ($custom_field_groups as $custom_field_group) { /* @var $custom_field_group kyTicketCustomFieldGroup */ $group_custom_fields = array(); foreach ($custom_field_group->getFields() as $custom_field) { /* @var $custom_field kyCustomField */ if (!$custom_field->getDefinition()->getIsUserEditable()) { continue; } if ($custom_field->getType() === kyCustomFieldDefinition::TYPE_FILE) { $file_custom_field_present = true; } $group_custom_fields[$custom_field->getDefinition()->getDisplayOrder()] = $custom_field; } if (count($group_custom_fields) > 0) { ksort($group_custom_fields, SORT_NUMERIC); $custom_fields[$custom_field_group->getTitle()] = array_values($group_custom_fields); } } return $custom_fields; }
/** * Sets the ticket post this attachment will be attached to. * * Automatically sets the ticket. * * @param kyTicketPost $ticket_post Ticket post. */ public function setTicketPost($ticket_post) { $this->ticket_post = ky_assure_object($ticket_post, 'kyTicketPost'); $this->ticket_post_id = $this->ticket_post !== null ? $this->ticket_post->getId() : null; $this->ticket = $this->ticket_post !== null ? $this->ticket_post->getTicket() : null; $this->ticket_id = $this->ticket !== null ? $this->ticket->getId() : null; }
public function createTicket($data) { $default_status_id = kyTicketStatus::getAll()->filterByTitle('New')->first()->getId(); $default_priority_id = kyTicketPriority::getAll()->filterByTitle('Normal')->first()->getId(); $default_type_id = $data['issue']; kyTicket::setDefaults($default_status_id, $default_priority_id, $default_type_id); $general_department = kyDepartment::getAll()->filterByTitle('Customer Service')->filterByModule(kyDepartment::MODULE_TICKETS)->first(); $ticket = kyTicket::createNewAuto($general_department, $data['name'], $data['email'], $data['comment'], $data['subject'])->create(); return true; }
//Include constants file require_once 'constants.php'; //Initialize the client kyConfig::set(new kyConfig(API_URL, API_KEY, SECRET_KEY)); $_ticketDepartmentObjectContainer = kyDepartment::getAll()->filterByModule(kyDepartment::MODULE_TICKETS)->filterByType(kyDepartment::TYPE_PUBLIC); $_ticketStatusObjectContainer = kyTicketStatus::getAll()->filterByType(kyTicketStatus::TYPE_PUBLIC)->first(); $_ticketStatusContainer = []; foreach ($_ticketStatusObjectContainer as $_ticketStatusObject) { $_ticketStatusID = $_ticketStatusObject->getId(); $_ticketStatus['ticketstatusid'] = $_ticketStatusID; $_ticketStatus['title'] = $_ticketStatusObject->getTitle(); $_ticketStatus['markasresolved'] = $_ticketStatusObject->getMarkAsResolved(); $_ticketStatusContainer[$_ticketStatusID] = $_ticketStatus; } $_ticketObjectContainer = kyTicket::getAll($_ticketDepartmentObjectContainer, $_ticketStatusObjectContainer, [], [], $_params['clientsdetails']['email'], $_settings['recordsperpage'], 0)->orderByLastActivity(); $_totalTicketCount = kyTicket::getTicketCount($_ticketDepartmentObjectContainer, $_ticketStatusObjectContainer, array(), array(), $clientsdetails['email']); $_ticketContainer = []; $_numActiveTickets = 0; foreach ($_ticketObjectContainer as $_ticketObject) { $_ticketID = $_ticketObject->getId(); $_ticketStatus = $_ticketObject->getStatusId(); if (isset($_ticketStatusContainer[$_ticketStatus]) && $_ticketStatusContainer[$_ticketStatus]['markasresolved'] == '1') { continue; } else { $_numActiveTickets++; } $_ticket = []; $_ticket['tid'] = $_ticketID; $_ticket['date'] = $_ticketObject->getCreationTime(); $_ticket['department'] = $_ticketObject->getDepartment()->getTitle(); $_ticket['status'] = $_ticketObject->getStatus()->getTitle();
/** * Sets the ticket that the post will be connected with. * * @param kyTicket $ticket Ticket. * @return kyTicketPost */ public function setTicket($ticket) { $this->ticket = ky_assure_object($ticket, 'kyTicket'); $this->ticket_id = $this->ticket !== null ? $this->ticket->getId() : null; return $this; }
/** * Creates new ticket time track. * WARNING: Data is not sent to Kayako unless you explicitly call create() on this method's result. * * @param kyTicket $ticket Ticket to attach the timetrack to. * @param string $contents Note contents. * @param kyStaff $staff Staff user - both creator and worker. * @param string $time_worked Worked time formatted as hh:mm. Work date will be set to current datetime. * @param string $time_billable Billable time formatted as hh:mm. Bill date will be set to current datetime. * @return kyTicketTimeTrack */ public static function createNew(kyTicket $ticket, $contents, kyStaff $staff, $time_worked, $time_billable) { $ticket_time_track = new self(); $ticket_time_track->setTicketId($ticket->getId()); $ticket_time_track->setContents($contents); $ticket_time_track->setCreatorStaff($staff); $ticket_time_track->setWorkerStaff($staff); $ticket_time_track->setBillingData($time_billable); $ticket_time_track->setWorkedData($time_worked); return $ticket_time_track; }
<?php /** * @copyright 2001-2015 Kayako * @license https://www.freebsd.org/copyright/freebsd-license.html * @link https://github.com/kayako/whmcs-integration */ $_ticket = kyTicket::get($_GET['ticketid']); $_ticket->setStatusId($_POST['ticketstatusid']); $_ticket->setPriorityId($_POST['ticketpriorityid']); $_ticket->update(); $_ticket->setCustomFieldValuesFromPOST(); $_ticket->updateCustomFields();
$templatefile = 'ticketform'; } else { header('Location: ' . WHMCS_URL . 'submitticket.php'); } } else { if ($_REQUEST['step'] == 3) { if (!empty($_POST)) { //Set Defaults for a new ticket $_defaultStatusID = kyTicketStatus::getAll()->filterByType(kyTicketStatus::TYPE_PUBLIC)->first()->getId(); $_defaultPriorityID = kyTicketPriority::getAll()->filterByType(kyTicketStatus::TYPE_PUBLIC)->first()->getId(); $_defaultTypeID = kyTicketType::getAll()->filterByType(kyTicketStatus::TYPE_PUBLIC)->first()->getId(); kyTicket::setDefaults($_defaultStatusID, $_defaultPriorityID, $_defaultTypeID); //Create ticket $_department = kyDepartment::get($_POST['departmentid']); $_priority = kyTicketPriority::get($_POST['ticketpriorityid']); $_ticket = kyTicket::createNewAuto($_department, $clientsdetails['firstname'] . ' ' . $clientsdetails['lastname'], $clientsdetails['email'], $_POST['ticketmessage'], $_POST['ticketsubject'])->setPriority($_priority)->setIgnoreAutoResponder($_settings['ignoreautoresponder'])->create(); $_ticketPosts = $_ticket->getPosts(); //Save ticket attachments foreach ($_FILES['ticketattachments']['tmp_name'] as $_key => $_ticketAttachment) { kyTicketAttachment::createNewFromFile($_ticketPosts[0], $_ticketAttachment, $_FILES['ticketattachments']['name'][$_key])->create(); } //Save custom fields $_ticket->setCustomFieldValuesFromPOST(); $_ticket->updateCustomFields(); $smarty->assign('_ticketDisplayID', $_ticket->getDisplayId()); $smarty->assign('_ticketSubject', $_POST['ticketsubject']); $smarty->assign('_ticketMessage', nl2br($_POST['ticketmessage'])); $templatefile = 'ticketConfirmation'; } else { header('Location: ' . WHMCS_URL . 'submitticket.php'); }
/** * Returns Ticket details * * @param int $_ticketID * * @return kyTicket */ public function getTicketDetails($_ticketID) { $_ticketObjectContainer = kyTicket::get($_ticketID); return $_ticketObjectContainer; }
/** * Creates new ticket with this staff user as the author. * WARNING: Data is not sent to Kayako unless you explicitly call create() on this method's result. * * @param kyDepartment $department Department where the ticket will be created. * @param string $contents Contents of the first post. * @param string $subject Subject of the ticket. * @return kyTicket */ public function newTicket(kyDepartment $department, $contents, $subject) { return kyTicket::createNew($department, $this, $contents, $subject); }
$email = JFactory::getUser()->email; if (empty($email) || !isset($email)) { throw new kyException(); } //Retrieve the get value $input = JFactory::getApplication()->input; //$edit_id = $input->get('id', null); $edit_id = $_REQUEST['ticketid']; JTickets::init(); $all_departments = kyDepartment::getAll()->filterByModule(kyDepartment::MODULE_TICKETS)->filterByType(kyDepartment::TYPE_PUBLIC); $department_titles = kyDepartment::getAll()->collectTitle(); $department_id = kyDepartment::getAll()->collectId(); $priority_list = kyTicketPriority::getAll(); $status_list = kyTicketStatus::getAll(); $ticket_type = kyTicketType::getAll(); $ticket_details = kyTicket::get($edit_id); $document =& JFactory::getDocument(); $document->addScript('/media/jui/js/jquery.min.js'); ?> <link rel="stylesheet" type="text/css" href="modules/mod_kayako/resources/css/style.css"> <script> jQuery(document).ready(function() { jQuery('#Reply').click(function() { jQuery('#div_reply').slideToggle("fast"); }); }); function AddTicketFile(_namePrefix) { jQuery('#' + _namePrefix + 'attachmentcontainer').append('<div class="ticketattachmentitem"><div class="ticketattachmentitemdelete" onclick="javascript: jQuery(this).parent().remove();"> </div><input name="' + _namePrefix + 'attachments[]" type="file" size="20" class="swifttextlarge swifttextfile" /></div>');
<?php /** * @copyright 2001-2015 Kayako * @license https://www.freebsd.org/copyright/freebsd-license.html * @link https://github.com/kayako/whmcs-integration */ if (!empty($_GET['tid'])) { $_ticketID = $_GET['tid']; } else { $_ticketID = $_GET['ticketid']; } //Get ticket properties $_ticketObject = kyTicket::get($_ticketID); if ($_ticketObject->getEmail() != $clientsdetails['email']) { $smarty->assign('_noPermissions', true); } else { $_ticketContainer = array(); $_ticketContainer['ticketid'] = $_ticketObject->getId(); $_ticketContainer['displayticketid'] = $_ticketObject->getDisplayId(); $_ticketContainer['departmentid'] = $_ticketObject->getDepartmentId(); $_ticketContainer['departmenttitle'] = $_ticketObject->getDepartment()->getTitle(); $_ticketContainer['departmenttype'] = $_ticketObject->getDepartment()->getType(); if ($_ticketContainer['departmenttype'] == kyDepartment::TYPE_PRIVATE) { $_ticketContainer['department'] = 'Private'; } else { $_ticketContainer['department'] = $_ticketContainer['departmenttitle']; } $_ticketContainer['ticketstatusid'] = $_ticketObject->getStatusId(); $_ticketContainer['status'] = $_ticketObject->getStatus()->getTitle(); $_ticketContainer['statusbgcolor'] = $_ticketObject->getStatus()->getStatusBackgroundColor();
/** * Post a message to the user * * @return bool */ public function postReply() { require_once 'modules/mod_kayako/includes/kayako-php-api/kyIncludes.php'; $confObject = JFactory::getApplication(); $tmp_path = $confObject->getCfg('tmp_path'); JTickets::init(); //Fetch Post data $input = JFactory::getApplication()->input; $form_value = $input->getArray(array('content' => null, 'id' => null, 'replyattachments' => null)); $img = $_FILES['replyattachments']['name']; //Fetch the email of login User $email = JFactory::getUser()->email; $user = kyUser::search($email)->getRawArray(); $ticket_object = kyTicket::get($form_value['id']); $user_reply_post = $ticket_object->newPost($user[0], $form_value['content'])->create(); foreach ($img as $key => $value) { $name = time() . $_FILES["replyattachments"]["name"][$key]; $temp_name = $_FILES["replyattachments"]["tmp_name"][$key]; $size = $_FILES["replyattachments"]["size"][$key]; if ($size < 1024 * 1024) { move_uploaded_file($temp_name, $tmp_path . "/" . $name); $user_reply_post->newAttachmentFromFile(JURI::Root() . "tmp/" . $name)->create(); } } return true; }
} if (!isset($_GET['sortby'])) { $_sortBy = 'LastActivity'; $_sortOrder = 'DESC'; $_order = false; } else { $_sortBy = $_GET['sortby']; } $_offset = $_GET['page'] > 1 ? ($_GET['page'] - 1) * $_settings['recordsperpage'] : 0; if ($_order) { $_sortOrderFlip = 'DESC'; } else { $_sortOrderFlip = 'ASC'; } $_totalTicketCount = kyTicket::getTicketCount($_ticketDepartmentContainer, $_ticketStatusObjectContainer, [], [], $clientsdetails['email']); $_ticketObjectContainer = kyTicket::getAll($_ticketDepartmentContainer, $_ticketStatusObjectContainer, [], [], $clientsdetails['email'], $_settings['recordsperpage'], $_offset, $_sortBy, $_sortOrder); $_ticketContainer = []; $_resolvedTicketCount = 0; foreach ($_ticketObjectContainer as $_ticketObject) { $_ticket = []; $_ticketID = $_ticketObject->getId(); $_ticketStatus = $_ticketObject->getStatusId(); $_ticket['ticketid'] = $_ticketID; $_ticket['ticketstatusid'] = $_ticketStatus; $_ticket['displayticketid'] = $_ticketObject->getDisplayId(); $_ticket['departmentid'] = $_ticketObject->getDepartmentId(); $_ticket['department'] = $_ticketObject->getDepartment()->getTitle(); $_ticket['status'] = $_ticketObject->getStatus()->getTitle(); $_ticket['statusbgcolor'] = $_ticketObject->getStatus()->getStatusBackgroundColor(); $_ticket['priorityid'] = $_ticketObject->getPriorityId(); $_ticket['priority'] = $_ticketObject->getPriority()->getTitle();
function get_tickets_by_dept_status($department, $status) { $tickets = kyTicket::getAll(kyDepartment::getAll()->filterByTitle(array("~", "/" . $department . "/i")), kyTicketStatus::getAll()->filterByTitle(array("=", $status)), array(), array()); return $tickets; }
/** * Creates new ticket in this department with creator user automatically created by server using provided name and e-mail. * WARNING: Data is not sent to Kayako unless you explicitly call create() on this method's result. * * @param string $creator_full_name Creator full name. * @param string $creator_email Creator e-mail. * @param string $contents Contents of the first post. * @param string $subject Subject of new ticket. * @return kyTicket */ public function newTicketAuto($creator_full_name, $creator_email, $contents, $subject) { return kyTicket::createNewAuto($this, $creator_full_name, $creator_email, $contents, $subject); }
<?php /** * @copyright 2001-2015 Kayako * @license https://www.freebsd.org/copyright/freebsd-license.html * @link https://github.com/kayako/whmcs-integration */ //Include config file require_once __DIR__ . '/config.php'; //Include all necessary classes and helper methods require_once 'API/kyIncludes.php'; //Include common functions require_once 'functions.php'; //Initialize the client kyConfig::set(new kyConfig(API_URL, API_KEY, SECRET_KEY)); $_ticketObject = kyTicket::get($_GET['tid']); $_customField = $_ticketObject->getCustomField($_GET['field']); $_customFieldValue = $_customField->getValue(); Download($_customFieldValue[0], $_customFieldValue[1]);
/** * Creates new ticket note. * WARNING: Data is not sent to Kayako unless you explicitly call create() on this method's result. * * @param kyTicket $ticket Ticket in which to create the post. * @param kyStaff $creator Creator (staff) of new note. * @param string $contents Contents of new note. * @return kyTicketNote */ public static function createNew(kyTicket $ticket, kyStaff $creator, $contents) { $new_ticket_note = new kyTicketNote(); $new_ticket_note->setTicketId($ticket->getId()); $new_ticket_note->setCreator($creator); $new_ticket_note->setContents($contents); return $new_ticket_note; }
/** * Returns statistics for all tickets in database. Result is cached. * Format or result: * <pre> * array( * 'departments' => array( //statistics per department (if there are no tickets in department then there will be no record with its id here) * <department id> => array( //tickets assigned to department with this id * 'last_activity' => <date and time of last activity on tickets in this department>, * 'total_items' => <total amount of tickets in this department>, * 'total_unresolved_items' => <total amount of unresolved tickets in this department>, * 'ticket_statuses' => array( //statistics per ticket status in the department * <ticket status id> => array( * 'last_activity' => <date and time of last activity on tickets with this status in this department>, * 'total_items' => <total amount of tickets with this status in this department> * ), * ... * ), * 'ticket_types' => array( //statistics per ticket type in the department * <ticket type id> => array( * 'last_activity' => <date and time of last activity on tickets of this type in this department>, * 'total_items' => <total amount of tickets of this type in this department>, * 'total_unresolved_items' => <total amount of unresolved tickets of this type in this department>, * ), * ..., * 'unknown' => array( //in Kayako 4.01.204 all ticket types will be unknown because of a bug (http://dev.kayako.com/browse/SWIFT-1465) * ... * ) * ) * 'ticket_owners' => array( //statistics per ticket owner in the department * <owner staff id> => array( * 'last_activity' => <date and time of last activity on tickets assigned to this staff in this department>, * 'total_items' => <total amount of tickets assigned to this staff in this department>, * 'total_unresolved_items' => <total amount of unresolved tickets assigned to this staff in this department>, * ), * ..., * 'unassigned' => array( //tickets not assigned to any staff * ... * ) * ) * ), * ..., * 'unknown' => array( //tickets in Trash * ... * ) * ), * 'ticket_statuses' => array( //statistics per ticket status in all departments * <ticket status id> => array( * 'last_activity' => <date and time of last activity on tickets with this status in all departments>, * 'total_items' => <total amount of tickets with this status in all departments> * ), * ... * ), * 'ticket_owners' => array( //statistics per ticket owner in all departments * <owner staff id> => array( * 'last_activity' => <date and time of last activity on tickets assigned to this staff in all department>, * 'total_items' => <total amount of tickets assigned to this staff in all department>, * 'total_unresolved_items' => <total amount of unresolved tickets assigned to this staff in all department>, * ), * ..., * 'unassigned' => array( //tickets not assigned to any staff no matter what department * ... * ) * ) * ) * </pre> * * @param bool $reload True to reload statistics data from server. * @return array */ public static function getStatistics($reload = false) { if (self::$statistics !== null && !$reload) { return self::$statistics; } self::$statistics = array('departments' => array(), 'ticket_statuses' => array(), 'ticket_owners' => array()); $raw_stats = self::getRESTClient()->get('/Tickets/TicketCount', array()); foreach ($raw_stats['departments'][0]['department'] as $department_raw_stats) { $department_id = intval($department_raw_stats['_attributes']['id']); $department_stats = array(); $department_stats['last_activity'] = intval($department_raw_stats['lastactivity']) > 0 ? date(kyConfig::get()->getDatetimeFormat(), $department_raw_stats['lastactivity']) : null; $department_stats['total_items'] = $department_raw_stats['totalitems']; $department_stats['total_unresolved_items'] = $department_raw_stats['totalunresolveditems']; foreach ($department_raw_stats['ticketstatus'] as $ticket_status_raw_stats) { $ticket_status_id = intval($ticket_status_raw_stats['_attributes']['id']); $ticket_status_stats = array(); $ticket_status_stats['last_activity'] = intval($ticket_status_raw_stats['_attributes']['lastactivity']) > 0 ? date(kyConfig::get()->getDatetimeFormat(), $ticket_status_raw_stats['_attributes']['lastactivity']) : null; $ticket_status_stats['total_items'] = $ticket_status_raw_stats['_attributes']['totalitems']; $department_stats['ticket_statuses'][$ticket_status_id] = $ticket_status_stats; } //this is broken in Kayako 4.01.240, tickettype id is always 0 (unknown) - http://dev.kayako.com/browse/SWIFT-1465 foreach ($department_raw_stats['tickettype'] as $ticket_type_raw_stats) { $ticket_type_id = intval($ticket_type_raw_stats['_attributes']['id']); $ticket_type_stats = array(); $ticket_type_stats['last_activity'] = intval($ticket_type_raw_stats['_attributes']['lastactivity']) > 0 ? date(kyConfig::get()->getDatetimeFormat(), $ticket_type_raw_stats['_attributes']['lastactivity']) : null; $ticket_type_stats['total_items'] = $ticket_type_raw_stats['_attributes']['totalitems']; $ticket_type_stats['total_unresolved_items'] = $ticket_type_raw_stats['_attributes']['totalunresolveditems']; $department_stats['ticket_types'][$ticket_type_id > 0 ? $ticket_type_id : 'unknown'] = $ticket_type_stats; } foreach ($department_raw_stats['ownerstaff'] as $owner_staff_raw_stats) { $staff_id = intval($owner_staff_raw_stats['_attributes']['id']); $owner_staff_stats = array(); $owner_staff_stats['last_activity'] = intval($owner_staff_raw_stats['_attributes']['lastactivity']) > 0 ? date(kyConfig::get()->getDatetimeFormat(), $owner_staff_raw_stats['_attributes']['lastactivity']) : null; $owner_staff_stats['total_items'] = $owner_staff_raw_stats['_attributes']['totalitems']; $owner_staff_stats['total_unresolved_items'] = $owner_staff_raw_stats['_attributes']['totalunresolveditems']; $department_stats['ticket_owners'][$staff_id > 0 ? $staff_id : 'unassigned'] = $owner_staff_stats; } //unknown department is for example for tickets in Trash self::$statistics['departments'][$department_id > 0 ? $department_id : 'unknown'] = $department_stats; } foreach ($raw_stats['statuses'][0]['ticketstatus'] as $ticket_status_raw_stats) { $ticket_status_id = intval($ticket_status_raw_stats['_attributes']['id']); $ticket_status_stats = array(); $ticket_status_stats['last_activity'] = intval($ticket_status_raw_stats['_attributes']['lastactivity']) > 0 ? date(kyConfig::get()->getDatetimeFormat(), $ticket_status_raw_stats['_attributes']['lastactivity']) : null; $ticket_status_stats['total_items'] = $ticket_status_raw_stats['_attributes']['totalitems']; self::$statistics['ticket_statuses'][$ticket_status_id] = $ticket_status_stats; } foreach ($raw_stats['owners'][0]['ownerstaff'] as $owner_staff_raw_stats) { $staff_id = intval($owner_staff_raw_stats['_attributes']['id']); $owner_staff_stats = array(); $owner_staff_stats['last_activity'] = intval($owner_staff_raw_stats['_attributes']['lastactivity']) > 0 ? date(kyConfig::get()->getDatetimeFormat(), $owner_staff_raw_stats['_attributes']['lastactivity']) : null; $owner_staff_stats['total_items'] = $owner_staff_raw_stats['_attributes']['totalitems']; $owner_staff_stats['total_unresolved_items'] = $owner_staff_raw_stats['_attributes']['totalunresolveditems']; self::$statistics['ticket_owners'][$staff_id > 0 ? $staff_id : 'unassigned'] = $owner_staff_stats; } return self::$statistics; }
* Search for tickets with "power cable" text in contents of posts or notes. */ $tickets = kyTicket::search("power cable", array(kyTicket::SEARCH_CONTENTS, kyTicket::SEARCH_NOTES)); //print them print "Searching tickets:\n" . $tickets; /** * Search for open and assigned tickets with no replies in all departments. * WARNING: Can be time consuming. */ $tickets = kyTicket::getAll(kyDepartment::getAll())->filterByStatusId(kyTicketStatus::getAll()->filterByTitle(array("!=", "Closed"))->collectId())->filterByReplies(array('<=', 1))->filterByOwnerStaffId(array("!=", null)); //print them print "Searching tickets:\n" . $tickets; /** * Filtering, sorting and paging results. */ //print available filter methods for User objects print "User available filter methods:\n"; print_r(kyUser::getAvailableFilterMethods()); //print available order methods for Staff objects print "Staff available order methods:\n"; print_r(kyStaff::getAvailableOrderMethods()); //find the user with email someuser@example.com $user = kyUser::getAll()->filterByEmail("*****@*****.**")->first(); //find ticket time tracks with billable time greater than 10 minutes and sort them ascending using time worked $time_tracks = $ticket->getTimeTracks()->filterByTimeBillable(array(">", 10 * 60))->orderByTimeWorked(); //find department with title "General" $general_department = kyDepartment::getAll()->filterByTitle("General")->first(); //find tickets in "General" department with word "help" in subject $tickets = kyTicket::getAll($general_department->getId())->filterBySubject(array("~", "/help/i")); //assuming 10 items per page, get second page from list of staff users ordered by fullname $staff_page_2 = kyStaff::getAll()->orderByFullName()->getPage(2, 10);