import rt 3.8.7
[freeside.git] / rt / lib / RT / Attachments_Overlay.pm
1 # BEGIN BPS TAGGED BLOCK {{{
2
3 # COPYRIGHT:
4
5 # This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
6 #                                          <jesse@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::Attachments - a collection of RT::Attachment objects
52
53 =head1 SYNOPSIS
54
55   use RT::Attachments;
56
57 =head1 DESCRIPTION
58
59 This module should never be called directly by client code. it's an internal module which
60 should only be accessed through exported APIs in Ticket, Queue and other similar objects.
61
62
63 =head1 METHODS
64
65
66
67 =cut
68
69
70 package RT::Attachments;
71
72 use strict;
73 no warnings qw(redefine);
74
75 use RT::Attachment;
76
77 sub _Init   {
78     my $self = shift;
79     $self->{'table'} = "Attachments";
80     $self->{'primary_key'} = "id";
81     $self->OrderBy(
82         FIELD => 'id',
83         ORDER => 'ASC',
84     );
85     return $self->SUPER::_Init( @_ );
86 }
87
88 sub CleanSlate {
89     my $self = shift;
90     delete $self->{_sql_transaction_alias};
91     return $self->SUPER::CleanSlate( @_ );
92 }
93
94
95 =head2 TransactionAlias
96
97 Returns alias for transactions table with applied join condition.
98 Always return the same alias, so if you want to build some complex
99 or recursive joining then you have to create new alias youself.
100
101 =cut
102
103 sub TransactionAlias {
104     my $self = shift;
105     return $self->{'_sql_transaction_alias'}
106         if $self->{'_sql_transaction_alias'};
107
108     my $res = $self->NewAlias('Transactions');
109     $self->Limit(
110         ENTRYAGGREGATOR => 'AND',
111         FIELD           => 'TransactionId',
112         VALUE           => $res . '.id',
113         QUOTEVALUE      => 0,
114     );
115     return $self->{'_sql_transaction_alias'} = $res;
116 }
117
118 =head2 ContentType (VALUE => 'text/plain', ENTRYAGGREGATOR => 'OR', OPERATOR => '=' ) 
119
120 Limit result set to attachments of ContentType 'TYPE'...
121
122 =cut
123
124
125 sub ContentType  {
126     my $self = shift;
127     my %args = (
128         VALUE           => 'text/plain',
129             OPERATOR        => '=',
130             ENTRYAGGREGATOR => 'OR',
131             @_
132     );
133
134     return $self->Limit ( %args, FIELD => 'ContentType' );
135 }
136
137 =head2 ChildrenOf ID
138
139 Limit result set to children of Attachment ID
140
141 =cut
142
143
144 sub ChildrenOf  {
145     my $self = shift;
146     my $attachment = shift;
147     return $self->Limit(
148         FIELD => 'Parent',
149         VALUE => $attachment
150     );
151 }
152
153 =head2 LimitNotEmpty
154
155 Limit result set to attachments with not empty content.
156
157 =cut
158
159 sub LimitNotEmpty {
160     my $self = shift;
161     $self->Limit(
162         ENTRYAGGREGATOR => 'AND',
163         FIELD           => 'Content',
164         OPERATOR        => 'IS NOT',
165         VALUE           => 'NULL',
166         QUOTEVALUE      => 0,
167     );
168
169     # http://rt3.fsck.com/Ticket/Display.html?id=12483
170     if ( RT->Config->Get('DatabaseType') ne 'Oracle' ) {
171         $self->Limit(
172             ENTRYAGGREGATOR => 'AND',
173             FIELD           => 'Content',
174             OPERATOR        => '!=',
175             VALUE           => '',
176         );
177     }
178     return;
179 }
180
181 =head2 LimitByTicket $ticket_id
182
183 Limit result set to attachments of a ticket.
184
185 =cut
186
187 sub LimitByTicket {
188     my $self = shift;
189     my $tid = shift;
190
191     my $transactions = $self->TransactionAlias;
192     $self->Limit(
193         ENTRYAGGREGATOR => 'AND',
194         ALIAS           => $transactions,
195         FIELD           => 'ObjectType',
196         VALUE           => 'RT::Ticket',
197     );
198
199     my $tickets = $self->NewAlias('Tickets');
200     $self->Limit(
201         ENTRYAGGREGATOR => 'AND',
202         ALIAS           => $tickets,
203         FIELD           => 'id',
204         VALUE           => $transactions . '.ObjectId',
205         QUOTEVALUE      => 0,
206     );
207     $self->Limit(
208         ENTRYAGGREGATOR => 'AND',
209         ALIAS           => $tickets,
210         FIELD           => 'EffectiveId',
211         VALUE           => $tid,
212     );
213     return;
214 }
215
216 # {{{ sub NewItem 
217 sub NewItem  {
218   my $self = shift;
219   return RT::Attachment->new( $self->CurrentUser );
220 }
221 # }}}
222
223 # {{{ sub Next
224 sub Next {
225     my $self = shift;
226
227     my $Attachment = $self->SUPER::Next;
228     return $Attachment unless $Attachment;
229
230     my $txn = $Attachment->TransactionObj;
231     if ( $txn->__Value('Type') eq 'Comment' ) {
232         return $Attachment if $txn->CurrentUserHasRight('ShowTicketComments');
233     } elsif ( $txn->CurrentUserHasRight('ShowTicket') ) {
234         return $Attachment;
235     }
236
237     # If the user doesn't have the right to show this ticket
238     return $self->Next;
239 }
240 # }}}
241
242 1;