| [ Index ] |
PHP Cross Reference of Drupal 6 (yi-drupal) |
[Summary view] [Print] [Text view]
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' => 800, 23 ), 24 'savelocation' => '', 25 'width' => '', 26 'title_display' => 0, 27 'description' => '', 28 'attributes' => array(), 29 'private' => FALSE, 30 ), 31 ); 32 } 33 34 /** 35 * Implements _webform_theme_component(). 36 */ 37 function _webform_theme_file() { 38 return array( 39 'webform_edit_file_extensions' => array( 40 'arguments' => array('element' => NULL), 41 'file' => 'components/file.inc', 42 ), 43 'webform_render_file' => array( 44 'arguments' => array('element' => NULL), 45 'file' => 'components/file.inc', 46 ), 47 'webform_display_file' => array( 48 'arguments' => array('element' => NULL), 49 'file' => 'components/file.inc', 50 ), 51 ); 52 } 53 54 /** 55 * Implements _webform_edit_component(). 56 */ 57 function _webform_edit_file($component) { 58 $form = array(); 59 60 $form['validation']['size'] = array( 61 '#type' => 'textfield', 62 '#title' => t('Max upload size'), 63 '#default_value' => $component['extra']['filtering']['size'], 64 '#description' => t('Enter the max file size a user may upload (in KB).'), 65 '#size' => 10, 66 '#field_suffix' => t('KB'), 67 '#parents' => array('extra', 'filtering', 'size'), 68 '#element_validate' => array('_webform_edit_file_size_validate'), 69 '#weight' => 1, 70 ); 71 72 $form['validation']['extensions'] = array( 73 '#element_validate' => array('_webform_edit_file_extensions_validate'), 74 '#parents' => array('extra', 'filtering'), 75 '#theme' => 'webform_edit_file_extensions', 76 '#title' => t('Allowed file extensions'), 77 '#weight' => 2, 78 ); 79 80 // Find the list of all currently valid extensions. 81 $current_types = isset($component['extra']['filtering']['types']) ? $component['extra']['filtering']['types'] : array(); 82 83 $types = array('gif', 'jpg', 'png'); 84 $form['validation']['extensions']['types']['webimages'] = array( 85 '#type' => 'checkboxes', 86 '#title' => t('Web images'), 87 '#options' => drupal_map_assoc($types), 88 '#default_value' => array_intersect($current_types, $types), 89 ); 90 91 $types = array('bmp', 'eps', 'tif', 'pict', 'psd'); 92 $form['validation']['extensions']['types']['desktopimages'] = array( 93 '#type' => 'checkboxes', 94 '#title' => t('Desktop images'), 95 '#options' => drupal_map_assoc($types), 96 '#default_value' => array_intersect($current_types, $types), 97 ); 98 99 $types = array('txt', 'rtf', 'html', 'odf', 'pdf', 'doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx', 'xml'); 100 $form['validation']['extensions']['types']['documents'] = array( 101 '#type' => 'checkboxes', 102 '#title' => t('Documents'), 103 '#options' => drupal_map_assoc($types), 104 '#default_value' => array_intersect($current_types, $types), 105 ); 106 107 $types = array('avi', 'mov', 'mp3', 'ogg', 'wav'); 108 $form['validation']['extensions']['types']['media'] = array( 109 '#type' => 'checkboxes', 110 '#title' => t('Media'), 111 '#options' => drupal_map_assoc($types), 112 '#default_value' => array_intersect($current_types, $types), 113 ); 114 115 $types = array('bz2', 'dmg', 'gz', 'jar', 'rar', 'sit', 'tar', 'zip'); 116 $form['validation']['extensions']['types']['archives'] = array( 117 '#type' => 'checkboxes', 118 '#title' => t('Archives'), 119 '#options' => drupal_map_assoc($types), 120 '#default_value' => array_intersect($current_types, $types), 121 ); 122 123 $form['validation']['extensions']['addextensions'] = array( 124 '#type' => 'textfield', 125 '#title' => t('Additional extensions'), 126 '#default_value' => $component['extra']['filtering']['addextensions'], 127 '#description' => t('Enter a list of additional file extensions for this upload field, seperated by commas.<br /> Entered extensions will be appended to checked items above.'), 128 '#size' => 20, 129 '#weight' => 3, 130 ); 131 132 $form['extra']['savelocation'] = array( 133 '#type' => 'textfield', 134 '#title' => t('Upload directory'), 135 '#default_value' => $component['extra']['savelocation'], 136 '#description' => t('Webform uploads are always saved in the site files directory. You may optionally specify a subfolder to store your files.'), 137 '#weight' => 3, 138 '#field_prefix' => file_directory_path() . '/webform/', 139 '#element_validate' => array('_webform_edit_file_check_directory'), 140 '#after_build' => array('_webform_edit_file_check_directory'), 141 ); 142 $form['display']['width'] = array( 143 '#type' => 'textfield', 144 '#title' => t('Width'), 145 '#default_value' => $component['extra']['width'], 146 '#description' => t('Width of the file field.') . ' ' . t('Leaving blank will use the default size.'), 147 '#size' => 5, 148 '#maxlength' => 10, 149 '#weight' => 4, 150 '#parents' => array('extra', 'width') 151 ); 152 return $form; 153 } 154 155 /** 156 * A Form API element validate function to check filesize is numeric. 157 */ 158 function _webform_edit_file_size_validate($element) { 159 if (!empty($element['#value'])) { 160 if (!is_numeric($element['#value']) || intval($element['#value']) != $element['#value']) { 161 form_error($element, t('Max upload size must be a number in KB.')); 162 } 163 } 164 } 165 166 /** 167 * A Form API after build and validate function. 168 * 169 * Ensure that the destination directory exists and is writable. 170 */ 171 function _webform_edit_file_check_directory($element) { 172 $base_dir = file_directory_path() . '/webform'; 173 $base_success = file_check_directory($base_dir, FILE_CREATE_DIRECTORY); 174 175 $destination_dir = $base_dir . '/' . $element['#value']; 176 177 // Sanity check input to prevent use parent (../) directories. 178 if (preg_match('/\.\.[\/\\\]/', $destination_dir . '/')) { 179 form_error($element, t('The save directory %directory is not valid.', array('%directory' => $destination_dir))); 180 } 181 else { 182 // Try to make the directory recursively before calling file_check_directory(). 183 // This may be removed in D7, as recusive is the default there. 184 @mkdir($destination_dir, 0775, TRUE); 185 $destination_success = file_check_directory($destination_dir, FILE_CREATE_DIRECTORY); 186 187 if (!$base_success || !$destination_success) { 188 form_error($element, t('The save directory %directory could not be created. Check that the webform files directory is writtable.', array('%directory' => $destination_dir))); 189 } 190 } 191 192 return $element; 193 } 194 195 /** 196 * A Form API element validate function. 197 * 198 * Change the submitted values of the component so that all filtering extensions 199 * are saved as a single array. 200 */ 201 function _webform_edit_file_extensions_validate($element, &$form_state) { 202 // Predefined types. 203 $extensions = array(); 204 foreach (element_children($element['types']) as $category) { 205 foreach (array_keys($element['types'][$category]['#value']) as $extension) { 206 if ($element['types'][$category][$extension]['#value']) { 207 $extensions[] = $extension; 208 } 209 } 210 } 211 212 // Additional types. 213 $additional_extensions = explode(',', $element['addextensions']['#value']); 214 foreach ($additional_extensions as $extension) { 215 $clean_extension = drupal_strtolower(trim($extension)); 216 if (!empty($clean_extension) && !in_array($clean_extension, $extensions)) { 217 $extensions[] = $clean_extension; 218 } 219 } 220 221 form_set_value($element['types'], $extensions, $form_state); 222 } 223 224 /** 225 * Output the list of allowed extensions as checkboxes. 226 */ 227 function theme_webform_edit_file_extensions($element) { 228 drupal_add_js(drupal_get_path('module', 'webform') . '/js/webform-admin.js'); 229 drupal_add_css(drupal_get_path('module', 'webform') . '/css/webform-admin.css'); 230 231 // Format the components into a table. 232 $rows = array(); 233 foreach (element_children($element['types']) as $filtergroup) { 234 $row = array(); 235 $first_row = count($rows); 236 if ($element['types'][$filtergroup]['#type'] == 'checkboxes') { 237 $select_link = ' <a href="#" class="webform-select-link webform-select-link-' . $filtergroup . '">(' . t('select') . ')</a>'; 238 $row[] = $element['types'][$filtergroup]['#title']; 239 $element['types'][$filtergroup]['#title'] = NULL; 240 $row[] = array('data' => $select_link, 'width' => 40); 241 $row[] = array('data' => drupal_render($element['types'][$filtergroup]), 'class' => 'webform-file-extensions webform-select-group-' . $filtergroup); 242 $rows[] = array('data' => $row); 243 unset($element['types'][$filtergroup]); 244 } 245 } 246 247 // Add the row for additional types. 248 $row = array(); 249 $title = $element['addextensions']['#title']; 250 $element['addextensions']['#title'] = NULL; 251 $row[] = array('data' => $title, 'colspan' => 2); 252 $row[] = drupal_render($element['addextensions']); 253 $rows[] = $row; 254 255 $header = array(array('data' => t('Category'), 'colspan' => '2'), array('data' => t('Types'))); 256 257 // Create the table inside the form. 258 $table = theme('table', $header, $rows, array('class' => 'webform-file-extensions')); 259 $element['types']['table'] = array( 260 '#value' => theme('form_element', $element, $table), 261 ); 262 263 return drupal_render($element); 264 } 265 266 /** 267 * Implements _webform_render_component(). 268 */ 269 function _webform_render_file($component, $value = NULL, $filter = TRUE) { 270 $node = isset($component['nid']) ? node_load($component['nid']) : NULL; 271 272 // Normally every file component is given a unique ID based on its key. 273 if (isset($component['nid'])) { 274 $node = node_load($component['nid']); 275 $form_key = implode('_', webform_component_parent_keys($node, $component)); 276 } 277 // If being used as a default though, we don't yet have a form key. 278 else { 279 $form_key = 'default'; 280 } 281 282 $element[$form_key] = array( 283 '#type' => 'file', 284 '#title' => $filter ? _webform_filter_xss($component['name']) : $component['name'], 285 '#title_display' => $component['extra']['title_display'] ? $component['extra']['title_display'] : 'before', 286 //'#required' => $component['mandatory'], // Drupal core bug with required file uploads. 287 '#description' => $filter ? _webform_filter_descriptions($component['extra']['description'], $node) : $component['extra']['description'], 288 '#attributes' => $component['extra']['attributes'], 289 '#tree' => FALSE, // file_check_upload assumes a flat $_FILES structure. 290 '#element_validate' => array( 291 '_webform_validate_file', 292 '_webform_required_file', // Custom required routine. 293 ), 294 '#pre_render' => array('webform_element_title_display'), 295 '#translatable' => array('title', 'description'), 296 '#webform_component' => $component, 297 ); 298 $element['#webform_required'] = $component['mandatory']; 299 $element['#webform_form_key'] = $form_key; 300 $element['#weight'] = $component['weight']; 301 $element['#theme'] = 'webform_render_file'; 302 $element['#title_display'] = $element[$form_key]['#title_display']; 303 $element['#theme_wrappers'] = array('webform_element_wrapper'); 304 $element['#post_render'] = array('webform_element_wrapper'); 305 306 // Change the 'width' option to the correct 'size' option. 307 if ($component['extra']['width'] > 0) { 308 $element[$form_key]['#size'] = $component['extra']['width']; 309 } 310 311 // Add a hidden element to store the FID for new files. 312 $element['_fid'] = array( 313 '#type' => 'hidden', 314 '#default_value' => '', 315 ); 316 317 // Add a hidden element to store the FID for existing files. 318 $element['_old'] = array( 319 '#type' => 'hidden', 320 '#value' => isset($value[0]) ? $value[0] : NULL, 321 ); 322 323 return $element; 324 } 325 326 /** 327 * Render a File component. 328 */ 329 function theme_webform_render_file($element) { 330 // Add information about the existing file, if any. 331 if (isset($element['#default_value'])) { 332 $element['_fid']['#value'] = $element['#default_value']; 333 } 334 $value = $element['_fid']['#value'] ? $element['_fid']['#value'] : $element['_old']['#value']; 335 336 if ($value && ($file = webform_get_file($value))) { 337 $firstchild = array_shift(element_children($element)); 338 $element[$firstchild]['#suffix'] = ' ' . l(t('Download @filename', array('@filename' => webform_file_name($file->filepath))), webform_file_url($file->filepath)) . (isset($element['#suffix']) ? $element['#suffix'] : ''); 339 $element[$firstchild]['#description'] = '<div class="webform-newfile-message">' . t('Uploading a new file will replace the current file.') . '</div>' . (isset($element[$firstchild]['#description']) ? $element[$firstchild]['#description'] : ''); 340 } 341 342 // Add the required asterisk. 343 if ($element['#webform_required']) { 344 $element[$element['#webform_form_key']]['#required'] = TRUE; 345 } 346 347 $output = ''; 348 foreach (element_children($element) as $key) { 349 $output .= drupal_render($element[$key]); 350 } 351 return $output; 352 } 353 354 /** 355 * A Form API element validate function. 356 * 357 * Fix Drupal core's handling of required file fields. 358 */ 359 function _webform_required_file($element, $form_state) { 360 $component = $element['#webform_component']; 361 $parents = $element['#array_parents']; 362 array_pop($parents); 363 $form_key = implode('_', $parents); 364 365 // Do not validate requiredness on back or draft button. 366 if (isset($form_state['clicked_button']['#validate']) && empty($form_state['clicked_button']['#validate'])) { 367 return; 368 } 369 370 // Check if a value is already set in the hidden field. 371 $values = $form_state['values']; 372 $key = array_shift($parents); 373 $found = FALSE; 374 while (isset($values[$key])) { 375 if (isset($values[$key])) { 376 $values = $values[$key]; 377 $found = TRUE; 378 } 379 else { 380 $found = FALSE; 381 } 382 $key = array_shift($parents); 383 } 384 385 if (!$found || (empty($values['_fid']) && empty($values['_old']))) { 386 if (empty($_FILES['files']['name'][$form_key]) && $component['mandatory']) { 387 form_error($element, t('%field field is required.', array('%field' => $component['name']))); 388 } 389 } 390 } 391 392 /** 393 * A Form API element validate function. 394 * 395 * Ensure that the uploaded file matches the specified file types. 396 */ 397 function _webform_validate_file($element, &$form_state) { 398 $component = $element['#webform_component']; 399 $form_key = implode('_', $element['#parents']); 400 401 if (empty($_FILES['files']['name'][$form_key])) { 402 return; 403 } 404 405 // Build a human readable list of extensions: 406 $extensions = $component['extra']['filtering']['types']; 407 $extension_list = ''; 408 if (count($extensions) > 1) { 409 for ($n = 0; $n < count($extensions) - 1; $n++) { 410 $extension_list .= $extensions[$n] . ', '; 411 } 412 $extension_list .= 'or ' . $extensions[count($extensions) - 1]; 413 } 414 elseif (!empty($extensions)) { 415 $extension_list = $extensions[0]; 416 } 417 418 if (in_array('jpg', $extensions)) { 419 $extensions[] = 'jpeg'; 420 } 421 422 $strrpos = function_exists('mb_strrpos') ? 'mb_strrpos' : 'strrpos'; 423 $dot = $strrpos($_FILES['files']['name'][$form_key], '.'); 424 $extension = drupal_strtolower(drupal_substr($_FILES['files']['name'][$form_key], $dot+1)); 425 $file_error = FALSE; 426 if (!empty($extensions) && !in_array($extension, $extensions)) { 427 form_error($element, t("Files with the '%ext' extension are not allowed, please upload a file with a %exts extension.", array('%ext' => $extension, '%exts' => $extension_list))); 428 $file_error = TRUE; 429 } 430 431 // Now let's check the file size (limit is set in KB). 432 if ($_FILES['files']['size'][$form_key] > $component['extra']['filtering']['size'] * 1024) { 433 form_error($element, t("The file '%filename' is too large (%filesize KB). Please upload a file %maxsize KB or smaller.", array('%filename' => $_FILES['files']['name'][$form_key], '%filesize' => (int) ($_FILES['files']['size'][$form_key]/1024), '%maxsize' => $component['extra']['filtering']['size']))); 434 $file_error = TRUE; 435 } 436 437 // Save the file to a temporary location. 438 if (!$file_error) { 439 $upload_dir = file_directory_path() . '/webform/' . $component['extra']['savelocation']; 440 if (file_check_directory($upload_dir, FILE_CREATE_DIRECTORY)) { 441 $file = file_save_upload($form_key, array(), $upload_dir); 442 if ($file) { 443 @chmod($file->filepath, 0664); 444 445 // Set the hidden field value. 446 $parents = $element['#array_parents']; 447 array_pop($parents); 448 $parents[] = '_fid'; 449 form_set_value(array('#parents' => $parents), $file->fid, $form_state); 450 } 451 else { 452 drupal_set_message(t('The uploaded file %filename was unable to be saved. The destination directory may not be writable.', array('%filename' => $file->filename)), 'error'); 453 } 454 } 455 else { 456 drupal_set_message(t('The uploaded file was unable to be saved. The destination directory does not exist.'), 'error'); 457 } 458 } 459 } 460 461 /** 462 * Implements _webform_submit_component(). 463 */ 464 function _webform_submit_file($component, $value) { 465 466 if ($value['_fid'] && ($file = webform_get_file($value['_fid']))) { 467 // Save any new files permanently. 468 file_set_status($file, FILE_STATUS_PERMANENT); 469 470 // Delete any previous files. 471 if ($value['_old'] && $value['_old'] != $value['_fid'] && ($existing = webform_get_file($value['_old']))) { 472 file_delete($existing->filepath); 473 db_query("DELETE FROM {files} WHERE fid = %d", $existing->fid); 474 } 475 476 $value = $file->fid; 477 } 478 else { 479 $value = $value['_old'] ? $value['_old'] : NULL; 480 } 481 482 return $value; 483 } 484 485 /** 486 * Implements _webform_display_component(). 487 */ 488 function _webform_display_file($component, $value, $format = 'html') { 489 $fid = isset($value[0]) ? $value[0] : NULL; 490 return array( 491 '#title' => $component['name'], 492 '#value' => $fid ? webform_get_file($fid) : NULL, 493 '#weight' => $component['weight'], 494 '#theme' => 'webform_display_file', 495 '#theme_wrappers' => $format == 'html' ? array('webform_element', 'webform_element_wrapper') : array('webform_element_text'), 496 '#post_render' => array('webform_element_wrapper'), 497 '#format' => $format, 498 '#translatable' => array('title'), 499 ); 500 } 501 502 /** 503 * Format the output of text data for this component 504 */ 505 function theme_webform_display_file($element) { 506 $file = $element['#value']; 507 $url = !empty($file) ? webform_file_url($file->filepath) : t('no upload'); 508 return !empty($file) ? ($element['#format'] == 'text' ? $url : l($file->filename, $url)) : ' '; 509 } 510 511 /** 512 * Implements _webform_delete_component(). 513 */ 514 function _webform_delete_file($component, $value) { 515 // Delete an individual submission file. 516 if (!empty($value[0]) && ($file = webform_get_file($value[0]))) { 517 unlink($file->filepath); 518 db_query("DELETE FROM {files} WHERE fid = '%d'", $file->fid); 519 } 520 } 521 522 /** 523 * Implements _webform_analysis_component(). 524 */ 525 function _webform_analysis_file($component, $sids = array()) { 526 $placeholders = count($sids) ? array_fill(0, count($sids), "'%s'") : array(); 527 $sidfilter = count($sids) ? " AND sid in (" . implode(",", $placeholders) . ")" : ""; 528 $query = 'SELECT data ' . 529 ' FROM {webform_submitted_data} ' . 530 ' WHERE nid = %d ' . 531 ' AND cid = %d' . $sidfilter; 532 $nonblanks = 0; 533 $sizetotal = 0; 534 $submissions = 0; 535 536 $result = db_query($query, array_merge(array($component['nid'], $component['cid']), $sids)); 537 while ($data = db_fetch_array($result)) { 538 $file = webform_get_file($data['data']); 539 if (isset($file->filesize)) { 540 $nonblanks++; 541 $sizetotal += $file->filesize; 542 } 543 $submissions++; 544 } 545 546 $rows[0] = array(t('Left Blank'), ($submissions - $nonblanks)); 547 $rows[1] = array(t('User uploaded file'), $nonblanks); 548 $rows[2] = array(t('Average uploaded file size'), ($sizetotal != 0 ? (int) (($sizetotal/$nonblanks)/1024) . ' KB' : '0')); 549 return $rows; 550 } 551 552 /** 553 * Implements _webform_table_component(). 554 */ 555 function _webform_table_file($component, $value) { 556 $output = ''; 557 $file = webform_get_file($value[0]); 558 if (!empty($file->fid)) { 559 $output = '<a href="' . webform_file_url($file->filepath) . '">' . check_plain(webform_file_name($file->filepath)) . '</a>'; 560 $output .= ' (' . (int) ($file->filesize/1024) . ' KB)'; 561 } 562 return $output; 563 } 564 565 /** 566 * Implements _webform_csv_headers_component(). 567 */ 568 function _webform_csv_headers_file($component, $export_options) { 569 $header = array(); 570 // Two columns in header. 571 $header[0] = array('', ''); 572 $header[1] = array($component['name'], ''); 573 $header[2] = array(t('Name'), t('Filesize (KB)')); 574 return $header; 575 } 576 577 /** 578 * Implements _webform_csv_data_component(). 579 */ 580 function _webform_csv_data_file($component, $export_options, $value) { 581 $file = webform_get_file($value[0]); 582 return empty($file->filename) ? array('', '') : array(webform_file_url($file->filepath), (int) ($file->filesize/1024)); 583 } 584 585 /** 586 * Helper function to create proper file names for uploaded file. 587 */ 588 function webform_file_name($filepath) { 589 if (!empty($filepath)) { 590 $info = pathinfo($filepath); 591 $file_name = $info['basename']; 592 } 593 return isset($file_name) ? $file_name : ''; 594 } 595 596 /** 597 * Helper function to create proper URLs for uploaded file. 598 */ 599 function webform_file_url($filepath) { 600 if (!empty($filepath)) { 601 $info = pathinfo($filepath); 602 switch (variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC)) { 603 case FILE_DOWNLOADS_PUBLIC: 604 $path = $info['dirname'] . '/' . rawurlencode($info['basename']); 605 break; 606 case FILE_DOWNLOADS_PRIVATE: 607 // Private file paths must not be encoded as they are run through url() 608 // which performs the file encoding. 609 $path = $info['dirname'] . '/' . $info['basename']; 610 break; 611 } 612 $file_url = file_create_url($path); 613 } 614 return isset($file_url) ? $file_url : ''; 615 } 616 617 /** 618 * Helper function to load a file from the database. 619 */ 620 function webform_get_file($fid) { 621 static $files; 622 623 if (!isset($files[$fid])) { 624 if (empty($fid)) { 625 $files[$fid] = FALSE; 626 } 627 else { 628 $files[$fid] = db_fetch_object(db_query("SELECT * FROM {files} WHERE fid = %d", $fid)); 629 } 630 } 631 632 return $files[$fid]; 633 } 634 635 /** 636 * Implements _webform_attachments_component(). 637 */ 638 function _webform_attachments_file($component, $value) { 639 $file = (array) webform_get_file($value[0]); 640 $files = array($file); 641 return $files; 642 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Mon Jul 9 18:01:44 2012 | Cross-referenced by PHPXref 0.7 |