[Svn] r2356 - in branches/devel-api: plugins/database_attachments plugins/filesystem_attachments program/steps/mail

trac at roundcube.net trac at roundcube.net
Tue Mar 17 16:04:05 CET 2009


Author: thomasb
Date: 2009-03-17 10:04:05 -0500 (Tue, 17 Mar 2009)
New Revision: 2356

Modified:
   branches/devel-api/plugins/database_attachments/database_attachments.php
   branches/devel-api/plugins/filesystem_attachments/filesystem_attachments.php
   branches/devel-api/program/steps/mail/attachments.inc
   branches/devel-api/program/steps/mail/compose.inc
   branches/devel-api/program/steps/mail/sendmail.inc
Log:
Refactoring of the attachments core plugins:
- let the application manage the compose-attachments array
- unify input and output parameters
- get rid of local temp files, directly pass file contents
- codestyle improvements


Modified: branches/devel-api/plugins/database_attachments/database_attachments.php
===================================================================
--- branches/devel-api/plugins/database_attachments/database_attachments.php	2009-03-17 14:36:00 UTC (rev 2355)
+++ branches/devel-api/plugins/database_attachments/database_attachments.php	2009-03-17 15:04:05 UTC (rev 2356)
@@ -19,98 +19,109 @@
     // A prefix for the cache key used in the session and in the key field of the cache table
     private $cache_prefix = "db_attach";
 
