Projet

Général

Profil

Paste
Télécharger (12,2 ko) Statistiques
| Branche: | Révision:

root / drupal7 / modules / simpletest / tests / file_test.module @ 76597ebf

1
<?php
2

    
3
/**
4
 * @file
5
 * Helper module for the file tests.
6
 *
7
 * The caller is must call file_test_reset() to initializing this module before
8
 * calling file_test_get_calls() or file_test_set_return().
9
 */
10

    
11

    
12
define('FILE_URL_TEST_CDN_1', 'http://cdn1.example.com');
13
define('FILE_URL_TEST_CDN_2', 'http://cdn2.example.com');
14

    
15

    
16
/**
17
 * Implements hook_menu().
18
 */
19
function file_test_menu() {
20
  $items['file-test/upload'] = array(
21
    'title' => 'Upload test',
22
    'page callback' => 'drupal_get_form',
23
    'page arguments' => array('_file_test_form'),
24
    'access arguments' => array('access content'),
25
    'type' => MENU_CALLBACK,
26
  );
27
  return $items;
28
}
29

    
30
/**
31
 * Implements hook_stream_wrappers().
32
 */
33
function file_test_stream_wrappers() {
34
  return array(
35
    'dummy' => array(
36
      'name' => t('Dummy files'),
37
      'class' => 'DrupalDummyStreamWrapper',
38
      'description' => t('Dummy wrapper for simpletest.'),
39
    ),
40
    'dummy-remote' => array(
41
      'name' => t('Dummy files (remote)'),
42
      'class' => 'DrupalDummyRemoteStreamWrapper',
43
      'description' => t('Dummy wrapper for simpletest (remote).'),
44
    ),
45
  );
46
}
47

    
48
/**
49
 * Form to test file uploads.
50
 */
51
function _file_test_form($form, &$form_state) {
52
  $form['file_test_upload'] = array(
53
    '#type' => 'file',
54
    '#title' => t('Upload a file'),
55
  );
56
  $form['file_test_replace'] = array(
57
    '#type' => 'select',
58
    '#title' => t('Replace existing image'),
59
    '#options' => array(
60
      FILE_EXISTS_RENAME => t('Appends number until name is unique'),
61
      FILE_EXISTS_REPLACE => t('Replace the existing file'),
62
      FILE_EXISTS_ERROR => t('Fail with an error'),
63
    ),
64
    '#default_value' => FILE_EXISTS_RENAME,
65
  );
66
  $form['file_subdir'] = array(
67
    '#type' => 'textfield',
68
    '#title' => t('Subdirectory for test file'),
69
    '#default_value' => '',
70
  );
71

    
72
  $form['extensions'] = array(
73
    '#type' => 'textfield',
74
    '#title' => t('Allowed extensions.'),
75
    '#default_value' => '',
76
  );
77

    
78
  $form['allow_all_extensions'] = array(
79
    '#type' => 'checkbox',
80
    '#title' => t('Allow all extensions?'),
81
    '#default_value' => FALSE,
82
  );
83

    
84
  $form['is_image_file'] = array(
85
    '#type' => 'checkbox',
86
    '#title' => t('Is this an image file?'),
87
    '#default_value' => TRUE,
88
  );
89

    
90
  $form['submit'] = array(
91
    '#type' => 'submit',
92
    '#value' => t('Submit'),
93
  );
94
  return $form;
95
}
96

    
97
/**
98
 * Process the upload.
99
 */
