Changeset 2356 in subversion
- Timestamp:
- Mar 17, 2009 11:04:05 AM (4 years ago)
- Location:
- branches/devel-api
- Files:
-
- 5 edited
-
plugins/database_attachments/database_attachments.php (modified) (3 diffs)
-
plugins/filesystem_attachments/filesystem_attachments.php (modified) (3 diffs)
-
program/steps/mail/attachments.inc (modified) (4 diffs)
-
program/steps/mail/compose.inc (modified) (2 diffs)
-
program/steps/mail/sendmail.inc (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
branches/devel-api/plugins/database_attachments/database_attachments.php
r2336 r2356 20 20 private $cache_prefix = "db_attach"; 21 21 22 23 function _key($filepath){ 22 /** 23 * Helper method to generate a unique key for the given attachment file 24 */ 25 private function _key($filepath) 26 { 24 27 return $this->cache_prefix.md5(mktime().$filepath.$_SESSION['user_id']); 25 28 } 26 29 27 // Save a newly uploaded attachment 28 function upload($args){ 29 $args['status'] = TRUE; 30 /** 31 * Save a newly uploaded attachment 32 */ 33 function upload($args) 34 { 35 $args['status'] = false; 30 36 $rcmail = rcmail::get_instance(); 31 $key = $this->_key($args[' filepath']);32 $data = base64_encode(file_get_contents($args[' filepath']));37 $key = $this->_key($args['path']); 38 $data = base64_encode(file_get_contents($args['path'])); 33 39 34 40 $status = $rcmail->db->query( 35 41 "INSERT INTO ".get_table_name('cache')." 36 (created, user_id, cache_key, data)37 VALUES (".$rcmail->db->now().", ?, ?, ?)",42 (created, user_id, cache_key, data) 43 VALUES (".$rcmail->db->now().", ?, ?, ?)", 38 44 $_SESSION['user_id'], 39 45 $key, 40 $data); 41 if($status){ 46 $data); 47 48 if ($status) { 42 49 $args['id'] = $key; 43 $_SESSION['compose']['attachments'][$key] = array( 44 'name' => $_FILES['_attachments']['name'][$args['index']], 45 'mimetype' => rc_mime_content_type($args['filepath'], $_FILES['_attachments']['type'][0]), 46 'path' => "stored in database", 47 ); 48 } else { 49 $args['status'] = FALSE; 50 $args['status'] = true; 51 unset($args['path']); 50 52 } 53 51 54 return $args; 52 55 } 53 56 54 // Save an attachment from a non-upload source (draft or forward) 55 function save($args){ 56 $args['status'] = TRUE; 57 /** 58 * Save an attachment from a non-upload source (draft or forward) 59 */ 60 function save($args) 61 { 62 $args['status'] = false; 57 63 $rcmail = rcmail::get_instance(); 58 64 59 $key = $this->_key($args[' filename']);60 $data = base64_encode($args[' attachment']);65 $key = $this->_key($args['name']); 66 $data = base64_encode($args['data']); 61 67 62 68 $status = $rcmail->db->query( 63 69 "INSERT INTO ".get_table_name('cache')." 64 (created, user_id, cache_key, data)65 VALUES (".$rcmail->db->now().", ?, ?, ?)",70 (created, user_id, cache_key, data) 71 VALUES (".$rcmail->db->now().", ?, ?, ?)", 66 72 $_SESSION['user_id'], 67 73 $key, 68 $data); 69 $args['id'] = $key;70 if ( !$status)71 {72 $args['status'] = FALSE;74 $data); 75 76 if ($status) { 77 $args['id'] = $key; 78 $args['status'] = true; 73 79 } 74 80 … … 76 82 } 77 83 78 // Remove an attachment from storage 79 // This is triggered by the remove attachment button on the compose screen 80 function remove($args){ 81 $args['status'] = TRUE; 84 /** 85 * Remove an attachment from storage 86 * This is triggered by the remove attachment button on the compose screen 87 */ 88 function remove($args) 89 { 90 $args['status'] = false; 82 91 $rcmail = rcmail::get_instance(); 83 92 $status = $rcmail->db->query( 84 93 "DELETE FROM ".get_table_name('cache')." 85 WHERE user_id=?86 AND cache_key=?",94 WHERE user_id=? 95 AND cache_key=?", 87 96 $_SESSION['user_id'], 88 97 $args['id']); 89 98 90 if (!$status){91 $args['status'] = false;99 if ($status) { 100 $args['status'] = true; 92 101 } 102 93 103 return $args; 94 104 } 95 105 96 // When composing an html message, image attachments may be shown 97 // For this plugin, $this->get_attachment will check the file and 98 // place it on disk 99 function display($args){ 106 /** 107 * When composing an html message, image attachments may be shown 108 * For this plugin, $this->get_attachment will check the file and 109 * return it's contents 110 */ 111 function display($args) 112 { 100 113 return $this->get_attachment($args); 101 114 } 102 115 103 // When displaying or sending the attachment the file must be temporarily 104 // copied to disk. This function is also called by the display_attachment hook. 105 function get_attachment($args){ 106 $args['status'] = TRUE; 107 $args['erase_after_send'] = TRUE; 116 /** 117 * When displaying or sending the attachment the file contents are fetched 118 * using this method. This is also called by the display_attachment hook. 119 */ 120 function get_attachment($args) 121 { 108 122 $rcmail = rcmail::get_instance(); 109 if (!is_array($_SESSION['compose']['attachments'][$args['id']])){ 110 $args['status'] = FALSE; 111 } 112 else{ 113 $sql_result = $rcmail->db->query( 123 124 $sql_result = $rcmail->db->query( 114 125 "SELECT cache_id, data 115 126 FROM ".get_table_name('cache')." … … 119 130 $args['id']); 120 131 121 if ($sql_arr = $rcmail->db->fetch_assoc($sql_result)) { 122 $cache_data = base64_decode($sql_arr['data']); 123 $temp_dir = unslashify($rcmail->config->get('temp_dir')); 124 $tmp_path = tempnam($temp_dir, 'rcmAttmnt'); 125 file_put_contents($tmp_path, $cache_data); 126 $_SESSION['compose']['attachments'][$args['id']]['path'] = $tmp_path; 127 $_SESSION['plugins']['database_attachments']['tmp_files'][] = $tmp_path; 128 $args['attachment']['path'] = $tmp_path; 129 } else { 130 $args['status'] = FALSE; 131 } 132 132 if ($sql_arr = $rcmail->db->fetch_assoc($sql_result)) { 133 $args['data'] = base64_decode($sql_arr['data']); 134 $args['status'] = true; 133 135 } 136 134 137 return $args; 135 138 } 136 // Delete all temp files associated with this user 137 function cleanup($args){ 139 140 /** 141 * Delete all temp files associated with this user 142 */ 143 function cleanup($args) 144 { 138 145 $rcmail = rcmail::get_instance(); 139 146 $rcmail->db->query( 140 147 "DELETE FROM ".get_table_name('cache')." 141 WHERE user_id=? 142 AND cache_key like '{$this->cache_prefix}%'", 143 $_SESSION['user_id']); 144 145 // When sending, attachments are copied to disk and should now be cleaned up 146 // Note that the cleanup must happen during the same php script execution 147 // as the send so that we can be sure it's the same machine in load ballanced 148 // environments. 149 if (is_array($_SESSION['plugins']['database_attachments']['tmp_files'])){ 150 foreach ($_SESSION['plugins']['database_attachments']['tmp_files'] as $i=>$filename){ 151 if(file_exists($filename)){ 152 unlink($filename); 153 } 154 unset($_SESSION['plugins']['database_attachments']['tmp_files']); 155 } 156 } 157 return $args; 148 WHERE user_id=? 149 AND cache_key like '{$this->cache_prefix}%'", 150 $_SESSION['user_id']); 158 151 } 159 152 } -
branches/devel-api/plugins/filesystem_attachments/filesystem_attachments.php
r2336 r2356 11 11 * Developers may wish to extend this class when creating attachment 12 12 * handler plugins: 13 * 14 * require_once('plugins/filesystem_attachments/filesystem_attachments.php'); 15 * class myCustom_attachments extends filesystem_attachments 13 * require_once('plugins/filesystem_attachments/filesystem_attachments.php'); 14 * class myCustom_attachments extends filesystem_attachments 16 15 * 17 16 * @author Ziba Scott <ziba@umich.edu> … … 21 20 class filesystem_attachments extends rcube_plugin 22 21 { 23 22 public $task = 'mail'; 23 24 24 function init() 25 25 { … … 43 43 } 44 44 45 // Save a newly uploaded attachment 46 function upload($args){ 47 $args['status'] = TRUE; 45 /** 46 * Save a newly uploaded attachment 47 */ 48 function upload($args) 49 { 50 $args['status'] = false; 48 51 $rcmail = rcmail::get_instance(); 52 49 53 // use common temp dir for file uploads 50 54 $temp_dir = unslashify($rcmail->config->get('temp_dir')); 51 55 $tmpfname = tempnam($temp_dir, 'rcmAttmnt'); 52 $_SESSION['plugins']['filesystem_attachments']['tmp_files'][] = $tmpfname; 53 if (move_uploaded_file($args['filepath'], $tmpfname)) { 54 $id = count($_SESSION['compose']['attachments']); 55 $args['id'] = $id; 56 57 $_SESSION['compose']['attachments'][] = array( 58 'name' => $_FILES['_attachments']['name'][$args['index']], 59 'mimetype' => rc_mime_content_type($tmpfname, $_FILES['_attachments']['type'][0]), 60 'path' => $tmpfname, 61 ); 56 57 if (move_uploaded_file($args['path'], $tmpfname)) { 58 $args['id'] = count($_SESSION['plugins']['filesystem_attachments']['tmp_files'])+1; 59 $args['path'] = $tmpfname; 60 $args['status'] = true; 62 61 63 62 // Note the file for later cleanup 64 63 $_SESSION['plugins']['filesystem_attachments']['tmp_files'][] = $tmpfname; 65 64 } 66 else{ 67 $args['status'] = FALSE; 68 } 65 69 66 return $args; 70 67 } 71 68 72 // Save an attachment from a non-upload source (draft or forward) 73 function save($args){ 74 $args['status'] = TRUE; 69 /** 70 * Save an attachment from a non-upload source (draft or forward) 71 */ 72 function save($args) 73 { 74 $args['status'] = false; 75 75 $rcmail = rcmail::get_instance(); 76 76 $temp_dir = unslashify($rcmail->config->get('temp_dir')); 77 77 $tmp_path = tempnam($temp_dir, 'rcmAttmnt'); 78 78 79 // Note the file for later cleanup 80 $_SESSION['plugins']['filesystem_attachments']['tmp_files'][] = $tmp_path; 81 82 if ($fp = fopen($tmp_path, 'w')) 83 { 84 fwrite($fp, $args['attachment']); 79 if ($fp = fopen($tmp_path, 'w')) { 80 fwrite($fp, $args['data']); 85 81 fclose($fp); 82 83 $args['id'] = count($_SESSION['plugins']['filesystem_attachments']['tmp_files'])+1; 84 $args['path'] = $tmp_path; 85 $args['status'] = true; 86 87 // Note the file for later cleanup 88 $_SESSION['plugins']['filesystem_attachments']['tmp_files'][] = $tmp_path; 86 89 } 87 else{88 $args['status'] = FALSE;89 }90 91 $args['tmp_path'] = $tmp_path;92 $args['id'] = count($_SESSION['compose']['attachments']);93 90 94 91 return $args; 95 92 } 96 93 97 // Remove an attachment from storage 98 // This is triggered by the remove attachment button on the compose screen 99 function remove($args){ 100 $args['status'] = TRUE; 101 $id = $args['id']; 102 if (is_array($_SESSION['compose']['attachments'][$id])) 103 { 104 @unlink($_SESSION['compose']['attachments'][$id]['path']); 105 } else { 106 $args['status'] = TRUE; 107 } 94 /** 95 * Remove an attachment from storage 96 * This is triggered by the remove attachment button on the compose screen 97 */ 98 function remove($args) 99 { 100 $args['status'] = @unlink($args['path']); 108 101 return $args; 109 102 } 110 103 111 / / When composing an html message, image attachments may be shown112 // For this plugin, the file is already in place, just check for113 // the existance of the proper metadata114 function display($args){115 $args['status'] = TRUE;116 if (!is_array($_SESSION['compose']['attachments'][$args['id']])){117 $args['status'] = FALSE;118 }104 /** 105 * When composing an html message, image attachments may be shown 106 * For this plugin, the file is already in place, just check for 107 * the existance of the proper metadata 108 */ 109 function display($args) 110 { 111 $args['status'] = file_exists($args['path']); 119 112 return $args; 120 113 } 121 114 122 // This attachment plugin doesn't require any steps to put the file 123 // on disk for use. This stub function is kept here to make this 124 // class handy as a parent class for other plugins which may need it. 125 function get_attachment($args){ 115 /** 116 * This attachment plugin doesn't require any steps to put the file 117 * on disk for use. This stub function is kept here to make this 118 * class handy as a parent class for other plugins which may need it. 119 */ 120 function get_attachment($args) 121 { 126 122 return $args; 127 123 } 128 // Delete all temp files associated with this user 129 function cleanup($args){ 124 125 /** 126 * Delete all temp files associated with this user 127 */ 128 function cleanup($args) 129 { 130 130 // $_SESSION['compose']['attachments'] is not a complete record of 131 131 // temporary files because loading a draft or starting a forward copies -
branches/devel-api/program/steps/mail/attachments.inc
r2336 r2356 29 29 if ($RCMAIL->action=='remove-attachment') 30 30 { 31 $plugin = rcmail::get_instance()->plugins->exec_hook('remove_attachment',array('id'=>substr($_POST['_file'],7))); 32 if ($plugin['status']) 33 { 34 $id = $plugin['id']; 35 if (is_array($_SESSION['compose']['attachments'][$id])) 36 { 31 $id = 'undefined'; 32 if (preg_match('/^rcmfile(\w+)$/', $_POST['_file'], $regs)) 33 $id = $regs[1]; 34 if ($attachment = $_SESSION['compose']['attachments'][$id]) 35 $attachment = $RCMAIL->plugins->exec_hook('remove_attachment', $attachment); 36 if ($attachment['status']) { 37 if (is_array($_SESSION['compose']['attachments'][$id])) { 37 38 unset($_SESSION['compose']['attachments'][$id]); 38 39 $OUTPUT->command('remove_from_attachment_list', "rcmfile$id"); 39 $OUTPUT->send();40 40 } 41 41 } 42 43 $OUTPUT->send(); 42 44 exit; 43 45 } … … 45 47 if ($RCMAIL->action=='display-attachment') 46 48 { 47 $plugin = rcmail::get_instance()->plugins->exec_hook('display_attachment',array('id'=>substr($_GET['_file'],7))); 48 if ($plugin['status']) 49 { 50 $id = $plugin['id']; 51 $apath = $_SESSION['compose']['attachments'][$id]['path']; 52 header('Content-Type: ' . $_SESSION['compose']['attachments'][$id]['mimetype']); 53 header('Content-Length: ' . filesize($apath)); 54 readfile($apath); 55 // plugins that don't use disk storage will want this temp file removed after use 56 if($plugin['erase_after_send']){ 57 unlink($apath); 58 } 49 $id = 'undefined'; 50 if (preg_match('/^rcmfile(\w+)$/', $_GET['_file'], $regs)) 51 $id = $regs[1]; 52 if ($attachment = $_SESSION['compose']['attachments'][$id]) 53 $attachment = $RCMAIL->plugins->exec_hook('display_attachment', $attachment); 54 55 if ($attachment['status']) { 56 $size = $attachment['data'] ? strlen($attachment['data']) : @filesize($attachment['path']); 57 header('Content-Type: ' . $attachment['mimetype']); 58 header('Content-Length: ' . $size); 59 60 if ($attachment['data']) 61 echo $attachment['data']; 62 else if ($attachment['path']) 63 readfile($attachment['path']); 59 64 } 60 65 exit; … … 75 80 if (is_array($_FILES['_attachments']['tmp_name'])) { 76 81 foreach ($_FILES['_attachments']['tmp_name'] as $i => $filepath) { 77 $plugin = rcmail::get_instance()->plugins->exec_hook('upload_attachment',array('filepath'=>$filepath,'index'=>$i)); 78 if ($plugin['status']) { 79 $id = $plugin['id']; 82 83 $attachment = array( 84 'path' => $filepath, 85 'name' => $_FILES['_attachments']['name'][$i], 86 'mimetype' => rc_mime_content_type($tmpfname, $_FILES['_attachments']['type'][$i]) 87 ); 88 89 $attachment = $RCMAIL->plugins->exec_hook('upload_attachment', $attachment); 90 if ($attachment['status']) { 91 $id = $attachment['id']; 92 93 // store new attachment in session 94 unset($attachment['status']); 95 $_SESSION['compose']['attachments'][$id] = $attachment; 96 80 97 if (is_file($icon = $CONFIG['skin_path'] . '/images/icons/remove-attachment.png')) { 81 98 $button = html::img(array( … … 94 111 'title' => rcube_label('delete'), 95 112 ), $button); 96 97 $content .= Q($ _FILES['_attachments']['name'][$i]);113 114 $content .= Q($attachment['name']); 98 115 99 116 $OUTPUT->command('add2attachment_list', "rcmfile$id", $content); -
branches/devel-api/program/steps/mail/compose.inc
r2336 r2356 613 613 function rcmail_save_attachment(&$message, $pid) 614 614 { 615 global $RCMAIL;616 617 615 $part = $message->mime_parts[$pid]; 618 616 619 $attachment = $message->get_part_content($pid);620 $plugin = rcmail::get_instance()->plugins->exec_hook('save_attachment',array('attachment'=>$attachment,'filename'=>$part->filename));621 if ($plugin['status'])622 {623 return array(624 'mimetype' => $part->ctype_primary . '/' . $part->ctype_secondary,625 'name' => $part->filename,626 'path' => $plugin['tmp_path'],627 'content_id' => $part->content_id,628 'id' => $plugin['id']629 );630 } else {631 return FALSE; 632 }617 $attachment = array( 618 'name' => $part->filename, 619 'mimetype' => $part->ctype_primary . '/' . $part->ctype_secondary, 620 'content_id' => $part->content_id, 621 'data' => $message->get_part_content($pid), 622 ); 623 624 $attachment = rcmail::get_instance()->plugins->exec_hook('save_attachment', $attachment); 625 if ($attachment['status']) { 626 unset($attachment['data'], $attachment['status']); 627 return $attachment; 628 } 629 630 return false; 633 631 } 634 632 … … 710 708 'href' => "#delete", 711 709 'title' => rcube_label('delete'), 712 'onclick' => sprintf("return %s.command('remove-attachment','rcmfile% d', this)", JS_OBJECT_NAME, $id)),710 'onclick' => sprintf("return %s.command('remove-attachment','rcmfile%s', this)", JS_OBJECT_NAME, $id)), 713 711 $button) . Q($a_prop['name'])); 714 712 } -
branches/devel-api/program/steps/mail/sendmail.inc
r2336 r2356 296 296 297 297 // add stored attachments, if any 298 if (is_array($_SESSION['compose']['attachments'])) 299 foreach ($_SESSION['compose']['attachments'] as $id => $attachment) 300 { 298 if (is_array($_SESSION['compose']['attachments'])) { 299 foreach ($_SESSION['compose']['attachments'] as $id => $attachment) { 301 300 // This hook gives attachment handlers a chance to place the file on disk 302 $ plugin = rcmail::get_instance()->plugins->exec_hook('get_attachment', array('id' => $id,'attachment'=>$attachment));303 $attachment = $plugin['attachment']; 304 $dispurl = '/\ssrc\s*=\s*[\'"]?\S+display-attachment\S+file=rcmfile' . $ id. '[\'"]?/';301 $attachment = $RCMAIL->plugins->exec_hook('get_attachment', $attachment); 302 303 $dispurl = '/\ssrc\s*=\s*[\'"]?\S+display-attachment\S+file=rcmfile' . $attachment['id'] . '[\'"]?/'; 305 304 $match = preg_match($dispurl, $message_body); 306 if ($isHtml && ($match > 0)) 307 { 305 if ($isHtml && ($match > 0)) { 308 306 $message_body = preg_replace($dispurl, ' src="'.$attachment['name'].'"', $message_body); 309 307 $MAIL_MIME->setHTMLBody($message_body); 310 $MAIL_MIME->addHTMLImage($attachment['path'], $attachment['mimetype'], $attachment['name']); 311 } 312 else 313 { 308 if ($attachment['data']) 309 $MAIL_MIME->addHTMLImage($attachment['data'], $attachment['mimetype'], $attachment['name'], false); 310 else 311 $MAIL_MIME->addHTMLImage($attachment['path'], $attachment['mimetype'], $attachment['name'], true); 312 } 313 else { 314 314 $ctype = str_replace('image/pjpeg', 'image/jpeg', $attachment['mimetype']); // #1484914 315 $file = $attachment['data'] ? $attachment['data'] : $attachment['path']; 315 316 316 317 // .eml attachments send inline 317 $MAIL_MIME->addAttachment($ attachment['path'],318 $MAIL_MIME->addAttachment($file, 318 319 $ctype, 319 $attachment['name'], true, 320 $attachment['name'], 321 ($attachment['data'] ? false : true), 320 322 ($ctype == 'message/rfc822' ? $transfer_encoding : 'base64'), 321 323 ($ctype == 'message/rfc822' ? 'inline' : 'attachment'), 322 324 $message_charset, '', '', 323 $CONFIG['mime_param_folding'] ? 'quoted-printable' : NULL, 324 $CONFIG['mime_param_folding'] == 2 ? 'quoted-printable' : NULL 325 ); 326 } 327 if($plugin['erase_after_send']){ 328 unlink($plugin['attachment']['path']); 329 } 330 } 325 $CONFIG['mime_param_folding'] ? 'quoted-printable' : NULL, 326 $CONFIG['mime_param_folding'] == 2 ? 'quoted-printable' : NULL 327 ); 328 } 329 } 330 } 331 331 332 332 // add submitted attachments 333 if (is_array($_FILES['_attachments']['tmp_name'])) 334 foreach ($_FILES['_attachments']['tmp_name'] as $i => $filepath) 335 { 333 if (is_array($_FILES['_attachments']['tmp_name'])) { 334 foreach ($_FILES['_attachments']['tmp_name'] as $i => $filepath) { 336 335 $ctype = $files['type'][$i]; 337 336 $ctype = str_replace('image/pjpeg', 'image/jpeg', $ctype); // #1484914 338 337 339 338 $MAIL_MIME->addAttachment($filepath, $ctype, $files['name'][$i], true, 340 $ctype == 'message/rfc822' ? $transfer_encoding : 'base64',341 'attachment', $message_charset, '', '',342 $CONFIG['mime_param_folding'] ? 'quoted-printable' : NULL,343 $CONFIG['mime_param_folding'] == 2 ? 'quoted-printable' : NULL344 );345 }346 339 $ctype == 'message/rfc822' ? $transfer_encoding : 'base64', 340 'attachment', $message_charset, '', '', 341 $CONFIG['mime_param_folding'] ? 'quoted-printable' : NULL, 342 $CONFIG['mime_param_folding'] == 2 ? 'quoted-printable' : NULL 343 ); 344 } 345 } 347 346 348 347 // encoding settings for mail composing
Note: See TracChangeset
for help on using the changeset viewer.
