/[drupal]/contributions/modules/mmb/mmb.module
ViewVC logotype

Diff of /contributions/modules/mmb/mmb.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph | View Patch Patch

revision 1.5.2.9.2.2, Mon Jul 13 06:43:06 2009 UTC revision 1.5.2.9.2.3, Tue Aug 4 09:18:46 2009 UTC
# Line 1  Line 1 
1  <?php  <?php
2  /* $Id: mmb.module,v 1.5.2.9.2.1 2009/07/13 06:40:56 sanduhrs Exp $ */  /* $Id: mmb.module,v 1.5.2.9.2.2 2009/07/13 06:43:06 sanduhrs Exp $ */
3    
4  /**  /**
5   * @file   * @file
# Line 8  Line 8 
8   * @author   * @author
9   * Stefan Auditor <stefan.auditor@erdfisch.de>   * Stefan Auditor <stefan.auditor@erdfisch.de>
10   * for erdfisch http://erdfisch.de   * for erdfisch http://erdfisch.de
  *  
  * TODO:  
  * - Setting to attach images using image_attach.module  
  * - Setting to create nodes instead of attachments if applicable (image,audio,video)  
  * - Patch inline.module to display filetypes other than image inline ;)  
  *   (this seems to be a bigger problem than I thought by now http://drupal.org/node/35709)  
11   */   */
12    
13  /**  /**
14   * Implementation of hook_mailhandler().   * Implementation of hook_mailhandler().
15   */   */
16  function mmb_mailhandler($node, $result, $i, $header, $mailbox) {  function mmb_mailhandler($node, $result, $i, $header, $mailbox) {
17    global $user;    mmb_save_mimeparts($node);
   
   //Check if user is allowed to upload files  
   if (!user_access('upload files')) {  
     watchdog('error', t("The user '%u' may not upload files.", array('%u' => $user->name ? $user->name : variable_get('anonymous', t('Anonymous')))));  
     return $node;  
   }  
   
   //Get e-mail attachments  
   $files = array();  
   mmb_get_parts($files, $result, $i, $structure = false, $part_number = false);  
   
   //Attach them to the node  
   $node->files = $files;  
   
   //Save the attachments  
   _mmb_validate($node);  
   
18    return $node;    return $node;
19  }  }
20    
21  /**  /**
22   * Helper function to save a file temporarily   * Attach the files to the node
23   */   *
24  function mmb_save_part($data) {   * @param $node
   $tmp_file = tempnam(file_directory_temp(), 'mmb_');  
   $file = file_save_data($data, $tmp_file);  
   
   return $file;  
 }  
   
 /**  
  * Get all parts of the e-mail an save the attachments  
25   */   */
26  function mmb_get_parts(&$files, $stream, $msg_number, $mime_type, $structure = false, $part_number = false) {  function mmb_save_mimeparts(&$node) {
27    $mimetypes = array('text', 'multipart', 'message', 'application', 'audio', 'image', 'video', 'other');    if (is_array($node->mimeparts)) {
28        foreach ($node->mimeparts as $key => $part) {
29    if (!$structure) {        if ($file = mmb_file_save($part)) {
30      $structure = imap_fetchstructure($stream, $msg_number);          $node->files[$file->fid] = $file;
   }  
   if ($structure) {  
     foreach ($structure->parameters as $parameter) {  
   
       if (strtoupper($parameter->attribute) == 'CHARSET') {  
         $encoding = $parameter->value;  
       }  
     }  
   
     if (!$part_number) {  
       $part_number = '1';  
     }  
   
     $index = explode('.', $part_number);  
     $data = imap_fetchbody($stream, $msg_number, $index[1]);  
   
     if ($structure->encoding == 3) {  
       $data = base64_decode($data);  
     }  
     else if ($structure->encoding == 4) {  
       $data = quoted_printable_decode($data);  
     }  
     else {  
       $data = $data;  
     }  
   
     if (strtolower($structure->dparameters[0]->attribute) == 'filename' AND $structure->dparameters[0]->value != '') {  
       $key = 'upload_'. (count($files)+1);  
       $files[$key]['fid']       = $key;  
       $files[$key]['source']    = $key;  
       $files[$key]['filename']  = strtolower(imap_utf8($structure->dparameters[0]->value));  
       $files[$key]['filepath']  = mmb_save_part($data);  
       $files[$key]['filemime']  = $mimetypes[strtolower($structure->type)] .'/'. strtolower($structure->subtype);  
       $files[$key]['filesize']  = strlen($data);  
       $files[$key]['list']      = variable_get('upload_list_default', 1);  
     }  
   
     if ($structure->type == 1) { /* multipart */  
       while (list($index, $sub_structure) = each ($structure->parts)) {  
         if ($part_number) {  
           $prefix = $part_number .'.';  
         }  
         mmb_get_parts($files, $stream, $msg_number, $mime_type, $sub_structure, $prefix . ($index + 1));  
31        }        }
32      }      }
33    }    }
   
   return;  
34  }  }
35    
36  /**  /**
37   * From upload.module   * Validate and save file
38   * Changed from form_set_error- to watchdog-messages   *
39     * @param $part
40     * @param $validators
41     * @return unknown_type
42   */   */
43  function _mmb_validate(&$node) {  function mmb_file_save($part) {
44    // Accumulator for disk space quotas.    global $user;
45    $filesize = 0;  
46      // Build the list of non-munged extensions.
47    // Check if node->files exists, and if it contains something.    $extensions = '';
48    if (is_array($node->files)) {    foreach ($user->roles as $rid => $name) {
49      // Update existing files with form data.      $extensions .= ' '. variable_get("upload_extensions_$rid",
50      foreach ($node->files as $fid => $file) {      variable_get('upload_extensions_default', 'jpg jpeg gif png txt html doc xls pdf ppt pps odt ods odp'));
       // Convert file to object for compatibility  
       $file = (object)$file;  
   
       // Validate new uploads.  
       if (strpos($fid, 'upload') !== false && !$file->remove) {  
         global $user;  
   
         // Bypass validation for uid  = 1.  
         if ($user->uid != 1) {  
           // Update filesize accumulator.  
           $filesize += $file->filesize;  
   
           // Validate file against all users roles.  
           // Only denies an upload when all roles prevent it.  
   
           $total_usersize = upload_space_used($user->uid) + $filesize;  
           $error = array();  
           foreach ($user->roles as $rid => $name) {  
             $extensions = variable_get("upload_extensions_$rid", 'jpg jpeg gif png txt html doc xls pdf ppt pps odt ods odp');  
             $uploadsize = variable_get("upload_uploadsize_$rid", 1) * 1024 * 1024;  
             $usersize = variable_get("upload_usersize_$rid", 10) * 1024 * 1024;  
   
             $regex = '/\.('. ereg_replace(' +', '|', preg_quote($extensions)) .')$/i';  
   
             if (!preg_match($regex, $file->filename)) {  
               $error['extension']++;  
             }  
   
             if ($uploadsize && $file->filesize > $uploadsize) {  
               $error['uploadsize']++;  
             }  
   
             if ($usersize && $total_usersize + $file->filesize > $usersize) {  
               $error['usersize']++;  
             }  
           }  
   
           $user_roles = count($user->roles);  
           $valid = TRUE;  
           if ($error['extension'] == $user_roles) {  
             // form_set_error('upload', t('The selected file %name can not be attached to this post, because it is only possible to attach files with the following extensions: %files-allowed.', array('%name' => $file->filename, '%files-allowed' => $extensions)));  
             watchdog('mmb', 'The selected file %name can not be attached to this post, because it is only possible to attach files with the following extensions: %files-allowed.', array('%name' => $file->filename, '%files-allowed' => $extensions));  
             $valid = FALSE;  
           }  
           elseif ($error['uploadsize'] == $user_roles) {  
             // form_set_error('upload', t('The selected file %name can not be attached to this post, because it exceeded the maximum filesize of %maxsize.', array('%name' => $file->filename, '%maxsize' => format_size($uploadsize))));  
             watchdog('mmb', 'The selected file %name can not be attached to this post, because it exceeded the maximum filesize of %maxsize.', array('%name' => $file->filename, '%maxsize' => format_size($uploadsize)));  
             $valid = FALSE;  
           }  
           elseif ($error['usersize'] == $user_roles) {  
             // form_set_error('upload', t('The selected file %name can not be attached to this post, because the disk quota of %quota has been reached.', array('%name' => $file->filename, '%quota' => format_size($usersize))));  
             watchdog('mmb', 'The selected file %name can not be attached to this post, because the disk quota of %quota has been reached.', array('%name' => $file->filename, '%quota' => format_size($usersize)));  
             $valid = FALSE;  
           }  
           elseif (strlen($file->filename) > 255) {  
             // form_set_error('upload', t('The selected file %name can not be attached to this post, because the filename is too long.', array('%name' => $file->filename)));  
             watchdog('mmb', 'The selected file %name can not be attached to this post, because the filename is too long.', array('%name' => $file->filename));  
             $valid = FALSE;  
           }  
   
           if (!$valid) {  
             unset($node->files[$fid], $_SESSION['file_previews'][$fid]);  
             file_delete($file->filepath);  
           }  
         }  
       }  
     }  
51    }    }
 }  
