diff --git a/include/ajax.config.php b/include/ajax.config.php index 0bf0a4420411304e02d14ae639f450ddb6bdbda6..132da3daf9de1003d3c5625b723880430416f714 100644 --- a/include/ajax.config.php +++ b/include/ajax.config.php @@ -38,7 +38,7 @@ class ConfigAjaxAPI extends AjaxController { list($primary_sl, $primary_locale) = explode('_', $primary); $config=array( - 'lock_time' => ($cfg->getLockTime()*60), + 'lock_time' => $cfg->getTicketLockMode() == Lock::MODE_DISABLED ? 0 : ($cfg->getLockTime()*60), 'html_thread' => (bool) $cfg->isRichTextEnabled(), 'date_format' => $cfg->getDateFormat(true), 'lang' => $lang, diff --git a/include/ajax.tickets.php b/include/ajax.tickets.php index 30a8b74d74075d8e044f80d5a07ac733adfbc94e..31457ec4f80497849129f1a5f126ac7d8a4c21fb 100644 --- a/include/ajax.tickets.php +++ b/include/ajax.tickets.php @@ -92,7 +92,7 @@ class TicketsAjaxAPI extends AjaxController { function acquireLock($tid) { global $cfg, $thisstaff; - if(!$cfg || !$cfg->getLockTime()) + if(!$cfg || !$cfg->getLockTime() || $cfg->getTicketLockMode() == Lock::MODE_DISABLED) Http::response(418, $this->encode(array('id'=>0, 'retry'=>false))); if(!$tid || !is_numeric($tid) || !$thisstaff) diff --git a/include/class.config.php b/include/class.config.php index 984a83c1619b23f1200622432333fedb5c898bf7..b3c75485c1ed9d8862656cb4e9c2e8ea1d1dc20f 100644 --- a/include/class.config.php +++ b/include/class.config.php @@ -176,6 +176,7 @@ class OsticketConfig extends Config { 'verify_email_addrs' => 1, 'client_avatar' => 'gravatar.mm', 'agent_avatar' => 'gravatar.mm', + 'ticket_lock' => 2, // Lock on activity ); function OsticketConfig($section=null) { @@ -424,6 +425,10 @@ class OsticketConfig extends Config { return $this->get('autolock_minutes'); } + function getTicketLockMode() { + return $this->get('ticket_lock'); + } + function getAgentNameFormat() { return $this->get('agent_name_format'); } @@ -1204,6 +1209,7 @@ class OsticketConfig extends Config { 'show_related_tickets'=>isset($vars['show_related_tickets'])?1:0, 'hide_staff_name'=>isset($vars['hide_staff_name'])?1:0, 'allow_client_updates'=>isset($vars['allow_client_updates'])?1:0, + 'ticket_lock' => $vars['ticket_lock'], )); } diff --git a/include/class.lock.php b/include/class.lock.php index d1c5bc3655748f72ff16c092657f32e74c843365..e5da2f048e894bd60733254a0604a5ae51c6fcf9 100644 --- a/include/class.lock.php +++ b/include/class.lock.php @@ -38,6 +38,10 @@ class Lock extends VerySimpleModel { ), ); + const MODE_DISABLED = 0; + const MODE_ON_VIEW = 1; + const MODE_ON_ACTIVITY = 2; + function getId() { return $this->lock_id; } diff --git a/include/staff/settings-tickets.inc.php b/include/staff/settings-tickets.inc.php index 8edf21818a2268df33dfbfea2c977ede1afea26f..4fe241476415916aac3d6295ee943fd12ef6caf9 100644 --- a/include/staff/settings-tickets.inc.php +++ b/include/staff/settings-tickets.inc.php @@ -145,6 +145,23 @@ if(!($maxfileuploads=ini_get('max_file_uploads'))) <span class="error"><?php echo $errors['default_help_topic']; ?></span> </td> </tr> + <tr> + <td width="180"><?php echo __('Lock Semantics'); ?>:</td> + <td> + <select name="ticket_lock" <?php if ($cfg->getLockTime() == 0) echo 'disabled="disabled"'; ?>> +<?php foreach (array( + Lock::MODE_DISABLED => __('Disabled'), + Lock::MODE_ON_VIEW => __('Lock on view'), + Lock::MODE_ON_ACTIVITY => __('Lock on activity'), +) as $v => $desc) { ?> + <option value="<?php echo $v; ?>" <?php + if ($config['ticket_lock'] == $v) echo 'selected="selected"'; + ?>><?php echo $desc; ?></option> +<?php } ?> + </select> + <div class="error"><?php echo $errors['ticket_lock']; ?></div> + </td> + </tr> <tr> <td><?php echo __('Maximum <b>Open</b> Tickets');?>:</td> <td> diff --git a/include/staff/ticket-view.inc.php b/include/staff/ticket-view.inc.php index 6ec03ae8992c1da3ac8d7bd6aa08a789c5902d93..156b2c323556a57f4de5771baae88a64eb123fc0 100644 --- a/include/staff/ticket-view.inc.php +++ b/include/staff/ticket-view.inc.php @@ -16,6 +16,8 @@ $user = $ticket->getOwner(); //Ticket User (EndUser) $team = $ticket->getTeam(); //Assigned team. $sla = $ticket->getSLA(); $lock = $ticket->getLock(); //Ticket lock obj +if (!$lock && $cfg->getTicketLockMode() == Lock::MODE_ON_VIEW) + $lock = $ticket->acquireLock($thisstaff->getId()); $mylock = ($lock && $lock->getStaffId() == $thisstaff->getId()) ? $lock : null; $id = $ticket->getId(); //Ticket ID. diff --git a/scp/js/ticket.js b/scp/js/ticket.js index 61ba8c7b84f9364b1863042dd32a4986dacbf598..b16cc8ea386dca8cf6931a9bd1e1b6b81aabeaf9 100644 --- a/scp/js/ticket.js +++ b/scp/js/ticket.js @@ -20,30 +20,29 @@ if (!this.$element.data('lockObjectId')) return; this.objectId = this.$element.data('lockObjectId'); - this.lockId = options.lockId || this.$element.data('lockId') || undefined; this.fails = 0; this.disabled = false; getConfig().then(function(c) { if (c.lock_time) - this.setup(); + this.setup(options.lockId || this.$element.data('lockId') || undefined); }.bind(this)); } Lock.prototype = { constructor: Lock, + registry: [], - setup: function() { + setup: function(lockId) { // When something inside changes or is clicked which requires a lock, // attempt to fetch one (lazily) $(':input', this.$element).on('keyup, change', this.acquire.bind(this)); $(':submit', this.$element).click(this.ensureLocked.bind(this)); - $(document).on('pjax:start', this.shutdown.bind(this)); // If lock already held, assume full time of lock remains, but warn // user about pending expiration - if (this.lockId) { + if (lockId) { getConfig().then(function(c) { - this.lockTimeout(c.lock_time - 20); + this.update({id: lockId, time: c.lock_time - 10}); }.bind(this)); } }, @@ -126,12 +125,20 @@ type: 'POST', url: 'ajax.php/lock/{0}/release'.replace('{0}', this.lockId), data: 'delete', - async: false, cache: false, + success: this.clearAll.bind(this), complete: this.destroy.bind(this) }); }, + clearAll: function() { + // Clear all other current locks with the same ID as this + $.each(Lock.prototype.registry, function(i, l) { + if (l.lockId && l.lockId == this.lockId) + l.shutdown(); + }.bind(this)); + }, + shutdown: function() { clearTimeout(this.warning); clearTimeout(this.retryTimer); @@ -159,6 +166,7 @@ // Set up release on away navigation $(document).off('.exclusive'); $(document).on('pjax:click.exclusive', $.proxy(this.release, this)); + Lock.prototype.registry.push(this); } this.lockId = lock.id;