1 # $Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Queue.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
5 RT::Queue - an RT Queue object
34 @STATUS = qw(new open stalled resolved dead);
38 Returns an array of all statuses for this queue
48 =head2 IsValidStatus VALUE
50 Returns true if VALUE is a valid status. Otherwise, returns 0
53 my $q = new RT::Queue($RT::SystemUser);
54 ok($q->IsValidStatus('new')== 1, 'New is a valid status');
55 ok($q->IsValidStatus('f00')== 0, 'f00 is not a valid status');
63 my $retval = grep (/^$value$/, $self->StatusArray);
74 $self->{'table'} = "Queues";
75 return ($self->SUPER::_Init(@_));
83 my %Cols = ( Name => 'read/write',
84 CorrespondAddress => 'read/write',
85 Description => 'read/write',
86 CommentAddress => 'read/write',
87 InitialPriority => 'read/write',
88 FinalPriority => 'read/write',
89 DefaultDueIn => 'read/write',
90 Creator => 'read/auto',
91 Created => 'read/auto',
92 LastUpdatedBy => 'read/auto',
93 LastUpdated => 'read/auto',
94 Disabled => 'read/write',
97 return($self->SUPER::_Accessible(@_, %Cols));
106 Create takes the name of the new queue
107 If you pass the ACL check, it creates the queue and returns its queue id.
113 my %args = ( Name => undef,
114 CorrespondAddress => '',
116 CommentAddress => '',
117 InitialPriority => "0",
118 FinalPriority => "0",
122 unless ($self->CurrentUser->HasSystemRight('AdminQueue')) { #Check them ACLs
123 return (0, "No permission to create queues")
126 unless ($self->ValidateName($args{'Name'})) {
127 return(0, 'Queue already exists');
129 #TODO better input validation
131 my $id = $self->SUPER::Create(%args);
133 return (0, 'Queue could not be created');
136 return ($id, "Queue $id created");
145 return (0, 'Deleting this object would break referential integrity');
150 # {{{ sub SetDisabled
155 1 will cause this queue to no longer be avaialble for tickets.
156 0 will re-enable this queue
166 Takes either a numerical id or a textual Name and loads the specified queue.
173 my $identifier = shift;
178 if ($identifier !~ /\D/) {
179 $self->SUPER::LoadById($identifier);
182 $self->LoadByCol("Name", $identifier);
191 # {{{ sub ValidateName
193 =head2 ValidateName NAME
195 Takes a queue name. Returns true if it's an ok name for
196 a new queue. Returns undef if there's already a queue by that name.
204 my $tempqueue = new RT::Queue($RT::SystemUser);
205 $tempqueue->Load($name);
207 #If we couldn't load it :)
208 unless ($tempqueue->id()) {
212 #If this queue exists, return undef
213 #Avoid the ACL check.
214 if ($tempqueue->Name()){
218 #If the queue doesn't exist, return 1
232 Returns an RT::Templates object of all of this queue's templates.
240 my $templates = RT::Templates->new($self->CurrentUser);
242 if ($self->CurrentUserHasRight('ShowTemplate')) {
243 $templates->LimitToQueue($self->id);
251 # {{{ Dealing with watchers
257 Watchers returns a Watchers object preloaded with this queue\'s watchers.
264 require RT::Watchers;
265 my $watchers =RT::Watchers->new($self->CurrentUser);
267 if ($self->CurrentUserHasRight('SeeQueue')) {
268 $watchers->LimitToQueue($self->id);
276 # {{{ sub WatchersAsString
277 =head2 WatchersAsString
279 Returns a string of all queue watchers email addresses concatenated with ','s.
283 sub WatchersAsString {
285 return($self->Watchers->EmailsAsString());
290 # {{{ sub AdminCcAsString
292 =head2 AdminCcAsString
294 Takes nothing. returns a string: All Ticket/Queue AdminCcs.
299 sub AdminCcAsString {
302 return($self->AdminCc->EmailsAsString());
311 B<Returns> String: All Queue Ccs as a comma delimited set of email addresses.
318 return ($self->Cc->EmailsAsString());
328 Returns a watchers object which contains this queue\'s Cc watchers
334 my $cc = $self->Watchers();
335 if ($self->CurrentUserHasRight('SeeQueue')) {
341 # A helper function for Cc, so that we can call it from the ACL checks
342 # without going through acl checks.
346 my $cc = $self->Watchers();
359 Returns this queue's administrative Ccs as an RT::Watchers object
365 my $admin_cc = $self->Watchers();
366 if ($self->CurrentUserHasRight('SeeQueue')) {
367 $admin_cc->LimitToAdminCc();
372 #helper function for AdminCc so we can call it without ACLs
375 my $admin_cc = $self->Watchers();
376 $admin_cc->LimitToAdminCc();
382 # {{{ IsWatcher, IsCc, IsAdminCc
386 # a generic routine to be called by IsRequestor, IsCc and IsAdminCc
390 Takes a param hash with the attributes Type and User. User is either a user object or string containing an email address. Returns true if that user or string
391 is a queue watcher. Returns undef otherwise
398 my %args = ( Type => 'Requestor',
403 #ACL check - can't do it. we need this method for ACL checks
404 # unless ($self->CurrentUserHasRight('SeeQueue')) {
409 my %cols = ('Type' => $args{'Type'},
413 if (defined ($args{'Id'})) {
414 if (ref($args{'Id'})){ #If it's a ref, assume it's an RT::User object;
415 #Dangerous but ok for now
416 $cols{'Owner'} = $args{'Id'}->Id;
418 elsif ($args{'Id'} =~ /^\d+$/) { # if it's an integer, it's an RT::User obj
419 $cols{'Owner'} = $args{'Id'};
422 $cols{'Email'} = $args{'Id'};
426 if (defined $args{'Email'}) {
427 $cols{'Email'} = $args{'Email'};
431 $description = join(":",%cols);
433 #If we've cached a positive match...
434 if (defined $self->{'watchers_cache'}->{"$description"}) {
435 if ($self->{'watchers_cache'}->{"$description"} == 1) {
438 #If we've cached a negative match...
445 my $watcher = new RT::Watcher($self->CurrentUser);
446 $watcher->LoadByCols(%cols);
450 $self->{'watchers_cache'}->{"$description"} = 1;
454 $self->{'watchers_cache'}->{"$description"} = 0;
466 Takes a string. Returns true if the string is a Cc watcher of the current queue
470 Should also be able to handle an RT::User object
479 return ($self->IsWatcher( Type => 'Cc', Id => $cc ));
489 Takes a string. Returns true if the string is an AdminCc watcher of the current queue
493 Should also be able to handle an RT::User object
501 return ($self->IsWatcher( Type => 'AdminCc', Id => $admincc ));
513 Takes a paramhash of Email, Owner and Type. Type is one of 'Cc' or 'AdminCc',
514 We need either an Email Address in Email or a userid in Owner
520 my %args = ( Email => undef,
527 #If the watcher we're trying to add is for the current user
528 if ( ( ( defined $args{'Email'}) &&
529 ( $args{'Email'} eq $self->CurrentUser->EmailAddress) ) or
530 ($args{'Owner'} eq $self->CurrentUser->Id)) {
532 # If it's an AdminCc and they don't have
533 # 'WatchAsAdminCc' or 'ModifyQueueWatchers', bail
534 if ($args{'Type'} eq 'AdminCc') {
535 unless ($self->CurrentUserHasRight('ModifyQueueWatchers') or
536 $self->CurrentUserHasRight('WatchAsAdminCc')) {
537 return(0, 'Permission Denied');
541 # If it's a Requestor or Cc and they don't have
542 # 'Watch' or 'ModifyQueueWatchers', bail
543 elsif ($args{'Type'} eq 'Cc') {
544 unless ($self->CurrentUserHasRight('ModifyQueueWatchers') or
545 $self->CurrentUserHasRight('Watch')) {
546 return(0, 'Permission Denied');
550 $RT::Logger->warn("$self -> AddWatcher hit code".
551 " it never should. We got passed ".
552 " a type of ". $args{'Type'});
553 return (0,'Error in parameters to $self AddWatcher');
556 # If the watcher isn't the current user
557 # and the current user doesn't have 'ModifyQueueWatchers'
560 unless ($self->CurrentUserHasRight('ModifyQueueWatchers')) {
561 return (0, "Permission Denied");
567 my $Watcher = new RT::Watcher ($self->CurrentUser);
568 return ($Watcher->Create(Scope => 'Queue',
570 Email => $args{'Email'},
571 Type => $args{'Type'},
572 Owner => $args{'Owner'}
582 Add a Cc to this queue.
583 Takes a paramhash of Email and Owner.
584 We need either an Email Address in Email or a userid in Owner
591 return ($self->AddWatcher( Type => 'Cc', @_));
599 Add an Administrative Cc to this queue.
600 Takes a paramhash of Email and Owner.
601 We need either an Email Address in Email or a userid in Owner
607 return ($self->AddWatcher( Type => 'AdminCc', @_));
611 # {{{ sub DeleteWatcher
613 =head2 DeleteWatcher id [type]
615 DeleteWatcher takes a single argument which is either an email address
617 If the first argument is an email address, you need to specify the watcher type you're talking
618 about as the second argument. Valid values are 'Cc' or 'AdminCc'.
619 It removes that watcher from this Queue\'s list of watchers.
631 $type = shift if (@_);
635 my $Watcher = new RT::Watcher($self->CurrentUser);
637 #If it\'s a numeric watcherid
638 if ($id =~ /^(\d*)$/) {
642 #Otherwise, we'll assume it's an email address
645 $Watcher->LoadByValue( Email => $id,
649 return (0,$msg) unless ($result);
653 return(0,"Can\'t delete a watcher by email address without specifying a type");
658 #If the watcher we're trying to delete is for the current user
659 if ($Watcher->Email eq $self->CurrentUser->EmailAddress) {
661 # If it's an AdminCc and they don't have
662 # 'WatchAsAdminCc' or 'ModifyQueueWatchers', bail
663 if ($Watcher->Type eq 'AdminCc') {
664 unless ($self->CurrentUserHasRight('ModifyQueueWatchers') or
665 $self->CurrentUserHasRight('WatchAsAdminCc')) {
666 return(0, 'Permission Denied');
670 # If it's a Cc and they don't have
671 # 'Watch' or 'ModifyQueueWatchers', bail
672 elsif ($Watcher->Type eq 'Cc') {
673 unless ($self->CurrentUserHasRight('ModifyQueueWatchers') or
674 $self->CurrentUserHasRight('Watch')) {
675 return(0, 'Permission Denied');
679 $RT::Logger->warn("$self -> DeleteWatcher hit code".
680 " it never should. We got passed ".
681 " a type of ". $args{'Type'});
682 return (0,'Error in parameters to $self DeleteWatcher');
685 # If the watcher isn't the current user
686 # and the current user doesn't have 'ModifyQueueWatchers'
689 unless ($self->CurrentUserHasRight('ModifyQueueWatchers')) {
690 return (0, "Permission Denied");
696 unless (($Watcher->Scope eq 'Queue') and
697 ($Watcher->Value == $self->id) ) {
698 return (0, "Not a watcher for this queue");
702 #Clear out the watchers hash.
703 $self->{'watchers'} = undef;
705 my $retval = $Watcher->Delete();
708 return(0,"Watcher could not be deleted.");
711 return(1, "Watcher deleted");
716 =head2 DeleteCc EMAIL
718 Takes an email address. It calls DeleteWatcher with a preset
727 return ($self->DeleteWatcher ($id, 'Cc'))
732 # {{{ sub DeleteAdminCc
734 =head2 DeleteAdminCc EMAIL
736 Takes an email address. It calls DeleteWatcher with a preset
745 return ($self->DeleteWatcher ($id, 'AdminCc'))
755 # {{{ Dealing with keyword selects
757 # {{{ sub AddKeywordSelect
759 =head2 AddKeywordSelect
761 Takes a paramhash of Name, Keyword, Depth and Single. Adds a new KeywordSelect for
762 this queue with those attributes.
767 sub AddKeywordSelect {
769 my %args = ( Keyword => undef,
775 #ACLS get handled in KeywordSelect
776 my $NewKeywordSelect = new RT::KeywordSelect($self->CurrentUser);
778 return ($NewKeywordSelect->Create (Keyword => $args{'Keyword'},
779 Depth => $args{'Depth'},
780 Name => $args{'Name'},
781 Single => $args{'Single'},
782 ObjectType => 'Ticket',
783 ObjectField => 'Queue',
784 ObjectValue => $self->Id()
790 # {{{ sub KeywordSelect
792 =head2 KeywordSelect([NAME])
794 Takes the name of a keyword select for this queue or that's global.
795 Returns the relevant KeywordSelect object. Prefers a keywordselect that's
796 specific to this queue over a global one. If it can't find the proper
797 Keword select or the user doesn't have permission, returns an empty
806 require RT::KeywordSelect;
808 my $select = RT::KeywordSelect->new($self->CurrentUser);
809 if ($self->CurrentUserHasRight('SeeQueue')) {
810 $select->LoadByName( Name => $name, Queue => $self->Id);
818 # {{{ sub KeywordSelects
820 =head2 KeywordSelects
822 Returns an B<RT::KeywordSelects> object containing the collection of
823 B<RT::KeywordSelect> objects which apply to this queue. (Both queue specific keyword selects
824 and global keyword selects.
832 use RT::KeywordSelects;
833 my $KeywordSelects = new RT::KeywordSelects($self->CurrentUser);
835 if ($self->CurrentUserHasRight('SeeQueue')) {
836 $KeywordSelects->LimitToQueue($self->id);
837 $KeywordSelects->IncludeGlobals();
839 return ($KeywordSelects);
851 #Returns an RT::ACL object of ACEs everyone who has anything to do with this queue.
859 my $acl = new RT::ACL($self->CurrentUser);
861 if ($self->CurrentUserHasRight('ShowACL')) {
862 $acl->LimitToQueue($self->Id);
874 unless ($self->CurrentUserHasRight('AdminQueue')) {
875 return(0, 'Permission Denied');
877 return ($self->SUPER::_Set(@_));
886 unless ($self->CurrentUserHasRight('SeeQueue')) {
890 return ($self->__Value(@_));
895 # {{{ sub CurrentUserHasRight
897 =head2 CurrentUserHasRight
899 Takes one argument. A textual string with the name of the right we want to check.
900 Returns true if the current user has that right for this queue.
901 Returns undef otherwise.
905 sub CurrentUserHasRight {
909 return ($self->HasRight( Principal=> $self->CurrentUser,
920 Takes a param hash with the fields 'Right' and 'Principal'.
921 Principal defaults to the current user.
922 Returns true if the principal has that right for this queue.
923 Returns undef otherwise.
927 # TAKES: Right and optional "Principal" which defaults to the current user
930 my %args = ( Right => undef,
931 Principal => $self->CurrentUser,
933 unless(defined $args{'Principal'}) {
934 $RT::Logger->debug("Principal undefined in Queue::HasRight");
937 return($args{'Principal'}->HasQueueRight(QueueObj => $self,
938 Right => $args{'Right'}));