* @copyright 2005 by http://wombat.exit0.net * @package wombatSite * @subpackage event */ /** * ticket * * @version 1.2.0 * @package wombatSite * @subpackage event */ class wbTicket { /** * Database connection * @var array $_ds */ var $_ds; /** * current ticket id * @var array $_id */ var $_id; /** * current ticket data * @var array $_data */ var $_data; /** * current ticket's comments * @var array $_comments */ var $_comments; /** * primary keys of tables * @var array $_primary */ var $_primary; /** * constructor * * @access public */ function __construct() { $this->_ds = wbFactory::create( 'wbDatasource' ); $this->_ds->setCallback( $this ); $this->clear(); $this->_primary['ticket'] = $this->_ds->getPrimaryKey( 'ticket' ); $this->_primary['ticketrcpt'] = $this->_ds->getPrimaryKey( 'ticketrcpt' ); $this->_primary['ticketcomment'] = $this->_ds->getPrimaryKey( 'ticketcomment' ); $this->_primary['user'] = $this->_ds->getPrimaryKey( 'user' ); wbFactory::includeClass( 'wbLog' ); wbFactory::includeClass( 'wbEvent' ); } /** * constructor wrapper for PHP4 * * @access public * @see __construct() */ function wbTicket() { $this->__construct(); } /** * whether the ticket manager is available or not * * @access public * @return bool */ function isAvailable() { if( empty( $this->_primary['ticket'] ) ) { return false; } return true; } /** * recieve current ticket id * * @access public * @return int $id */ function getId() { return $this->_id; } /** * recieve current ticket data * * @access public * @return array $data */ function getData() { return $this->_data; } /** * recieve current ticket's comments * * @access public * @return array $data */ function getComments() { return $this->_comments; } /** * recieve current ticket data * * @access public * @return array $data */ function getRcpts() { return array_values( $this->_rcpts ); } /** * wipe out current ticket data * * @access public * @return int $id current ticket id */ function clear() { $id = $this->_id; $this->_id = null; $this->_rcpts = array(); $this->_comments = array(); $this->_data = array( 'uid' => 0, 'type' => 'info', 'status' => 'new', 'title' => null, 'message' => null, 'link' => array() ); return $id; } /** * create a new ticket * * @param array $data ticket information * @return int $id ticket id or patError object on error */ function create( $data ) { $this->clear(); foreach( array_keys( $this->_data ) as $key ) { if( isset( $data[$key] ) ) { $this->_data[$key] = $data[$key]; } } $data = $this->_data; $this->_id = $this->_ds->save( 'ticket', 'new', $data ); $data['id'] = $this->_id; wbLog::info( 'ticket', array( 'create', 'id: ' . $this->_id ) ); wbEvent::trigger( 'ticket:create', _( 'Created new ticket id: "{ID}"'), $data ); return $this->_id; } /** * load a ticket with knowladge of ticket id * * @param int $id ticket id * @return int $id ticket id or patError object on error */ function loadTicketById( $id ) { $this->clear(); // major ticket data $data = $this->_ds->getEntry( 'ticket', $id ); if( patErrorManager::isError( $data ) ) { return $data; } // ticket recipients $rctps = $this->getRcpts4Ticket( $id ); if( patErrorManager::isError( $rcpts ) ) { return $rcpts; } // ticket comments $cmt = $this->_ds->getEntries( 'ticketcomment', $id ); if( patErrorManager::isError( $cmt ) ) { return $cmt; } $this->_id = $id; $this->_data = $data; $this->_rcpts = $rcpts; $this->_comments = $cmt; return $this->_id; } /** * assign the current ticket * * @param int $user user id or 0 (zero) to unassign * @return int $id ticket id or patError object on error */ function assign( $user ) { if( $this->_id == null ) { return false; } $status = 'assigned'; if( $user == 0 ) { $status = 'new'; } $data = array( $this->_primary['user'] => $user, 'status' => $status ); $id = $this->_ds->save( 'ticket', $this->_id, $data ); if( patErrorManager::isError( $id ) ) { return $id; } $data['id'] = $this->_id; $data['user'] = $user; wbLog::info( 'ticket', array( 'assign', 'id: ' . $this->_id, 'user: ' . $user ) ); wbEvent::trigger( 'ticket:assign', _( 'Ticket id: "{ID}" assigned to {USER}'), $data ); return $id; } /** * save ticket information * * @param array $data updated ticket information * @return int $id ticket id or patError object on error */ function save( $data ) { if( $this->_id == null ) { return false; } $id = $this->_ds->save( 'ticket', $this->_id, $data ); return $id; } /** * solve ticket * * @param mixed $id ticket id or 'null' to set status of current ticket * @return int $id ticket id or patError object on error */ function solve( $id = null ) { if( $id === null ) { $id = $this->_id; } if( $id == null ) { return false; } $data = array( 'status' => 'solved' ); $id = $this->_ds->save( 'ticket', $id, $data ); if( patErrorManager::isError( $id ) ) { return $id; } $data['id'] = $id; wbLog::info( 'ticket', array( 'solve', 'id: ' . $this->_id ) ); wbEvent::trigger( 'ticket:solve', _( 'Ticket id: "{ID}" solved'), $data ); return $id; } /** * reject ticket * * @param mixed $id ticket id or 'null' to set status of current ticket * @return int $id ticket id or patError object on error */ function reject( $id = null ) { if( $id === null ) { $id = $this->_id; } if( $id == null ) { return false; } $data = array( 'status' => 'rejected' ); $id = $this->_ds->save( 'ticket', $id, $data ); if( patErrorManager::isError( $id ) ) { return $id; } $data['id'] = $id; wbLog::info( 'ticket', array( 'reject', 'id: ' . $this->_id ) ); wbEvent::trigger( 'ticket:solve', _( 'Ticket id: "{ID}" solved'), $data ); return $id; } /** * delete current tickets * * @return int $id ticket id or patError object on error */ function delete() { if( $this->_id == null ) { return false; } $id = $this->_id; // remove recipients foreach( array_keys( $this->_rcpts ) as $rcpt ) { $result = $this->_ds->delete( 'ticketrcpt', $rcpt ); if( patErrorManager::isError( $rcpt ) ) { return $result; } } // remove ticket itself $result = $this->_ds->delete( 'ticket', $id ); if( patErrorManager::isError( $rcpt ) ) { return $result; } $this->clear(); wbLog::info( 'ticket', array( 'delete', 'id: ' . $this->_id ) ); return $id; } /** * add a comment * * * @param int $user user id * @return int $id id of bew recipient or patError object on error */ function addComment( $user, $comment ) { $data = array( $this->_primary['ticket'] => $this->_id, $this->_primary['user'] => $user, 'comment' => $comment ); $id = $this->_ds->save( 'ticketcomment', 'new', $data ); if( patErrorManager::isError( $id ) ) { return $id; } $cmt = $this->_ds->getEntry( 'ticketcomment', $id ); array_push( $this->_comments, $cmt ); wbLog::debug( 'ticket', array( 'comment', 'id: ' . $this->_id, 'user: ' . $user ) ); return $id; } /** * add a recipient * * Add recipient to current ticket * * @param int $user user id * @return int $id id of bew recipient or patError object on error */ function addRcpt( $user ) { // check wheather the recipient is already in the list if( in_array( $user, $this->_rcpts ) ) { $id = array_search( $user, $this->_rcpts ); return $id; } $data = array( $this->_primary['ticket'] => $this->_id, $this->_primary['user'] => $user ); $id = $this->_ds->save( 'ticketrcpt', 'new', $data ); if( patErrorManager::isError( $id ) ) { return $id; } $this->_rcpts[$id] = $user; wbLog::debug( 'ticket', array( 'addrcpt', 'id: ' . $this->_id, 'user: ' . $user ) ); return $id; } /** * remove a recipient * * Add recipient to current ticket * * @param int $user user id * @return int $id id of bew recipient or patError object on error */ function removeRcpt( $user ) { // check wheather the recipient is already in the list if( !in_array( $user, $this->_rcpts ) ) { return false; } $id = array_search( $user, $this->_rcpts ); $result = $this->_ds->delete( 'ticketrcpt', $id ); if( patErrorManager::isError( $result ) ) { return $result; } unset( $this->_rcpts[$id] ); wbLog::debug( 'ticket', array( 'removercpt', 'id: ' . $this->_id, 'user: ' . $user ) ); return $id; } /** * get recipients * * Get list of user ids of a ticket * * @param int $id ticket id * @return array $rcpts or patError object on error */ function getRcpts4Ticket( $id ) { $clause = array( array( 'field' => $this->_primary['ticket'], 'value' => $id ) ); $result = $this->_ds->getEntries( 'ticketrcpt', null, $clause ); if( patErrorManager::isError( $result ) ) { return $result; } $rcpts = array(); foreach( $result as $value ) { $rcpts[$value[$this->_primary['ticketrcpt']]] = $value[$this->_primary['user']]; } return $rcpts; } /** * get tickets * * Get all ticket ids * * @param string required ticket status * @return array $tickets or patError object on error */ function getTickets( $status = '!solved,!rejected' ) { $clause = array(); $this->_status2Clause( $status, $clause ); $tickets = $this->_ds->getIds( 'ticket', null, $clause ); if( patErrorManager::isError( $tickets ) ) { return $tickets; } return $tickets; } /** * get its of all assigned tickets * * Get all ticket ids * * @param int $id user id * @param string required ticket status * @return array $tickets or patError object on error */ function getAssignedTickets( $id, $status = '!solved,!rejected' ) { $clause = array( array( 'field' => $this->_primary['user'], 'value' => $id ) ); $this->_status2Clause( $status, $clause ); $tickets = $this->_ds->getIds( 'ticket', null, $clause ); if( patErrorManager::isError( $tickets ) ) { return $tickets; } return $tickets; } /** * get recipient's tickets * * Get all ticket ids that belong to a recipient * * @param int $id user id * @param string required ticket status * @return array $tickets or patError object on error */ function getTickets4Rcpt( $id, $status = '!solved,!rejected' ) { $tables = array( 'ticket', 'ticketrcpt' ); $select = array( 'ticket' => array( array( 'field' => $this->_primary['ticket'], 'as' => 'id' ) ), 'ticketrcpt' => 'none' ); $clause = array( array( 'table' => 'ticketrcpt', 'field' => $this->_primary['user'], 'value' => $id ), array( 'field' => $this->_primary['ticket'], 'foreign' => 'ticketrcpt', 'valuetype' => 'foreign', 'value' => $this->_primary['ticket'] ) ); $this->_status2Clause( $status, $clause ); $options = array( 'limit' => -1 ); $result = $this->_ds->getJoin( $tables, $select, $clause, $options ); if( patErrorManager::isError( $result ) ) { return $result; } $tickets = array(); foreach( $result as $value ) { array_push( $tickets, $value['id'] ); } return $tickets; } /** * get list of tickets * * Get all ticket information * * @param mixed $ids ids of tickets or "all" for any ticket * @param string required ticket status * @return array $list of ticket information or patError object on error */ function getTicketList( $ids = 'all', $status = '!solved,!rejected' ) { if( $ids == 'all' ) { $ids = $this->getTickets( $status ); } else if( !is_array( $ids ) ) { $ids = array( $ids ); } if( patErrorManager::isError( $ids ) ) { return $ids; } // no tickets found if( empty( $ids ) ) { return array(); } // create select for all tickets $subClause = array(); foreach( $ids as $id ) { array_push( $subClause, array( 'field' => $this->_primary['ticket'], 'value' => $id ) ); } $clause = array( array( 'bond' => 'or', 'type' => 'complex', 'clause' => $subClause ) ); $list = $this->_ds->getEntries( 'ticket', null, $clause ); return $list; } /** * translate status expression to clause * * @access public * @param string $status * @param array $clause * @return boolean true */ function _status2Clause( $status, &$clause ) { $states = explode( ',', trim( $status ) ); foreach( $states as $state ) { $state = trim( $state ); $rel = 'in_set'; if( $state[0] === '!' ) { $rel = 'not_in_set'; $state = substr( $state, 1 ); } array_push( $clause, array( 'field' => 'status', 'relation' => $rel, 'value' => $state ) ); } return true; } /** * callback function * * @access public * @param string $table * @param array $data * @param int $id * @return boolean true */ function callForGetEntry( $table, &$data, $id ) { if( $table == 'ticket' ) { $data['link'] = unserialize( $data['link'] ); } } /** * callback function * * @access public * @param string $table * @param array $data * @param int $id * @return boolean true */ function callForGetEntries( $table, &$data, $id ) { if( $table == 'ticket' ) { $data['id'] = $id; if( isset( $data['link'] ) && !empty( $data['link'] ) ) { $data['link'] = unserialize( $data['link'] ); $link = array(); foreach( $data['link'] as $key => $value ) { array_push( $link, $key . '=' . urlencode( $value ) ); } $data['link_urlencoded'] = implode( '&', $link ); } } } /** * callback function * * @access public * @param string $table * @param array $data * @param int $id * @return boolean true */ function callForSave( $table, &$data, $id ) { if( $table == 'ticketcomment' ) { if( $id == 'new' ) { $data['created'] = date( 'Y-m-d H:i:s' ); } return true; } if( $table != 'ticket' ) { return true; } // add timestamps $data['changed'] = date( 'Y-m-d H:i:s' ); $this->_data['changed'] = $data['changed']; if( isset( $data['link'] ) ) { $data['link'] = serialize( $data['link'] ); } if( $id == 'new' ) { $data['created'] = $data['changed']; $this->_data['created'] = $data['changed']; } return true; } } ?>