52    
53      // Begin building file object.
54      $file = new stdClass();
55      $file->new = TRUE;
56      $file->list = 1;
57    
58      if ($part->filename == 'unnamed_attachment') {
59        $part->filename = $part->filename .'.txt';
60        $file->list = 0;
61      }
62    
63      $file->filename = truncate_utf8(file_munge_filename(trim($part->filename, '.'), $extensions, FALSE), 255);
64      $file->filepath = file_destination(file_create_path(file_directory_path() .'/'. $file->filename), FILE_EXISTS_RENAME);
65      $file->filemime = $part->filemime;
66      $file->filesize = strlen($part->data);
67    
68      // Rename potentially executable files, to help prevent exploits.
69      if (preg_match('/\.(php|pl|py|cgi|asp|js)$/i', $file->filename) && (substr($file->filename, -4) != '.txt')) {
70        $file->filemime = 'text/plain';
71        $file->filepath .= '.txt';
72        $file->filename .= '.txt';
73      }
74    
75      // If we made it this far it's safe to record this file in the database.
76      $file->uid = $user->uid;
77      $file->status = FILE_STATUS_PERMANENT;
78      $file->timestamp = time();
79      if ($file->filepath = file_save_data($part->data, $file->filepath)) {
80        drupal_write_record('files', $file);
81        return $file;
82      }
83    
84      return FALSE;
85    }

Legend:
Removed from v.1.5.2.9.2.2  
changed lines
  Added in v.1.5.2.9.2.3

  ViewVC Help
Powered by ViewVC 1.1.2