| [ Index ] |
PHP Cross Reference of Drupal 6 (gatewave) |
[Summary view] [Print] [Text view]
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 }
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 |