import rt 2.0.14
[freeside.git] / rt / lib / RT / Record.pm
1 #$Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Record.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
2
3 =head1 NAME
4
5   RT::Record - Base class for RT record objects
6
7 =head1 SYNOPSIS
8
9
10 =head1 DESCRIPTION
11
12
13 =begin testing
14
15 ok (require RT::Record);
16
17 =end testing
18
19 =head1 METHODS
20
21 =cut
22
23
24 package RT::Record;
25 use DBIx::SearchBuilder::Record::Cachable;
26 use RT::Date;
27 use RT::User;
28
29 @ISA= qw(DBIx::SearchBuilder::Record::Cachable);
30
31 # {{{ sub _Init 
32
33 sub _Init  {
34   my $self = shift;
35   $self->_MyCurrentUser(@_);
36   
37 }
38
39 # }}}
40
41 # {{{ _PrimaryKeys
42
43 =head2 _PrimaryKeys
44
45 The primary keys for RT classes is 'id'
46
47 =cut
48
49 sub _PrimaryKeys {
50     my $self = shift;
51     return(['id']);
52 }
53
54 # }}}
55
56 # {{{ sub _MyCurrentUser 
57
58 sub _MyCurrentUser  {
59     my $self = shift;
60   
61     $self->CurrentUser(@_);
62     if(!defined($self->CurrentUser)) {
63         use Carp;
64         Carp::cluck();
65         $RT::Logger->err("$self was created without a CurrentUser\n"); 
66       return(0);
67     }
68 }
69
70 # }}}
71
72 # {{{ sub _Handle 
73 sub _Handle  {
74   my $self = shift;
75   return($RT::Handle);
76 }
77 # }}}
78
79 # {{{ sub Create 
80
81 sub Create  {
82     my $self = shift;
83     my $now = new RT::Date($self->CurrentUser);
84     $now->Set(Format=> 'unix', Value => time);
85     push @_, 'Created', $now->ISO()
86       if ($self->_Accessible('Created', 'auto'));
87     
88
89     push @_, 'Creator', $self->{'user'}->id
90       if $self->_Accessible('Creator', 'auto');
91     
92     push @_, 'LastUpdated', $now->ISO()
93       if ($self->_Accessible('LastUpdated', 'auto'));
94
95     push @_, 'LastUpdatedBy', $self->{'user'}->id
96       if $self->_Accessible('LastUpdatedBy', 'auto');
97     
98     
99
100    my $id = $self->SUPER::Create(@_);
101     
102     if ($id) {
103         $self->Load($id);
104     }
105     
106     return($id);
107     
108 }
109
110 # }}}
111
112
113 # {{{ sub LoadByCols
114
115 =head2 LoadByCols
116
117 Override DBIx::SearchBuilder::LoadByCols to do case-insensitive loads if the 
118 DB is case sensitive
119
120 =cut
121
122 sub LoadByCols {
123     my $self = shift;
124     my %hash = (@_);
125
126     # If this database is case sensitive we need to uncase objects for
127     # explicit loading
128     if ($self->_Handle->CaseSensitive) {
129          my %newhash;
130          foreach my $key (keys %hash) {
131         # If we've been passed an empty value, we can't do the lookup. 
132                 # We don't need to explicitly downcase integers or an id.
133                 if ($key =~ '^id$' || $hash{$key} =~/^\d+$/ || !defined ($hash{$key}) ) {
134                         $newhash{$key} = $hash{$key};
135                 }
136                 else {
137                         $newhash{"lower(".$key.")"} = lc($hash{$key});  
138                 }
139          }
140         $self->SUPER::LoadByCols(%newhash);
141     }
142     else {
143         $self->SUPER::LoadByCols(%hash);
144     }
145 }
146
147 # }}}
148
149
150 # {{{ Datehandling
151
152 # There is room for optimizations in most of those subs:
153
154 # {{{ LastUpdatedObj
155
156 sub LastUpdatedObj {
157     my $self=shift;
158     my $obj = new RT::Date($self->CurrentUser);
159     
160     $obj->Set(Format => 'sql', Value => $self->LastUpdated);
161     return $obj;
162 }
163
164 # }}}
165
166 # {{{ CreatedObj
167
168 sub CreatedObj {
169     my $self=shift;
170     my $obj = new RT::Date($self->CurrentUser);
171     
172     $obj->Set(Format => 'sql', Value => $self->Created);
173
174     
175     return $obj;
176 }
177
178 # }}}
179
180 # {{{ AgeAsString
181 #
182 # TODO: This should be deprecated
183 #
184 sub AgeAsString {
185     my $self=shift;
186     return($self->CreatedObj->AgeAsString());
187 }
188 # }}}
189
190 # {{{ LastUpdatedAsString
191
192 # TODO this should be deprecated
193
194 sub LastUpdatedAsString {
195     my $self=shift;
196     if ($self->LastUpdated) {
197         return ($self->LastUpdatedObj->AsString());
198           
199     } else {
200         return "never";
201     }
202 }
203
204 # }}}
205
206 # {{{ CreatedAsString
207 #
208 # TODO This should be deprecated 
209 #
210 sub CreatedAsString {
211     my $self = shift;
212     return ($self->CreatedObj->AsString());
213 }
214 # }}}
215
216 # {{{ LongSinceUpdateAsString
217 #
218 # TODO This should be deprecated
219 #
220 sub LongSinceUpdateAsString {
221     my $self=shift;
222     if ($self->LastUpdated) {
223       
224         return ($self->LastUpdatedObj->AgeAsString());
225         
226     } else {
227         return "never";
228     }
229 }
230 # }}}
231
232 # }}} Datehandling
233
234
235 # {{{ sub _Set 
236 sub _Set  {
237   my $self = shift;
238
239   my %args = ( Field => undef,
240                Value => undef,
241                IsSQL => undef,
242                @_ );
243
244
245   #if the user is trying to modify the record
246   if ((!defined ($args{'Field'})) || (!defined ($args{'Value'}))) {
247     $args{'Value'} = 0; 
248    }
249
250   $self->_SetLastUpdated();
251   $self->SUPER::_Set(Field => $args{'Field'},
252                      Value => $args{'Value'},
253                      IsSQL => $args{'IsSQL'});
254   
255   
256 }
257 # }}}
258
259 # {{{ sub _SetLastUpdated
260
261 =head2 _SetLastUpdated
262
263 This routine updates the LastUpdated and LastUpdatedBy columns of the row in question
264 It takes no options. Arguably, this is a bug
265
266 =cut
267
268 sub _SetLastUpdated {
269     my $self = shift;
270     use RT::Date;
271     my $now = new RT::Date($self->CurrentUser);
272     $now->SetToNow();
273
274     if ($self->_Accessible('LastUpdated','auto')) {
275         my ($msg, $val) = $self->__Set( Field => 'LastUpdated',
276                                         Value => $now->ISO);
277     }
278     if ($self->_Accessible('LastUpdatedBy','auto')) {
279         my ($msg, $val) = $self->__Set( Field => 'LastUpdatedBy', 
280                                         Value => $self->CurrentUser->id);
281     }
282 }
283
284 # }}}
285
286 # {{{ sub CreatorObj 
287
288 =head2 CreatorObj
289
290 Returns an RT::User object with the RT account of the creator of this row
291
292 =cut
293
294 sub CreatorObj  {
295   my $self = shift;
296   unless (exists $self->{'CreatorObj'}) {
297     
298     $self->{'CreatorObj'} = RT::User->new($self->CurrentUser);
299     $self->{'CreatorObj'}->Load($self->Creator);
300   }
301   return($self->{'CreatorObj'});
302 }
303 # }}}
304
305 # {{{ sub LastUpdatedByObj
306
307 =head2 LastUpdatedByObj
308
309   Returns an RT::User object of the last user to touch this object
310
311 =cut
312
313 sub LastUpdatedByObj {
314     my $self=shift;
315     unless (exists $self->{LastUpdatedByObj}) {
316         $self->{'LastUpdatedByObj'}=RT::User->new($self->CurrentUser);
317         $self->{'LastUpdatedByObj'}->Load($self->LastUpdatedBy);
318     }
319     return $self->{'LastUpdatedByObj'};
320 }
321
322 # }}}
323
324 # {{{ sub CurrentUser 
325
326 =head2 CurrentUser
327
328 If called with an argument, sets the current user to that user object.
329 This will affect ACL decisions, etc.  
330 Returns the current user
331
332 =cut
333
334 sub CurrentUser  {
335   my $self = shift;
336
337   if (@_) {
338     $self->{'user'} = shift;
339   }
340   return ($self->{'user'});
341 }
342 # }}}
343
344
345 1;