]>
Commit | Line | Data |
---|---|---|
84fb5b46 MKG |
1 | # BEGIN BPS TAGGED BLOCK {{{ |
2 | # | |
3 | # COPYRIGHT: | |
4 | # | |
320f0092 | 5 | # This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC |
84fb5b46 MKG |
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 | package RT::ObjectCustomFieldValue; | |
50 | ||
51 | use strict; | |
52 | use warnings; | |
af59614d | 53 | use base 'RT::Record'; |
84fb5b46 MKG |
54 | |
55 | use RT::Interface::Web; | |
56 | use Regexp::Common qw(RE_net_IPv4); | |
57 | use Regexp::IPv6 qw($IPv6_re); | |
58 | use Regexp::Common::net::CIDR; | |
59 | require Net::CIDR; | |
60 | ||
61 | # Allow the empty IPv6 address | |
62 | $IPv6_re = qr/(?:$IPv6_re|::)/; | |
63 | ||
84fb5b46 | 64 | use RT::CustomField; |
84fb5b46 MKG |
65 | |
66 | sub Table {'ObjectCustomFieldValues'} | |
67 | ||
68 | ||
69 | ||
70 | ||
71 | sub Create { | |
72 | my $self = shift; | |
73 | my %args = ( | |
74 | CustomField => 0, | |
75 | ObjectType => '', | |
76 | ObjectId => 0, | |
77 | Disabled => 0, | |
78 | Content => '', | |
79 | LargeContent => undef, | |
80 | ContentType => '', | |
81 | ContentEncoding => '', | |
82 | @_, | |
83 | ); | |
84 | ||
85 | ||
86 | my $cf_as_sys = RT::CustomField->new(RT->SystemUser); | |
87 | $cf_as_sys->Load($args{'CustomField'}); | |
88 | ||
89 | if($cf_as_sys->Type eq 'IPAddress') { | |
90 | if ( $args{'Content'} ) { | |
91 | $args{'Content'} = $self->ParseIP( $args{'Content'} ); | |
92 | } | |
93 | ||
94 | unless ( defined $args{'Content'} ) { | |
95 | return | |
96 | wantarray | |
97 | ? ( 0, $self->loc("Content is an invalid IP address") ) | |
98 | : 0; | |
99 | } | |
100 | } | |
101 | ||
102 | if($cf_as_sys->Type eq 'IPAddressRange') { | |
103 | if ($args{'Content'}) { | |
104 | ($args{'Content'}, $args{'LargeContent'}) = $self->ParseIPRange( $args{'Content'} ); | |
105 | } | |
106 | $args{'ContentType'} = 'text/plain'; | |
107 | ||
108 | unless ( defined $args{'Content'} ) { | |
109 | return | |
110 | wantarray | |
111 | ? ( 0, $self->loc("Content is an invalid IP address range") ) | |
112 | : 0; | |
113 | } | |
114 | } | |
115 | ||
116 | if ( defined $args{'Content'} && length( Encode::encode_utf8($args{'Content'}) ) > 255 ) { | |
117 | if ( defined $args{'LargeContent'} && length $args{'LargeContent'} ) { | |
118 | $RT::Logger->error("Content is longer than 255 bytes and LargeContent specified"); | |
119 | } | |
120 | else { | |
121 | $args{'LargeContent'} = $args{'Content'}; | |
af59614d | 122 | $args{'Content'} = undef; |
84fb5b46 MKG |
123 | $args{'ContentType'} ||= 'text/plain'; |
124 | } | |
125 | } | |
126 | ||
127 | ( $args{'ContentEncoding'}, $args{'LargeContent'} ) = | |
128 | $self->_EncodeLOB( $args{'LargeContent'}, $args{'ContentType'} ) | |
129 | if defined $args{'LargeContent'}; | |
130 | ||
131 | return $self->SUPER::Create( | |
132 | CustomField => $args{'CustomField'}, | |
133 | ObjectType => $args{'ObjectType'}, | |
134 | ObjectId => $args{'ObjectId'}, | |
135 | Disabled => $args{'Disabled'}, | |
136 | Content => $args{'Content'}, | |
137 | LargeContent => $args{'LargeContent'}, | |
138 | ContentType => $args{'ContentType'}, | |
139 | ContentEncoding => $args{'ContentEncoding'}, | |
140 | ); | |
141 | } | |
142 | ||
143 | ||
144 | sub LargeContent { | |
145 | my $self = shift; | |
146 | return $self->_DecodeLOB( | |
147 | $self->ContentType, | |
148 | $self->ContentEncoding, | |
149 | $self->_Value( 'LargeContent', decode_utf8 => 0 ) | |
150 | ); | |
151 | } | |
152 | ||
153 | ||
154 | =head2 LoadByCols | |
155 | ||
156 | =cut | |
157 | ||
158 | sub LoadByCols { | |
159 | my $self = shift; | |
160 | my %args = (@_); | |
161 | my $cf; | |
162 | if ( $args{CustomField} ) { | |
163 | $cf = RT::CustomField->new( $self->CurrentUser ); | |
164 | $cf->Load( $args{CustomField} ); | |
165 | if ( $cf->Type && $cf->Type eq 'IPAddressRange' ) { | |
166 | ||
167 | my ( $sIP, $eIP ) = $cf->ParseIPRange( $args{'Content'} ); | |
168 | if ( $sIP && $eIP ) { | |
169 | $self->SUPER::LoadByCols( %args, | |
170 | Content => $sIP, | |
171 | LargeContent => $eIP | |
172 | ); | |
173 | } | |
174 | } | |
175 | } | |
176 | return $self->SUPER::LoadByCols(%args); | |
177 | } | |
178 | ||
179 | =head2 LoadByTicketContentAndCustomField { Ticket => TICKET, CustomField => CUSTOMFIELD, Content => CONTENT } | |
180 | ||
181 | Loads a custom field value by Ticket, Content and which CustomField it's tied to | |
182 | ||
183 | =cut | |
184 | ||
185 | ||
186 | sub LoadByTicketContentAndCustomField { | |
187 | my $self = shift; | |
188 | my %args = ( | |
189 | Ticket => undef, | |
190 | CustomField => undef, | |
191 | Content => undef, | |
192 | @_ | |
193 | ); | |
194 | ||
195 | return $self->LoadByCols( | |
196 | Content => $args{'Content'}, | |
197 | CustomField => $args{'CustomField'}, | |
198 | ObjectType => 'RT::Ticket', | |
199 | ObjectId => $args{'Ticket'}, | |
200 | Disabled => 0 | |
201 | ); | |
202 | } | |
203 | ||
204 | sub LoadByObjectContentAndCustomField { | |
205 | my $self = shift; | |
206 | my %args = ( | |
207 | Object => undef, | |
208 | CustomField => undef, | |
209 | Content => undef, | |
210 | @_ | |
211 | ); | |
212 | ||
213 | my $obj = $args{'Object'} or return; | |
214 | ||
215 | return $self->LoadByCols( | |
216 | Content => $args{'Content'}, | |
217 | CustomField => $args{'CustomField'}, | |
218 | ObjectType => ref($obj), | |
219 | ObjectId => $obj->Id, | |
220 | Disabled => 0 | |
221 | ); | |
222 | } | |
223 | ||
224 | =head2 CustomFieldObj | |
225 | ||
226 | Returns the CustomField Object which has the id returned by CustomField | |
227 | ||
228 | =cut | |
229 | ||
230 | sub CustomFieldObj { | |
231 | my $self = shift; | |
232 | my $CustomField = RT::CustomField->new( $self->CurrentUser ); | |
233 | $CustomField->SetContextObject( $self->Object ); | |
234 | $CustomField->Load( $self->__Value('CustomField') ); | |
235 | return $CustomField; | |
236 | } | |
237 | ||
238 | ||
239 | =head2 Content | |
240 | ||
241 | Return this custom field's content. If there's no "regular" | |
242 | content, try "LargeContent" | |
243 | ||
244 | =cut | |
245 | ||
246 | my $re_ip_sunit = qr/[0-1][0-9][0-9]|2[0-4][0-9]|25[0-5]/; | |
247 | my $re_ip_serialized = qr/$re_ip_sunit(?:\.$re_ip_sunit){3}/; | |
248 | ||
249 | sub Content { | |
250 | my $self = shift; | |
251 | ||
252 | return undef unless $self->CustomFieldObj->CurrentUserHasRight('SeeCustomField'); | |
253 | ||
254 | my $content = $self->_Value('Content'); | |
255 | if ( $self->CustomFieldObj->Type eq 'IPAddress' | |
256 | || $self->CustomFieldObj->Type eq 'IPAddressRange' ) | |
257 | { | |
258 | ||
259 | if ( $content =~ /^\s*($re_ip_serialized)\s*$/o ) { | |
260 | $content = sprintf "%d.%d.%d.%d", split /\./, $1; | |
261 | } | |
262 | ||
263 | return $content if $self->CustomFieldObj->Type eq 'IPAddress'; | |
264 | ||
265 | my $large_content = $self->__Value('LargeContent'); | |
266 | if ( $large_content =~ /^\s*($re_ip_serialized)\s*$/o ) { | |
267 | my $eIP = sprintf "%d.%d.%d.%d", split /\./, $1; | |
268 | if ( $content eq $eIP ) { | |
269 | return $content; | |
270 | } | |
271 | else { | |
272 | return $content . "-" . $eIP; | |
273 | } | |
274 | } | |
275 | elsif ( $large_content =~ /^\s*($IPv6_re)\s*$/o ) { | |
276 | my $eIP = $1; | |
277 | if ( $content eq $eIP ) { | |
278 | return $content; | |
279 | } | |
280 | else { | |
281 | return $content . "-" . $eIP; | |
282 | } | |
283 | } | |
284 | else { | |
285 | return $content; | |
286 | } | |
287 | } | |
288 | ||
289 | if ( !(defined $content && length $content) && $self->ContentType && $self->ContentType eq 'text/plain' ) { | |
290 | return $self->LargeContent; | |
291 | } else { | |
292 | return $content; | |
293 | } | |
294 | } | |
295 | ||
296 | =head2 Object | |
297 | ||
298 | Returns the object this value applies to | |
299 | ||
300 | =cut | |
301 | ||
302 | sub Object { | |
303 | my $self = shift; | |
304 | my $Object = $self->__Value('ObjectType')->new( $self->CurrentUser ); | |
305 | $Object->LoadById( $self->__Value('ObjectId') ); | |
306 | return $Object; | |
307 | } | |
308 | ||
309 | ||
310 | =head2 Delete | |
311 | ||
312 | Disable this value. Used to remove "current" values from records while leaving them in the history. | |
313 | ||
314 | =cut | |
315 | ||
316 | ||
317 | sub Delete { | |
318 | my $self = shift; | |
319 | return $self->SetDisabled(1); | |
320 | } | |
321 | ||
322 | =head2 _FillInTemplateURL URL | |
323 | ||
324 | Takes a URL containing placeholders and returns the URL as filled in for this | |
325 | ObjectCustomFieldValue. The values for the placeholders will be URI-escaped. | |
326 | ||
327 | Available placeholders: | |
328 | ||
329 | =over | |
330 | ||
331 | =item __id__ | |
332 | ||
333 | The id of the object in question. | |
334 | ||
335 | =item __CustomField__ | |
336 | ||
337 | The value of this custom field for the object in question. | |
338 | ||
339 | =item __WebDomain__, __WebPort__, __WebPath__, __WebBaseURL__ and __WebURL__ | |
340 | ||
341 | The value of the config option. | |
342 | ||
343 | =back | |
344 | ||
345 | =cut | |
346 | ||
347 | { | |
348 | my %placeholders = ( | |
349 | id => { value => sub { $_[0]->ObjectId }, escape => 1 }, | |
350 | CustomField => { value => sub { $_[0]->Content }, escape => 1 }, | |
351 | WebDomain => { value => sub { RT->Config->Get('WebDomain') } }, | |
352 | WebPort => { value => sub { RT->Config->Get('WebPort') } }, | |
353 | WebPath => { value => sub { RT->Config->Get('WebPath') } }, | |
354 | WebBaseURL => { value => sub { RT->Config->Get('WebBaseURL') } }, | |
355 | WebURL => { value => sub { RT->Config->Get('WebURL') } }, | |
356 | ); | |
357 | ||
358 | sub _FillInTemplateURL { | |
359 | my $self = shift; | |
360 | my $url = shift; | |
361 | ||
362 | return undef unless defined $url && length $url; | |
363 | ||
364 | # special case, whole value should be an URL | |
365 | if ( $url =~ /^__CustomField__/ ) { | |
366 | my $value = $self->Content; | |
367 | # protect from potentially malicious URLs | |
368 | if ( $value =~ /^\s*(?:javascript|data):/i ) { | |
369 | my $object = $self->Object; | |
370 | $RT::Logger->error( | |
371 | "Potentially dangerous URL type in custom field '". $self->CustomFieldObj->Name ."'" | |
372 | ." on ". ref($object) ." #". $object->id | |
373 | ); | |
374 | return undef; | |
375 | } | |
376 | $url =~ s/^__CustomField__/$value/; | |
377 | } | |
378 | ||
379 | # default value, uri-escape | |
380 | for my $key (keys %placeholders) { | |
381 | $url =~ s{__${key}__}{ | |
382 | my $value = $placeholders{$key}{'value'}->( $self ); | |
383 | $value = '' if !defined($value); | |
384 | RT::Interface::Web::EscapeURI(\$value) if $placeholders{$key}{'escape'}; | |
385 | $value | |
386 | }gxe; | |
387 | } | |
388 | ||
389 | return $url; | |
390 | } } | |
391 | ||
392 | ||
393 | =head2 ValueLinkURL | |
394 | ||
395 | Returns a filled in URL template for this ObjectCustomFieldValue, suitable for | |
396 | constructing a hyperlink in RT's webui. Returns undef if this custom field doesn't have | |
397 | a LinkValueTo | |
398 | ||
399 | =cut | |
400 | ||
401 | sub LinkValueTo { | |
402 | my $self = shift; | |
403 | return $self->_FillInTemplateURL($self->CustomFieldObj->LinkValueTo); | |
404 | } | |
405 | ||
406 | ||
407 | ||
408 | =head2 ValueIncludeURL | |
409 | ||
410 | Returns a filled in URL template for this ObjectCustomFieldValue, suitable for | |
411 | constructing a hyperlink in RT's webui. Returns undef if this custom field doesn't have | |
412 | a IncludeContentForValue | |
413 | ||
414 | =cut | |
415 | ||
416 | sub IncludeContentForValue { | |
417 | my $self = shift; | |
418 | return $self->_FillInTemplateURL($self->CustomFieldObj->IncludeContentForValue); | |
419 | } | |
420 | ||
421 | ||
422 | sub ParseIPRange { | |
423 | my $self = shift; | |
424 | my $value = shift or return; | |
425 | $value = lc $value; | |
426 | $value =~ s!^\s+!!; | |
427 | $value =~ s!\s+$!!; | |
428 | ||
429 | if ( $value =~ /^$RE{net}{CIDR}{IPv4}{-keep}$/go ) { | |
430 | my $cidr = join( '.', map $_||0, (split /\./, $1)[0..3] ) ."/$2"; | |
431 | $value = (Net::CIDR::cidr2range( $cidr ))[0] || $value; | |
432 | } | |
433 | elsif ( $value =~ /^$IPv6_re(?:\/\d+)?$/o ) { | |
434 | $value = (Net::CIDR::cidr2range( $value ))[0] || $value; | |
435 | } | |
436 | ||
437 | my ($sIP, $eIP); | |
438 | if ( $value =~ /^($RE{net}{IPv4})$/o ) { | |
439 | $sIP = $eIP = sprintf "%03d.%03d.%03d.%03d", split /\./, $1; | |
440 | } | |
441 | elsif ( $value =~ /^($RE{net}{IPv4})-($RE{net}{IPv4})$/o ) { | |
442 | $sIP = sprintf "%03d.%03d.%03d.%03d", split /\./, $1; | |
443 | $eIP = sprintf "%03d.%03d.%03d.%03d", split /\./, $2; | |
444 | } | |
445 | elsif ( $value =~ /^($IPv6_re)$/o ) { | |
446 | $sIP = $self->ParseIP( $1 ); | |
447 | $eIP = $sIP; | |
448 | } | |
449 | elsif ( $value =~ /^($IPv6_re)-($IPv6_re)$/o ) { | |
450 | ($sIP, $eIP) = ( $1, $2 ); | |
451 | $sIP = $self->ParseIP( $sIP ); | |
452 | $eIP = $self->ParseIP( $eIP ); | |
453 | } | |
454 | else { | |
455 | return; | |
456 | } | |
457 | ||
458 | ($sIP, $eIP) = ($eIP, $sIP) if $sIP gt $eIP; | |
459 | ||
460 | return $sIP, $eIP; | |
461 | } | |
462 | ||
463 | sub ParseIP { | |
464 | my $self = shift; | |
465 | my $value = shift or return; | |
466 | $value = lc $value; | |
467 | $value =~ s!^\s+!!; | |
468 | $value =~ s!\s+$!!; | |
469 | ||
470 | if ( $value =~ /^($RE{net}{IPv4})$/o ) { | |
471 | return sprintf "%03d.%03d.%03d.%03d", split /\./, $1; | |
472 | } | |
473 | elsif ( $value =~ /^$IPv6_re$/o ) { | |
474 | ||
475 | # up_fields are before '::' | |
476 | # low_fields are after '::' but without v4 | |
477 | # v4_fields are the v4 | |
478 | my ( @up_fields, @low_fields, @v4_fields ); | |
479 | my $v6; | |
480 | if ( $value =~ /(.*:)(\d+\..*)/ ) { | |
481 | ( $v6, my $v4 ) = ( $1, $2 ); | |
482 | chop $v6 unless $v6 =~ /::$/; | |
483 | while ( $v4 =~ /(\d+)\.(\d+)/g ) { | |
484 | push @v4_fields, sprintf '%.2x%.2x', $1, $2; | |
485 | } | |
486 | } | |
487 | else { | |
488 | $v6 = $value; | |
489 | } | |
490 | ||
491 | my ( $up, $low ); | |
492 | if ( $v6 =~ /::/ ) { | |
493 | ( $up, $low ) = split /::/, $v6; | |
494 | } | |
495 | else { | |
496 | $up = $v6; | |
497 | } | |
498 | ||
499 | @up_fields = split /:/, $up; | |
500 | @low_fields = split /:/, $low if $low; | |
501 | ||
502 | my @zero_fields = | |
503 | ('0000') x ( 8 - @v4_fields - @up_fields - @low_fields ); | |
504 | my @fields = ( @up_fields, @zero_fields, @low_fields, @v4_fields ); | |
505 | ||
506 | return join ':', map { sprintf "%.4x", hex "0x$_" } @fields; | |
507 | } | |
508 | return; | |
509 | } | |
510 | ||
511 | ||
512 | =head2 id | |
513 | ||
514 | Returns the current value of id. | |
515 | (In the database, id is stored as int(11).) | |
516 | ||
517 | ||
518 | =cut | |
519 | ||
520 | ||
521 | =head2 CustomField | |
522 | ||
523 | Returns the current value of CustomField. | |
524 | (In the database, CustomField is stored as int(11).) | |
525 | ||
526 | ||
527 | ||
528 | =head2 SetCustomField VALUE | |
529 | ||
530 | ||
531 | Set CustomField to VALUE. | |
532 | Returns (1, 'Status message') on success and (0, 'Error Message') on failure. | |
533 | (In the database, CustomField will be stored as a int(11).) | |
534 | ||
535 | ||
536 | =cut | |
537 | ||
538 | =head2 ObjectType | |
539 | ||
540 | Returns the current value of ObjectType. | |
541 | (In the database, ObjectType is stored as varchar(255).) | |
542 | ||
543 | ||
544 | ||
545 | =head2 SetObjectType VALUE | |
546 | ||
547 | ||
548 | Set ObjectType to VALUE. | |
549 | Returns (1, 'Status message') on success and (0, 'Error Message') on failure. | |
550 | (In the database, ObjectType will be stored as a varchar(255).) | |
551 | ||
552 | ||
553 | =cut | |
554 | ||
555 | ||
556 | =head2 ObjectId | |
557 | ||
558 | Returns the current value of ObjectId. | |
559 | (In the database, ObjectId is stored as int(11).) | |
560 | ||
561 | ||
562 | ||
563 | =head2 SetObjectId VALUE | |
564 | ||
565 | ||
566 | Set ObjectId to VALUE. | |
567 | Returns (1, 'Status message') on success and (0, 'Error Message') on failure. | |
568 | (In the database, ObjectId will be stored as a int(11).) | |
569 | ||
570 | ||
571 | =cut | |
572 | ||
573 | ||
574 | =head2 SortOrder | |
575 | ||
576 | Returns the current value of SortOrder. | |
577 | (In the database, SortOrder is stored as int(11).) | |
578 | ||
579 | ||
580 | ||
581 | =head2 SetSortOrder VALUE | |
582 | ||
583 | ||
584 | Set SortOrder to VALUE. | |
585 | Returns (1, 'Status message') on success and (0, 'Error Message') on failure. | |
586 | (In the database, SortOrder will be stored as a int(11).) | |
587 | ||
588 | ||
589 | =cut | |
590 | ||
591 | ||
592 | =head2 Content | |
593 | ||
594 | Returns the current value of Content. | |
595 | (In the database, Content is stored as varchar(255).) | |
596 | ||
597 | ||
598 | ||
599 | =head2 SetContent VALUE | |
600 | ||
601 | ||
602 | Set Content to VALUE. | |
603 | Returns (1, 'Status message') on success and (0, 'Error Message') on failure. | |
604 | (In the database, Content will be stored as a varchar(255).) | |
605 | ||
606 | ||
607 | =cut | |
608 | ||
609 | ||
610 | =head2 LargeContent | |
611 | ||
612 | Returns the current value of LargeContent. | |
613 | (In the database, LargeContent is stored as longblob.) | |
614 | ||
615 | ||
616 | ||
617 | =head2 SetLargeContent VALUE | |
618 | ||
619 | ||
620 | Set LargeContent to VALUE. | |
621 | Returns (1, 'Status message') on success and (0, 'Error Message') on failure. | |
622 | (In the database, LargeContent will be stored as a longblob.) | |
623 | ||
624 | ||
625 | =cut | |
626 | ||
627 | ||
628 | =head2 ContentType | |
629 | ||
630 | Returns the current value of ContentType. | |
631 | (In the database, ContentType is stored as varchar(80).) | |
632 | ||
633 | ||
634 | ||
635 | =head2 SetContentType VALUE | |
636 | ||
637 | ||
638 | Set ContentType to VALUE. | |
639 | Returns (1, 'Status message') on success and (0, 'Error Message') on failure. | |
640 | (In the database, ContentType will be stored as a varchar(80).) | |
641 | ||
642 | ||
643 | =cut | |
644 | ||
645 | ||
646 | =head2 ContentEncoding | |
647 | ||
648 | Returns the current value of ContentEncoding. | |
649 | (In the database, ContentEncoding is stored as varchar(80).) | |
650 | ||
651 | ||
652 | ||
653 | =head2 SetContentEncoding VALUE | |
654 | ||
655 | ||
656 | Set ContentEncoding to VALUE. | |
657 | Returns (1, 'Status message') on success and (0, 'Error Message') on failure. | |
658 | (In the database, ContentEncoding will be stored as a varchar(80).) | |
659 | ||
660 | ||
661 | =cut | |
662 | ||
663 | ||
664 | =head2 Creator | |
665 | ||
666 | Returns the current value of Creator. | |
667 | (In the database, Creator is stored as int(11).) | |
668 | ||
669 | ||
670 | =cut | |
671 | ||
672 | ||
673 | =head2 Created | |
674 | ||
675 | Returns the current value of Created. | |
676 | (In the database, Created is stored as datetime.) | |
677 | ||
678 | ||
679 | =cut | |
680 | ||
681 | ||
682 | =head2 LastUpdatedBy | |
683 | ||
684 | Returns the current value of LastUpdatedBy. | |
685 | (In the database, LastUpdatedBy is stored as int(11).) | |
686 | ||
687 | ||
688 | =cut | |
689 | ||
690 | ||
691 | =head2 LastUpdated | |
692 | ||
693 | Returns the current value of LastUpdated. | |
694 | (In the database, LastUpdated is stored as datetime.) | |
695 | ||
696 | ||
697 | =cut | |
698 | ||
699 | ||
700 | =head2 Disabled | |
701 | ||
702 | Returns the current value of Disabled. | |
703 | (In the database, Disabled is stored as smallint(6).) | |
704 | ||
705 | ||
706 | ||
707 | =head2 SetDisabled VALUE | |
708 | ||
709 | ||
710 | Set Disabled to VALUE. | |
711 | Returns (1, 'Status message') on success and (0, 'Error Message') on failure. | |
712 | (In the database, Disabled will be stored as a smallint(6).) | |
713 | ||
714 | ||
715 | =cut | |
716 | ||
717 | ||
718 | ||
719 | sub _CoreAccessible { | |
720 | { | |
721 | ||
722 | id => | |
af59614d | 723 | {read => 1, sql_type => 4, length => 11, is_blob => 0, is_numeric => 1, type => 'int(11)', default => ''}, |
84fb5b46 | 724 | CustomField => |
af59614d | 725 | {read => 1, write => 1, sql_type => 4, length => 11, is_blob => 0, is_numeric => 1, type => 'int(11)', default => ''}, |
84fb5b46 | 726 | ObjectType => |
af59614d | 727 | {read => 1, write => 1, sql_type => 12, length => 255, is_blob => 0, is_numeric => 0, type => 'varchar(255)', default => ''}, |
84fb5b46 | 728 | ObjectId => |
af59614d | 729 | {read => 1, write => 1, sql_type => 4, length => 11, is_blob => 0, is_numeric => 1, type => 'int(11)', default => ''}, |
84fb5b46 | 730 | SortOrder => |
af59614d | 731 | {read => 1, write => 1, sql_type => 4, length => 11, is_blob => 0, is_numeric => 1, type => 'int(11)', default => '0'}, |
84fb5b46 | 732 | Content => |
af59614d | 733 | {read => 1, write => 1, sql_type => 12, length => 255, is_blob => 0, is_numeric => 0, type => 'varchar(255)', default => ''}, |
84fb5b46 | 734 | LargeContent => |
af59614d | 735 | {read => 1, write => 1, sql_type => -4, length => 0, is_blob => 1, is_numeric => 0, type => 'longblob', default => ''}, |
84fb5b46 | 736 | ContentType => |
af59614d | 737 | {read => 1, write => 1, sql_type => 12, length => 80, is_blob => 0, is_numeric => 0, type => 'varchar(80)', default => ''}, |
84fb5b46 | 738 | ContentEncoding => |
af59614d | 739 | {read => 1, write => 1, sql_type => 12, length => 80, is_blob => 0, is_numeric => 0, type => 'varchar(80)', default => ''}, |
84fb5b46 | 740 | Creator => |
af59614d | 741 | {read => 1, auto => 1, sql_type => 4, length => 11, is_blob => 0, is_numeric => 1, type => 'int(11)', default => '0'}, |
84fb5b46 | 742 | Created => |
af59614d | 743 | {read => 1, auto => 1, sql_type => 11, length => 0, is_blob => 0, is_numeric => 0, type => 'datetime', default => ''}, |
84fb5b46 | 744 | LastUpdatedBy => |
af59614d | 745 | {read => 1, auto => 1, sql_type => 4, length => 11, is_blob => 0, is_numeric => 1, type => 'int(11)', default => '0'}, |
84fb5b46 | 746 | LastUpdated => |
af59614d | 747 | {read => 1, auto => 1, sql_type => 11, length => 0, is_blob => 0, is_numeric => 0, type => 'datetime', default => ''}, |
84fb5b46 | 748 | Disabled => |
af59614d | 749 | {read => 1, write => 1, sql_type => 5, length => 6, is_blob => 0, is_numeric => 1, type => 'smallint(6)', default => '0'}, |
84fb5b46 MKG |
750 | |
751 | } | |
752 | }; | |
753 | ||
af59614d MKG |
754 | sub FindDependencies { |
755 | my $self = shift; | |
756 | my ($walker, $deps) = @_; | |
757 | ||
758 | $self->SUPER::FindDependencies($walker, $deps); | |
759 | ||
760 | $deps->Add( out => $self->CustomFieldObj ); | |
761 | $deps->Add( out => $self->Object ); | |
762 | } | |
763 | ||
84fb5b46 MKG |
764 | RT::Base->_ImportOverlays(); |
765 | ||
766 | 1; |