[ Index ]

PHP Cross Reference of Drupal 6 (gatewave)

title

Body

[close]

/sites/all/modules/filefield_sources/ -> filefield_sources.module (source)

   1  <?php
   2  // $Id: filefield_sources.module,v 1.9 2010/08/09 04:11:54 quicksketch Exp $
   3  
   4  /**
   5   * @file
   6   * Extend FileField to allow files from multiple sources.
   7   */
   8  
   9  /**
  10   * Implementation of hook_menu().
  11   */
  12  function filefield_sources_menu() {
  13    $params = array();
  14    return filefield_sources_invoke_all('menu', $params);
  15  }
  16  
  17  /**
  18   * Implementation of hook_init().
  19   */
  20  function filefield_sources_init() {
  21    // Currently needed for IMCE to set a custom variable.
  22    filefield_sources_includes();
  23  }
  24  
  25  /**
  26   * Implementation of hook_elements().
  27   */
  28  function filefield_sources_elements() {
  29    $elements = array();
  30  
  31    foreach (module_invoke_all('filefield_sources_widgets') as $widget) {
  32      $elements[$widget]['#process'] = array('filefield_sources_process');
  33      $elements[$widget]['#element_validate'] = array('filefield_sources_validate');
  34      $elements[$widget]['#filefield_value_callback'] = array('filefield_sources_value');
  35    }
  36  
  37    return $elements;
  38  }
  39  
  40  /**
  41   * Implementation of hook_theme().
  42   */
  43  function filefield_sources_theme() {
  44    $params = array();
  45    $theme = filefield_sources_invoke_all('theme', $params);
  46  
  47    $theme['filefield_sources_list'] = array(
  48      'arguments' => array('sources' => NULL),
  49    );
  50  
  51    return $theme;
  52  }
  53  
  54  /**
  55   * Implementation of hook_filefield_sources_widgets().
  56   *
  57   * This returns a list of widgets that are compatible with FileField Sources.
  58   */
  59  function filefield_sources_filefield_sources_widgets() {
  60    return array('filefield_widget', 'imagefield_widget');
  61  }
  62  
  63  /**
  64   * Implementation of hook_widget_settings_alter().
  65   */
  66  function filefield_sources_widget_settings_alter(&$settings, $op, $widget) {
  67    // Only support modules that implement hook_insert_widgets().
  68    $widget_type = isset($widget['widget_type']) ? $widget['widget_type'] : $widget['type'];
  69    if (!in_array($widget_type, module_invoke_all('filefield_sources_widgets'))) {
  70      return;
  71    }
  72  
  73    if ($op == 'form') {
  74      $settings = array_merge($settings, filefield_sources_form($widget));
  75    }
  76  
  77    if ($op == 'save') {
  78      $settings = array_merge($settings, filefield_sources_widget_settings($widget));
  79    }
  80  }
  81  
  82  /**
  83   * A list of settings needed by FileField Sources module on widgets.
  84   */
  85  function filefield_sources_widget_settings($widget) {
  86    $settings = array(
  87      'filefield_sources',
  88    );
  89    $params = array('save', $widget);
  90    $settings = array_merge($settings, filefield_sources_invoke_all('settings', $params));
  91    return $settings;
  92  }
  93  
  94  /**
  95   * Configuration form for editing FileField Sources settings for a widget.
  96   */
  97  function filefield_sources_form($widget) {
  98  
  99    $form['filefield_sources'] = array(
 100      '#type' => 'fieldset',
 101      '#title' => t('File sources'),
 102      '#collapsible' => TRUE,
 103      '#collapsed' => TRUE,
 104      '#weight' => 15,
 105    );
 106  
 107    $sources = filefield_sources_list(FALSE);
 108    $sources = array_intersect_key(array_merge((array) $widget['filefield_sources'], $sources), $sources);
 109    $form['filefield_sources']['filefield_sources'] = array(
 110      '#type' => 'checkboxes',
 111      '#title' => t('Enabled sources'),
 112      '#options' => $sources,
 113      '#default_value' => (array) $widget['filefield_sources'],
 114      '#description' => t('Select the available locations from which this widget may select files.'),
 115    );
 116  
 117    $params = array('form', $widget);
 118    $form['filefield_sources'] = array_merge($form['filefield_sources'], filefield_sources_invoke_all('settings', $params));
 119  
 120    return $form;
 121  }
 122  
 123  /**
 124   * A #process callback to extend the filefield_widget element type.
 125   *
 126   * Add the central JavaScript and CSS files that allow switching between
 127   * different sources. Third-party modules can also add to the list of sources
 128   * by implementing hook_filefield_sources_info().
 129   */
 130  function filefield_sources_process($element, $edit, &$form_state, $form) {
 131    static $js_added;
 132  
 133    // Do all processing as needed by each source.
 134    $sources = filefield_sources_info();
 135    $field = content_fields($element['#field_name'], $element['#type_name']);
 136    $enabled_sources = (array) $field['widget']['filefield_sources'];
 137    foreach ($sources as $source_name => $source) {
 138      if (!$enabled_sources[$source_name]) {
 139        unset($sources[$source_name]);
 140      }
 141      elseif (isset($source['process'])) {
 142        $function = $source['process'];
 143        $element = $function($element, $edit, $form_state, $form);
 144      }
 145    }
 146  
 147    // Exit out if not adding any sources.
 148    if (empty($sources)) {
 149      return $element;
 150    }
 151  
 152    // Add basic JS and CSS.
 153    $path = drupal_get_path('module', 'filefield_sources');
 154    drupal_add_css($path .'/filefield_sources.css');
 155    drupal_add_js($path .'/filefield_sources.js');
 156  
 157    // Check the element for hint text that might need to be added.
 158    foreach (element_children($element) as $key) {
 159      if (isset($element[$key]['#filefield_sources_hint_text']) && !isset($js_added[$key])) {
 160        $type = str_replace('filefield_', '', $key);
 161        drupal_add_js(array('fileFieldSources' => array($type => array('hintText' => $element[$key]['#filefield_sources_hint_text']))), 'setting');
 162        $js_added[$key] = TRUE;
 163      }
 164    }
 165  
 166    // Add the list of sources to the element for toggling between sources.
 167    if (empty($element['fid']['#value'])) {
 168      $element['filefield_sources_list'] = array(
 169        '#type' => 'markup',
 170        '#value' => theme('filefield_sources_list', $element, $sources),
 171        '#weight' => -1,
 172      );
 173    }
 174  
 175    return $element;
 176  }
 177  
 178  /**
 179   * An #element_validate function to run source validations.
 180   */
 181  function filefield_sources_validate($element, &$form_state, $form) {
 182    // Do all processing as needed by each source.
 183    $sources = filefield_sources_info();
 184    foreach ($sources as $source) {
 185      if (isset($source['validate'])) {
 186        $function = $source['validate'];
 187        $function($element, $form_state, $form);
 188      }
 189    }
 190  }
 191  
 192  /**
 193   * A #filefield_value_callback to run source value callbacks.
 194   */
 195  function filefield_sources_value($element, &$item) {
 196    // Do all processing as needed by each source.
 197    $sources = filefield_sources_info();
 198    foreach ($sources as $source) {
 199      if (isset($source['value'])) {
 200        $function = $source['value'];
 201        $function($element, $item);
 202      }
 203    }
 204  }
 205  
 206  /**
 207   * Call all FileField Source hooks stored in the available include files.
 208   */
 209  function filefield_sources_invoke_all($method, &$params) {
 210    $return = array();
 211    foreach (filefield_sources_includes() as $source) {
 212      $function = 'filefield_source_' . $source . '_' . $method;
 213      if (function_exists($function)) {
 214        $result = call_user_func_array($function, $params);
 215        if (isset($result) && is_array($result)) {
 216          $return = array_merge_recursive($return, $result);
 217        }
 218        else if (isset($result)) {
 219          $return[] = $result;
 220        }
 221      }
 222    }
 223    return $return;
 224  }
 225  
 226  /**
 227   * Load hook_filefield_sources_info() data from all modules.
 228   */
 229  function filefield_sources_info() {
 230    $info = module_invoke_all('filefield_sources_info');
 231    drupal_alter('filefield_sources_info', $info);
 232    uasort($info, '_filefield_sources_sort');
 233    return $info;
 234  }
 235  
 236  /**
 237   * Create a list of FileField Sources by name, suitable for a select list.
 238   */
 239  function filefield_sources_list($include_default = TRUE) {
 240    $info = filefield_sources_info();
 241    $list = array();
 242  
 243    if ($include_default) {
 244      $list['upload'] = t('Upload');
 245    }
 246  
 247    foreach ($info as $key => $source) {
 248      $list[$key] = $source['name'];
 249    }
 250  
 251    return $list;
 252  }
 253  
 254  /**
 255   * Implementation of hook_filefield_sources_info().
 256   */
 257  function filefield_sources_filefield_sources_info() {
 258    $params = array();
 259    return filefield_sources_invoke_all('info', $params);
 260  }
 261  
 262  /**
 263   * Load all the potential sources.
 264   */
 265  function filefield_sources_includes($include = TRUE, $enabled_only = TRUE) {
 266    if ($enabled_only) {
 267      $enabled_includes = variable_get('filefield_sources', filefield_sources_includes(FALSE, FALSE));
 268    }
 269  
 270    $includes = array();
 271    $directory = drupal_get_path('module', 'filefield_sources') . '/sources';
 272    foreach (file_scan_directory($directory, '.inc$') as $file) {
 273      if (!$enabled_only || in_array($file->name, $enabled_includes)) {
 274        $includes[] = $file->name;
 275        if ($include) {
 276          include_once($file->filename);
 277        }
 278      }
 279    }
 280    return $includes;
 281  }
 282  
 283  /**
 284   * Clean up the file name, munging extensions and transliterating.
 285   *
 286   * @param $filepath
 287   *   A string containing a file name or full path. Only the file name will
 288   *   actually be modified.
 289   * @return
 290   *   A file path with a cleaned-up file name.
 291   */
 292  function filefield_sources_clean_filename($filepath) {
 293    global $user;
 294  
 295    $filename = basename($filepath);
 296  
 297    if (module_exists('transliteration')) {
 298      module_load_include('inc', 'transliteration');
 299  
 300      $langcode = NULL;
 301      if (!empty($_POST['language'])) {
 302        $languages = language_list();
 303        $langcode = isset($languages[$_POST['language']]) ? $_POST['language'] : NULL;
 304      }
 305      $filename = transliteration_clean_filename($filename, $langcode);
 306    }
 307  
 308    // Because this transfer mechanism does not use file_save_upload(), we need
 309    // to manually munge the filename to prevent dangerous extensions.
 310    // See file_save_upload().
 311    $extensions = '';
 312    foreach ($user->roles as $rid => $name) {
 313      $extensions .= ' '. variable_get("upload_extensions_$rid",
 314      variable_get('upload_extensions_default', 'jpg jpeg gif png txt html doc xls pdf ppt pps odt ods odp'));
 315    }
 316    $filename = file_munge_filename($filename, $extensions);
 317  
 318    $directory = dirname($filepath);
 319    return ($directory ? $directory . '/' : $directory) . $filename;
 320  }
 321  
 322  /**
 323   * Theme the display of the sources list.
 324   */
 325  function theme_filefield_sources_list($element, $sources) {
 326    $links = array();
 327  
 328    // Add the default "Upload" since it's not in our list.
 329    $default['upload'] = array(
 330      'label' => t('Upload'),
 331      'description' => t('Upload a file from your computer.'),
 332    );
 333    $sources = array_merge($default, $sources);
 334  
 335    foreach ($sources as $name => $source) {
 336      $links[] = '<a href="#" onclick="return false;" title="' . $source['description'] . '" id="' . $element['#id'] . '-' . $name . '-source" class="filefield-source filefield-source-' . $name . '">' . $source['label'] . '</a>';
 337    }
 338    return '<div class="filefield-sources-list">' . implode(' | ', $links) . '</div>';
 339  }
 340  
 341  /**
 342   * Validate a file based on the $element['#upload_validators'] property.
 343   */
 344  function filefield_sources_element_validate($element, $file) {
 345    $validators = $element['#upload_validators'];
 346    $errors = array();
 347  
 348    // Since this frequently is used to reference existing files, check that
 349    // they exist first in addition to the normal validations.
 350    if (!file_exists($file->filepath)) {
 351      $errors[] = t('The file does not exist.');
 352    }
 353    // Call the validation functions.
 354    else {
 355      foreach ($validators as $function => $args) {
 356        // Add the $file variable to the list of arguments and pass it by
 357        // reference (required for PHP 5.3 and higher).
 358        array_unshift($args, NULL);
 359        $args[0] = &$file;
 360        $errors = array_merge($errors, call_user_func_array($function, $args));
 361      }
 362    }
 363  
 364    // Check for validation errors.
 365    if (!empty($errors)) {
 366      $message = t('The selected file %name could not be referenced.', array('%name' => $file->filename));
 367      if (count($errors) > 1) {
 368        $message .= '<ul><li>'. implode('</li><li>', $errors) .'</li></ul>';
 369      }
 370      else {
 371        $message .= ' '. array_pop($errors);
 372      }
 373      form_error($element, $message);
 374      return 0;
 375    }
 376  
 377    return 1;
 378  }
 379  
 380  /**
 381   * Generate help text based on the $element['#upload_validators'] property.
 382   */
 383  function filefield_sources_element_validation_help($validators) {
 384    $desc = array();
 385    foreach ($validators as $callback => $arguments) {
 386      $help_func = $callback .'_help';
 387      if (function_exists($help_func)) {
 388        $desc[] = call_user_func_array($help_func, $arguments);
 389      }
 390    }
 391    return empty($desc) ? '' : implode('<br />', $desc);
 392  }
 393  
 394  /**
 395   * Custom sort function for ordering sources.
 396   */
 397  function _filefield_sources_sort($a, $b) {
 398    $a = (array)$a + array('weight' => 0, 'label' => '');
 399    $b = (array)$b + array('weight' => 0, 'label' => '');
 400    return $a['weight'] < $b['weight'] ? -1 : ($a['weight'] > $b['weight'] ? 1 : strnatcasecmp($a['label'], $b['label']));
 401  }


Generated: Thu Mar 24 11:18:33 2011 Cross-referenced by PHPXref 0.7