100
function _file_test_form_submit(&$form, &$form_state) {
101
  // Process the upload and perform validation. Note: we're using the
102
  // form value for the $replace parameter.
103
  if (!empty($form_state['values']['file_subdir'])) {
104
    $destination = 'temporary://' . $form_state['values']['file_subdir'];
105
    file_prepare_directory($destination, FILE_CREATE_DIRECTORY);
106
  }
107
  else {
108
    $destination = FALSE;
109
  }
110

    
111
  // Setup validators.
112
  $validators = array();
113
  if ($form_state['values']['is_image_file']) {
114
    $validators['file_validate_is_image'] = array();
115
  }
116

    
117
  if ($form_state['values']['allow_all_extensions']) {
118
    $validators['file_validate_extensions'] = array();
119
  }
120
  elseif (!empty($form_state['values']['extensions'])) {
121
    $validators['file_validate_extensions'] = array($form_state['values']['extensions']);
122
  }
123

    
124
  $file = file_save_upload('file_test_upload', $validators, $destination, $form_state['values']['file_test_replace']);
125
  if ($file) {
126
    $form_state['values']['file_test_upload'] = $file;
127
    drupal_set_message(t('File @filepath was uploaded.', array('@filepath' => $file->uri)));
128
    drupal_set_message(t('File name is @filename.', array('@filename' => $file->filename)));
129
    drupal_set_message(t('File MIME type is @mimetype.', array('@mimetype' => $file->filemime)));
130
    drupal_set_message(t('You WIN!'));
131
  }
132
  elseif ($file === FALSE) {
133
    drupal_set_message(t('Epic upload FAIL!'), 'error');
134
  }
135
}
136

    
137

    
138
/**
139
 * Reset/initialize the history of calls to the file_* hooks.
140
 *
141
 * @see file_test_get_calls()
142
 * @see file_test_reset()
143
 */
144
function file_test_reset() {
145
  // Keep track of calls to these hooks
146
  $results = array(
147
    'load' => array(),
148
    'validate' => array(),
149
    'download' => array(),
150
    'insert' => array(),
151
    'update' => array(),
152
    'copy' => array(),
153
    'move' => array(),
154
    'delete' => array(),
155
  );
156
  variable_set('file_test_results', $results);
157

    
158
  // These hooks will return these values, see file_test_set_return().
159
  $return = array(
160
    'validate' => array(),
161
    'download' => NULL,
162
  );
163
  variable_set('file_test_return', $return);
164
}
165

    
166
/**
167
 * Get the arguments passed to invocation of a given hook since
168
 * file_test_reset() was last called.
169
 *
170
 * @param $op
171
 *   One of the hook_file_* operations: 'load', 'validate', 'download',
172
 *   'insert', 'update', 'copy', 'move', 'delete'.
173
 *
174
 * @return
175
 *   Array of the parameters passed to each call.
176
 *
177
 * @see _file_test_log_call()
178
 * @see file_test_reset()
179
 */
180
function file_test_get_calls($op) {
181
  $results = variable_get('file_test_results', array());
182
  return $results[$op];
183
}
184

    
185
/**
186
 * Get an array with the calls for all hooks.
187
 *
188
 * @return
189
 *   An array keyed by hook name ('load', 'validate', 'download', 'insert',
190
 *   'update', 'copy', 'move', 'delete') with values being arrays of parameters
191
 *   passed to each call.
192
 */
193
function file_test_get_all_calls() {
194
  return variable_get('file_test_results', array());
195
}
196

    
197
/**
198
 * Store the values passed to a hook invocation.
199
 *
200
 * @param $op
201
 *   One of the hook_file_* operations: 'load', 'validate', 'download',
202
 *   'insert', 'update', 'copy', 'move', 'delete'.
203
 * @param $args
204
 *   Values passed to hook.
205
 *
206
 * @see file_test_get_calls()
207
 * @see file_test_reset()
208
 */
209
function _file_test_log_call($op, $args) {
210
  $results = variable_get('file_test_results', array());
211
  $results[$op][] = $args;
212
  variable_set('file_test_results', $results);
213
}
214

    
215
/**
216
 * Load the appropriate return value.
217
 *
218
 * @param $op
219
 *   One of the hook_file_[validate,download] operations.
220
 *
221
 * @return
222
 *   Value set by file_test_set_return().
223
 *
224
 * @see file_test_set_return()
225
 * @see file_test_reset()
226
 */
