diff --git a/include/class.nav.php b/include/class.nav.php index aafb4dc2562c92c4cc8cf09e2308cabf6343040a..e69014817a1496e555f15de1f94fae2bd6e7dbb9 100644 --- a/include/class.nav.php +++ b/include/class.nav.php @@ -344,7 +344,7 @@ class UserNav { $navs['new']=array('desc'=>__('Open a New Ticket'),'href'=>'open.php','title'=>''); if($user && $user->isValid()) { if(!$user->isGuest()) { - $navs['tickets']=array('desc'=>sprintf(__('Tickets (%d)'),$user->getNumTickets()), + $navs['tickets']=array('desc'=>sprintf(__('Tickets (%d)'),$user->getNumTickets($user->canSeeOrgTickets())), 'href'=>'tickets.php', 'title'=>__('Show all tickets')); } else { diff --git a/include/class.organization.php b/include/class.organization.php index 75024ec6bf832b6070b8883302de53e3456c3662..aae39975fd1c2e2b36a8cc3d297a48de98686ab5 100644 --- a/include/class.organization.php +++ b/include/class.organization.php @@ -35,6 +35,9 @@ class OrganizationModel extends VerySimpleModel { const COLLAB_PRIMARY_CONTACT = 0x0002; const ASSIGN_AGENT_MANAGER = 0x0004; + const SHARE_PRIMARY_CONTACT = 0x0008; + const SHARE_EVERYBODY = 0x0010; + const PERM_CREATE = 'org.create'; const PERM_EDIT = 'org.edit'; const PERM_DELETE = 'org.delete'; @@ -100,6 +103,14 @@ class OrganizationModel extends VerySimpleModel { return $this->check(self::ASSIGN_AGENT_MANAGER); } + function shareWithPrimaryContacts() { + return $this->check(self::SHARE_PRIMARY_CONTACT); + } + + function shareWithEverybody() { + return $this->check(self::SHARE_EVERYBODY); + } + function getUpdateDate() { return $this->updated; } @@ -206,6 +217,8 @@ implements TemplateVariable { 'collab-all-flag' => Organization::COLLAB_ALL_MEMBERS, 'collab-pc-flag' => Organization::COLLAB_PRIMARY_CONTACT, 'assign-am-flag' => Organization::ASSIGN_AGENT_MANAGER, + 'sharing-primary' => Organization::SHARE_PRIMARY_CONTACT, + 'sharing-all' => Organization::SHARE_EVERYBODY, ) as $ck=>$flag) { if ($this->check($flag)) $base[$ck] = true; @@ -393,6 +406,16 @@ implements TemplateVariable { $this->clearStatus($flag); } + foreach (array( + 'sharing-primary' => Organization::SHARE_PRIMARY_CONTACT, + 'sharing-all' => Organization::SHARE_EVERYBODY, + ) as $ck=>$flag) { + if ($vars['sharing'] == $ck) + $this->setStatus($flag); + else + $this->clearStatus($flag); + } + // Set staff and primary contacts $this->set('domain', $vars['domain']); $this->set('manager', $vars['manager'] ?: ''); diff --git a/include/class.ticket.php b/include/class.ticket.php index 55e3f9fbbb1da0e82d2aecf0df3258ad6e4d96e3..f849340c57ebf4d9a849d2da055e0a5124be5af8 100644 --- a/include/class.ticket.php +++ b/include/class.ticket.php @@ -358,6 +358,18 @@ implements RestrictedAccess, Threadable { if ($user->getId() == $this->getUserId()) return true; + // Organization + if ($user->canSeeOrgTickets() + && ($U = $this->getUser()) + && ($U->getOrgId() == $user->getOrgId()) + ) { + // The owner of this ticket is in the same organization as the + // user in question, and the organization is configured to allow + // the user in question to see other tickets in the + // organization. + return true; + } + // Collaborator? // 1) If the user was authorized via this ticket. if ($user->getTicketId() == $this->getId() diff --git a/include/class.user.php b/include/class.user.php index 4fcb2c3cee37b3fdf58e62f639a87f09bb540507..8d5b6836859e2aa0531bdbd659f1c680bb61c8ea 100644 --- a/include/class.user.php +++ b/include/class.user.php @@ -432,6 +432,12 @@ implements TemplateVariable { return (string) $account->getStatus(); } + function canSeeOrgTickets() { + return $this->org && ( + $this->org->shareWithEverybody() + || ($this->isPrimaryContact() && $this->org->shareWithPrimaryContacts())); + } + function register($vars, &$errors) { // user already registered? diff --git a/include/client/tickets.inc.php b/include/client/tickets.inc.php index 0b10183a927130e06f18c72d782472493a615792..32ad5abf8fc8def44985e6b56214b5fad6b7d613 100644 --- a/include/client/tickets.inc.php +++ b/include/client/tickets.inc.php @@ -16,17 +16,20 @@ if (isset($_REQUEST['status'])) { $settings['status'] = $_REQUEST['status']; } +$org_tickets = $thisclient->canSeeOrgTickets(); if ($settings['keywords']) { // Don't show stat counts for searches $openTickets = $closedTickets = -1; } elseif ($settings['topic_id']) { - $openTickets = $thisclient->getNumTopicTicketsInState($settings['topic_id'], 'open'); - $closedTickets = $thisclient->getNumTopicTicketsInState($settings['topic_id'], 'closed'); + $openTickets = $thisclient->getNumTopicTicketsInState($settings['topic_id'], + 'open', $org_tickets); + $closedTickets = $thisclient->getNumTopicTicketsInState($settings['topic_id'], + 'closed', $org_tickets); } else { - $openTickets = $thisclient->getNumOpenTickets(); - $closedTickets = $thisclient->getNumClosedTickets(); + $openTickets = $thisclient->getNumOpenTickets($org_tickets); + $closedTickets = $thisclient->getNumClosedTickets($org_tickets); } $tickets = TicketModel::objects(); @@ -63,10 +66,15 @@ $x=$sort.'_sort'; $$x=' class="'.strtolower($_REQUEST['order'] ?: 'desc').'" '; // Add visibility constraints -$tickets->filter(Q::any(array( +$visibility = Q::any(array( 'user_id' => $thisclient->getId(), 'thread__collaborators__user_id' => $thisclient->getId(), -))); +)); + +if ($thisclient->canSeeOrgTickets()) + $visibility->add(array('user__org_id' => $thisclient->getOrgId())); + +$tickets->filter($visibility); // Perform basic search if ($settings['keywords']) { @@ -122,8 +130,9 @@ $tickets->values( <?php echo __('Help Topic'); ?>: <select name="topic_id" class="nowarn" onchange="javascript: this.form.submit(); "> <option value="">— <?php echo __('All Help Topics');?> —</option> -<?php foreach (Topic::getHelpTopics(true) as $id=>$name) { - $count = $thisclient->getNumTopicTickets($id); +<?php +foreach (Topic::getHelpTopics(true) as $id=>$name) { + $count = $thisclient->getNumTopicTickets($id, $org_tickets); if ($count == 0) continue; ?> diff --git a/include/staff/templates/org-profile.tmpl.php b/include/staff/templates/org-profile.tmpl.php index 90420dab8b8909fac2d7a53d1ed0e28a31b85376..d22ba8bb4156ac79acc984cad913da6982f879db 100644 --- a/include/staff/templates/org-profile.tmpl.php +++ b/include/staff/templates/org-profile.tmpl.php @@ -98,6 +98,22 @@ if ($ticket && $ticket->getOwnerId() == $user->getId()) </select> <br/><span class="error"><?php echo $errors['contacts']; ?></span> </td> + </tr> + <tr> + <td width="180"> + <?php echo __('Ticket Sharing'); ?>: + </td> + <td> + <select name="sharing"> + <option value=""><?php echo __('Disable'); ?></option> + <option value="sharing-primary" <?php echo $info['sharing-primary'] ? 'selected="selected"' : ''; + ?>><?php echo __('Primary contacts see all tickets'); ?></option> + <option value="sharing-all" <?php echo $info['sharing-all'] ? 'selected="selected"' : ''; + ?>><?php echo __('All members see all tickets'); ?></option> + </select> + <i class="help-tip icon-question-sign" href="#org-sharing"></i> + </td> + </tr> <tr> <th colspan="2"> <?php echo __('Automated Collaboration'); ?>: @@ -123,7 +139,7 @@ if ($ticket && $ticket->getOwnerId() == $user->getId()) </tr> <tr> <th colspan="2"> - <?php echo __('Main Domain'); ?> + <?php echo __('Email Domain'); ?> </th> </tr> <tr> diff --git a/tickets.php b/tickets.php index 3467bc9ecf7d9f7e705caf97aaee615a61d3a12a..2c80ec91a0acea906a7ff5d1b9fcb050188fe78c 100644 --- a/tickets.php +++ b/tickets.php @@ -128,7 +128,7 @@ if($ticket && $ticket->checkUserAccess($thisclient)) { } else $inc='view.inc.php'; -} elseif($thisclient->getNumTickets()) { +} elseif($thisclient->getNumTickets($thisclient->canSeeOrgTickets())) { $inc='tickets.inc.php'; } else { $nav->setActiveNav('new');