source: github/program/steps/mail/attachments.inc @ 06dc983

HEADcourier-fixdev-browser-capabilitiespdorelease-0.7release-0.8
Last change on this file since 06dc983 was 06dc983, checked in by thomascube <thomas@…>, 21 months ago

Fix session race conditions when composing new messages

  • Property mode set to 100644
File size: 5.6 KB
Line 
1<?php
2
3/*
4 +-----------------------------------------------------------------------+
5 | program/steps/mail/attachments.inc                                    |
6 |                                                                       |
7 | This file is part of the Roundcube Webmail client                     |
8 | Copyright (C) 2005-2009, The Roundcube Dev Team                       |
9 | Licensed under the GNU GPL                                            |
10 |                                                                       |
11 | PURPOSE:                                                              |
12 |   Upload, remove, display attachments in compose form                 |
13 |                                                                       |
14 +-----------------------------------------------------------------------+
15 | Author: Thomas Bruederli <roundcube@gmail.com>                        |
16 +-----------------------------------------------------------------------+
17
18 $Id$
19
20*/
21
22// Upload progress update
23if (!empty($_GET['_progress'])) {
24  rcube_upload_progress();
25}
26
27$COMPOSE_ID = get_input_value('_id', RCUBE_INPUT_GPC);
28$_SESSION['compose'] = $_SESSION['compose_data_'.$COMPOSE_ID];
29
30if (!$_SESSION['compose']) {
31  die("Invalid session var!");
32}
33
34
35// remove an attachment
36if ($RCMAIL->action=='remove-attachment')
37{
38  $id = 'undefined';
39  if (preg_match('/^rcmfile(\w+)$/', $_POST['_file'], $regs))
40    $id = $regs[1];
41  if ($attachment = $_SESSION['compose']['attachments'][$id])
42    $attachment = $RCMAIL->plugins->exec_hook('attachment_delete', $attachment);
43  if ($attachment['status']) {
44    if (is_array($_SESSION['compose']['attachments'][$id])) {
45      unset($_SESSION['compose']['attachments'][$id]);
46      $OUTPUT->command('remove_from_attachment_list', "rcmfile$id");
47    }
48  }
49 
50  $OUTPUT->send();
51  exit;
52}
53
54if ($RCMAIL->action=='display-attachment')
55{
56  $id = 'undefined';
57  if (preg_match('/^rcmfile(\w+)$/', $_GET['_file'], $regs))
58    $id = $regs[1];
59  if ($attachment = $_SESSION['compose']['attachments'][$id])
60    $attachment = $RCMAIL->plugins->exec_hook('attachment_display', $attachment);
61   
62  if ($attachment['status']) {
63    if (empty($attachment['size']))
64      $attachment['size'] = $attachment['data'] ? strlen($attachment['data']) : @filesize($attachment['path']);
65
66    header('Content-Type: ' . $attachment['mimetype']);
67    header('Content-Length: ' . $attachment['size']);
68   
69    if ($attachment['data'])
70      echo $attachment['data'];
71    else if ($attachment['path'])
72      readfile($attachment['path']);
73  }
74  exit;
75}
76
77// attachment upload action
78
79if (!is_array($_SESSION['compose']['attachments'])) {
80  $_SESSION['compose']['attachments'] = array();
81}
82
83// clear all stored output properties (like scripts and env vars)
84$OUTPUT->reset();
85
86$uploadid = get_input_value('_uploadid', RCUBE_INPUT_GET);
87
88if (is_array($_FILES['_attachments']['tmp_name'])) {
89  foreach ($_FILES['_attachments']['tmp_name'] as $i => $filepath) {
90    // Process uploaded attachment if there is no error
91    $err = $_FILES['_attachments']['error'][$i];
92
93    if (!$err) {
94      $attachment = array(
95        'path' => $filepath,
96        'size' => $_FILES['_attachments']['size'][$i],
97        'name' => $_FILES['_attachments']['name'][$i],
98        'mimetype' => rc_mime_content_type($filepath, $_FILES['_attachments']['name'][$i], $_FILES['_attachments']['type'][$i]),
99        'group' => $COMPOSE_ID,
100      );
101
102      $attachment = $RCMAIL->plugins->exec_hook('attachment_upload', $attachment);
103    }
104
105    if (!$err && $attachment['status'] && !$attachment['abort']) {
106      $id = $attachment['id'];
107
108      // store new attachment in session
109      unset($attachment['status'], $attachment['abort']);
110      $_SESSION['compose']['attachments'][$id] = $attachment;
111
112      if (($icon = $_SESSION['compose']['deleteicon']) && is_file($icon)) {
113        $button = html::img(array(
114          'src' => $icon,
115          'alt' => rcube_label('delete')
116        ));
117      }
118      else {
119        $button = Q(rcube_label('delete'));
120      }
121
122      $content = html::a(array(
123        'href' => "#delete",
124        'onclick' => sprintf("return %s.command('remove-attachment','rcmfile%s', this)", JS_OBJECT_NAME, $id),
125        'title' => rcube_label('delete'),
126      ), $button);
127
128      $content .= Q($attachment['name']);
129
130      $OUTPUT->command('add2attachment_list', "rcmfile$id", array(
131        'html' => $content,
132        'name' => $attachment['name'],
133        'mimetype' => $attachment['mimetype'],
134        'complete' => true), $uploadid);
135    }
136    else {  // upload failed
137      if ($err == UPLOAD_ERR_INI_SIZE || $err == UPLOAD_ERR_FORM_SIZE) {
138        $msg = rcube_label(array('name' => 'filesizeerror', 'vars' => array('size' => show_bytes(parse_bytes(ini_get('upload_max_filesize'))))));
139      }
140      else if ($attachment['error']) {
141        $msg = $attachment['error'];
142      }
143      else {
144        $msg = rcube_label('fileuploaderror');
145      }
146
147      $OUTPUT->command('display_message', $msg, 'error');
148      $OUTPUT->command('remove_from_attachment_list', $uploadid);
149    }
150  }
151}
152else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
153  // if filesize exceeds post_max_size then $_FILES array is empty,
154  // show filesizeerror instead of fileuploaderror
155  if ($maxsize = ini_get('post_max_size'))
156    $msg = rcube_label(array('name' => 'filesizeerror', 'vars' => array('size' => show_bytes(parse_bytes($maxsize)))));
157  else
158    $msg = rcube_label('fileuploaderror');
159  $OUTPUT->command('display_message', $msg, 'error');
160  $OUTPUT->command('remove_from_attachment_list', $uploadid);
161}
162
163// send html page with JS calls as response
164$OUTPUT->command('auto_save_start', false);
165$OUTPUT->send('iframe');
166
Note: See TracBrowser for help on using the repository browser.