alecpl
2009-07-19 a640647edd0776555b9d2083fd968b2317143c8c
- handle big attachments with file pointers to not exceed memory_limit in rcmail_save_attachment()


3 files modified
63 ■■■■ changed files
plugins/database_attachments/database_attachments.php 4 ●●●● patch | view | raw | blame | history
plugins/filesystem_attachments/filesystem_attachments.php 30 ●●●●● patch | view | raw | blame | history
program/steps/mail/compose.inc 29 ●●●● patch | view | raw | blame | history
plugins/database_attachments/database_attachments.php
@@ -63,6 +63,10 @@
        $rcmail = rcmail::get_instance();
        $key = $this->_key($args['name']);
    if ($args['path'])
        $args['data'] = file_get_contents($args['path']);
        $data = base64_encode($args['data']);
        $status = $rcmail->db->query(
plugins/filesystem_attachments/filesystem_attachments.php
@@ -73,21 +73,25 @@
    function save($args)
    {
        $args['status'] = false;
        $rcmail = rcmail::get_instance();
        $temp_dir = unslashify($rcmail->config->get('temp_dir'));
        $tmp_path = tempnam($temp_dir, 'rcmAttmnt');
    if (!$args['path']) {
            $rcmail = rcmail::get_instance();
            $temp_dir = unslashify($rcmail->config->get('temp_dir'));
            $tmp_path = tempnam($temp_dir, 'rcmAttmnt');
        if ($fp = fopen($tmp_path, 'w')) {
            fwrite($fp, $args['data']);
            fclose($fp);
            if ($fp = fopen($tmp_path, 'w')) {
            fwrite($fp, $args['data']);
            fclose($fp);
            $args['path'] = $tmp_path;
            } else
        return $args;
    }
    $args['id'] = count($_SESSION['plugins']['filesystem_attachments']['tmp_files'])+1;
        $args['status'] = true;
            
            $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;
        }
        // Note the file for later cleanup
        $_SESSION['plugins']['filesystem_attachments']['tmp_files'][] = $args['path'];
        return $args;
    }
program/steps/mail/compose.inc
@@ -601,7 +601,7 @@
function rcmail_write_compose_attachments(&$message, $bodyIsHtml)
{
  global $OUTPUT;
echo "^^^^^";
  $cid_map = array();
  foreach ((array)$message->mime_parts as $pid => $part)
  {
@@ -643,20 +643,41 @@
function rcmail_save_attachment(&$message, $pid)
{
  $part = $message->mime_parts[$pid];
  $mem_limit = parse_bytes(ini_get('memory_limit'));
  $curr_mem = function_exists('memory_get_usage') ? memory_get_usage() : 16*1024*1024; // safe value: 16MB
  $data = $path = null;
  // don't load too big attachments into memory
  if ($mem_limit > 0 && $part->size > $mem_limit - $curr_mem) {
    $rcmail = rcmail::get_instance();
    $temp_dir = unslashify($rcmail->config->get('temp_dir'));
    $path = tempnam($temp_dir, 'rcmAttmnt');
    if ($fp = fopen($path, 'w')) {
      $message->get_part_content($pid, $fp);
      fclose($fp);
    } else
      return false;
  } else {
    $data = $message->get_part_content($pid);
  }
  $attachment = array(
    'name' => $part->filename ? $part->filename : 'Part_'.$pid.'.'.$part->ctype_secondary,
    'mimetype' => $part->ctype_primary . '/' . $part->ctype_secondary,
    'content_id' => $part->content_id,
    'data' => $message->get_part_content($pid),
    'data' => $data,
    'path' => $path
  );
  
  $attachment = rcmail::get_instance()->plugins->exec_hook('save_attachment', $attachment);
  if ($attachment['status']) {
    unset($attachment['data'], $attachment['status']);
    return $attachment;
  } else if ($path) {
    @unlink($path);
  }
  return false;
}