Mercurial > hg > rr-repo
comparison sites/all/modules/webform/components/file.inc @ 0:ff03f76ab3fe
initial version
author | danieleb <danielebarchiesi@me.com> |
---|---|
date | Wed, 21 Aug 2013 18:51:11 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:ff03f76ab3fe |
---|---|
1 <?php | |
2 | |
3 /** | |
4 * @file | |
5 * Webform module file component. | |
6 */ | |
7 | |
8 /** | |
9 * Implements _webform_defaults_component(). | |
10 */ | |
11 function _webform_defaults_file() { | |
12 return array( | |
13 'name' => '', | |
14 'form_key' => NULL, | |
15 'mandatory' => 0, | |
16 'pid' => 0, | |
17 'weight' => 0, | |
18 'extra' => array( | |
19 'filtering' => array( | |
20 'types' => array('gif', 'jpg', 'png'), | |
21 'addextensions' => '', | |
22 'size' => '2 MB', | |
23 ), | |
24 'scheme' => 'public', | |
25 'directory' => '', | |
26 'progress_indicator' => 'throbber', | |
27 'title_display' => 0, | |
28 'description' => '', | |
29 'attributes' => array(), | |
30 'private' => FALSE, | |
31 ), | |
32 ); | |
33 } | |
34 | |
35 /** | |
36 * Implements _webform_theme_component(). | |
37 */ | |
38 function _webform_theme_file() { | |
39 return array( | |
40 'webform_edit_file_extensions' => array( | |
41 'render element' => 'element', | |
42 'file' => 'components/file.inc', | |
43 ), | |
44 'webform_display_file' => array( | |
45 'render element' => 'element', | |
46 'file' => 'components/file.inc', | |
47 ), | |
48 ); | |
49 } | |
50 | |
51 /** | |
52 * Implements _webform_edit_component(). | |
53 */ | |
54 function _webform_edit_file($component) { | |
55 $form = array(); | |
56 $form['#element_validate'] = array('_webform_edit_file_check_directory'); | |
57 $form['#after_build'] = array('_webform_edit_file_check_directory'); | |
58 | |
59 $form['validation']['size'] = array( | |
60 '#type' => 'textfield', | |
61 '#title' => t('Max upload size'), | |
62 '#default_value' => $component['extra']['filtering']['size'], | |
63 '#description' => t('Enter the max file size a user may upload such as 2 MB or 800 KB. Your server has a max upload size of @size.', array('@size' => format_size(file_upload_max_size()))), | |
64 '#size' => 10, | |
65 '#parents' => array('extra', 'filtering', 'size'), | |
66 '#element_validate' => array('_webform_edit_file_size_validate'), | |
67 '#weight' => 1, | |
68 ); | |
69 | |
70 $form['validation']['extensions'] = array( | |
71 '#element_validate' => array('_webform_edit_file_extensions_validate'), | |
72 '#parents' => array('extra', 'filtering'), | |
73 '#theme' => 'webform_edit_file_extensions', | |
74 '#theme_wrappers' => array('form_element'), | |
75 '#title' => t('Allowed file extensions'), | |
76 '#attached' => array( | |
77 'js' => array(drupal_get_path('module', 'webform') . '/js/webform-admin.js'), | |
78 'css' => array(drupal_get_path('module', 'webform') . '/css/webform-admin.css'), | |
79 ), | |
80 '#weight' => 2, | |
81 ); | |
82 | |
83 // Find the list of all currently valid extensions. | |
84 $current_types = isset($component['extra']['filtering']['types']) ? $component['extra']['filtering']['types'] : array(); | |
85 | |
86 $types = array('gif', 'jpg', 'png'); | |
87 $form['validation']['extensions']['types']['webimages'] = array( | |
88 '#type' => 'checkboxes', | |
89 '#title' => t('Web images'), | |
90 '#options' => drupal_map_assoc($types), | |
91 '#default_value' => array_intersect($current_types, $types), | |
92 ); | |
93 | |
94 $types = array('bmp', 'eps', 'tif', 'pict', 'psd'); | |
95 $form['validation']['extensions']['types']['desktopimages'] = array( | |
96 '#type' => 'checkboxes', | |
97 '#title' => t('Desktop images'), | |
98 '#options' => drupal_map_assoc($types), | |
99 '#default_value' => array_intersect($current_types, $types), | |
100 ); | |
101 | |
102 $types = array('txt', 'rtf', 'html', 'odf', 'pdf', 'doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx', 'xml'); | |
103 $form['validation']['extensions']['types']['documents'] = array( | |
104 '#type' => 'checkboxes', | |
105 '#title' => t('Documents'), | |
106 '#options' => drupal_map_assoc($types), | |
107 '#default_value' => array_intersect($current_types, $types), | |
108 ); | |
109 | |
110 $types = array('avi', 'mov', 'mp3', 'ogg', 'wav'); | |
111 $form['validation']['extensions']['types']['media'] = array( | |
112 '#type' => 'checkboxes', | |
113 '#title' => t('Media'), | |
114 '#options' => drupal_map_assoc($types), | |
115 '#default_value' => array_intersect($current_types, $types), | |
116 ); | |
117 | |
118 $types = array('bz2', 'dmg', 'gz', 'jar', 'rar', 'sit', 'tar', 'zip'); | |
119 $form['validation']['extensions']['types']['archives'] = array( | |
120 '#type' => 'checkboxes', | |
121 '#title' => t('Archives'), | |
122 '#options' => drupal_map_assoc($types), | |
123 '#default_value' => array_intersect($current_types, $types), | |
124 ); | |
125 | |
126 $form['validation']['extensions']['addextensions'] = array( | |
127 '#type' => 'textfield', | |
128 '#title' => t('Additional extensions'), | |
129 '#default_value' => $component['extra']['filtering']['addextensions'], | |
130 '#description' => t('Enter a list of additional file extensions for this upload field, separated by commas.<br /> Entered extensions will be appended to checked items above.'), | |
131 '#size' => 20, | |
132 '#weight' => 3, | |
133 ); | |
134 | |
135 $scheme_options = array(); | |
136 foreach (file_get_stream_wrappers(STREAM_WRAPPERS_WRITE_VISIBLE) as $scheme => $stream_wrapper) { | |
137 $scheme_options[$scheme] = $stream_wrapper['name']; | |
138 } | |
139 $form['extra']['scheme'] = array( | |
140 '#type' => 'radios', | |
141 '#title' => t('Upload destination'), | |
142 '#options' => $scheme_options, | |
143 '#default_value' => $component['extra']['scheme'], | |
144 '#description' => t('Private file storage has significantly more overhead than public files, but restricts file access to users who can view submissions.'), | |
145 '#weight' => 4, | |
146 '#access' => count($scheme_options) > 1, | |
147 ); | |
148 $form['extra']['directory'] = array( | |
149 '#type' => 'textfield', | |
150 '#title' => t('Upload directory'), | |
151 '#default_value' => $component['extra']['directory'], | |
152 '#description' => t('You may optionally specify a sub-directory to store your files.'), | |
153 '#weight' => 5, | |
154 '#field_prefix' => 'webform/', | |
155 ); | |
156 | |
157 $form['display']['progress_indicator'] = array( | |
158 '#type' => 'radios', | |
159 '#title' => t('Progress indicator'), | |
160 '#options' => array( | |
161 'throbber' => t('Throbber'), | |
162 'bar' => t('Bar with progress meter'), | |
163 ), | |
164 '#default_value' => $component['extra']['progress_indicator'], | |
165 '#description' => t('The throbber display does not show the status of uploads but takes up less space. The progress bar is helpful for monitoring progress on large uploads.'), | |
166 '#weight' => 16, | |
167 '#access' => file_progress_implementation(), | |
168 '#parents' => array('extra', 'progress_indicator'), | |
169 ); | |
170 | |
171 // TODO: Make managed_file respect the "size" parameter. | |
172 /* | |
173 $form['display']['width'] = array( | |
174 '#type' => 'textfield', | |
175 '#title' => t('Width'), | |
176 '#default_value' => $component['extra']['width'], | |
177 '#description' => t('Width of the file field.') . ' ' . t('Leaving blank will use the default size.'), | |
178 '#size' => 5, | |
179 '#maxlength' => 10, | |
180 '#weight' => 4, | |
181 '#parents' => array('extra', 'width') | |
182 ); | |
183 */ | |
184 | |
185 return $form; | |
186 } | |
187 | |
188 /** | |
189 * A Form API element validate function to check filesize is valid. | |
190 */ | |
191 function _webform_edit_file_size_validate($element) { | |
192 if (!empty($element['#value'])) { | |
193 $set_filesize = parse_size($element['#value']); | |
194 if ($set_filesize == FALSE) { | |
195 form_error($element, t('File size @value is not a valid filesize. Use a value such as 2 MB or 800 KB.', array('@value' => $element['#value']))); | |
196 } | |
197 else { | |
198 $max_filesize = parse_size(file_upload_max_size()); | |
199 if ($max_filesize < $set_filesize) { | |
200 form_error($element, t('An upload size of @value is too large, you are allow to upload files @max or less.', array('@value' => $element['#value'], '@max' => format_size($max_filesize)))); | |
201 } | |
202 } | |
203 } | |
204 } | |
205 | |
206 /** | |
207 * A Form API after build and validate function. | |
208 * | |
209 * Ensure that the destination directory exists and is writable. | |
210 */ | |
211 function _webform_edit_file_check_directory($element) { | |
212 $scheme = $element['extra']['scheme']['#value']; | |
213 $directory = $element['extra']['directory']['#value']; | |
214 | |
215 $destination_dir = file_stream_wrapper_uri_normalize($scheme . '://' . $directory . '/webform'); | |
216 | |
217 // Sanity check input to prevent use parent (../) directories. | |
218 if (preg_match('/\.\.[\/\\\]/', $destination_dir . '/')) { | |
219 form_error($element['extra']['directory'], t('The save directory %directory is not valid.', array('%directory' => $directory))); | |
220 } | |
221 else { | |
222 $destination_success = file_prepare_directory($destination_dir, FILE_CREATE_DIRECTORY); | |
223 if (!$destination_success) { | |
224 form_error($element['extra']['directory'], t('The save directory %directory could not be created. Check that the webform files directory is writable.', array('%directory' => $directory))); | |
225 } | |
226 } | |
227 | |
228 return $element; | |
229 } | |
230 | |
231 /** | |
232 * A Form API element validate function. | |
233 * | |
234 * Change the submitted values of the component so that all filtering extensions | |
235 * are saved as a single array. | |
236 */ | |
237 function _webform_edit_file_extensions_validate($element, &$form_state) { | |
238 // Predefined types. | |
239 $extensions = array(); | |
240 foreach (element_children($element['types']) as $category) { | |
241 foreach (array_keys($element['types'][$category]['#value']) as $extension) { | |
242 if ($element['types'][$category][$extension]['#value']) { | |
243 $extensions[] = $extension; | |
244 } | |
245 } | |
246 } | |
247 | |
248 // Additional types. | |
249 $additional_extensions = explode(',', $element['addextensions']['#value']); | |
250 foreach ($additional_extensions as $extension) { | |
251 $clean_extension = drupal_strtolower(trim($extension)); | |
252 if (!empty($clean_extension) && !in_array($clean_extension, $extensions)) { | |
253 $extensions[] = $clean_extension; | |
254 } | |
255 } | |
256 | |
257 form_set_value($element['types'], $extensions, $form_state); | |
258 } | |
259 | |
260 /** | |
261 * Output the list of allowed extensions as checkboxes. | |
262 */ | |
263 function theme_webform_edit_file_extensions($variables) { | |
264 $element = $variables['element']; | |
265 | |
266 // Format the components into a table. | |
267 $rows = array(); | |
268 foreach (element_children($element['types']) as $filtergroup) { | |
269 $row = array(); | |
270 $first_row = count($rows); | |
271 if ($element['types'][$filtergroup]['#type'] == 'checkboxes') { | |
272 $select_link = ' <a href="#" class="webform-select-link webform-select-link-' . $filtergroup . '">(' . t('select') . ')</a>'; | |
273 $row[] = $element['types'][$filtergroup]['#title']; | |
274 $row[] = array('data' => $select_link, 'width' => 40); | |
275 $row[] = array('data' => drupal_render_children($element['types'][$filtergroup]), 'class' => array('webform-file-extensions', 'webform-select-group-' . $filtergroup)); | |
276 $rows[] = array('data' => $row); | |
277 unset($element['types'][$filtergroup]); | |
278 } | |
279 } | |
280 | |
281 // Add the row for additional types. | |
282 $row = array(); | |
283 $title = $element['addextensions']['#title']; | |
284 $element['addextensions']['#title'] = NULL; | |
285 $row[] = array('data' => $title, 'colspan' => 2); | |
286 $row[] = drupal_render($element['addextensions']); | |
287 $rows[] = $row; | |
288 | |
289 $header = array(array('data' => t('Category'), 'colspan' => '2'), array('data' => t('Types'))); | |
290 | |
291 // Create the table inside the form. | |
292 $element['types']['table'] = array( | |
293 '#theme' => 'table', | |
294 '#header' => $header, | |
295 '#rows' => $rows, | |
296 '#attributes' => array('class' => array('webform-file-extensions')), | |
297 ); | |
298 | |
299 return drupal_render_children($element); | |
300 } | |
301 | |
302 /** | |
303 * Implements _webform_render_component(). | |
304 */ | |
305 function _webform_render_file($component, $value = NULL, $filter = TRUE) { | |
306 $node = isset($component['nid']) ? node_load($component['nid']) : NULL; | |
307 | |
308 // Cap the upload size according to the PHP limit. | |
309 $max_filesize = parse_size(file_upload_max_size()); | |
310 $set_filesize = $component['extra']['filtering']['size']; | |
311 if (!empty($set_filesize) && parse_size($set_filesize) < $max_filesize) { | |
312 $max_filesize = parse_size($set_filesize); | |
313 } | |
314 | |
315 $element = array( | |
316 '#type' => 'managed_file', | |
317 '#title' => $filter ? _webform_filter_xss($component['name']) : $component['name'], | |
318 '#title_display' => $component['extra']['title_display'] ? $component['extra']['title_display'] : 'before', | |
319 '#required' => $component['mandatory'], | |
320 '#default_value' => isset($value[0]) ? $value[0] : NULL, | |
321 '#attributes' => $component['extra']['attributes'], | |
322 '#upload_validators' => array( | |
323 'file_validate_size' => array($max_filesize), | |
324 'file_validate_extensions' => array(implode(' ', $component['extra']['filtering']['types'])), | |
325 ), | |
326 '#pre_render' => array_merge(element_info_property('managed_file', '#pre_render'), array('webform_file_allow_access')), | |
327 '#upload_location' => $component['extra']['scheme'] . '://webform/' . $component['extra']['directory'], | |
328 '#progress_indicator' => $component['extra']['progress_indicator'], | |
329 '#description' => $filter ? _webform_filter_descriptions($component['extra']['description'], $node) : $component['extra']['description'], | |
330 '#weight' => $component['weight'], | |
331 '#theme_wrappers' => array('webform_element'), | |
332 '#translatable' => array('title', 'description'), | |
333 ); | |
334 | |
335 return $element; | |
336 } | |
337 | |
338 /** | |
339 * Implements _webform_submit_component(). | |
340 */ | |
341 function _webform_submit_file($component, $value) { | |
342 if (is_array($value)) { | |
343 return !empty($value['fid']) ? $value['fid'] : ''; | |
344 } | |
345 else { | |
346 return !empty($value) ? $value : ''; | |
347 } | |
348 } | |
349 | |
350 /** | |
351 * Pre-render callback to allow access to uploaded files. | |
352 * | |
353 * Files that have not yet been saved into a submission must be accessible to | |
354 * the user who uploaded it, but no one else. After the submission is saved, | |
355 * access is granted through the file_usage table. Before then, we use a | |
356 * $_SESSION value to record a user's upload. | |
357 * | |
358 * @see webform_file_download() | |
359 */ | |
360 function webform_file_allow_access($element) { | |
361 if (!empty($element['#value']['fid'])) { | |
362 $fid = $element['#value']['fid']; | |
363 $_SESSION['webform_files'][$fid] = $fid; | |
364 } | |
365 | |
366 return $element; | |
367 } | |
368 | |
369 /** | |
370 * Implements _webform_display_component(). | |
371 */ | |
372 function _webform_display_file($component, $value, $format = 'html') { | |
373 $fid = isset($value[0]) ? $value[0] : NULL; | |
374 return array( | |
375 '#title' => $component['name'], | |
376 '#value' => $fid ? webform_get_file($fid) : NULL, | |
377 '#weight' => $component['weight'], | |
378 '#theme' => 'webform_display_file', | |
379 '#theme_wrappers' => $format == 'text' ? array('webform_element_text') : array('webform_element'), | |
380 '#format' => $format, | |
381 '#translatable' => array('title'), | |
382 ); | |
383 } | |
384 | |
385 /** | |
386 * Format the output of text data for this component | |
387 */ | |
388 function theme_webform_display_file($variables) { | |
389 $element = $variables['element']; | |
390 | |
391 $file = $element['#value']; | |
392 $url = !empty($file) ? webform_file_url($file->uri) : t('no upload'); | |
393 return !empty($file) ? ($element['#format'] == 'text' ? $url : l($file->filename, $url)) : ' '; | |
394 } | |
395 | |
396 /** | |
397 * Implements _webform_delete_component(). | |
398 */ | |
399 function _webform_delete_file($component, $value) { | |
400 // Delete an individual submission file. | |
401 if (!empty($value[0]) && ($file = webform_get_file($value[0]))) { | |
402 file_usage_delete($file, 'webform'); | |
403 file_delete($file); | |
404 } | |
405 } | |
406 | |
407 /** | |
408 * Implements _webform_attachments_component(). | |
409 */ | |
410 function _webform_attachments_file($component, $value) { | |
411 $file = (array) webform_get_file($value[0]); | |
412 //This is necessary until the next release of mimemail is out, see [#1388786] | |
413 $file['filepath'] = $file['uri']; | |
414 $files = array($file); | |
415 return $files; | |
416 } | |
417 /** | |
418 * Implements _webform_analysis_component(). | |
419 */ | |
420 function _webform_analysis_file($component, $sids = array()) { | |
421 $query = db_select('webform_submitted_data', 'wsd', array('fetch' => PDO::FETCH_ASSOC)) | |
422 ->fields('wsd', array('no', 'data')) | |
423 ->condition('nid', $component['nid']) | |
424 ->condition('cid', $component['cid']); | |
425 | |
426 if (count($sids)) { | |
427 $query->condition('sid', $sids, 'IN'); | |
428 } | |
429 | |
430 $nonblanks = 0; | |
431 $sizetotal = 0; | |
432 $submissions = 0; | |
433 | |
434 $result = $query->execute(); | |
435 foreach ($result as $data) { | |
436 $file = webform_get_file($data['data']); | |
437 if (isset($file->filesize)) { | |
438 $nonblanks++; | |
439 $sizetotal += $file->filesize; | |
440 } | |
441 $submissions++; | |
442 } | |
443 | |
444 $rows[0] = array(t('Left Blank'), ($submissions - $nonblanks)); | |
445 $rows[1] = array(t('User uploaded file'), $nonblanks); | |
446 $rows[2] = array(t('Average uploaded file size'), ($sizetotal != 0 ? (int) (($sizetotal/$nonblanks)/1024) . ' KB' : '0')); | |
447 return $rows; | |
448 } | |
449 | |
450 /** | |
451 * Implements _webform_table_component(). | |
452 */ | |
453 function _webform_table_file($component, $value) { | |
454 $output = ''; | |
455 $file = webform_get_file($value[0]); | |
456 if (!empty($file->fid)) { | |
457 $output = '<a href="' . webform_file_url($file->uri) . '">' . check_plain(webform_file_name($file->uri)) . '</a>'; | |
458 $output .= ' (' . (int) ($file->filesize/1024) . ' KB)'; | |
459 } | |
460 return $output; | |
461 } | |
462 | |
463 /** | |
464 * Implements _webform_csv_headers_component(). | |
465 */ | |
466 function _webform_csv_headers_file($component, $export_options) { | |
467 $header = array(); | |
468 // Two columns in header. | |
469 $header[0] = array('', ''); | |
470 $header[1] = array($component['name'], ''); | |
471 $header[2] = array(t('Name'), t('Filesize (KB)')); | |
472 return $header; | |
473 } | |
474 | |
475 /** | |
476 * Implements _webform_csv_data_component(). | |
477 */ | |
478 function _webform_csv_data_file($component, $export_options, $value) { | |
479 $file = webform_get_file($value[0]); | |
480 return empty($file->filename) ? array('', '') : array(webform_file_url($file->uri), (int) ($file->filesize/1024)); | |
481 } | |
482 | |
483 /** | |
484 * Helper function to create proper file names for uploaded file. | |
485 */ | |
486 function webform_file_name($filepath) { | |
487 if (!empty($filepath)) { | |
488 $info = pathinfo($filepath); | |
489 $file_name = $info['basename']; | |
490 } | |
491 return isset($file_name) ? $file_name : ''; | |
492 } | |
493 | |
494 /** | |
495 * Helper function to create proper URLs for uploaded file. | |
496 */ | |
497 function webform_file_url($uri) { | |
498 if (!empty($uri)) { | |
499 $file_url = file_create_url($uri); | |
500 } | |
501 return isset($file_url) ? $file_url : ''; | |
502 } | |
503 | |
504 /** | |
505 * Helper function to load a file from the database. | |
506 */ | |
507 function webform_get_file($fid) { | |
508 // Simple check to prevent loading of NULL values, which throws an entity | |
509 // system error. | |
510 return $fid ? file_load($fid) : FALSE; | |
511 } | |
512 | |
513 /** | |
514 * Given a submission with file_usage set, add or remove file usage entries. | |
515 */ | |
516 function webform_file_usage_adjust($submission) { | |
517 if (isset($submission->file_usage)) { | |
518 $files = file_load_multiple($submission->file_usage['added_fids']); | |
519 foreach ($files as $file) { | |
520 $file->status = 1; | |
521 file_save($file); | |
522 file_usage_add($file, 'webform', 'submission', $submission->sid); | |
523 } | |
524 | |
525 $files = file_load_multiple($submission->file_usage['deleted_fids']); | |
526 foreach ($files as $file) { | |
527 file_usage_delete($file, 'webform', 'submission', $submission->sid); | |
528 file_delete($file); | |
529 } | |
530 } | |
531 } | |
532 |