227
function _file_test_get_return($op) {
228
  $return = variable_get('file_test_return', array($op => NULL));
229
  return $return[$op];
230
}
231

    
232
/**
233
 * Assign a return value for a given operation.
234
 *
235
 * @param $op
236
 *   One of the hook_file_[validate,download] operations.
237
 * @param $value
238
 *   Value for the hook to return.
239
 *
240
 * @see _file_test_get_return()
241
 * @see file_test_reset()
242
 */
243
function file_test_set_return($op, $value) {
244
  $return = variable_get('file_test_return', array());
245
  $return[$op] = $value;
246
  variable_set('file_test_return', $return);
247
}
248

    
249
/**
250
 * Implements hook_file_load().
251
 */
252
function file_test_file_load($files) {
253
  foreach ($files as $file) {
254
    _file_test_log_call('load', array($file));
255
    // Assign a value on the object so that we can test that the $file is passed
256
    // by reference.
257
    $file->file_test['loaded'] = TRUE;
258
  }
259
}
260

    
261
/**
262
 * Implements hook_file_validate().
263
 */
264
function file_test_file_validate($file) {
265
  _file_test_log_call('validate', array($file));
266
  return _file_test_get_return('validate');
267
}
268

    
269
/**
270
 * Implements hook_file_download().
271
 */
272
function file_test_file_download($uri) {
273
  _file_test_log_call('download', array($uri));
274
  return _file_test_get_return('download');
275
}
276

    
277
/**
278
 * Implements hook_file_insert().
279
 */
280
function file_test_file_insert($file) {
281
  _file_test_log_call('insert', array($file));
282
}
283

    
284
/**
285
 * Implements hook_file_update().
286
 */
287
function file_test_file_update($file) {
288
  _file_test_log_call('update', array($file));
289
}
290

    
291
/**
292
 * Implements hook_file_copy().
293
 */
294
function file_test_file_copy($file, $source) {
295
  _file_test_log_call('copy', array($file, $source));
296
}
297

    
298
/**
299
 * Implements hook_file_move().
300
 */
301
function file_test_file_move($file, $source) {
302
  _file_test_log_call('move', array($file, $source));
303
}
304

    
305
/**
306
 * Implements hook_file_delete().
307
 */
308
function file_test_file_delete($file) {
309
  _file_test_log_call('delete', array($file));
310
}
311

    
312
/**
313
 * Implements hook_file_url_alter().
314
 */