-
-    function _key($filepath){
+    /**
+     * Helper method to generate a unique key for the given attachment file
+     */
+    private function _key($filepath)
+    {
         return  $this->cache_prefix.md5(mktime().$filepath.$_SESSION['user_id']); 
     }
 
-    // Save a newly uploaded attachment
-    function upload($args){
-        $args['status'] = TRUE;
+    /**
+     * Save a newly uploaded attachment
+     */
+    function upload($args)
+    {
+        $args['status'] = false;
         $rcmail = rcmail::get_instance();
-        $key = $this->_key($args['filepath']);
-        $data = base64_encode(file_get_contents($args['filepath']));  
+        $key = $this->_key($args['path']);
+        $data = base64_encode(file_get_contents($args['path']));
 
         $status = $rcmail->db->query(
             "INSERT INTO ".get_table_name('cache')."
-            (created, user_id, cache_key, data)
-            VALUES (".$rcmail->db->now().", ?, ?, ?)",          
+             (created, user_id, cache_key, data)
+             VALUES (".$rcmail->db->now().", ?, ?, ?)",
             $_SESSION['user_id'],
             $key,
-            $data);   
-        if($status){
+            $data);
+            
+        if ($status) {
             $args['id'] = $key;
-            $_SESSION['compose']['attachments'][$key] = array(
-                'name' => $_FILES['_attachments']['name'][$args['index']],
-                'mimetype' => rc_mime_content_type($args['filepath'], $_FILES['_attachments']['type'][0]),
-                'path' => "stored in database",
-            );
-        } else {
-            $args['status'] = FALSE;
+            $args['status'] = true;
+            unset($args['path']);
         }
+        
         return $args;
     }
 
-    // Save an attachment from a non-upload source (draft or forward)
-    function save($args){
-        $args['status'] = TRUE;
+    /**
+     * Save an attachment from a non-upload source (draft or forward)
+     */
+    function save($args)
+    {
+        $args['status'] = false;
         $rcmail = rcmail::get_instance();
 
-        $key = $this->_key($args['filename']);
-        $data = base64_encode($args['attachment']);  
+        $key = $this->_key($args['name']);
+        $data = base64_encode($args['data']);
 
         $status = $rcmail->db->query(
             "INSERT INTO ".get_table_name('cache')."
-            (created, user_id, cache_key, data)
-            VALUES (".$rcmail->db->now().", ?, ?, ?)",          
+             (created, user_id, cache_key, data)
+             VALUES (".$rcmail->db->now().", ?, ?, ?)",
             $_SESSION['user_id'],
             $key,
-            $data);   
-        $args['id'] = $key;
-        if (!$status)
-        {
-            $args['status'] = FALSE;
+            $data);
+        
+        if ($status) {
+            $args['id'] = $key;
+            $args['status'] = true;
         }
 
         return $args;
     }
 
-    // Remove an attachment from storage
-    // This is triggered by the remove attachment button on the compose screen
-    function remove($args){
-        $args['status'] = TRUE;
+    /**
+     * Remove an attachment from storage
+     * This is triggered by the remove attachment button on the compose screen
+     */
+    function remove($args)
+    {
+        $args['status'] = false;
         $rcmail = rcmail::get_instance();
         $status = $rcmail->db->query(
             "DELETE FROM ".get_table_name('cache')."
-            WHERE  user_id=?
-            AND    cache_key=?",
+             WHERE  user_id=?
+             AND    cache_key=?",
             $_SESSION['user_id'],
             $args['id']);
     
-        if(!$status){
-            $args['status'] = false;
+        if ($status) {
+            $args['status'] = true;
         }
+        
         return $args;
     }
 
-    // When composing an html message, image attachments may be shown
-    // For this plugin, $this->get_attachment will check the file and
-    // place it on disk
-    function display($args){
+    /**
+     * When composing an html message, image attachments may be shown
+     * For this plugin, $this->get_attachment will check the file and
+     * return it's contents
+     */
+    function display($args)
+    {
         return $this->get_attachment($args);
     }
 
-    // When displaying or sending the attachment the file must be temporarily
-    // copied to disk.  This function is also called by the display_attachment hook.
-    function get_attachment($args){
-        $args['status'] = TRUE;
-        $args['erase_after_send'] = TRUE;
+    /**
+     * When displaying or sending the attachment the file contents are fetched
+     * using this method. This is also called by the display_attachment hook.
+     */
+    function get_attachment($args)
+    {
         $rcmail = rcmail::get_instance();
-        if (!is_array($_SESSION['compose']['attachments'][$args['id']])){
-            $args['status'] = FALSE;
-        }
-        else{
-          $sql_result = $rcmail->db->query(
+        
+        $sql_result = $rcmail->db->query(
             "SELECT cache_id, data
              FROM ".get_table_name('cache')."
              WHERE  user_id=?
@@ -118,42 +129,24 @@
             $_SESSION['user_id'],
             $args['id']);
 
-          if ($sql_arr = $rcmail->db->fetch_assoc($sql_result)) {
-              $cache_data = base64_decode($sql_arr['data']);
-              $temp_dir = unslashify($rcmail->config->get('temp_dir'));
-              $tmp_path = tempnam($temp_dir, 'rcmAttmnt');
-              file_put_contents($tmp_path, $cache_data);
-              $_SESSION['compose']['attachments'][$args['id']]['path'] = $tmp_path;
-              $_SESSION['plugins']['database_attachments']['tmp_files'][] = $tmp_path;
-              $args['attachment']['path'] = $tmp_path;
-          } else {
-            $args['status'] = FALSE;
-          }
-
+        if ($sql_arr = $rcmail->db->fetch_assoc($sql_result)) {
+            $args['data'] = base64_decode($sql_arr['data']);
+            $args['status'] = true;
         }
+        
         return $args;
     }
-    // Delete all temp files associated with this user
-    function cleanup($args){
+    
+    /**
+     * Delete all temp files associated with this user
+     */
+    function cleanup($args)
+    {
         $rcmail = rcmail::get_instance();
         $rcmail->db->query(
             "DELETE FROM ".get_table_name('cache')."
-            WHERE  user_id=?
-            AND cache_key like '{$this->cache_prefix}%'",
-                $_SESSION['user_id']);
-
-        // When sending, attachments are copied to disk and should now be cleaned up
-        // Note that the cleanup must happen during the same php script execution
-        // as the send so that we can be sure it's the same machine in load ballanced 
-        // environments.
-        if (is_array($_SESSION['plugins']['database_attachments']['tmp_files'])){
-            foreach ($_SESSION['plugins']['database_attachments']['tmp_files'] as $i=>$filename){
-                if(file_exists($filename)){
-                    unlink($filename);
-                }
-                unset($_SESSION['plugins']['database_attachments']['tmp_files']);
-            }
-        }
-        return $args;
+             WHERE  user_id=?
+             AND cache_key like '{$this->cache_prefix}%'",
+            $_SESSION['user_id']);
     }
 }

Modified: branches/devel-api/plugins/filesystem_attachments/filesystem_attachments.php
===================================================================
--- branches/devel-api/plugins/filesystem_attachments/filesystem_attachments.php	2009-03-17 14:36:00 UTC (rev 2355)
+++ branches/devel-api/plugins/filesystem_attachments/filesystem_attachments.php	2009-03-17 15:04:05 UTC (rev 2356)
@@ -10,17 +10,17 @@
  *
  * Developers may wish to extend this class when creating attachment
  * handler plugins:
+ *   require_once('plugins/filesystem_attachments/filesystem_attachments.php');
+ *   class myCustom_attachments extends filesystem_attachments
  *
- * require_once('plugins/filesystem_attachments/filesystem_attachments.php');
- * class myCustom_attachments extends filesystem_attachments
- *
  * @author Ziba Scott <ziba at umich.edu>
  * @author Thomas Bruederli <roundcube at gmail.com>
  * 
  */
 class filesystem_attachments extends rcube_plugin
 {
-
+    public $task = 'mail';
+    
     function init()
     {
         // Save a newly uploaded attachment
@@ -42,91 +42,91 @@
         $this->add_hook('cleanup_attachments', array($this, 'cleanup'));
     }
 
-    // Save a newly uploaded attachment
-    function upload($args){
-        $args['status'] = TRUE;
+    /**
+     * Save a newly uploaded attachment
+     */
+    function upload($args)
+    {
+        $args['status'] = false;
         $rcmail = rcmail::get_instance();
+        
         // use common temp dir for file uploads
         $temp_dir = unslashify($rcmail->config->get('temp_dir'));
         $tmpfname = tempnam($temp_dir, 'rcmAttmnt');
-        $_SESSION['plugins']['filesystem_attachments']['tmp_files'][] = $tmpfname;
-        if (move_uploaded_file($args['filepath'], $tmpfname)) {
-            $id = count($_SESSION['compose']['attachments']);
-            $args['id'] = $id;
+        
+        if (move_uploaded_file($args['path'], $tmpfname)) {
+            $args['id'] = count($_SESSION['plugins']['filesystem_attachments']['tmp_files'])+1;
+            $args['path'] = $tmpfname;
+            $args['status'] = true;
 
-            $_SESSION['compose']['attachments'][] = array(
-                'name' => $_FILES['_attachments']['name'][$args['index']],
-                'mimetype' => rc_mime_content_type($tmpfname, $_FILES['_attachments']['type'][0]),
-                'path' => $tmpfname,
-            );
-
             // Note the file for later cleanup
             $_SESSION['plugins']['filesystem_attachments']['tmp_files'][] = $tmpfname;
         }
-        else{
-            $args['status'] = FALSE;
-        }
+
         return $args;
     }
 
-    // Save an attachment from a non-upload source (draft or forward)
-    function save($args){
-        $args['status'] = TRUE;
+    /**
+     * Save an attachment from a non-upload source (draft or forward)
+     */
+    function save($args)
+    {
+        $args['status'] = false;
         $rcmail = rcmail::get_instance();
         $temp_dir = unslashify($rcmail->config->get('temp_dir'));
         $tmp_path = tempnam($temp_dir, 'rcmAttmnt');
 
-        // Note the file for later cleanup
-        $_SESSION['plugins']['filesystem_attachments']['tmp_files'][] = $tmp_path;
-
-        if ($fp = fopen($tmp_path, 'w'))
-        {
-            fwrite($fp, $args['attachment']);
+        if ($fp = fopen($tmp_path, 'w')) {
+            fwrite($fp, $args['data']);
             fclose($fp);
+            
+            $args['id'] = count($_SESSION['plugins']['filesystem_attachments']['tmp_files'])+1;
+            $args['path'] = $tmp_path;
+            $args['status'] = true;
+            
+            // Note the file for later cleanup
+            $_SESSION['plugins']['filesystem_attachments']['tmp_files'][] = $tmp_path;
         }
-        else{
-            $args['status'] = FALSE;
-        }
 
-        $args['tmp_path'] = $tmp_path;
-        $args['id'] = count($_SESSION['compose']['attachments']);
-
         return $args;
     }
 
-    // Remove an attachment from storage
-    // This is triggered by the remove attachment button on the compose screen
-    function remove($args){
-        $args['status'] = TRUE;
-        $id = $args['id'];
-        if (is_array($_SESSION['compose']['attachments'][$id]))
-        {
-            @unlink($_SESSION['compose']['attachments'][$id]['path']);
-        } else {
-            $args['status'] = TRUE;
-        }
+    /**
+     * Remove an attachment from storage
+     * This is triggered by the remove attachment button on the compose screen
+     */
+    function remove($args)
+    {
+        $args['status'] = @unlink($args['path']);
         return $args;
     }
 
-    // When composing an html message, image attachments may be shown
-    // For this plugin, the file is already in place, just check for
-    // the existance of the proper metadata
-    function display($args){
-        $args['status'] = TRUE;
-        if (!is_array($_SESSION['compose']['attachments'][$args['id']])){
-            $args['status'] = FALSE;
-        }
+    /**
+     * When composing an html message, image attachments may be shown
+     * For this plugin, the file is already in place, just check for
+     * the existance of the proper metadata
+     */
+    function display($args)
+    {
+        $args['status'] = file_exists($args['path']);
         return $args;
     }
 
-    // This attachment plugin doesn't require any steps to put the file
-    // on disk for use.  This stub function is kept here to make this 
-    // class handy as a parent class for other plugins which may need it.
-    function get_attachment($args){
+    /**
+     * This attachment plugin doesn't require any steps to put the file
+     * on disk for use.  This stub function is kept here to make this 
+     * class handy as a parent class