Rev 719 | Rev 800 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
635 | daniel-mar | 1 | <?php |
2 | |||
3 | /* |
||
4 | * OIDplus 2.0 |
||
5 | * Copyright 2019 - 2021 Daniel Marschall, ViaThinkSoft |
||
6 | * |
||
7 | * Licensed under the Apache License, Version 2.0 (the "License"); |
||
8 | * you may not use this file except in compliance with the License. |
||
9 | * You may obtain a copy of the License at |
||
10 | * |
||
11 | * http://www.apache.org/licenses/LICENSE-2.0 |
||
12 | * |
||
13 | * Unless required by applicable law or agreed to in writing, software |
||
14 | * distributed under the License is distributed on an "AS IS" BASIS, |
||
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||
16 | * See the License for the specific language governing permissions and |
||
17 | * limitations under the License. |
||
18 | */ |
||
19 | |||
20 | if (!defined('INSIDE_OIDPLUS')) die(); |
||
21 | |||
22 | class OIDplusPagePublicAttachments extends OIDplusPagePluginPublic { |
||
23 | |||
24 | const DIR_UNLOCK_FILE = 'oidplus_upload.dir'; |
||
25 | |||
26 | private static function checkUploadDir($dir) { |
||
27 | if (!is_dir($dir)) { |
||
28 | throw new OIDplusException(_L('The attachment directory "%1" is not existing.', $dir)); |
||
29 | } |
||
30 | |||
31 | $realdir = realpath($dir); |
||
32 | if ($realdir === false) { |
||
33 | throw new OIDplusException(_L('The attachment directory "%1" cannot be resolved (realpath).', $dir)); |
||
34 | } |
||
35 | |||
36 | $unlock_file = $realdir . DIRECTORY_SEPARATOR . self::DIR_UNLOCK_FILE; |
||
37 | if (!file_exists($unlock_file)) { |
||
38 | throw new OIDplusException(_L('Unlock file "%1" is not existing in attachment directory "%2".', self::DIR_UNLOCK_FILE, $dir)); |
||
39 | } |
||
40 | |||
41 | if (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') { |
||
42 | // Linux check 1: Check for critical directories |
||
43 | if (self::isCriticalLinuxDirectory($realdir)) { |
||
44 | throw new OIDplusException(_L('The attachment directory must not be inside a critical system directory!')); |
||
45 | } |
||
46 | |||
47 | // Linux check 2: Check file owner |
||
48 | $file_owner_a = fileowner(OIDplus::localpath().'index.php'); |
||
49 | if ($file_owner_a === false) { |
||
50 | $file_owner_a = -1; |
||
51 | $file_owner_a_name = '???'; |
||
52 | } else { |
||
720 | daniel-mar | 53 | $tmp = function_exists('posix_getpwuid') ? posix_getpwuid($file_owner_a) : false; |
635 | daniel-mar | 54 | $file_owner_a_name = $tmp !== false ? $tmp['name'] : 'UID '.$file_owner_a; |
55 | } |
||
56 | |||
57 | $file_owner_b = fileowner($unlock_file); |
||
58 | if ($file_owner_b === false) { |
||
59 | $file_owner_b = -1; |
||
60 | $file_owner_b_name = '???'; |
||
61 | } else { |
||
720 | daniel-mar | 62 | $tmp = function_exists('posix_getpwuid') ? posix_getpwuid($file_owner_b) : false; |
635 | daniel-mar | 63 | $file_owner_b_name = $tmp !== false ? $tmp['name'] : 'UID '.$file_owner_b; |
64 | } |
||
65 | |||
66 | if ($file_owner_a != $file_owner_b) { |
||
67 | throw new OIDplusException(_L('Owner of unlock file "%1" is wrong. It is "%2", but it should be "%3".', $unlock_file, $file_owner_b_name, $file_owner_a_name)); |
||
68 | } |
||
69 | } else { |
||
70 | // Windows check 1: Check for critical directories |
||
71 | if (self::isCriticalWindowsDirectory($realdir)) { |
||
72 | throw new OIDplusException(_L('The attachment directory must not be inside a critical system directory!')); |
||
73 | } |
||
74 | |||
75 | // Note: We will not query the file owner in Windows systems. |
||
76 | // It would be possible, however, on Windows systems, the file |
||
77 | // ownership is rather hidden to the user and the user needs |
||
78 | // to go into several menus and windows in order to see/change |
||
79 | // the owner. We don't want to over-complicate it to the Windows admin. |
||
80 | } |
||
81 | } |
||
82 | |||
83 | private static function isCriticalWindowsDirectory($dir) { |
||
84 | $dir .= '\\'; |
||
85 | $windir = isset($_SERVER['SystemRoot']) ? $_SERVER['SystemRoot'].'\\' : 'C:\\Windows\\'; |
||
86 | if (stripos($dir,$windir) === 0) return true; |
||
87 | return false; |
||
88 | } |
||
89 | |||
90 | private static function isCriticalLinuxDirectory($dir) { |
||
91 | if ($dir == '/') return true; |
||
92 | $dir .= '/'; |
||
93 | if (strpos($dir,'/bin/') === 0) return true; |
||
94 | if (strpos($dir,'/boot/') === 0) return true; |
||
95 | if (strpos($dir,'/dev/') === 0) return true; |
||
96 | if (strpos($dir,'/etc/') === 0) return true; |
||
97 | if (strpos($dir,'/lib') === 0) return true; |
||
98 | if (strpos($dir,'/opt/') === 0) return true; |
||
99 | if (strpos($dir,'/proc/') === 0) return true; |
||
100 | if (strpos($dir,'/root/') === 0) return true; |
||
101 | if (strpos($dir,'/run/') === 0) return true; |
||
102 | if (strpos($dir,'/sbin/') === 0) return true; |
||
103 | if (strpos($dir,'/sys/') === 0) return true; |
||
104 | if (strpos($dir,'/tmp/') === 0) return true; |
||
105 | if (strpos($dir,'/usr/bin/') === 0) return true; |
||
106 | if (strpos($dir,'/usr/include/') === 0) return true; |
||
107 | if (strpos($dir,'/usr/lib') === 0) return true; |
||
108 | if (strpos($dir,'/usr/sbin/') === 0) return true; |
||
109 | if (strpos($dir,'/usr/src/') === 0) return true; |
||
110 | if (strpos($dir,'/var/cache/') === 0) return true; |
||
111 | if (strpos($dir,'/var/lib') === 0) return true; |
||
112 | if (strpos($dir,'/var/lock/') === 0) return true; |
||
113 | if (strpos($dir,'/var/log/') === 0) return true; |
||
114 | if (strpos($dir,'/var/mail/') === 0) return true; |
||
115 | if (strpos($dir,'/var/opt/') === 0) return true; |
||
116 | if (strpos($dir,'/var/run/') === 0) return true; |
||
117 | if (strpos($dir,'/var/spool/') === 0) return true; |
||
118 | if (strpos($dir,'/var/tmp/') === 0) return true; |
||
119 | return false; |
||
120 | } |
||
121 | |||
122 | public static function getUploadDir($id=null) { |
||
123 | // Get base path |
||
124 | $cfg = OIDplus::config()->getValue('attachment_upload_dir', ''); |
||
125 | $cfg = trim($cfg); |
||
126 | if ($cfg === '') { |
||
127 | $basepath = OIDplus::localpath() . 'userdata' . DIRECTORY_SEPARATOR . 'attachments'; |
||
128 | } else { |
||
129 | $basepath = $cfg; |
||
130 | } |
||
131 | |||
132 | try { |
||
133 | self::checkUploadDir($basepath); |
||
134 | } catch (Exception $e) { |
||
135 | $error = _L('This functionality is not available due to a misconfiguration'); |
||
136 | if (OIDplus::authUtils()->isAdminLoggedIn()) { |
||
137 | $error .= ': '.$e->getMessage(); |
||
138 | } else { |
||
139 | $error .= '. '._L('Please notify the system administrator. After they log-in, they can see the reason at this place.'); |
||
140 | } |
||
141 | throw new OIDplusException($error); |
||
142 | } |
||
143 | |||
144 | // Get object-specific path |
||
145 | if (!is_null($id)) { |
||
146 | $obj = OIDplusObject::parse($id); |
||
147 | if ($obj === null) throw new OIDplusException(_L('Invalid object "%1"',$id)); |
||
148 | |||
149 | $path_v1 = $basepath . DIRECTORY_SEPARATOR . $obj->getLegacyDirectoryName(); |
||
150 | $path_v1_bug = $basepath . $obj->getLegacyDirectoryName(); |
||
151 | $path_v2 = $basepath . DIRECTORY_SEPARATOR . $obj->getDirectoryName(); |
||
152 | |||
153 | if (is_dir($path_v1)) return $path_v1; // backwards compatibility |
||
154 | if (is_dir($path_v1_bug)) return $path_v1_bug; // backwards compatibility |
||
155 | return $path_v2; |
||
156 | } else { |
||
157 | return $basepath; |
||
158 | } |
||
159 | } |
||
160 | |||
161 | private function raMayDelete() { |
||
162 | return OIDplus::config()->getValue('attachments_allow_ra_delete', 0); |
||
163 | } |
||
164 | |||
165 | private function raMayUpload() { |
||
166 | return OIDplus::config()->getValue('attachments_allow_ra_upload', 0); |
||
167 | } |
||
168 | |||
169 | public function action($actionID, $params) { |
||
170 | |||
171 | if ($actionID == 'deleteAttachment') { |
||
172 | _CheckParamExists($params, 'id'); |
||
173 | $id = $params['id']; |
||
174 | $obj = OIDplusObject::parse($id); |
||
175 | if ($obj === null) throw new OIDplusException(_L('Invalid object "%1"',$id)); |
||
176 | if (!$obj->userHasWriteRights()) throw new OIDplusException(_L('Authentication error. Please log in as admin, or as the RA of "%1" to upload an attachment.',$id)); |
||
177 | |||
178 | if (!OIDplus::authUtils()->isAdminLoggedIn() && !$this->raMayDelete()) { |
||
179 | throw new OIDplusException(_L('The administrator has disabled deleting attachments by RAs.')); |
||
180 | } |
||
181 | |||
182 | _CheckParamExists($params, 'filename'); |
||
183 | $req_filename = $params['filename']; |
||
184 | if (strpos($req_filename, '/') !== false) throw new OIDplusException(_L('Illegal file name')); |
||
185 | if (strpos($req_filename, '\\') !== false) throw new OIDplusException(_L('Illegal file name')); |
||
186 | if (strpos($req_filename, '..') !== false) throw new OIDplusException(_L('Illegal file name')); |
||
187 | if (strpos($req_filename, chr(0)) !== false) throw new OIDplusException(_L('Illegal file name')); |
||
188 | |||
189 | $uploaddir = self::getUploadDir($id); |
||
190 | $uploadfile = $uploaddir . DIRECTORY_SEPARATOR . basename($req_filename); |
||
191 | |||
192 | if (!file_exists($uploadfile)) throw new OIDplusException(_L('File does not exist')); |
||
193 | @unlink($uploadfile); |
||
194 | if (file_exists($uploadfile)) { |
||
195 | OIDplus::logger()->log("[ERR]OID($id)+[ERR]A!", "Attachment file '".basename($uploadfile)."' could not be deleted from object '$id' (problem with permissions?)"); |
||
196 | $msg = _L('Attachment file "%1" could not be deleted from object "%2" (problem with permissions?)',basename($uploadfile),$id); |
||
197 | if (OIDplus::authUtils()->isAdminLoggedIn()) { |
||
198 | throw new OIDplusException($msg); |
||
199 | } else { |
||
200 | throw new OIDplusException($msg.'. '._L('Please contact the system administrator.')); |
||
201 | } |
||
202 | } else { |
||
203 | // If it was the last file, delete the empty directory |
||
719 | daniel-mar | 204 | $ary = @glob($uploaddir . DIRECTORY_SEPARATOR . '*'); |
205 | if (is_array($ary) && (count($ary) == 0)) @rmdir($uploaddir); |
||
635 | daniel-mar | 206 | } |
207 | |||
208 | OIDplus::logger()->log("[OK]OID($id)+[?INFO/!OK]OIDRA($id)?/[?INFO/!OK]A?", "Deleted attachment '".basename($uploadfile)."' from object '$id'"); |
||
209 | |||
210 | return array("status" => 0); |
||
211 | |||
212 | } else if ($actionID == 'uploadAttachment') { |
||
213 | _CheckParamExists($params, 'id'); |
||
214 | $id = $params['id']; |
||
215 | $obj = OIDplusObject::parse($id); |
||
216 | if ($obj === null) throw new OIDplusException(_L('Invalid object "%1"',$id)); |
||
217 | if (!$obj->userHasWriteRights()) throw new OIDplusException(_L('Authentication error. Please log in as admin, or as the RA of "%1" to upload an attachment.',$id)); |
||
218 | |||
219 | if (!OIDplus::authUtils()->isAdminLoggedIn() && !$this->raMayUpload()) { |
||
220 | throw new OIDplusException(_L('The administrator has disabled uploading attachments by RAs.')); |
||
221 | } |
||
222 | |||
223 | if (!isset($_FILES['userfile'])) { |
||
224 | throw new OIDplusException(_L('Please choose a file.')); |
||
225 | } |
||
226 | |||
227 | if (!OIDplus::authUtils()->isAdminLoggedIn()) { |
||
228 | $banned = explode(',', OIDplus::config()->getValue('attachments_block_extensions', '')); |
||
229 | foreach ($banned as $ext) { |
||
230 | $ext = trim($ext); |
||
231 | if ($ext == '') continue; |
||
232 | if (strtolower(substr(basename($_FILES['userfile']['name']), -strlen($ext)-1)) == strtolower('.'.$ext)) { |
||
233 | throw new OIDplusException(_L('The file extension "%1" is banned by the administrator (it can be uploaded by the administrator though)',$ext)); |
||
234 | } |
||
235 | } |
||
236 | } |
||
237 | |||
238 | $req_filename = $_FILES['userfile']['name']; |
||
239 | if (strpos($req_filename, '/') !== false) throw new OIDplusException(_L('Illegal file name')); |
||
240 | if (strpos($req_filename, '\\') !== false) throw new OIDplusException(_L('Illegal file name')); |
||
241 | if (strpos($req_filename, '..') !== false) throw new OIDplusException(_L('Illegal file name')); |
||
242 | if (strpos($req_filename, chr(0)) !== false) throw new OIDplusException(_L('Illegal file name')); |
||
243 | |||
244 | $uploaddir = self::getUploadDir($id); |
||
245 | $uploadfile = $uploaddir . DIRECTORY_SEPARATOR . basename($req_filename); |
||
246 | |||
247 | if (!is_dir($uploaddir)) { |
||
248 | @mkdir($uploaddir, 0777, true); |
||
249 | if (!is_dir($uploaddir)) { |
||
250 | OIDplus::logger()->log("[ERR]OID($id)+[ERR]A!", "Upload attachment '".basename($uploadfile)."' to object '$id' failed: Cannot create directory '".basename($uploaddir)."' (problem with permissions?)"); |
||
251 | $msg = _L('Upload attachment "%1" to object "%2" failed',basename($uploadfile),$id).': '._L('Cannot create directory "%1" (problem with permissions?)',basename($uploaddir)); |
||
252 | if (OIDplus::authUtils()->isAdminLoggedIn()) { |
||
253 | throw new OIDplusException($msg); |
||
254 | } else { |
||
255 | throw new OIDplusException($msg.'. '._L('Please contact the system administrator.')); |
||
256 | } |
||
257 | } |
||
258 | } |
||
259 | |||
260 | if (!@move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) { |
||
261 | OIDplus::logger()->log("[ERR]OID($id)+[ERR]A!", "Upload attachment '".basename($uploadfile)."' to object '$id' failed: Cannot move uploaded file into directory (problem with permissions?)"); |
||
262 | $msg = _L('Upload attachment "%1" to object "%2" failed',basename($uploadfile),$id).': '._L('Cannot move uploaded file into directory (problem with permissions?)'); |
||
263 | if (OIDplus::authUtils()->isAdminLoggedIn()) { |
||
264 | throw new OIDplusException($msg); |
||
265 | } else { |
||
266 | throw new OIDplusException($msg.'. '._L('Please contact the system administrator.')); |
||
267 | } |
||
268 | } |
||
269 | |||
270 | OIDplus::logger()->log("[OK]OID($id)+[?INFO/!OK]OIDRA($id)?/[?INFO/!OK]A?", "Uploaded attachment '".basename($uploadfile)."' to object '$id'"); |
||
271 | |||
272 | return array("status" => 0); |
||
273 | } else { |
||
274 | throw new OIDplusException(_L('Unknown action ID')); |
||
275 | } |
||
276 | } |
||
277 | |||
278 | public function init($html=true) { |
||
279 | OIDplus::config()->prepareConfigKey('attachments_block_extensions', 'Block file name extensions being used in file attachments (comma separated)', 'exe,scr,pif,bat,com,vbs,cmd', OIDplusConfig::PROTECTION_EDITABLE, function($value) { |
||
280 | }); |
||
281 | OIDplus::config()->prepareConfigKey('attachments_allow_ra_delete', 'Allow that RAs delete file attachments? (0=no, 1=yes)', '0', OIDplusConfig::PROTECTION_EDITABLE, function($value) { |
||
282 | if (!is_numeric($value) || ($value < 0) || ($value > 1)) { |
||
283 | throw new OIDplusException(_L('Please enter a valid value (0=no, 1=yes).')); |
||
284 | } |
||
285 | }); |
||
286 | OIDplus::config()->prepareConfigKey('attachments_allow_ra_upload', 'Allow that RAs upload file attachments? (0=no, 1=yes)', '0', OIDplusConfig::PROTECTION_EDITABLE, function($value) { |
||
287 | if (!is_numeric($value) || ($value < 0) || ($value > 1)) { |
||
288 | throw new OIDplusException(_L('Please enter a valid value (0=no, 1=yes).')); |
||
289 | } |
||
290 | }); |
||
291 | |||
292 | $info_txt = 'Alternative directory for attachments. It must contain a file named "'; |
||
293 | $info_txt .= self::DIR_UNLOCK_FILE; |
||
294 | $info_txt .= '"'; |
||
295 | if (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') { |
||
296 | $info_txt .= ' with the same owner as index.php'; |
||
297 | } |
||
298 | $info_txt .= '. If this setting is empty, then the userdata directory is used.'; |
||
299 | OIDplus::config()->prepareConfigKey('attachment_upload_dir', $info_txt, '', OIDplusConfig::PROTECTION_EDITABLE, function($value) { |
||
300 | if (trim($value) !== '') { |
||
301 | self::checkUploadDir($value); |
||
302 | } |
||
303 | }); |
||
304 | } |
||
305 | |||
306 | public function gui($id, &$out, &$handled) { |
||
307 | // Nothing |
||
308 | } |
||
309 | |||
310 | public function publicSitemap(&$out) { |
||
311 | // Nothing |
||
312 | } |
||
313 | |||
314 | public function tree(&$json, $ra_email=null, $nonjs=false, $req_goto='') { |
||
315 | return false; |
||
316 | } |
||
317 | |||
318 | private static function convert_filesize($bytes, $decimals = 2){ |
||
319 | $size = array(_L('Bytes'),_L('KiB'),_L('MiB'),_L('GiB'),_L('TiB'),_L('PiB'),_L('EiB'),_L('ZiB'),_L('YiB')); |
||
320 | $factor = floor((strlen($bytes) - 1) / 3); |
||
321 | return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . ' ' . @$size[$factor]; |
||
322 | } |
||
323 | |||
324 | public function implementsFeature($id) { |
||
325 | if (strtolower($id) == '1.3.6.1.4.1.37476.2.5.2.3.2') return true; // modifyContent |
||
326 | if (strtolower($id) == '1.3.6.1.4.1.37476.2.5.2.3.3') return true; // beforeObject*, afterObject* |
||
327 | if (strtolower($id) == '1.3.6.1.4.1.37476.2.5.2.3.4') return true; // whois*Attributes |
||
328 | return false; |
||
329 | } |
||
330 | |||
331 | public function modifyContent($id, &$title, &$icon, &$text) { |
||
332 | // Interface 1.3.6.1.4.1.37476.2.5.2.3.2 |
||
333 | |||
334 | $output = ''; |
||
335 | $doshow = false; |
||
336 | |||
337 | try { |
||
338 | $upload_dir = self::getUploadDir($id); |
||
719 | daniel-mar | 339 | $files = @glob($upload_dir . DIRECTORY_SEPARATOR . '*'); |
635 | daniel-mar | 340 | $found_files = false; |
341 | |||
342 | $obj = OIDplusObject::parse($id); |
||
343 | if ($obj === null) throw new OIDplusException(_L('Invalid object "%1"',$id)); |
||
344 | $can_upload = OIDplus::authUtils()->isAdminLoggedIn() || ($this->raMayUpload() && $obj->userHasWriteRights()); |
||
345 | $can_delete = OIDplus::authUtils()->isAdminLoggedIn() || ($this->raMayDelete() && $obj->userHasWriteRights()); |
||
346 | |||
347 | if (OIDplus::authUtils()->isAdminLoggedIn()) { |
||
348 | $output .= '<p>'._L('Admin info: The directory is %1','<b>'.htmlentities($upload_dir).'</b>').'</p>'; |
||
349 | $doshow = true; |
||
350 | } |
||
351 | |||
352 | $output .= '<div id="fileattachments_table" class="table-responsive">'; |
||
353 | $output .= '<table class="table table-bordered table-striped">'; |
||
354 | $output .= '<tr>'; |
||
355 | $output .= '<th>'._L('Filename').'</th>'; |
||
356 | $output .= '<th>'._L('Size').'</th>'; |
||
357 | $output .= '<th>'._L('File type').'</th>'; |
||
358 | $output .= '<th>'._L('Download').'</th>'; |
||
359 | if ($can_delete) $output .= '<th>'._L('Delete').'</th>'; |
||
360 | $output .= '</tr>'; |
||
719 | daniel-mar | 361 | if ($files) foreach ($files as $file) { |
635 | daniel-mar | 362 | if (is_dir($file)) continue; |
363 | |||
364 | $output .= '<tr>'; |
||
365 | $output .= '<td>'.htmlentities(basename($file)).'</td>'; |
||
366 | $output .= '<td>'.htmlentities(self::convert_filesize(filesize($file), 0)).'</td>'; |
||
367 | $lookup_files = array( |
||
368 | OIDplus::localpath().'userdata/attachments/filetypes$'.OIDplus::getCurrentLang().'.conf', |
||
369 | OIDplus::localpath().'userdata/attachments/filetypes.conf', |
||
370 | OIDplus::localpath().'vendor/danielmarschall/fileformats/filetypes$'.OIDplus::getCurrentLang().'.local', // not recommended |
||
371 | OIDplus::localpath().'vendor/danielmarschall/fileformats/filetypes.local', // not recommended |
||
372 | OIDplus::localpath().'vendor/danielmarschall/fileformats/filetypes$'.OIDplus::getCurrentLang().'.conf', |
||
373 | OIDplus::localpath().'vendor/danielmarschall/fileformats/filetypes.conf' |
||
374 | ); |
||
375 | $output .= '<td>'.htmlentities(VtsFileTypeDetect::getDescription($file, $lookup_files)).'</td>'; |
||
376 | |||
377 | $output .= ' <td><button type="button" name="download_'.md5($file).'" id="download_'.md5($file).'" class="btn btn-success btn-xs download" onclick="OIDplusPagePublicAttachments.downloadAttachment('.js_escape(OIDplus::webpath(__DIR__)).', current_node,'.js_escape(basename($file)).')">'._L('Download').'</button></td>'; |
||
378 | if ($can_delete) { |
||
379 | $output .= ' <td><button type="button" name="delete_'.md5($file).'" id="delete_'.md5($file).'" class="btn btn-danger btn-xs delete" onclick="OIDplusPagePublicAttachments.deleteAttachment(current_node,'.js_escape(basename($file)).')">'._L('Delete').'</button></td>'; |
||
380 | } |
||
381 | |||
382 | $output .= '</tr>'; |
||
383 | $doshow = true; |
||
384 | $found_files = true; |
||
385 | } |
||
386 | |||
387 | if (!$found_files) $output .= '<tr><td colspan="'.($can_delete ? 5 : 4).'"><i>'._L('No attachments').'</i></td></tr>'; |
||
388 | |||
389 | $output .= '</table></div>'; |
||
390 | |||
391 | if ($can_upload) { |
||
392 | $output .= '<form action="javascript:void(0);" onsubmit="return OIDplusPagePublicAttachments.uploadAttachmentOnSubmit(this);" enctype="multipart/form-data" id="uploadAttachmentForm">'; |
||
393 | $output .= '<input type="hidden" name="id" value="'.htmlentities($id).'">'; |
||
394 | $output .= '<div>'._L('Add a file attachment').':<input type="file" name="userfile" value="" id="fileAttachment">'; |
||
395 | $output .= '<br><input type="submit" value="'._L('Upload').'"></div>'; |
||
396 | $output .= '</form>'; |
||
397 | $doshow = true; |
||
398 | } |
||
399 | } catch (Exception $e) { |
||
400 | $doshow = true; |
||
401 | $output = '<p>'.$e->getMessage().'</p>'; |
||
402 | } |
||
403 | |||
404 | $output = '<h2>'._L('File attachments').'</h2>' . |
||
405 | '<div class="container box">' . |
||
406 | $output . |
||
407 | '</div>'; |
||
408 | if ($doshow) $text .= $output; |
||
409 | } |
||
410 | |||
411 | public function beforeObjectDelete($id) {} // Interface 1.3.6.1.4.1.37476.2.5.2.3.3 |
||
412 | public function afterObjectDelete($id) { |
||
413 | // Interface 1.3.6.1.4.1.37476.2.5.2.3.3 |
||
414 | // Delete the attachment folder including all files in it (note: Subfolders are not possible) |
||
415 | $uploaddir = self::getUploadDir($id); |
||
416 | if ($uploaddir != '') { |
||
719 | daniel-mar | 417 | $ary = @glob($uploaddir . DIRECTORY_SEPARATOR . '*'); |
418 | if ($ary) foreach ($ary as $a) @unlink($a); |
||
635 | daniel-mar | 419 | @rmdir($uploaddir); |
420 | if (is_dir($uploaddir)) { |
||
421 | OIDplus::logger()->log("[WARN]OID($id)+[WARN]A!", "Attachment directory '$uploaddir' could not be deleted during the deletion of the OID"); |
||
422 | } |
||
423 | } |
||
424 | } |
||
425 | public function beforeObjectUpdateSuperior($id, &$params) {} // Interface 1.3.6.1.4.1.37476.2.5.2.3.3 |
||
426 | public function afterObjectUpdateSuperior($id, &$params) {} // Interface 1.3.6.1.4.1.37476.2.5.2.3.3 |
||
427 | public function beforeObjectUpdateSelf($id, &$params) {} // Interface 1.3.6.1.4.1.37476.2.5.2.3.3 |
||
428 | public function afterObjectUpdateSelf($id, &$params) {} // Interface 1.3.6.1.4.1.37476.2.5.2.3.3 |
||
429 | public function beforeObjectInsert($id, &$params) {} // Interface 1.3.6.1.4.1.37476.2.5.2.3.3 |
||
430 | public function afterObjectInsert($id, &$params) {} // Interface 1.3.6.1.4.1.37476.2.5.2.3.3 |
||
431 | |||
432 | public function tree_search($request) { |
||
433 | return false; |
||
434 | } |
||
435 | |||
436 | public function whoisObjectAttributes($id, &$out) { |
||
437 | // Interface 1.3.6.1.4.1.37476.2.5.2.3.4 |
||
438 | |||
719 | daniel-mar | 439 | $files = @glob(self::getUploadDir($id) . DIRECTORY_SEPARATOR . '*'); |
440 | if ($files) foreach ($files as $file) { |
||
635 | daniel-mar | 441 | $out[] = 'attachment-name: '.basename($file); |
442 | $out[] = 'attachment-url: '.OIDplus::webpath(__DIR__).'download.php?id='.urlencode($id).'&filename='.urlencode(basename($file)); |
||
443 | } |
||
444 | |||
445 | } |
||
446 | public function whoisRaAttributes($email, &$out) {} // Interface 1.3.6.1.4.1.37476.2.5.2.3.4 |
||
447 | } |