rt 4.0.23
[freeside.git] / rt / lib / RT / Attributes.pm
1 # BEGIN BPS TAGGED BLOCK {{{
2 #
3 # COPYRIGHT:
4 #
5 # This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC
6 #                                          <sales@bestpractical.com>
7 #
8 # (Except where explicitly superseded by other copyright notices)
9 #
10 #
11 # LICENSE:
12 #
13 # This work is made available to you under the terms of Version 2 of
14 # the GNU General Public License. A copy of that license should have
15 # been provided with this software, but in any event can be snarfed
16 # from www.gnu.org.
17 #
18 # This work is distributed in the hope that it will be useful, but
19 # WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21 # General Public License for more details.
22 #
23 # You should have received a copy of the GNU General Public License
24 # along with this program; if not, write to the Free Software
25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 # 02110-1301 or visit their web page on the internet at
27 # http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
28 #
29 #
30 # CONTRIBUTION SUBMISSION POLICY:
31 #
32 # (The following paragraph is not intended to limit the rights granted
33 # to you to modify and distribute this software under the terms of
34 # the GNU General Public License and is only of importance to you if
35 # you choose to contribute your changes and enhancements to the
36 # community by submitting them to Best Practical Solutions, LLC.)
37 #
38 # By intentionally submitting any modifications, corrections or
39 # derivatives to this work, or any other work intended for use with
40 # Request Tracker, to Best Practical Solutions, LLC, you confirm that
41 # you are the copyright holder for those contributions and you grant
42 # Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
43 # royalty-free, perpetual, license to use, copy, create derivative
44 # works based on those contributions, and sublicense and distribute
45 # those contributions and any derivatives thereof.
46 #
47 # END BPS TAGGED BLOCK }}}
48
49 =head1 NAME
50
51 RT::Attributes - collection of RT::Attribute objects
52
53 =head1 SYNOPSIS
54
55     use RT::Attributes;
56     my $Attributes = RT::Attributes->new($CurrentUser);
57
58 =head1 DESCRIPTION
59
60
61 =head1 METHODS
62
63 =cut
64
65
66 package RT::Attributes;
67
68 use strict;
69 use warnings;
70
71
72 use RT::Attribute;
73
74 use base 'RT::SearchBuilder';
75
76 sub Table { 'Attributes'}
77
78
79 sub _DoSearch {
80     my $self = shift;
81     $self->SUPER::_DoSearch();
82 # if _DoSearch doesn't fully succeed, 'must_redo_search' will be true
83 # and call _BuildAccessTable then will result in a deep recursion
84     if ( $self->{'must_redo_search'} ) {
85         $RT::Logger->crit(
86 "_DoSearch is not so successful as it still needs redo search, won't call _BuildAccessTable"
87         );
88     }
89     else {
90         $self->_BuildAccessTable();
91     }
92 }
93
94
95 sub _BuildAccessTable {
96     my $self = shift;
97     delete $self->{'attr'};
98     while (my $attr = $self->Next) {
99         push @{$self->{'attr'}->{$attr->Name}}, $attr;
100     }
101 }
102
103
104 sub _AttrHash {
105     my $self = shift;
106     $self->_DoSearch if ($self->{'must_redo_search'} && $self->{'is_limited'});
107     unless ($self->{'attr'}) {
108         $self->{'attr'}->{'__none'} = RT::Attribute->new($self->CurrentUser);
109     }
110     return ($self->{'attr'});
111 }
112
113 =head2 Names
114
115 Returns a list of the Names of all attributes for this object. 
116
117 =cut
118
119 sub Names {
120     my $self = shift;
121     my @keys =  keys %{$self->_AttrHash};
122     return(@keys);
123
124
125 }
126
127 =head2 Named STRING
128
129 Returns an array of all the RT::Attribute objects with the name STRING
130
131 =cut
132
133 sub Named {
134     my $self = shift;
135     my $name = shift;
136     my @attributes; 
137     if ($self->_AttrHash) {
138         @attributes = @{($self->_AttrHash->{$name}||[])};
139     }
140     return (@attributes);   
141 }
142
143 =head2 WithId ID
144
145 Returns the RT::Attribute objects with the id ID
146
147 XXX TODO XXX THIS NEEDS A BETTER ACL CHECK
148
149 =cut
150
151 sub WithId {
152     my $self = shift;
153     my $id = shift;
154
155     my $attr = RT::Attribute->new($self->CurrentUser);
156     $attr->LoadByCols( id => $id );
157     return($attr);
158 }
159
160 =head2 DeleteEntry { Name =>   Content => , id => }
161
162 Deletes attributes with
163     the matching name 
164  and the matching content or id
165
166 If Content and id are both undefined, delete all attributes with
167 the matching name.
168
169 =cut
170
171
172 sub DeleteEntry {
173     my $self = shift;
174     my %args = (
175         Name    => undef,
176         Content => undef,
177         id      => undef,
178         @_
179     );
180     my $found = 0;
181     foreach my $attr ( $self->Named( $args{'Name'} ) ) {
182         if ( ( !defined $args{'id'} and !defined $args{'Content'} )
183              or ( defined $args{'id'} and $attr->id eq $args{'id'} )
184              or ( defined $args{'Content'} and $attr->Content eq $args{'Content'} ) )
185         {
186             my ($id, $msg) = $attr->Delete;
187             return ($id, $msg) unless $id;
188             $found = 1;
189         }
190     }
191     return (0, "No entry found") unless $found;
192     $self->RedoSearch;
193     # XXX: above string must work but because of bug in DBIx::SB it doesn't,
194     # to reproduce delete string below and run t/api/attribute-tests.t
195     $self->_DoSearch;
196     return (1, $self->loc('Attribute Deleted'));
197 }
198
199
200
201 =head2 LimitToObject $object
202
203 Limit the Attributes to rights for the object $object. It needs to be an RT::Record class.
204
205 =cut
206
207 sub LimitToObject {
208     my $self = shift;
209     my $obj = shift;
210     unless (eval { $obj->id} ){
211         return undef;
212     }
213
214     my $type = $obj->isa("RT::CurrentUser") ? "RT::User" : ref($obj);
215
216     $self->Limit(FIELD => 'ObjectType', OPERATOR=> '=', VALUE => $type, ENTRYAGGREGATOR => 'OR');
217     $self->Limit(FIELD => 'ObjectId', OPERATOR=> '=', VALUE => $obj->id, ENTRYAGGREGATOR => 'OR', QUOTEVALUE => 0);
218
219 }
220
221
222
223 =head2 NewItem
224
225 Returns an empty new RT::Attribute item
226
227 =cut
228
229 sub NewItem {
230     my $self = shift;
231     return(RT::Attribute->new($self->CurrentUser));
232 }
233 RT::Base->_ImportOverlays();
234
235 1;