+ 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;
+
+ 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;
+
+ 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;
+
+ 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;
+
+ my ( undef, undef, $TransObj ) = $self->_NewTransaction(
+ Field => 'Encrypting', #loc
+ Type => $value ? "Enabled" : "Disabled"
+ );
+
+ return ($status, scalar $TransObj->BriefDescription);
+}
+
+=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 {