# BEGIN BPS TAGGED BLOCK {{{
-#
+#
# COPYRIGHT:
-#
-# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
-# <jesse@bestpractical.com>
-#
+#
+# This software is Copyright (c) 1996-2015 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/copyleft/gpl.html.
-#
-#
+# 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
# 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 }}}
-# Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
-# WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.
-#
-# !! DO NOT EDIT THIS FILE !!
#
-
-use strict;
-
+# END BPS TAGGED BLOCK }}}
=head1 NAME
-RT::Queue
-
+ RT::Queue - an RT Queue object
=head1 SYNOPSIS
+ use RT::Queue;
+
=head1 DESCRIPTION
+An RT queue object.
+
=head1 METHODS
=cut
+
package RT::Queue;
-use RT::Record;
+
+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.
-use vars qw( @ISA );
-@ISA= qw( RT::Record );
+=cut
-sub _Init {
- my $self = shift;
+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") );
+ }
- $self->Table('Queues');
- $self->SUPER::_Init(@_);
+ {
+ my ($val, $msg) = $self->_ValidateName( $args{'Name'} );
+ return ($val, $msg) unless $val;
+ }
+
+ $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;
+
+ #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') );
+ }
+
+ 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;
+ }
+
+ RT->System->QueueCacheNeedsUpdate(1);
+
+ return ( $id, $self->loc("Queue created") );
}
+sub Delete {
+ my $self = shift;
+ return ( 0,
+ $self->loc('Deleting this object would break referential integrity') );
+}
-=head2 Create PARAMHASH
-Create takes a hash of values and creates a row in the database:
+=head2 SetDisabled
- varchar(200) 'Name'.
- varchar(255) 'Description'.
- varchar(120) 'CorrespondAddress'.
- varchar(120) 'CommentAddress'.
- int(11) 'InitialPriority'.
- int(11) 'FinalPriority'.
- int(11) 'DefaultDueIn'.
- smallint(6) 'Disabled'.
+Takes a boolean.
+1 will cause this queue to no longer be available for tickets.
+0 will re-enable this queue.
=cut
+sub SetDisabled {
+ my $self = shift;
+ my $val = shift;
+ $RT::Handle->BeginTransaction();
+ my ($ok, $msg) = $self->_Set( Field =>'Disabled', Value => $val);
+ unless ($ok) {
+ $RT::Handle->Rollback();
+ $RT::Logger->warning("Couldn't ".(($val == 0) ? "enable" : "disable")." queue ".$self->Name.": $msg");
+ return ($ok, $msg);
+ }
+ $self->_NewTransaction( Type => ($val == 0) ? "Enabled" : "Disabled" );
+ $RT::Handle->Commit();
-sub Create {
+ RT->System->QueueCacheNeedsUpdate(1);
+
+ if ( $val == 0 ) {
+ return (1, $self->loc("Queue enabled"));
+ } else {
+ return (1, $self->loc("Queue disabled"));
+ }
+
+}
+
+
+
+=head2 Load
+
+Takes either a numerical id or a textual Name and loads the specified queue.
+
+=cut
+
+sub Load {
+ my $self = shift;
+
+ my $identifier = shift;
+ if ( !$identifier ) {
+ return (undef);
+ }
+
+ if ( $identifier =~ /^(\d+)$/ ) {
+ $self->SUPER::LoadById($identifier);
+ }
+ else {
+ $self->LoadByCols( Name => $identifier );
+ }
+
+ return ( $self->Id );
+
+}
+
+
+
+=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.
+
+=cut
+
+sub ValidateName {
+ my $self = shift;
+ my $name = shift;
+
+ 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;
+
+ # 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);
+}
+
+
+=head2 SetSign
+
+=cut
+
+sub Sign {
+ my $self = shift;
+ my $value = shift;
+
+ 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 ( 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;
+ return ($status, $self->loc('Signing enabled')) if $value;
+ return ($status, $self->loc('Signing disabled'));
+}
+
+sub SignAuto {
+ my $self = shift;
+ my $value = shift;
+
+ return undef unless $self->CurrentUserHasRight('SeeQueue');
+ my $attr = $self->FirstAttribute('SignAuto') or return 0;
+ return $attr->Content;
+}
+
+sub SetSignAuto {
+ my $self = shift;
+ 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;
+ return ($status, $self->loc('Signing enabled')) if $value;
+ return ($status, $self->loc('Signing disabled'));
+}
+
+sub Encrypt {
+ my $self = shift;
+ my $value = shift;
+
+ return undef unless $self->CurrentUserHasRight('SeeQueue');
+ my $attr = $self->FirstAttribute('Encrypt') or return 0;
+ return $attr->Content;
+}
+
+sub SetEncrypt {
+ my $self = shift;
+ my $value = shift;
+
+ return ( 0, $self->loc('Permission Denied') )
+ unless $self->CurrentUserHasRight('AdminQueue');
+
+ my ($status, $msg) = $self->SetAttribute(
+ Name => 'Encrypt',
+ Description => 'Encrypt outgoing messages by default',
+ Content => $value,
+ );
+ return ($status, $msg) unless $status;
+ return ($status, $self->loc('Encrypting enabled')) if $value;
+ return ($status, $self->loc('Encrypting disabled'));
+}
+
+=head2 Templates
+
+Returns an RT::Templates object of all of this queue's templates.
+
+=cut
+
+sub Templates {
+ my $self = shift;
+
+ my $templates = RT::Templates->new( $self->CurrentUser );
+
+ if ( $self->CurrentUserHasRight('ShowTemplate') ) {
+ $templates->LimitToQueue( $self->id );
+ }
+
+ return ($templates);
+}
+
+
+
+
+=head2 CustomField NAME
+
+Load the Ticket Custom Field applied to this Queue named NAME.
+Does not load Global custom fields.
+
+=cut
+
+sub CustomField {
+ my $self = shift;
+ my $name = shift;
+ my $cf = RT::CustomField->new($self->CurrentUser);
+ $cf->LoadByName(
+ Name => $name,
+ LookupType => RT::Ticket->CustomFieldLookupType,
+ ObjectId => $self->id,
+ );
+ return ($cf);
+}
+
+
+
+=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);
+}
+
+
+
+
+
+=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 AllRoleGroupTypes {
+ RT->Deprecated(
+ Remove => "4.4",
+ Instead => "RT::Queue->Roles",
+ );
+ shift->Roles;
+}
+
+=head2 IsRoleGroupType
+
+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
+
+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>.
+
+=cut
+
+sub ManageableRoleGroupTypes {
+ shift->Roles( ACLOnly => 0 )
+}
+
+=head2 IsManageableRoleGroupType
+
+Returns whether the passed-in type is a manageable role group type.
+
+=cut
+
+sub IsManageableRoleGroupType {
+ my $self = shift;
+ 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;
+}
+
+
+=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 tuple of (status, message).
+
+=cut
+
+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'}) ));
+}
+
+
+=head2 DeleteWatcher
+
+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>.
+
+Returns a tuple of (status, message).
+
+=cut
+
+sub DeleteWatcher {
+ 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->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'}) ));
+}
+
+
+
+=head2 AdminCcAddresses
+
+returns String: All queue AdminCc email addresses as a string
+
+=cut
+
+sub AdminCcAddresses {
+ my $self = shift;
+
+ unless ( $self->CurrentUserHasRight('SeeQueue') ) {
+ return undef;
+ }
+
+ return ( $self->AdminCc->MemberEmailAddressesAsString )
+
+}
+
+
+
+=head2 CcAddresses
+
+returns String: All queue Ccs as a string of email addresses
+
+=cut
+
+sub CcAddresses {
+ my $self = shift;
+
+ unless ( $self->CurrentUserHasRight('SeeQueue') ) {
+ return undef;
+ }
+
+ return ( $self->Cc->MemberEmailAddressesAsString);
+
+}
+
+
+
+=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;
+
+ return RT::Group->new($self->CurrentUser)
+ unless $self->CurrentUserHasRight('SeeQueue');
+ return $self->RoleGroup( 'Cc' );
+}
+
+
+
+=head2 AdminCc
+
+Takes nothing.
+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;
+
+ return RT::Group->new($self->CurrentUser)
+ unless $self->CurrentUserHasRight('SeeQueue');
+ return $self->RoleGroup( 'AdminCc' );
+}
+
+
+
+# a generic routine to be called by IsRequestor, IsCc and IsAdminCc
+
+=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
+
+
+=cut
+
+sub IsWatcher {
+ my $self = shift;
+
+ my %args = ( Type => 'Cc',
+ PrincipalId => 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));
+}
+
+
+
+
+=head2 IsCc PRINCIPAL_ID
+
+Takes an RT::Principal id.
+Returns true if the principal is a requestor of the current queue.
+
+
+=cut
+
+sub IsCc {
+ my $self = shift;
+ my $cc = shift;
+
+ return ( $self->IsWatcher( Type => 'Cc', PrincipalId => $cc ) );
+
+}
+
+
+
+=head2 IsAdminCc PRINCIPAL_ID
+
+Takes an RT::Principal id.
+Returns true if the principal is a requestor of the current queue.
+
+=cut
+
+sub IsAdminCc {
+ my $self = shift;
+ my $person = shift;
+
+ return ( $self->IsWatcher( Type => 'AdminCc', PrincipalId => $person ) );
+
+}
+
+
+
+
+
+
+
+
+
+
+sub _Set {
+ my $self = shift;
+
+ unless ( $self->CurrentUserHasRight('AdminQueue') ) {
+ return ( 0, $self->loc('Permission Denied') );
+ }
+ RT->System->QueueCacheNeedsUpdate(1);
+ return ( $self->SUPER::_Set(@_) );
+}
+
+
+
+sub _Value {
my $self = shift;
- my %args = (
- Name => '',
- Description => '',
- CorrespondAddress => '',
- CommentAddress => '',
- InitialPriority => '0',
- FinalPriority => '0',
- DefaultDueIn => '0',
- Disabled => '0',
- @_);
- $self->SUPER::Create(
- Name => $args{'Name'},
- Description => $args{'Description'},
- CorrespondAddress => $args{'CorrespondAddress'},
- CommentAddress => $args{'CommentAddress'},
- InitialPriority => $args{'InitialPriority'},
- FinalPriority => $args{'FinalPriority'},
- DefaultDueIn => $args{'DefaultDueIn'},
- Disabled => $args{'Disabled'},
-);
+ unless ( $self->CurrentUserHasRight('SeeQueue') ) {
+ return (undef);
+ }
+ return ( $self->__Value(@_) );
}
+=head2 CurrentUserCanSee
+Returns true if the current user can see the queue, using SeeQueue
+
+=cut
+
+sub CurrentUserCanSee {
+ my $self = shift;
+
+ return $self->CurrentUserHasRight('SeeQueue');
+}
=head2 id
=cut
+=head2 Lifecycle
+
+Returns the current value of Lifecycle.
+(In the database, Lifecycle is stored as varchar(32).)
+
+
+
+=head2 SetLifecycle VALUE
+
+
+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
+
+=head2 SubjectTag
+
+Returns the current value of SubjectTag.
+(In the database, SubjectTag is stored as varchar(120).)
+
+
+
+=head2 SetSubjectTag VALUE
+
+
+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).)
+
+
+=cut
+
+
=head2 InitialPriority
Returns the current value of InitialPriority.
{
id =>
- {read => 1, sql_type => 4, length => 11, is_blob => 0, is_numeric => 1, type => 'int(11)', default => ''},
+ {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 => ''},
+ {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 => ''},
+ {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 => ''},
+ {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 => ''},
+ {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'},
+ {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'},
+ {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'},
+ {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'},
+ {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 => ''},
+ {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'},
+ {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 => ''},
+ {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'},
+ {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 ($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 );
+}
- eval "require RT::Queue_Overlay";
- if ($@ && $@ !~ qr{^Can't locate RT/Queue_Overlay.pm}) {
- die $@;
- };
-
- eval "require RT::Queue_Vendor";
- if ($@ && $@ !~ qr{^Can't locate RT/Queue_Vendor.pm}) {
- die $@;
- };
-
- eval "require RT::Queue_Local";
- if ($@ && $@ !~ qr{^Can't locate RT/Queue_Local.pm}) {
- die $@;
- };
-
-
-
+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 );
+}
-=head1 SEE ALSO
-This class allows "overlay" methods to be placed
-into the following files _Overlay is for a System overlay by the original author,
-_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations.
+sub PreInflate {
+ my $class = shift;
+ my ($importer, $uid, $data) = @_;
-These overlay files can contain new subs or subs to replace existing subs in this module.
+ $class->SUPER::PreInflate( $importer, $uid, $data );
-Each of these files should begin with the line
+ $data->{Name} = $importer->Qualify($data->{Name})
+ if $data->{Name} ne "___Approvals";
- no warnings qw(redefine);
+ return if $importer->MergeBy( "Name", $class, $uid, $data );
-so that perl does not kick and scream when you redefine a subroutine or variable in your overlay.
+ return 1;
+}
-RT::Queue_Overlay, RT::Queue_Vendor, RT::Queue_Local
-=cut
+RT::Base->_ImportOverlays();
1;