315
function file_test_file_url_alter(&$uri) {
316
  // Only run this hook when this variable is set. Otherwise, we'd have to add
317
  // another hidden test module just for this hook.
318
  $alter_mode = variable_get('file_test_hook_file_url_alter', FALSE);
319
  if (!$alter_mode) {
320
    return;
321
  }
322
  // Test alteration of file URLs to use a CDN.
323
  elseif ($alter_mode == 'cdn') {
324
    $cdn_extensions = array('css', 'js', 'gif', 'jpg', 'jpeg', 'png');
325

    
326
    // Most CDNs don't support private file transfers without a lot of hassle,
327
    // so don't support this in the common case.
328
    $schemes = array('public');
329

    
330
    $scheme = file_uri_scheme($uri);
331

    
332
    // Only serve shipped files and public created files from the CDN.
333
    if (!$scheme || in_array($scheme, $schemes)) {
334
      // Shipped files.
335
      if (!$scheme) {
336
        $path = $uri;
337
      }
338
      // Public created files.
339
      else {
340
        $wrapper = file_stream_wrapper_get_instance_by_scheme($scheme);
341
        $path = $wrapper->getDirectoryPath() . '/' . file_uri_target($uri);
342
      }
343

    
344
      // Clean up Windows paths.
345
      $path = str_replace('\\', '/', $path);
346

    
347
      // Serve files with one of the CDN extensions from CDN 1, all others from
348
      // CDN 2.
349
      $pathinfo = pathinfo($path);
350
      if (array_key_exists('extension', $pathinfo) && in_array($pathinfo['extension'], $cdn_extensions)) {
351
        $uri = FILE_URL_TEST_CDN_1 . '/' . $path;
352
      }
353
      else {
354
        $uri = FILE_URL_TEST_CDN_2 . '/' . $path;
355
      }
356
    }
357
  }
358
  // Test alteration of file URLs to use root-relative URLs.
359
  elseif ($alter_mode == 'root-relative') {
360
    // Only serve shipped files and public created files with root-relative
361
    // URLs.
362
    $scheme = file_uri_scheme($uri);
363
    if (!$scheme || $scheme == 'public') {
364
      // Shipped files.
365
      if (!$scheme) {
366
        $path = $uri;
367
      }
368
      // Public created files.
369
      else {
370
        $wrapper = file_stream_wrapper_get_instance_by_scheme($scheme);
371
        $path = $wrapper->getDirectoryPath() . '/' . file_uri_target($uri);
372
      }
373

    
374
      // Clean up Windows paths.
375
      $path = str_replace('\\', '/', $path);
376

    
377
      // Generate a root-relative URL.
378
      $uri = base_path() . '/' . $path;
379
    }
380
  }
381
  // Test alteration of file URLs to use protocol-relative URLs.
382
  elseif ($alter_mode == 'protocol-relative') {
383
    // Only serve shipped files and public created files with protocol-relative
384
    // URLs.
385
    $scheme = file_uri_scheme($uri);
386
    if (!$scheme || $scheme == 'public') {
387
      // Shipped files.
388
      if (!$scheme) {
389
        $path = $uri;
390
      }
391
      // Public created files.
392
      else {
393
        $wrapper = file_stream_wrapper_get_instance_by_scheme($scheme);
394
        $path = $wrapper->getDirectoryPath() . '/' . file_uri_target($uri);
395
      }
396

    
397
      // Clean up Windows paths.
398
      $path = str_replace('\\', '/', $path);
399

    
400
      // Generate a protocol-relative URL.
401
      $uri = '/' . base_path() . '/' . $path;
402
    }
403
  }
404
}
405

    
406
/**
407
 * Implements hook_file_mimetype_mapping_alter().
408
 */
409
function file_test_file_mimetype_mapping_alter(&$mapping) {
410
  // Add new mappings.
411
  $mapping['mimetypes']['file_test_mimetype_1'] = 'madeup/file_test_1';
412
  $mapping['mimetypes']['file_test_mimetype_2'] = 'madeup/file_test_2';
413
  $mapping['mimetypes']['file_test_mimetype_3'] = 'madeup/doc';
414
  $mapping['extensions']['file_test_1'] = 'file_test_mimetype_1';
415
  $mapping['extensions']['file_test_2'] = 'file_test_mimetype_2';
416
  $mapping['extensions']['file_test_3'] = 'file_test_mimetype_2';
417
  // Override existing mapping.
418
  $mapping['extensions']['doc'] = 'file_test_mimetype_3';
419
}
420

    
421
/**
422
 * Helper class for testing the stream wrapper registry.
423
 *
424
 * Dummy stream wrapper implementation (dummy://).
425
 */
426
class DrupalDummyStreamWrapper extends DrupalLocalStreamWrapper {
427
  function getDirectoryPath() {
428
    return variable_get('stream_public_path', 'sites/default/files');
429
  }
430

    
431
  /**
432
   * Override getInternalUri().
433
   *
434
   * Return a dummy path for testing.
435
   */
436
  function getInternalUri() {
437
    return '/dummy/example.txt';
438
  }
439

    
440
  /**
441
   * Override getExternalUrl().
442
   *
443
   * Return the HTML URI of a public file.
444
   */
445
  function getExternalUrl() {
446
    return '/dummy/example.txt';
447
  }
448
}
449

    
450
/**
451
 * Helper class for testing the stream wrapper registry.
452
 *
453
 * Dummy remote stream wrapper implementation (dummy-remote://).
454
 *
455
 * Basically just the public scheme but not returning a local file for realpath.
456
 */
457
class DrupalDummyRemoteStreamWrapper extends DrupalPublicStreamWrapper {
458
  function realpath() {
459
    return FALSE;
460
  }
461
}