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