diff --git a/include/ajax.config.php b/include/ajax.config.php index 132da3daf9de1003d3c5625b723880430416f714..1ac326e98d5ec5b8bb4a873b6fb891cbf1d0c6e8 100644 --- a/include/ajax.config.php +++ b/include/ajax.config.php @@ -48,7 +48,7 @@ class ConfigAjaxAPI extends AjaxController { 'primary_lang_flag' => strtolower($primary_info['flag'] ?: $primary_locale ?: $primary_sl), 'primary_language' => Internationalization::rfc1766($primary), 'secondary_languages' => $cfg->getSecondaryLanguages(), - 'page_size' => $thisstaff->getPageLimit(), + 'page_size' => $thisstaff->getPageLimit() ?: PAGE_LIMIT, ); return $this->json_encode($config); } diff --git a/include/ajax.tasks.php b/include/ajax.tasks.php index 6c4c159244ab892151e2d385742fce5896dd9485..6fa9e052633b41fae05d27ac3d9caa0b40b4f932 100644 --- a/include/ajax.tasks.php +++ b/include/ajax.tasks.php @@ -483,7 +483,7 @@ class TasksAjaxAPI extends AjaxController { $info = array( ':title' => sprintf(__('Task #%s: %s'), $task->getNumber(), - __('Tranfer')), + __('Transfer')), ':action' => sprintf('#tasks/%d/transfer', $task->getId()) ); diff --git a/include/class.forms.php b/include/class.forms.php index e7558c7d444d5b425909fc103356c53020db93c3..ecdd90910ab86a19c92b73b9dfa6410c147b4585 100644 --- a/include/class.forms.php +++ b/include/class.forms.php @@ -540,15 +540,19 @@ class FormField { static $more_types = array(); static $uid = null; + function _uid() { + return ++self::$uid; + } + function __construct($options=array()) { $this->ht = array_merge($this->ht, $options); if (!isset($this->ht['id'])) - $this->ht['id'] = self::$uid++; + $this->ht['id'] = self::_uid(); } function __clone() { $this->_widget = null; - $this->ht['id'] = self::$uid++; + $this->ht['id'] = self::_uid(); } static function addFieldTypes($group, $callable) { diff --git a/include/class.report.php b/include/class.report.php index efa078001d6d60154236e59b7590160a7630d233..d65fd1cc5a63fac47ff221763c104f148fc71c5d 100644 --- a/include/class.report.php +++ b/include/class.report.php @@ -24,24 +24,53 @@ class OverviewReport { var $start; var $end; - function __construct($start, $end='now') { + var $format; + + function __construct($start, $end='now', $format=null) { + global $cfg; + $this->start = $start; $this->end = $end; + $this->format = $format ?: $cfg->getDateFormat(true); } + + function getStartDate($format=null, $translate=true) { + + if (!$this->start) + return ''; + + $format = $format ?: $this->format; + if ($translate) { + $format = str_replace( + array('y', 'Y', 'm'), + array('yy', 'yyyy', 'mm'), + $format); + } + + return Format::date(Misc::dbtime($this->start), false, $format); + } + + function getDateRange() { global $cfg; $start = $this->start ?: 'last month'; $stop = $this->end ?: 'now'; - $start = strtotime($start); - - if (substr($stop, 0, 1) == '+') - $stop = strftime('%Y-%m-%d ', $start) . $stop; + // Convert user time to db time + $start = Misc::dbtime($start); + // Stop time can be relative. + if ($stop[0] == '+') { + // $start time + time(X days) + $now = time(); + $stop = $start + (strtotime($stop, $now)-$now); + } else { + $stop = Misc::dbtime($stop); + } $start = 'FROM_UNIXTIME('.$start.')'; - $stop = 'FROM_UNIXTIME('.strtotime($stop).')'; + $stop = 'FROM_UNIXTIME('.$stop.')'; return array($start, $stop); } diff --git a/include/class.thread.php b/include/class.thread.php index f0a92c78b108fad7e70e9e71dd9a4c3e1ed102b9..a7a380a79cd6c76f6a897135da8653f1dbde9b61 100644 --- a/include/class.thread.php +++ b/include/class.thread.php @@ -1567,7 +1567,7 @@ class ThreadEvent extends VerySimpleModel { const OVERDUE = 'overdue'; const REOPENED = 'reopened'; const STATUS = 'status'; - const TRANFERRED = 'transferred'; + const TRANSFERRED = 'transferred'; const VIEWED = 'viewed'; const MODE_STAFF = 1; diff --git a/include/class.ticket.php b/include/class.ticket.php index 9d32abcdecaea4b559f069f53f92329fcf3dd741..d9b65087e13d52a262ea2b9ff8068e850c882e87 100644 --- a/include/class.ticket.php +++ b/include/class.ticket.php @@ -145,6 +145,11 @@ class TicketModel extends VerySimpleModel { /* @trans */ 'Phone', 'Email' => /* @trans */ 'Email', + + 'Web' => + /* @trans */ 'Web', + 'API' => + /* @trans */ 'API', 'Other' => /* @trans */ 'Other', ); @@ -211,7 +216,13 @@ EOF; } static function getSources() { - return self::$sources; + static $translated = false; + if (!$translated) { + foreach (static::$sources as $k=>$v) + static::$sources[$k] = __($v); + } + + return static::$sources; } } @@ -1099,7 +1110,11 @@ implements RestrictedAccess, Threadable { if ($slaId == $this->getSLAId()) return true; - $this->sla = Sla::lookup($slaId); + $sla = null; + if ($slaId && !($sla = Sla::lookup($slaId))) + return false; + + $this->sla = $sla; return $this->save(); } /** @@ -1690,9 +1705,17 @@ implements RestrictedAccess, Threadable { //Log an internal note - no alerts on the internal note. if ($user_comments) { - $note = $this->logNote( - sprintf(_S('Ticket Assigned to %s'), $assignee->getName()), - $comments, $assigner, false); + if ($assignee instanceof Staff + && $thisstaff + // self assignment + && $assignee->getId() == $thisstaff->getId()) + $title = sprintf(_S('Ticket claimed by %s'), + $thisstaff->getName()); + else + $title = sprintf(_S('Ticket Assigned to %s'), + $assignee->getName()); + + $note = $this->logNote($title, $comments, $assigner, false); } // See if we need to send alerts @@ -1966,7 +1989,7 @@ implements RestrictedAccess, Threadable { return $save ? $this->save() : true; } - //Dept Tranfer...with alert.. done by staff + //Dept Transfer...with alert.. done by staff function transfer(TransferForm $form, &$errors, $alert=true) { global $thisstaff, $cfg; @@ -2004,7 +2027,8 @@ implements RestrictedAccess, Threadable { // Set SLA of the new department if (!$this->getSLAId() || $this->getSLA()->isTransient()) - $this->selectSLAId(); + if (($slaId=$this->getDept()->getSLAId())) + $this->selectSLAId($slaId); // Log transfer event $this->logEvent('transferred'); @@ -2160,10 +2184,12 @@ implements RestrictedAccess, Threadable { $errors['err'] = __('Permission denied'); } else { $this->staff_id = $assignee->getId(); - if ($thisstaff && $thisstaff->getId() == $assignee->getId()) + if ($thisstaff && $thisstaff->getId() == $assignee->getId()) { + $alert = false; $evd['claim'] = true; - else + } else { $evd['staff'] = array($assignee->getId(), (string) $assignee->getName()->getOriginal()); + } } } elseif ($assignee instanceof Team) { if ($this->getTeamId() == $assignee->getId()) { @@ -2302,9 +2328,9 @@ implements RestrictedAccess, Threadable { if ($autorespond && $message->isBounceOrAutoReply()) $autorespond = false; - $this->onMessage($message, $autorespond); //must be called b4 sending alerts to staff. + $this->onMessage($message, ($autorespond && $alerts)); //must be called b4 sending alerts to staff. - if ($autorespond && $cfg && $cfg->notifyCollabsONNewMessage()) + if ($autorespond && $alerts && $cfg && $cfg->notifyCollabsONNewMessage()) $this->notifyCollaborators($message, array('signature' => '')); if (!($alerts && $autorespond)) @@ -2731,6 +2757,11 @@ implements RestrictedAccess, Threadable { $errors['duedate']=__('Due date must be in the future'); } + if (isset($vars['source']) // Check ticket source if provided + && !array_key_exists($vars['source'], Ticket::getSources())) + $errors['source'] = sprintf( __('Invalid source given - %s'), + Format::htmlchars($vars['source'])); + // Validate dynamic meta-data $forms = DynamicFormEntry::forTicket($this->getId()); foreach ($forms as $form) { @@ -3382,8 +3413,12 @@ implements RestrictedAccess, Threadable { // Assign ticket to staff or team (new ticket by staff) if ($vars['assignId']) { - $asnform = $ticket->getAssignmentForm(array('assignee' => $vars['assignId'])); - $ticket->assign($asnform, $vars['note']); + $asnform = $ticket->getAssignmentForm(array( + 'assignee' => $vars['assignId'], + 'comments' => $vars['note']) + ); + $e = array(); + $ticket->assign($asnform, $e); } else { // Auto assign staff or team - auto assignment based on filter diff --git a/include/staff/dashboard.inc.php b/include/staff/dashboard.inc.php index d75ee3ef97621897d87f86439b1b82c465764de3..d7b35af5ee0485a9b352ad8e2224d2b3c7c24a07 100644 --- a/include/staff/dashboard.inc.php +++ b/include/staff/dashboard.inc.php @@ -18,8 +18,11 @@ $plots = $report->getPlotData(); <?php echo csrf_token(); ?> <label> <?php echo __( 'Report timeframe'); ?>: - <input type="text" class="dp input-medium search-query" name="start" placeholder="<?php echo __('Last month');?>"i - value="<?php echo Format::htmlchars($_POST['start']); ?>" /> + <input type="text" class="dp input-medium search-query" + name="start" placeholder="<?php echo __('Last month');?>" + value="<?php + echo Format::htmlchars($report->getStartDate()); + ?>" /> </label> <label> <?php echo __( 'period');?>: diff --git a/include/staff/ticket-edit.inc.php b/include/staff/ticket-edit.inc.php index c79f36d60285e0732dc46387aa1aea406c9502b6..37697ea8c5059688306ceef2b077df57e1f1bf13 100644 --- a/include/staff/ticket-edit.inc.php +++ b/include/staff/ticket-edit.inc.php @@ -70,12 +70,17 @@ if ($_POST) </td> <td> <select name="source"> - <option value="" selected >— <?php echo __('Select Source');?> —</option> - <option value="Phone" <?php echo ($info['source']=='Phone')?'selected="selected"':''; ?>><?php echo __('Phone');?></option> - <option value="Email" <?php echo ($info['source']=='Email')?'selected="selected"':''; ?>><?php echo __('Email');?></option> - <option value="Web" <?php echo ($info['source']=='Web')?'selected="selected"':''; ?>><?php echo __('Web');?></option> - <option value="API" <?php echo ($info['source']=='API')?'selected="selected"':''; ?>><?php echo __('API');?></option> - <option value="Other" <?php echo ($info['source']=='Other')?'selected="selected"':''; ?>><?php echo __('Other');?></option> + <option value="" selected >— <?php + echo __('Select Source');?> —</option> + <?php + $source = $info['source'] ?: 'Phone'; + foreach (Ticket::getSources() as $k => $v) { + echo sprintf('<option value="%s" %s>%s</option>', + $k, + ($source == $k ) ? 'selected="selected"' : '', + $v); + } + ?> </select> <font class="error"><b>*</b> <?php echo $errors['source']; ?></font> </td> diff --git a/include/staff/ticket-open.inc.php b/include/staff/ticket-open.inc.php index b8330a0f53b997a34bc54aa818cc16f16ed9bbde..c7680704fe2c8e8f9b6ec8d2100cb5592023b0cf 100644 --- a/include/staff/ticket-open.inc.php +++ b/include/staff/ticket-open.inc.php @@ -131,7 +131,9 @@ if ($_POST) <select name="source"> <?php $source = $info['source'] ?: 'Phone'; - foreach (Ticket::getSources() as $k => $v) + $sources = Ticket::getSources(); + unset($sources['Web'], $sources['API']); + foreach ($sources as $k => $v) echo sprintf('<option value="%s" %s>%s</option>', $k, ($source == $k ) ? 'selected="selected"' : '', diff --git a/js/filedrop.field.js b/js/filedrop.field.js index 8b863fc9f6f897b3c85b72f61d0422dc31394c7b..ce0bf154496ae63cdccdbe5c5537649bfde3f65d 100644 --- a/js/filedrop.field.js +++ b/js/filedrop.field.js @@ -196,7 +196,7 @@ var i = this.uploads.indexOf(filenode); if (i !== -1) this.uploads.splice(i,1); - filenode.slideUp('fast', function() { this.remove(); }); + filenode.slideUp('fast', function() { $(this).remove(); }); } }, cancelUpload: function(node) { diff --git a/scp/js/scp.js b/scp/js/scp.js index 2de80670d70a01fbff5d35caa3e9910497464507..2e6a116be5b998e44cf4ae812e2314c095cce14b 100644 --- a/scp/js/scp.js +++ b/scp/js/scp.js @@ -1057,7 +1057,7 @@ if ($.support.pjax) { var $this = $(this); if (!$this.hasClass('no-pjax') && !$this.closest('.no-pjax').length - && $this.attr('href')[0] != '#') + && $this.attr('href').charAt(0) != '#') $.pjax.click(event, {container: $this.data('pjaxContainer') || $('#pjax-container'), timeout: 2000}); }) } diff --git a/scp/staff.inc.php b/scp/staff.inc.php index 757befc8d5a449b78326531b2500387e904df846..e486cde88b72018c1464c3bc5b94240c482a4420 100644 --- a/scp/staff.inc.php +++ b/scp/staff.inc.php @@ -107,7 +107,7 @@ $ost->addExtraHeader('<meta name="csrf_token" content="'.$ost->getCSRFToken().'" require_once(INCLUDE_DIR.'class.nav.php'); /******* SET STAFF DEFAULTS **********/ -define('PAGE_LIMIT', $thisstaff->getPageLimit()?$thisstaff->getPageLimit():DEFAULT_PAGE_LIMIT); +define('PAGE_LIMIT', $thisstaff->getPageLimit() ?: DEFAULT_PAGE_LIMIT); $tabs=array(); $submenu=array();