-# $Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Queue.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
+# <sales@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
+# This work is made available to you under the terms of Version 2 of
+# the GNU General Public License. A copy of that license should have
+# been provided with this software, but in any event can be snarfed
+# from www.gnu.org.
+#
+# This work is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
=head1 NAME
=head1 DESCRIPTION
+An RT queue object.
=head1 METHODS
-=begin testing
-use RT::TestHarness;
+=cut
+
+
+package RT::Queue;
-use RT::Queue;
+use strict;
+use warnings;
+use base 'RT::Record';
+
+use Role::Basic 'with';
+with "RT::Record::Role::Lifecycle",
+ "RT::Record::Role::Links" => { -excludes => ["_AddLinksOnCreate"] },
+ "RT::Record::Role::Roles",
+ "RT::Record::Role::Rights";
+
+sub Table {'Queues'}
+
+sub LifecycleType { "ticket" }
+
+sub ModifyLinkRight { "AdminQueue" }
+
+require RT::ACE;
+RT::ACE->RegisterCacheHandler(sub {
+ my %args = (
+ Action => "",
+ RightName => "",
+ @_
+ );
+
+ return unless $args{Action} =~ /^(Grant|Revoke)$/i
+ and $args{RightName} =~ /^(SeeQueue|CreateTicket)$/;
+
+ RT->System->QueueCacheNeedsUpdate(1);
+});
+
+use RT::Groups;
+use RT::ACL;
+use RT::Interface::Email;
+
+__PACKAGE__->AddRight( General => SeeQueue => 'View queue' ); # loc
+__PACKAGE__->AddRight( Admin => AdminQueue => 'Create, modify and delete queue' ); # loc
+__PACKAGE__->AddRight( Admin => ShowACL => 'Display Access Control List' ); # loc
+__PACKAGE__->AddRight( Admin => ModifyACL => 'Create, modify and delete Access Control List entries' ); # loc
+__PACKAGE__->AddRight( Admin => ModifyQueueWatchers => 'Modify queue watchers' ); # loc
+__PACKAGE__->AddRight( General => SeeCustomField => 'View custom field values' ); # loc
+__PACKAGE__->AddRight( Staff => ModifyCustomField => 'Modify custom field values' ); # loc
+__PACKAGE__->AddRight( Admin => AssignCustomFields => 'Assign and remove queue custom fields' ); # loc
+__PACKAGE__->AddRight( Admin => ModifyTemplate => 'Modify Scrip templates' ); # loc
+__PACKAGE__->AddRight( Admin => ShowTemplate => 'View Scrip templates' ); # loc
+
+__PACKAGE__->AddRight( Admin => ModifyScrips => 'Modify Scrips' ); # loc
+__PACKAGE__->AddRight( Admin => ShowScrips => 'View Scrips' ); # loc
+
+__PACKAGE__->AddRight( General => ShowTicket => 'View ticket summaries' ); # loc
+__PACKAGE__->AddRight( Staff => ShowTicketComments => 'View ticket private commentary' ); # loc
+__PACKAGE__->AddRight( Staff => ShowOutgoingEmail => 'View exact outgoing email messages and their recipients' ); # loc
+
+__PACKAGE__->AddRight( General => Watch => 'Sign up as a ticket Requestor or ticket or queue Cc' ); # loc
+__PACKAGE__->AddRight( Staff => WatchAsAdminCc => 'Sign up as a ticket or queue AdminCc' ); # loc
+__PACKAGE__->AddRight( General => CreateTicket => 'Create tickets' ); # loc
+__PACKAGE__->AddRight( General => ReplyToTicket => 'Reply to tickets' ); # loc
+__PACKAGE__->AddRight( General => CommentOnTicket => 'Comment on tickets' ); # loc
+__PACKAGE__->AddRight( Staff => OwnTicket => 'Own tickets' ); # loc
+__PACKAGE__->AddRight( Staff => ModifyTicket => 'Modify tickets' ); # loc
+__PACKAGE__->AddRight( Staff => DeleteTicket => 'Delete tickets' ); # loc
+__PACKAGE__->AddRight( Staff => TakeTicket => 'Take tickets' ); # loc
+__PACKAGE__->AddRight( Staff => StealTicket => 'Steal tickets' ); # loc
+__PACKAGE__->AddRight( Staff => ReassignTicket => 'Modify ticket owner on owned tickets' ); # loc
+
+__PACKAGE__->AddRight( Staff => ForwardMessage => 'Forward messages outside of RT' ); # loc
+
+=head2 Create(ARGS)
+
+Arguments: ARGS is a hash of named parameters. Valid parameters are:
+
+ Name (required)
+ Description
+ CorrespondAddress
+ CommentAddress
+ InitialPriority
+ FinalPriority
+ DefaultDueIn
+
+If you pass the ACL check, it creates the queue and returns its queue id.
-=end testing
=cut
+sub Create {
+ my $self = shift;
+ my %args = (
+ Name => undef,
+ Description => '',
+ CorrespondAddress => '',
+ CommentAddress => '',
+ Lifecycle => 'default',
+ SubjectTag => undef,
+ InitialPriority => 0,
+ FinalPriority => 0,
+ DefaultDueIn => 0,
+ Sign => undef,
+ SignAuto => undef,
+ Encrypt => undef,
+ _RecordTransaction => 1,
+ @_
+ );
+
+ unless ( $self->CurrentUser->HasRight(Right => 'AdminQueue', Object => $RT::System) )
+ { #Check them ACLs
+ return ( 0, $self->loc("No permission to create queues") );
+ }
+ {
+ my ($val, $msg) = $self->_ValidateName( $args{'Name'} );
+ return ($val, $msg) unless $val;
+ }
-package RT::Queue;
-use RT::Record;
+ $args{'Lifecycle'} ||= 'default';
+
+ return ( 0, $self->loc('[_1] is not a valid lifecycle', $args{'Lifecycle'} ) )
+ unless $self->ValidateLifecycle( $args{'Lifecycle'} );
+
+ my %attrs = map {$_ => 1} $self->ReadableAttributes;
-@ISA= qw(RT::Record);
+ #TODO better input validation
+ $RT::Handle->BeginTransaction();
+ my $id = $self->SUPER::Create( map { $_ => $args{$_} } grep exists $args{$_}, keys %attrs );
+ unless ($id) {
+ $RT::Handle->Rollback();
+ return ( 0, $self->loc('Queue could not be created') );
+ }
-use vars (@STATUS);
+ my $create_ret = $self->_CreateRoleGroups();
+ unless ($create_ret) {
+ $RT::Handle->Rollback();
+ return ( 0, $self->loc('Queue could not be created') );
+ }
+ if ( $args{'_RecordTransaction'} ) {
+ $self->_NewTransaction( Type => "Create" );
+ }
+ $RT::Handle->Commit;
+
+ for my $attr (qw/Sign SignAuto Encrypt/) {
+ next unless defined $args{$attr};
+ my $set = "Set" . $attr;
+ my ($status, $msg) = $self->$set( $args{$attr} );
+ $RT::Logger->error("Couldn't set attribute '$attr': $msg")
+ unless $status;
+ }
-@STATUS = qw(new open stalled resolved dead);
+ RT->System->QueueCacheNeedsUpdate(1);
+
+ return ( $id, $self->loc("Queue created") );
+}
-=head2 StatusArray
-Returns an array of all statuses for this queue
+
+sub Delete {
+ my $self = shift;
+ return ( 0,
+ $self->loc('Deleting this object would break referential integrity') );
+}
+
+=head2 Load
+
+Takes either a numerical id or a textual Name and loads the specified queue.
=cut
-sub StatusArray {
+sub Load {
my $self = shift;
- return (@STATUS);
+
+ my $identifier = shift;
+ if ( !$identifier ) {
+ return (undef);
+ }
+
+ if ( $identifier =~ /^(\d+)$/ ) {
+ $self->SUPER::LoadById($identifier);
+ }
+ else {
+ $self->LoadByCols( Name => $identifier );
+ }
+
+ return ( $self->Id );
+
}
-=head2 IsValidStatus VALUE
-Returns true if VALUE is a valid status. Otherwise, returns 0
+=head2 ValidateName NAME
-=for testing
-my $q = new RT::Queue($RT::SystemUser);
-ok($q->IsValidStatus('new')== 1, 'New is a valid status');
-ok($q->IsValidStatus('f00')== 0, 'f00 is not a valid status');
+Takes a queue name. Returns true if it's an ok name for
+a new queue. Returns undef if there's already a queue by that name.
=cut
-sub IsValidStatus {
- my $self = shift;
- my $value = shift;
+sub ValidateName {
+ my $self = shift;
+ my $name = shift;
- my $retval = grep (/^$value$/, $self->StatusArray);
- return ($retval);
+ my ($ok, $msg) = $self->_ValidateName($name);
+ return $ok ? 1 : 0;
}
-
+sub _ValidateName {
+ my $self = shift;
+ my $name = shift;
+ return (undef, "Queue name is required") unless length $name;
-# {{{ sub _Init
-sub _Init {
- my $self = shift;
- $self->{'table'} = "Queues";
- return ($self->SUPER::_Init(@_));
+ # Validate via the superclass first
+ # Case: short circuit if it's an integer so we don't have
+ # fale negatives when loading a temp queue
+ unless ( my $q = $self->SUPER::ValidateName($name) ) {
+ return ($q, $self->loc("'[_1]' is not a valid name.", $name));
+ }
+
+ my $tempqueue = RT::Queue->new(RT->SystemUser);
+ $tempqueue->Load($name);
+
+ #If this queue exists, return undef
+ if ( $tempqueue->Name() && $tempqueue->id != $self->id) {
+ return (undef, $self->loc("Queue already exists") );
+ }
+
+ return (1);
}
-# }}}
-# {{{ sub _Accessible
-sub _Accessible {
- my $self = shift;
- my %Cols = ( Name => 'read/write',
- CorrespondAddress => 'read/write',
- Description => 'read/write',
- CommentAddress => 'read/write',
- InitialPriority => 'read/write',
- FinalPriority => 'read/write',
- DefaultDueIn => 'read/write',
- Creator => 'read/auto',
- Created => 'read/auto',
- LastUpdatedBy => 'read/auto',
- LastUpdated => 'read/auto',
- Disabled => 'read/write',
-
- );
- return($self->SUPER::_Accessible(@_, %Cols));
-}
-
-# }}}
-
-# {{{ sub Create
-
-=head2 Create
-
-Create takes the name of the new queue
-If you pass the ACL check, it creates the queue and returns its queue id.
+=head2 SetSign
=cut
-sub Create {
+sub Sign {
my $self = shift;
- my %args = ( Name => undef,
- CorrespondAddress => '',
- Description => '',
- CommentAddress => '',
- InitialPriority => "0",
- FinalPriority => "0",
- DefaultDueIn => "0",
- @_);
-
- unless ($self->CurrentUser->HasSystemRight('AdminQueue')) { #Check them ACLs
- return (0, "No permission to create queues")
- }
+ my $value = shift;
- unless ($self->ValidateName($args{'Name'})) {
- return(0, 'Queue already exists');
- }
- #TODO better input validation
-
- my $id = $self->SUPER::Create(%args);
- unless ($id) {
- return (0, 'Queue could not be created');
- }
+ return undef unless $self->CurrentUserHasRight('SeeQueue');
+ my $attr = $self->FirstAttribute('Sign') or return 0;
+ return $attr->Content;
+}
+
+sub SetSign {
+ my $self = shift;
+ my $value = shift;
- return ($id, "Queue $id created");
+ return ( 0, $self->loc('Permission Denied') )
+ unless $self->CurrentUserHasRight('AdminQueue');
+
+ my ($status, $msg) = $self->SetAttribute(
+ Name => 'Sign',
+ Description => 'Sign outgoing messages by default',
+ Content => $value,
+ );
+ return ($status, $msg) unless $status;
+
+ my ( undef, undef, $TransObj ) = $self->_NewTransaction(
+ Field => 'Signing', #loc
+ Type => $value ? "Enabled" : "Disabled"
+ );
+
+ return ($status, scalar $TransObj->BriefDescription);
}
-# }}}
+sub SignAuto {
+ my $self = shift;
+ my $value = shift;
-# {{{ sub Delete
+ return undef unless $self->CurrentUserHasRight('SeeQueue');
+ my $attr = $self->FirstAttribute('SignAuto') or return 0;
+ return $attr->Content;
+}
-sub Delete {
+sub SetSignAuto {
my $self = shift;
- return (0, 'Deleting this object would break referential integrity');
+ my $value = shift;
+
+ return ( 0, $self->loc('Permission Denied') )
+ unless $self->CurrentUserHasRight('AdminQueue');
+
+ my ($status, $msg) = $self->SetAttribute(
+ Name => 'SignAuto',
+ Description => 'Sign auto-generated outgoing messages',
+ Content => $value,
+ );
+ return ($status, $msg) unless $status;
+
+ my ( undef, undef, $TransObj ) = $self->_NewTransaction(
+ Field => 'AutoSigning', #loc
+ Type => $value ? "Enabled" : "Disabled"
+ );
+
+ return ($status, scalar $TransObj->BriefDescription);
}
-# }}}
+sub Encrypt {
+ my $self = shift;
+ my $value = shift;
-# {{{ sub SetDisabled
+ return undef unless $self->CurrentUserHasRight('SeeQueue');
+ my $attr = $self->FirstAttribute('Encrypt') or return 0;
+ return $attr->Content;
+}
-=head2 SetDisabled
+sub SetEncrypt {
+ my $self = shift;
+ my $value = shift;
-Takes a boolean.
-1 will cause this queue to no longer be avaialble for tickets.
-0 will re-enable this queue
+ return ( 0, $self->loc('Permission Denied') )
+ unless $self->CurrentUserHasRight('AdminQueue');
-=cut
+ my ($status, $msg) = $self->SetAttribute(
+ Name => 'Encrypt',
+ Description => 'Encrypt outgoing messages by default',
+ Content => $value,
+ );
+ return ($status, $msg) unless $status;
-# }}}
+ my ( undef, undef, $TransObj ) = $self->_NewTransaction(
+ Field => 'Encrypting', #loc
+ Type => $value ? "Enabled" : "Disabled"
+ );
-# {{{ sub Load
+ return ($status, scalar $TransObj->BriefDescription);
+}
-=head2 Load
+=head2 Templates
+
+Returns an RT::Templates object of all of this queue's templates.
-Takes either a numerical id or a textual Name and loads the specified queue.
-
=cut
-sub Load {
+sub Templates {
my $self = shift;
-
- my $identifier = shift;
- if (!$identifier) {
- return (undef);
- }
-
- if ($identifier !~ /\D/) {
- $self->SUPER::LoadById($identifier);
- }
- else {
- $self->LoadByCol("Name", $identifier);
- }
- return ($self->Id);
+ my $templates = RT::Templates->new( $self->CurrentUser );
+ if ( $self->CurrentUserHasRight('ShowTemplate') ) {
+ $templates->LimitToQueue( $self->id );
+ }
+ return ($templates);
}
-# }}}
-# {{{ sub ValidateName
-=head2 ValidateName NAME
-Takes a queue name. Returns true if it's an ok name for
-a new queue. Returns undef if there's already a queue by that name.
+
+=head2 CustomField NAME
+
+Load the Ticket Custom Field applied to this Queue named NAME.
+Does not load Global custom fields.
=cut
-sub ValidateName {
+sub CustomField {
my $self = shift;
my $name = shift;
-
- my $tempqueue = new RT::Queue($RT::SystemUser);
- $tempqueue->Load($name);
+ my $cf = RT::CustomField->new($self->CurrentUser);
+ $cf->LoadByName(
+ Name => $name,
+ LookupType => RT::Ticket->CustomFieldLookupType,
+ ObjectId => $self->id,
+ );
+ return ($cf);
+}
- #If we couldn't load it :)
- unless ($tempqueue->id()) {
- return(1);
- }
- #If this queue exists, return undef
- #Avoid the ACL check.
- if ($tempqueue->Name()){
- return(undef);
- }
- #If the queue doesn't exist, return 1
- else {
- return(1);
+=head2 TicketCustomFields
+
+Returns an L<RT::CustomFields> object containing all global and
+queue-specific B<ticket> custom fields.
+
+=cut
+
+sub TicketCustomFields {
+ my $self = shift;
+
+ my $cfs = RT::CustomFields->new( $self->CurrentUser );
+ if ( $self->CurrentUserHasRight('SeeQueue') ) {
+ $cfs->SetContextObject( $self );
+ $cfs->LimitToGlobalOrObjectId( $self->Id );
+ $cfs->LimitToLookupType( 'RT::Queue-RT::Ticket' );
+ $cfs->ApplySortOrder;
}
+ return ($cfs);
+}
+
+
+
+=head2 TicketTransactionCustomFields
+
+Returns an L<RT::CustomFields> object containing all global and
+queue-specific B<transaction> custom fields.
+
+=cut
+sub TicketTransactionCustomFields {
+ my $self = shift;
+
+ my $cfs = RT::CustomFields->new( $self->CurrentUser );
+ if ( $self->CurrentUserHasRight('SeeQueue') ) {
+ $cfs->SetContextObject( $self );
+ $cfs->LimitToGlobalOrObjectId( $self->Id );
+ $cfs->LimitToLookupType( 'RT::Queue-RT::Ticket-RT::Transaction' );
+ $cfs->ApplySortOrder;
+ }
+ return ($cfs);
}
-# }}}
-# {{{ sub Templates
-=head2 Templates
-Returns an RT::Templates object of all of this queue's templates.
+=head2 AllRoleGroupTypes
+
+B<DEPRECATED> and will be removed in a future release. Use L</Roles>
+instead.
+
+Returns a list of the names of the various role group types for Queues,
+including roles used only for ACLs like Requestor and Owner. If you don't want
+them, see L</ManageableRoleGroupTypes>.
=cut
-sub Templates {
- my $self = shift;
-
+sub AllRoleGroupTypes {
+ RT->Deprecated(
+ Remove => "4.4",
+ Instead => "RT::Queue->Roles",
+ );
+ shift->Roles;
+}
- my $templates = RT::Templates->new($self->CurrentUser);
+=head2 IsRoleGroupType
- if ($self->CurrentUserHasRight('ShowTemplate')) {
- $templates->LimitToQueue($self->id);
- }
-
- return ($templates);
+B<DEPRECATED> and will be removed in a future release. Use L</HasRole> instead.
+
+Returns whether the passed-in type is a role group type.
+
+=cut
+
+sub IsRoleGroupType {
+ RT->Deprecated(
+ Remove => "4.4",
+ Instead => "RT::Queue->HasRole",
+ );
+ shift->HasRole(@_);
}
-# }}}
+=head2 ManageableRoleGroupTypes
-# {{{ Dealing with watchers
+Returns a list of the names of the various role group types for Queues,
+excluding ones used only for ACLs such as Requestor and Owner. If you want
+them, see L</Roles>.
-# {{{ sub Watchers
+=cut
-=head2 Watchers
+sub ManageableRoleGroupTypes {
+ shift->Roles( ACLOnly => 0 )
+}
-Watchers returns a Watchers object preloaded with this queue\'s watchers.
+=head2 IsManageableRoleGroupType
+
+Returns whether the passed-in type is a manageable role group type.
=cut
-sub Watchers {
+sub IsManageableRoleGroupType {
my $self = shift;
-
- require RT::Watchers;
- my $watchers =RT::Watchers->new($self->CurrentUser);
-
- if ($self->CurrentUserHasRight('SeeQueue')) {
- $watchers->LimitToQueue($self->id);
- }
-
- return($watchers);
+ my $type = shift;
+ return( $self->HasRole($type) and not $self->Role($type)->{ACLOnly} );
+}
+
+
+sub _HasModifyWatcherRight {
+ my $self = shift;
+ my ($type, $principal) = @_;
+
+ # ModifyQueueWatchers works in any case
+ return 1 if $self->CurrentUserHasRight('ModifyQueueWatchers');
+ # If the watcher isn't the current user then the current user has no right
+ return 0 unless $self->CurrentUser->PrincipalId == $principal->id;
+ # If it's an AdminCc and they don't have 'WatchAsAdminCc', bail
+ return 0 if $type eq 'AdminCc' and not $self->CurrentUserHasRight('WatchAsAdminCc');
+ # If it's a Requestor or Cc and they don't have 'Watch', bail
+ return 0 if ($type eq "Cc" or $type eq 'Requestor')
+ and not $self->CurrentUserHasRight('Watch');
+ return 1;
}
-# }}}
-# {{{ sub WatchersAsString
-=head2 WatchersAsString
+=head2 AddWatcher
+
+Applies access control checking, then calls
+L<RT::Record::Role::Roles/AddRoleMember>. Additionally, C<Email> is
+accepted as an alternative argument name for C<User>.
-Returns a string of all queue watchers email addresses concatenated with ','s.
+Returns a tuple of (status, message).
=cut
-sub WatchersAsString {
- my $self=shift;
- return($self->Watchers->EmailsAsString());
+sub AddWatcher {
+ my $self = shift;
+ my %args = (
+ Type => undef,
+ PrincipalId => undef,
+ Email => undef,
+ @_
+ );
+
+ $args{ACL} = sub { $self->_HasModifyWatcherRight( @_ ) };
+ $args{User} ||= delete $args{Email};
+ my ($principal, $msg) = $self->AddRoleMember( %args );
+ return ( 0, $msg) unless $principal;
+
+ return ( 1, $self->loc("Added [_1] to members of [_2] for this queue.",
+ $principal->Object->Name, $self->loc($args{'Type'}) ));
}
-# }}}
-# {{{ sub AdminCcAsString
+=head2 DeleteWatcher
-=head2 AdminCcAsString
+Applies access control checking, then calls
+L<RT::Record::Role::Roles/DeleteRoleMember>. Additionally, C<Email> is
+accepted as an alternative argument name for C<User>.
-Takes nothing. returns a string: All Ticket/Queue AdminCcs.
+Returns a tuple of (status, message).
=cut
+sub DeleteWatcher {
+ my $self = shift;
-sub AdminCcAsString {
- my $self=shift;
-
- return($self->AdminCc->EmailsAsString());
- }
+ my %args = (
+ Type => undef,
+ PrincipalId => undef,
+ Email => undef,
+ @_
+ );
+
+ $args{ACL} = sub { $self->_HasModifyWatcherRight( @_ ) };
+ $args{User} ||= delete $args{Email};
+ my ($principal, $msg) = $self->DeleteRoleMember( %args );
+ return ( 0, $msg) unless $principal;
+
+ return ( 1, $self->loc("Removed [_1] from members of [_2] for this queue.",
+ $principal->Object->Name, $self->loc($args{'Type'}) ));
+}
-# }}}
-# {{{ sub CcAsString
-=head2 CcAsString
+=head2 AdminCcAddresses
-B<Returns> String: All Queue Ccs as a comma delimited set of email addresses.
+returns String: All queue AdminCc email addresses as a string
=cut
-sub CcAsString {
- my $self=shift;
+sub AdminCcAddresses {
+ my $self = shift;
- return ($self->Cc->EmailsAsString());
-}
+ unless ( $self->CurrentUserHasRight('SeeQueue') ) {
+ return undef;
+ }
+
+ return ( $self->AdminCc->MemberEmailAddressesAsString )
+
+}
-# }}}
-# {{{ sub Cc
-=head2 Cc
+=head2 CcAddresses
-Takes nothing.
-Returns a watchers object which contains this queue\'s Cc watchers
+returns String: All queue Ccs as a string of email addresses
=cut
-sub Cc {
+sub CcAddresses {
my $self = shift;
- my $cc = $self->Watchers();
- if ($self->CurrentUserHasRight('SeeQueue')) {
- $cc->LimitToCc();
+
+ unless ( $self->CurrentUserHasRight('SeeQueue') ) {
+ return undef;
}
- return ($cc);
+
+ return ( $self->Cc->MemberEmailAddressesAsString);
+
}
-# A helper function for Cc, so that we can call it from the ACL checks
-# without going through acl checks.
-sub _Cc {
+
+=head2 Cc
+
+Takes nothing.
+Returns an RT::Group object which contains this Queue's Ccs.
+If the user doesn't have "ShowQueue" permission, returns an empty group
+
+=cut
+
+sub Cc {
my $self = shift;
- my $cc = $self->Watchers();
- $cc->LimitToCc();
- return($cc);
-
+
+ return RT::Group->new($self->CurrentUser)
+ unless $self->CurrentUserHasRight('SeeQueue');
+ return $self->RoleGroup( 'Cc' );
}
-# }}}
-# {{{ sub AdminCc
=head2 AdminCc
Takes nothing.
-Returns this queue's administrative Ccs as an RT::Watchers object
+Returns an RT::Group object which contains this Queue's AdminCcs.
+If the user doesn't have "ShowQueue" permission, returns an empty group
=cut
sub AdminCc {
my $self = shift;
- my $admin_cc = $self->Watchers();
- if ($self->CurrentUserHasRight('SeeQueue')) {
- $admin_cc->LimitToAdminCc();
- }
- return($admin_cc);
-}
-#helper function for AdminCc so we can call it without ACLs
-sub _AdminCc {
- my $self = shift;
- my $admin_cc = $self->Watchers();
- $admin_cc->LimitToAdminCc();
- return($admin_cc);
+ return RT::Group->new($self->CurrentUser)
+ unless $self->CurrentUserHasRight('SeeQueue');
+ return $self->RoleGroup( 'AdminCc' );
}
-# }}}
-
-# {{{ IsWatcher, IsCc, IsAdminCc
-# {{{ sub IsWatcher
# a generic routine to be called by IsRequestor, IsCc and IsAdminCc
-=head2 IsWatcher
+=head2 IsWatcher { Type => TYPE, PrincipalId => PRINCIPAL_ID }
+
+Takes a param hash with the attributes Type and PrincipalId
+
+Type is one of Requestor, Cc, AdminCc and Owner
+
+PrincipalId is an RT::Principal id
+
+Returns true if that principal is a member of the group Type for this queue
-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
-is a queue watcher. Returns undef otherwise
=cut
sub IsWatcher {
my $self = shift;
-
- my %args = ( Type => 'Requestor',
- Id => undef,
- Email => undef,
- @_
- );
- #ACL check - can't do it. we need this method for ACL checks
- # unless ($self->CurrentUserHasRight('SeeQueue')) {
- # return(undef);
- # }
-
-
- my %cols = ('Type' => $args{'Type'},
- 'Scope' => 'Queue',
- 'Value' => $self->Id
- );
- if (defined ($args{'Id'})) {
- if (ref($args{'Id'})){ #If it's a ref, assume it's an RT::User object;
- #Dangerous but ok for now
- $cols{'Owner'} = $args{'Id'}->Id;
- }
- elsif ($args{'Id'} =~ /^\d+$/) { # if it's an integer, it's an RT::User obj
- $cols{'Owner'} = $args{'Id'};
- }
- else {
- $cols{'Email'} = $args{'Id'};
- }
- }
-
- if (defined $args{'Email'}) {
- $cols{'Email'} = $args{'Email'};
- }
- my ($description);
- $description = join(":",%cols);
-
- #If we've cached a positive match...
- if (defined $self->{'watchers_cache'}->{"$description"}) {
- if ($self->{'watchers_cache'}->{"$description"} == 1) {
- return(1);
- }
- #If we've cached a negative match...
- else {
- return(undef);
- }
- }
+ my %args = ( Type => 'Cc',
+ PrincipalId => undef,
+ @_
+ );
- require RT::Watcher;
- my $watcher = new RT::Watcher($self->CurrentUser);
- $watcher->LoadByCols(%cols);
-
-
- if ($watcher->id) {
- $self->{'watchers_cache'}->{"$description"} = 1;
- return(1);
- }
- else {
- $self->{'watchers_cache'}->{"$description"} = 0;
- return(undef);
+ # Load the relevant group.
+ my $group = $self->RoleGroup( $args{'Type'} );
+ # Ask if it has the member in question
+
+ my $principal = RT::Principal->new($self->CurrentUser);
+ $principal->Load($args{'PrincipalId'});
+ unless ($principal->Id) {
+ return (undef);
}
-
+
+ return ($group->HasMemberRecursively($principal));
}
-# }}}
-# {{{ sub IsCc
-=head2 IsCc
-Takes a string. Returns true if the string is a Cc watcher of the current queue
+=head2 IsCc PRINCIPAL_ID
-=item Bugs
+Takes an RT::Principal id.
+Returns true if the principal is a requestor of the current queue.
-Should also be able to handle an RT::User object
=cut
-
sub IsCc {
- my $self = shift;
- my $cc = shift;
-
- return ($self->IsWatcher( Type => 'Cc', Id => $cc ));
-
-}
+ my $self = shift;
+ my $cc = shift;
-# }}}
+ return ( $self->IsWatcher( Type => 'Cc', PrincipalId => $cc ) );
-# {{{ sub IsAdminCc
+}
-=head2 IsAdminCc
-Takes a string. Returns true if the string is an AdminCc watcher of the current queue
-=item Bugs
+=head2 IsAdminCc PRINCIPAL_ID
-Should also be able to handle an RT::User object
+Takes an RT::Principal id.
+Returns true if the principal is a requestor of the current queue.
=cut
sub IsAdminCc {
- my $self = shift;
- my $admincc = shift;
-
- return ($self->IsWatcher( Type => 'AdminCc', Id => $admincc ));
-
+ my $self = shift;
+ my $person = shift;
+
+ return ( $self->IsWatcher( Type => 'AdminCc', PrincipalId => $person ) );
+
}
-# }}}
-# }}}
-# {{{ sub AddWatcher
-=head2 AddWatcher
-Takes a paramhash of Email, Owner and Type. Type is one of 'Cc' or 'AdminCc',
-We need either an Email Address in Email or a userid in Owner
-=cut
-sub AddWatcher {
+
+
+
+sub _Set {
my $self = shift;
- my %args = ( Email => undef,
- Type => undef,
- Owner => 0,
- @_
- );
-
- # {{{ Check ACLS
- #If the watcher we're trying to add is for the current user
- if ( ( ( defined $args{'Email'}) &&
- ( $args{'Email'} eq $self->CurrentUser->EmailAddress) ) or
- ($args{'Owner'} eq $self->CurrentUser->Id)) {
-
- # If it's an AdminCc and they don't have
- # 'WatchAsAdminCc' or 'ModifyQueueWatchers', bail
- if ($args{'Type'} eq 'AdminCc') {
- unless ($self->CurrentUserHasRight('ModifyQueueWatchers') or
- $self->CurrentUserHasRight('WatchAsAdminCc')) {
- return(0, 'Permission Denied');
- }
- }
-
- # If it's a Requestor or Cc and they don't have
- # 'Watch' or 'ModifyQueueWatchers', bail
- elsif ($args{'Type'} eq 'Cc') {
- unless ($self->CurrentUserHasRight('ModifyQueueWatchers') or
- $self->CurrentUserHasRight('Watch')) {
- return(0, 'Permission Denied');
- }
- }
- else {
- $RT::Logger->warn("$self -> AddWatcher hit code".
- " it never should. We got passed ".
- " a type of ". $args{'Type'});
- return (0,'Error in parameters to $self AddWatcher');
- }
+
+ my %args = (
+ Field => undef,
+ Value => undef,
+ TransactionType => 'Set',
+ RecordTransaction => 1,
+ @_
+ );
+
+ unless ( $self->CurrentUserHasRight('AdminQueue') ) {
+ return ( 0, $self->loc('Permission Denied') );
}
- # If the watcher isn't the current user
- # and the current user doesn't have 'ModifyQueueWatchers'
- # bail
- else {
- unless ($self->CurrentUserHasRight('ModifyQueueWatchers')) {
- return (0, "Permission Denied");
- }
+
+ my $Old = $self->SUPER::_Value("$args{'Field'}");
+
+ my ($ret, $msg) = $self->SUPER::_Set(
+ Field => $args{'Field'},
+ Value => $args{'Value'},
+ );
+
+ if ( $ret == 0 ) { return ( 0, $msg ); }
+
+ RT->System->QueueCacheNeedsUpdate(1);
+
+ if ( $args{'RecordTransaction'} == 1 ) {
+ if ($args{'Field'} eq 'Disabled') {
+ $args{'TransactionType'} = ($args{'Value'} == 1) ? "Disabled" : "Enabled";
+ delete $args{'Field'};
+ }
+ my ( undef, undef, $TransObj ) = $self->_NewTransaction(
+ Type => $args{'TransactionType'},
+ Field => $args{'Field'},
+ NewValue => $args{'Value'},
+ OldValue => $Old,
+ TimeTaken => $args{'TimeTaken'},
+ );
}
- # }}}
-
- require RT::Watcher;
- my $Watcher = new RT::Watcher ($self->CurrentUser);
- return ($Watcher->Create(Scope => 'Queue',
- Value => $self->Id,
- Email => $args{'Email'},
- Type => $args{'Type'},
- Owner => $args{'Owner'}
- ));
+
+ return ( $ret, $msg );
}
-# }}}
-# {{{ sub AddCc
-=head2 AddCc
+sub _Value {
+ my $self = shift;
-Add a Cc to this queue.
-Takes a paramhash of Email and Owner.
-We need either an Email Address in Email or a userid in Owner
+ unless ( $self->CurrentUserHasRight('SeeQueue') ) {
+ return (undef);
+ }
-=cut
+ return ( $self->__Value(@_) );
+}
+=head2 CurrentUserCanSee
-sub AddCc {
+Returns true if the current user can see the queue, using SeeQueue
+
+=cut
+
+sub CurrentUserCanSee {
my $self = shift;
- return ($self->AddWatcher( Type => 'Cc', @_));
+
+ return $self->CurrentUserHasRight('SeeQueue');
}
-# }}}
-# {{{ sub AddAdminCc
+=head2 id
-=head2 AddAdminCc
+Returns the current value of id.
+(In the database, id is stored as int(11).)
-Add an Administrative Cc to this queue.
-Takes a paramhash of Email and Owner.
-We need either an Email Address in Email or a userid in Owner
=cut
-sub AddAdminCc {
- my $self = shift;
- return ($self->AddWatcher( Type => 'AdminCc', @_));
-}
-# }}}
-# {{{ sub DeleteWatcher
+=head2 Name
+
+Returns the current value of Name.
+(In the database, Name is stored as varchar(200).)
+
+
+
+=head2 SetName VALUE
-=head2 DeleteWatcher id [type]
-DeleteWatcher takes a single argument which is either an email address
-or a watcher id.
-If the first argument is an email address, you need to specify the watcher type you're talking
-about as the second argument. Valid values are 'Cc' or 'AdminCc'.
-It removes that watcher from this Queue\'s list of watchers.
+Set Name to VALUE.
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Name will be stored as a varchar(200).)
=cut
-sub DeleteWatcher {
- my $self = shift;
- my $id = shift;
-
- my $type;
-
- $type = shift if (@_);
-
+=head2 Description
- require RT::Watcher;
- my $Watcher = new RT::Watcher($self->CurrentUser);
-
- #If it\'s a numeric watcherid
- if ($id =~ /^(\d*)$/) {
- $Watcher->Load($id);
- }
-
- #Otherwise, we'll assume it's an email address
- elsif ($type) {
- my ($result, $msg) =
- $Watcher->LoadByValue( Email => $id,
- Scope => 'Queue',
- Value => $self->id,
- Type => $type);
- return (0,$msg) unless ($result);
- }
-
- else {
- return(0,"Can\'t delete a watcher by email address without specifying a type");
- }
-
- # {{{ Check ACLS
-
- #If the watcher we're trying to delete is for the current user
- if ($Watcher->Email eq $self->CurrentUser->EmailAddress) {
-
- # If it's an AdminCc and they don't have
- # 'WatchAsAdminCc' or 'ModifyQueueWatchers', bail
- if ($Watcher->Type eq 'AdminCc') {
- unless ($self->CurrentUserHasRight('ModifyQueueWatchers') or
- $self->CurrentUserHasRight('WatchAsAdminCc')) {
- return(0, 'Permission Denied');
- }
- }
-
- # If it's a Cc and they don't have
- # 'Watch' or 'ModifyQueueWatchers', bail
- elsif ($Watcher->Type eq 'Cc') {
- unless ($self->CurrentUserHasRight('ModifyQueueWatchers') or
- $self->CurrentUserHasRight('Watch')) {
- return(0, 'Permission Denied');
- }
- }
- else {
- $RT::Logger->warn("$self -> DeleteWatcher hit code".
- " it never should. We got passed ".
- " a type of ". $args{'Type'});
- return (0,'Error in parameters to $self DeleteWatcher');
- }
- }
- # If the watcher isn't the current user
- # and the current user doesn't have 'ModifyQueueWatchers'
- # bail
- else {
- unless ($self->CurrentUserHasRight('ModifyQueueWatchers')) {
- return (0, "Permission Denied");
- }
- }
+Returns the current value of Description.
+(In the database, Description is stored as varchar(255).)
- # }}}
-
- unless (($Watcher->Scope eq 'Queue') and
- ($Watcher->Value == $self->id) ) {
- return (0, "Not a watcher for this queue");
- }
-
- #Clear out the watchers hash.
- $self->{'watchers'} = undef;
-
- my $retval = $Watcher->Delete();
-
- unless ($retval) {
- return(0,"Watcher could not be deleted.");
- }
-
- return(1, "Watcher deleted");
-}
-# {{{ sub DeleteCc
+=head2 SetDescription VALUE
-=head2 DeleteCc EMAIL
-Takes an email address. It calls DeleteWatcher with a preset
-type of 'Cc'
+Set Description to VALUE.
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Description will be stored as a varchar(255).)
=cut
-sub DeleteCc {
- my $self = shift;
- my $id = shift;
- return ($self->DeleteWatcher ($id, 'Cc'))
-}
-# }}}
+=head2 CorrespondAddress
+
+Returns the current value of CorrespondAddress.
+(In the database, CorrespondAddress is stored as varchar(120).)
+
-# {{{ sub DeleteAdminCc
-=head2 DeleteAdminCc EMAIL
+=head2 SetCorrespondAddress VALUE
-Takes an email address. It calls DeleteWatcher with a preset
-type of 'AdminCc'
+
+Set CorrespondAddress to VALUE.
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, CorrespondAddress will be stored as a varchar(120).)
=cut
-sub DeleteAdminCc {
- my $self = shift;
- my $id = shift;
- return ($self->DeleteWatcher ($id, 'AdminCc'))
-}
-# }}}
+=head2 CommentAddress
+Returns the current value of CommentAddress.
+(In the database, CommentAddress is stored as varchar(120).)
-# }}}
-# }}}
-# {{{ Dealing with keyword selects
+=head2 SetCommentAddress VALUE
-# {{{ sub AddKeywordSelect
-=head2 AddKeywordSelect
+Set CommentAddress to VALUE.
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, CommentAddress will be stored as a varchar(120).)
-Takes a paramhash of Name, Keyword, Depth and Single. Adds a new KeywordSelect for
-this queue with those attributes.
=cut
-sub AddKeywordSelect {
- my $self = shift;
- my %args = ( Keyword => undef,
- Depth => undef,
- Single => undef,
- Name => undef,
- @_);
-
- #ACLS get handled in KeywordSelect
- my $NewKeywordSelect = new RT::KeywordSelect($self->CurrentUser);
-
- return ($NewKeywordSelect->Create (Keyword => $args{'Keyword'},
- Depth => $args{'Depth'},
- Name => $args{'Name'},
- Single => $args{'Single'},
- ObjectType => 'Ticket',
- ObjectField => 'Queue',
- ObjectValue => $self->Id()
- ) );
-}
+=head2 Lifecycle
+
+Returns the current value of Lifecycle.
+(In the database, Lifecycle is stored as varchar(32).)
+
-# }}}
-# {{{ sub KeywordSelect
+=head2 SetLifecycle VALUE
-=head2 KeywordSelect([NAME])
-Takes the name of a keyword select for this queue or that's global.
-Returns the relevant KeywordSelect object. Prefers a keywordselect that's
-specific to this queue over a global one. If it can't find the proper
-Keword select or the user doesn't have permission, returns an empty
-KeywordSelect object
+Set Lifecycle to VALUE.
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Lifecycle will be stored as a varchar(32).)
+
=cut
-sub KeywordSelect {
- my $self = shift;
- my $name = shift;
-
- require RT::KeywordSelect;
+=head2 SubjectTag
+
+Returns the current value of SubjectTag.
+(In the database, SubjectTag is stored as varchar(120).)
- my $select = RT::KeywordSelect->new($self->CurrentUser);
- if ($self->CurrentUserHasRight('SeeQueue')) {
- $select->LoadByName( Name => $name, Queue => $self->Id);
- }
- return ($select);
-}
-# }}}
+=head2 SetSubjectTag VALUE
-# {{{ sub KeywordSelects
-=head2 KeywordSelects
+Set SubjectTag to VALUE.
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, SubjectTag will be stored as a varchar(120).)
-Returns an B<RT::KeywordSelects> object containing the collection of
-B<RT::KeywordSelect> objects which apply to this queue. (Both queue specific keyword selects
-and global keyword selects.
=cut
-sub KeywordSelects {
- my $self = shift;
+=head2 InitialPriority
- use RT::KeywordSelects;
- my $KeywordSelects = new RT::KeywordSelects($self->CurrentUser);
+Returns the current value of InitialPriority.
+(In the database, InitialPriority is stored as int(11).)
- if ($self->CurrentUserHasRight('SeeQueue')) {
- $KeywordSelects->LimitToQueue($self->id);
- $KeywordSelects->IncludeGlobals();
- }
- return ($KeywordSelects);
-}
-# }}}
-# }}}
-# {{{ ACCESS CONTROL
+=head2 SetInitialPriority VALUE
-# {{{ sub ACL
-=head2 ACL
+Set InitialPriority to VALUE.
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, InitialPriority will be stored as a int(11).)
-#Returns an RT::ACL object of ACEs everyone who has anything to do with this queue.
=cut
-sub ACL {
- my $self = shift;
-
- use RT::ACL;
- my $acl = new RT::ACL($self->CurrentUser);
-
- if ($self->CurrentUserHasRight('ShowACL')) {
- $acl->LimitToQueue($self->Id);
- }
-
- return ($acl);
-}
-# }}}
+=head2 FinalPriority
-# {{{ sub _Set
-sub _Set {
- my $self = shift;
+Returns the current value of FinalPriority.
+(In the database, FinalPriority is stored as int(11).)
- unless ($self->CurrentUserHasRight('AdminQueue')) {
- return(0, 'Permission Denied');
- }
- return ($self->SUPER::_Set(@_));
-}
-# }}}
-# {{{ sub _Value
-sub _Value {
- my $self = shift;
+=head2 SetFinalPriority VALUE
- unless ($self->CurrentUserHasRight('SeeQueue')) {
- return (undef);
- }
- return ($self->__Value(@_));
-}
+Set FinalPriority to VALUE.
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, FinalPriority will be stored as a int(11).)
+
+
+=cut
+
+
+=head2 DefaultDueIn
+
+Returns the current value of DefaultDueIn.
+(In the database, DefaultDueIn is stored as int(11).)
+
-# }}}
-# {{{ sub CurrentUserHasRight
+=head2 SetDefaultDueIn VALUE
-=head2 CurrentUserHasRight
-Takes one argument. A textual string with the name of the right we want to check.
-Returns true if the current user has that right for this queue.
-Returns undef otherwise.
+Set DefaultDueIn to VALUE.
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, DefaultDueIn will be stored as a int(11).)
+
=cut
-sub CurrentUserHasRight {
- my $self = shift;
- my $right = shift;
- return ($self->HasRight( Principal=> $self->CurrentUser,
- Right => "$right"));
+=head2 Creator
+
+Returns the current value of Creator.
+(In the database, Creator is stored as int(11).)
+
+
+=cut
+
+
+=head2 Created
+
+Returns the current value of Created.
+(In the database, Created is stored as datetime.)
+
+
+=cut
+
+
+=head2 LastUpdatedBy
+
+Returns the current value of LastUpdatedBy.
+(In the database, LastUpdatedBy is stored as int(11).)
+
+
+=cut
+
+
+=head2 LastUpdated
+
+Returns the current value of LastUpdated.
+(In the database, LastUpdated is stored as datetime.)
+
+
+=cut
+
+
+=head2 Disabled
+
+Returns the current value of Disabled.
+(In the database, Disabled is stored as smallint(6).)
-}
-# }}}
-# {{{ sub HasRight
+=head2 SetDisabled VALUE
-=head2 HasRight
-Takes a param hash with the fields 'Right' and 'Principal'.
-Principal defaults to the current user.
-Returns true if the principal has that right for this queue.
-Returns undef otherwise.
+Set Disabled to VALUE.
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Disabled will be stored as a smallint(6).)
+
=cut
-# TAKES: Right and optional "Principal" which defaults to the current user
-sub HasRight {
+
+
+sub _CoreAccessible {
+ {
+
+ id =>
+ {read => 1, sql_type => 4, length => 11, is_blob => 0, is_numeric => 1, type => 'int(11)', default => ''},
+ Name =>
+ {read => 1, write => 1, sql_type => 12, length => 200, is_blob => 0, is_numeric => 0, type => 'varchar(200)', default => ''},
+ Description =>
+ {read => 1, write => 1, sql_type => 12, length => 255, is_blob => 0, is_numeric => 0, type => 'varchar(255)', default => ''},
+ CorrespondAddress =>
+ {read => 1, write => 1, sql_type => 12, length => 120, is_blob => 0, is_numeric => 0, type => 'varchar(120)', default => ''},
+ CommentAddress =>
+ {read => 1, write => 1, sql_type => 12, length => 120, is_blob => 0, is_numeric => 0, type => 'varchar(120)', default => ''},
+ SubjectTag =>
+ {read => 1, write => 1, sql_type => 12, length => 120, is_blob => 0, is_numeric => 0, type => 'varchar(120)', default => ''},
+ Lifecycle =>
+ {read => 1, write => 1, sql_type => 12, length => 32, is_blob => 0, is_numeric => 0, type => 'varchar(32)', default => 'default'},
+ InitialPriority =>
+ {read => 1, write => 1, sql_type => 4, length => 11, is_blob => 0, is_numeric => 1, type => 'int(11)', default => '0'},
+ FinalPriority =>
+ {read => 1, write => 1, sql_type => 4, length => 11, is_blob => 0, is_numeric => 1, type => 'int(11)', default => '0'},
+ DefaultDueIn =>
+ {read => 1, write => 1, sql_type => 4, length => 11, is_blob => 0, is_numeric => 1, type => 'int(11)', default => '0'},
+ Creator =>
+ {read => 1, auto => 1, sql_type => 4, length => 11, is_blob => 0, is_numeric => 1, type => 'int(11)', default => '0'},
+ Created =>
+ {read => 1, auto => 1, sql_type => 11, length => 0, is_blob => 0, is_numeric => 0, type => 'datetime', default => ''},
+ LastUpdatedBy =>
+ {read => 1, auto => 1, sql_type => 4, length => 11, is_blob => 0, is_numeric => 1, type => 'int(11)', default => '0'},
+ LastUpdated =>
+ {read => 1, auto => 1, sql_type => 11, length => 0, is_blob => 0, is_numeric => 0, type => 'datetime', default => ''},
+ Disabled =>
+ {read => 1, write => 1, sql_type => 5, length => 6, is_blob => 0, is_numeric => 1, type => 'smallint(6)', default => '0'},
+
+ }
+};
+
+sub FindDependencies {
my $self = shift;
- my %args = ( Right => undef,
- Principal => $self->CurrentUser,
- @_);
- unless(defined $args{'Principal'}) {
- $RT::Logger->debug("Principal undefined in Queue::HasRight");
+ my ($walker, $deps) = @_;
+
+ $self->SUPER::FindDependencies($walker, $deps);
+
+ # Queue role groups( Cc, AdminCc )
+ my $objs = RT::Groups->new( $self->CurrentUser );
+ $objs->Limit( FIELD => 'Domain', VALUE => 'RT::Queue-Role', CASESENSITIVE => 0 );
+ $objs->Limit( FIELD => 'Instance', VALUE => $self->Id );
+ $deps->Add( in => $objs );
+
+ # Scrips
+ $objs = RT::ObjectScrips->new( $self->CurrentUser );
+ $objs->Limit( FIELD => 'ObjectId',
+ OPERATOR => '=',
+ VALUE => $self->id,
+ ENTRYAGGREGATOR => 'OR' );
+ $objs->Limit( FIELD => 'ObjectId',
+ OPERATOR => '=',
+ VALUE => 0,
+ ENTRYAGGREGATOR => 'OR' );
+ $deps->Add( in => $objs );
+
+ # Templates (global ones have already been dealt with)
+ $objs = RT::Templates->new( $self->CurrentUser );
+ $objs->Limit( FIELD => 'Queue', VALUE => $self->Id);
+ $deps->Add( in => $objs );
+
+ # Custom Fields on things _in_ this queue (CFs on the queue itself
+ # have already been dealt with)
+ $objs = RT::ObjectCustomFields->new( $self->CurrentUser );
+ $objs->Limit( FIELD => 'ObjectId',
+ OPERATOR => '=',
+ VALUE => $self->id,
+ ENTRYAGGREGATOR => 'OR' );
+ $objs->Limit( FIELD => 'ObjectId',
+ OPERATOR => '=',
+ VALUE => 0,
+ ENTRYAGGREGATOR => 'OR' );
+ my $cfs = $objs->Join(
+ ALIAS1 => 'main',
+ FIELD1 => 'CustomField',
+ TABLE2 => 'CustomFields',
+ FIELD2 => 'id',
+ );
+ $objs->Limit( ALIAS => $cfs,
+ FIELD => 'LookupType',
+ OPERATOR => 'STARTSWITH',
+ VALUE => 'RT::Queue-' );
+ $deps->Add( in => $objs );
+
+ # Tickets
+ $objs = RT::Tickets->new( $self->CurrentUser );
+ $objs->Limit( FIELD => "Queue", VALUE => $self->Id );
+ $objs->{allow_deleted_search} = 1;
+ $deps->Add( in => $objs );
+}
- }
- return($args{'Principal'}->HasQueueRight(QueueObj => $self,
- Right => $args{'Right'}));
+sub __DependsOn {
+ my $self = shift;
+ my %args = (
+ Shredder => undef,
+ Dependencies => undef,
+ @_,
+ );
+ my $deps = $args{'Dependencies'};
+ my $list = [];
+
+# Tickets
+ my $objs = RT::Tickets->new( $self->CurrentUser );
+ $objs->{'allow_deleted_search'} = 1;
+ $objs->Limit( FIELD => 'Queue', VALUE => $self->Id );
+ push( @$list, $objs );
+
+# Queue role groups( Cc, AdminCc )
+ $objs = RT::Groups->new( $self->CurrentUser );
+ $objs->Limit( FIELD => 'Domain', VALUE => 'RT::Queue-Role', CASESENSITIVE => 0 );
+ $objs->Limit( FIELD => 'Instance', VALUE => $self->Id );
+ push( @$list, $objs );
+
+# Scrips
+ $objs = RT::Scrips->new( $self->CurrentUser );
+ $objs->LimitToQueue( $self->id );
+ push( @$list, $objs );
+
+# Templates
+ $objs = $self->Templates;
+ push( @$list, $objs );
+
+# Custom Fields
+ $objs = RT::CustomFields->new( $self->CurrentUser );
+ $objs->SetContextObject( $self );
+ $objs->LimitToQueue( $self->id );
+ push( @$list, $objs );
+
+ $deps->_PushDependencies(
+ BaseObject => $self,
+ Flags => RT::Shredder::Constants::DEPENDS_ON,
+ TargetObjects => $list,
+ Shredder => $args{'Shredder'}
+ );
+ return $self->SUPER::__DependsOn( %args );
+}
+
+
+sub PreInflate {
+ my $class = shift;
+ my ($importer, $uid, $data) = @_;
+
+ $class->SUPER::PreInflate( $importer, $uid, $data );
+
+ $data->{Name} = $importer->Qualify($data->{Name})
+ if $data->{Name} ne "___Approvals";
+
+ return if $importer->MergeBy( "Name", $class, $uid, $data );
+
+ return 1;
}
-# }}}
-# }}}
+
+
+RT::Base->_ImportOverlays();
1;