1# -- 2# Copyright (C) 2001-2020 OTRS AG, https://otrs.com/ 3# -- 4# This software comes with ABSOLUTELY NO WARRANTY. For details, see 5# the enclosed file COPYING for license information (GPL). If you 6# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt. 7# -- 8 9package Kernel::System::Web::UploadCache::DB; 10 11use strict; 12use warnings; 13 14use MIME::Base64; 15 16our @ObjectDependencies = ( 17 'Kernel::Config', 18 'Kernel::System::DB', 19 'Kernel::System::Encode', 20 'Kernel::System::Log', 21 'Kernel::System::Main', 22); 23 24sub new { 25 my ( $Type, %Param ) = @_; 26 27 # allocate new hash for object 28 my $Self = {}; 29 bless( $Self, $Type ); 30 31 return $Self; 32} 33 34sub FormIDCreate { 35 my ( $Self, %Param ) = @_; 36 37 # return requested form id 38 return time() . '.' . rand(12341241); 39} 40 41sub FormIDRemove { 42 my ( $Self, %Param ) = @_; 43 44 for (qw(FormID)) { 45 if ( !$Param{$_} ) { 46 $Kernel::OM->Get('Kernel::System::Log')->Log( 47 Priority => 'error', 48 Message => "Need $_!" 49 ); 50 return; 51 } 52 } 53 54 return if !$Kernel::OM->Get('Kernel::System::DB')->Do( 55 SQL => ' 56 DELETE FROM web_upload_cache 57 WHERE form_id = ?', 58 Bind => [ \$Param{FormID} ], 59 ); 60 61 return 1; 62} 63 64sub FormIDAddFile { 65 my ( $Self, %Param ) = @_; 66 67 for (qw(FormID Filename ContentType)) { 68 if ( !$Param{$_} ) { 69 $Kernel::OM->Get('Kernel::System::Log')->Log( 70 Priority => 'error', 71 Message => "Need $_!" 72 ); 73 return; 74 } 75 } 76 77 $Param{Content} = '' if !defined( $Param{Content} ); 78 79 # get file size 80 $Param{Filesize} = bytes::length( $Param{Content} ); 81 82 # get database object 83 my $DBObject = $Kernel::OM->Get('Kernel::System::DB'); 84 85 # encode attachment if it's a postgresql backend!!! 86 if ( !$DBObject->GetDatabaseFunction('DirectBlob') ) { 87 88 $Kernel::OM->Get('Kernel::System::Encode')->EncodeOutput( \$Param{Content} ); 89 90 $Param{Content} = encode_base64( $Param{Content} ); 91 } 92 93 # create content id 94 my $ContentID = $Param{ContentID}; 95 my $Disposition = $Param{Disposition} || ''; 96 if ( !$ContentID && lc $Disposition eq 'inline' ) { 97 98 my $Random = rand 999999; 99 my $FQDN = $Kernel::OM->Get('Kernel::Config')->Get('FQDN'); 100 101 $ContentID = "$Disposition$Random.$Param{FormID}\@$FQDN"; 102 } 103 104 # write attachment to db 105 my $Time = time(); 106 107 return if !$DBObject->Do( 108 SQL => ' 109 INSERT INTO web_upload_cache (form_id, filename, content_type, content_size, content, 110 create_time_unix, content_id, disposition) 111 VALUES (?, ?, ?, ?, ?, ?, ?, ?)', 112 Bind => [ 113 \$Param{FormID}, \$Param{Filename}, \$Param{ContentType}, \$Param{Filesize}, 114 \$Param{Content}, \$Time, \$ContentID, \$Param{Disposition} 115 ], 116 ); 117 118 return 1; 119} 120 121sub FormIDRemoveFile { 122 my ( $Self, %Param ) = @_; 123 124 for (qw(FormID FileID)) { 125 if ( !$Param{$_} ) { 126 $Kernel::OM->Get('Kernel::System::Log')->Log( 127 Priority => 'error', 128 Message => "Need $_!" 129 ); 130 return; 131 } 132 } 133 134 my @Index = @{ $Self->FormIDGetAllFilesMeta(%Param) }; 135 136 # finish if files have been already removed by other process 137 return if !@Index; 138 139 my $ID = $Param{FileID} - 1; 140 $Param{Filename} = $Index[$ID]->{Filename}; 141 142 return if !$Kernel::OM->Get('Kernel::System::DB')->Do( 143 SQL => ' 144 DELETE FROM web_upload_cache 145 WHERE form_id = ? 146 AND filename = ?', 147 Bind => [ \$Param{FormID}, \$Param{Filename} ], 148 ); 149 150 return 1; 151} 152 153sub FormIDGetAllFilesData { 154 my ( $Self, %Param ) = @_; 155 156 my $Counter = 0; 157 my @Data; 158 for (qw(FormID)) { 159 if ( !$Param{$_} ) { 160 $Kernel::OM->Get('Kernel::System::Log')->Log( 161 Priority => 'error', 162 Message => "Need $_!" 163 ); 164 return; 165 } 166 } 167 168 # get database object 169 my $DBObject = $Kernel::OM->Get('Kernel::System::DB'); 170 171 $DBObject->Prepare( 172 SQL => ' 173 SELECT filename, content_type, content_size, content, content_id, disposition 174 FROM web_upload_cache 175 WHERE form_id = ? 176 ORDER BY create_time_unix', 177 Bind => [ \$Param{FormID} ], 178 Encode => [ 1, 1, 1, 0, 1, 1 ], 179 ); 180 181 while ( my @Row = $DBObject->FetchrowArray() ) { 182 $Counter++; 183 184 # encode attachment if it's a postgresql backend!!! 185 if ( !$DBObject->GetDatabaseFunction('DirectBlob') ) { 186 $Row[3] = decode_base64( $Row[3] ); 187 } 188 189 # add the info 190 push( 191 @Data, 192 { 193 Content => $Row[3], 194 ContentID => $Row[4], 195 ContentType => $Row[1], 196 Filename => $Row[0], 197 Filesize => $Row[2], 198 Disposition => $Row[5], 199 FileID => $Counter, 200 } 201 ); 202 } 203 204 return \@Data; 205} 206 207sub FormIDGetAllFilesMeta { 208 my ( $Self, %Param ) = @_; 209 210 my $Counter = 0; 211 my @Data; 212 for (qw(FormID)) { 213 if ( !$Param{$_} ) { 214 $Kernel::OM->Get('Kernel::System::Log')->Log( 215 Priority => 'error', 216 Message => "Need $_!" 217 ); 218 return; 219 } 220 } 221 222 # get database object 223 my $DBObject = $Kernel::OM->Get('Kernel::System::DB'); 224 225 $DBObject->Prepare( 226 SQL => ' 227 SELECT filename, content_type, content_size, content_id, disposition 228 FROM web_upload_cache 229 WHERE form_id = ? 230 ORDER BY create_time_unix', 231 Bind => [ \$Param{FormID} ], 232 ); 233 234 while ( my @Row = $DBObject->FetchrowArray() ) { 235 $Counter++; 236 237 # add the info 238 push( 239 @Data, 240 { 241 ContentID => $Row[3], 242 ContentType => $Row[1], 243 Filename => $Row[0], 244 Filesize => $Row[2], 245 Disposition => $Row[4], 246 FileID => $Counter, 247 } 248 ); 249 } 250 return \@Data; 251} 252 253sub FormIDCleanUp { 254 my ( $Self, %Param ) = @_; 255 256 my $CurrentTile = time() - ( 60 * 60 * 24 * 1 ); 257 258 return if !$Kernel::OM->Get('Kernel::System::DB')->Do( 259 SQL => ' 260 DELETE FROM web_upload_cache 261 WHERE create_time_unix < ?', 262 Bind => [ \$CurrentTile ], 263 ); 264 265 return 1; 266} 267 2681; 269