diff options
Diffstat (limited to 'rt/lib/RT/Topic.pm')
-rw-r--r-- | rt/lib/RT/Topic.pm | 376 |
1 files changed, 376 insertions, 0 deletions
diff --git a/rt/lib/RT/Topic.pm b/rt/lib/RT/Topic.pm new file mode 100644 index 000000000..3499a4d2f --- /dev/null +++ b/rt/lib/RT/Topic.pm @@ -0,0 +1,376 @@ +# BEGIN BPS TAGGED BLOCK {{{ +# +# COPYRIGHT: +# +# This software is Copyright (c) 1996-2012 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 }}} + +use warnings; +use strict; + +package RT::Topic; +use base 'RT::Record'; + +sub Table {'Topics'} + +# {{{ Create + +=head2 Create PARAMHASH + +Create takes a hash of values and creates a row in the database: + + int(11) 'Parent'. + varchar(255) 'Name'. + varchar(255) 'Description'. + varchar(64) 'ObjectType'. + int(11) 'ObjectId'. + +=cut + +sub Create { + my $self = shift; + my %args = ( + Parent => '', + Name => '', + Description => '', + ObjectType => '', + ObjectId => '0', + @_); + + my $obj = $RT::System; + if ($args{ObjectId}) { + $obj = $args{ObjectType}->new($self->CurrentUser); + $obj->Load($args{ObjectId}); + $obj = $RT::System unless $obj->id; + } + + return ( 0, $self->loc("Permission denied")) + unless ( $self->CurrentUser->HasRight( + Right => "AdminTopics", + Object => $obj, + EquivObjects => [ $RT::System, $obj ], + ) ); + + $self->SUPER::Create(@_); +} + +# }}} + + +# {{{ Delete + +=head2 Delete + +Deletes this topic, reparenting all sub-topics to this one's parent. + +=cut + +sub Delete { + my $self = shift; + + unless ( $self->CurrentUserHasRight('AdminTopics') ) { + return ( 0, $self->loc("Permission Denied") ); + } + + my $kids = RT::Topics->new($self->CurrentUser); + $kids->LimitToKids($self->Id); + while (my $topic = $kids->Next) { + $topic->setParent($self->Parent); + } + + $self->SUPER::Delete(@_); + return (0, "Topic deleted"); +} + +# }}} + + +# {{{ DeleteAll + +=head2 DeleteAll + +Deletes this topic, and all of its descendants. + +=cut + +sub DeleteAll { + my $self = shift; + + unless ( $self->CurrentUserHasRight('AdminTopics') ) { + return ( 0, $self->loc("Permission Denied") ); + } + + $self->SUPER::Delete(@_); + my $kids = RT::Topics->new($self->CurrentUser); + $kids->LimitToKids($self->Id); + while (my $topic = $kids->Next) { + $topic->DeleteAll; + } + + return (0, "Topic tree deleted"); +} + +# }}} + + +# {{{ ParentObj + +=head2 ParentObj + +Returns the parent Topic of this one. + +=cut + +sub ParentObj { + my $self = shift; + my $id = $self->Parent; + my $obj = RT::Topic->new($self->CurrentUser); + $obj->Load($id); + return $obj; +} + +# }}} + +# {{{ Children + +=head2 Children + +Returns a Topics object containing this topic's children, +sorted by Topic.Name. + +=cut + +sub Children { + my $self = shift; + unless ($self->{'Children'}) { + $self->{'Children'} = RT::Topics->new($self->CurrentUser); + $self->{'Children'}->Limit('FIELD' => 'Parent', + 'VALUE' => $self->Id); + $self->{'Children'}->OrderBy('FIELD' => 'Name'); + } + return $self->{'Children'}; +} + +# {{{ _Set + +=head2 _Set + +Intercept attempts to modify the Topic so we can apply ACLs + +=cut + +sub _Set { + my $self = shift; + + unless ( $self->CurrentUserHasRight('AdminTopics') ) { + return ( 0, $self->loc("Permission Denied") ); + } + $self->SUPER::_Set(@_); +} + +# }}} + + +# {{{ CurrentUserHasRight + +=head2 CurrentUserHasRight + +Returns true if the current user has the right for this topic, for the +whole system or for whatever object this topic is associated with + +=cut + +sub CurrentUserHasRight { + my $self = shift; + my $right = shift; + + my $equiv = [ $RT::System ]; + if ($self->ObjectId) { + my $obj = $self->ObjectType->new($self->CurrentUser); + $obj->Load($self->ObjectId); + push @{$equiv}, $obj; + } + if ($self->Id) { + return ( $self->CurrentUser->HasRight( + Right => $right, + Object => $self, + EquivObjects => $equiv, + ) ); + } else { + # If we don't have an ID, we don't even know what object we're + # attached to -- so the only thing we can fall back on is the + # system object. + return ( $self->CurrentUser->HasRight( + Right => $right, + Object => $RT::System, + ) ); + } + + +} + +# }}} + + +=head2 id + +Returns the current value of id. +(In the database, id is stored as int(11).) + + +=cut + + +=head2 Parent + +Returns the current value of Parent. +(In the database, Parent is stored as int(11).) + + + +=head2 SetParent VALUE + + +Set Parent to VALUE. +Returns (1, 'Status message') on success and (0, 'Error Message') on failure. +(In the database, Parent will be stored as a int(11).) + + +=cut + + +=head2 Name + +Returns the current value of Name. +(In the database, Name is stored as varchar(255).) + + + +=head2 SetName VALUE + + +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(255).) + + +=cut + + +=head2 Description + +Returns the current value of Description. +(In the database, Description is stored as varchar(255).) + + + +=head2 SetDescription VALUE + + +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 + + +=head2 ObjectType + +Returns the current value of ObjectType. +(In the database, ObjectType is stored as varchar(64).) + + + +=head2 SetObjectType VALUE + + +Set ObjectType to VALUE. +Returns (1, 'Status message') on success and (0, 'Error Message') on failure. +(In the database, ObjectType will be stored as a varchar(64).) + + +=cut + + +=head2 ObjectId + +Returns the current value of ObjectId. +(In the database, ObjectId is stored as int(11).) + + + +=head2 SetObjectId VALUE + + +Set ObjectId to VALUE. +Returns (1, 'Status message') on success and (0, 'Error Message') on failure. +(In the database, ObjectId will be stored as a int(11).) + + +=cut + + + +sub _CoreAccessible { + { + + id => + {read => 1, type => 'int(11)', default => ''}, + Parent => + {read => 1, write => 1, type => 'int(11)', default => ''}, + Name => + {read => 1, write => 1, type => 'varchar(255)', default => ''}, + Description => + {read => 1, write => 1, type => 'varchar(255)', default => ''}, + ObjectType => + {read => 1, write => 1, type => 'varchar(64)', default => ''}, + ObjectId => + {read => 1, write => 1, type => 'int(11)', default => '0'}, + + } +}; + +RT::Base->_ImportOverlays(); +1; |