Projet

Général

Profil

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

root / drupal7 / modules / simpletest / tests / file_test.module @ cee0424c

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' => 'radios',
80
    '#options' => array(
81
      'false' => 'No',
82
      'empty_array' => 'Empty array',
83
      'empty_string' => 'Empty string',
84
    ),
85
    '#default_value' => 'false',
86
  );
87

    
88
  $form['is_image_file'] = array(
89
    '#type' => 'checkbox',
90
    '#title' => t('Is this an image file?'),
91
    '#default_value' => TRUE,
92
  );
93

    
94
  $form['submit'] = array(
95
    '#type' => 'submit',
96
    '#value' => t('Submit'),
97
  );
98
  return $form;
99
}
100

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

    
115
  // Setup validators.
116
  $validators = array();
117
  if ($form_state['values']['is_image_file']) {
118
    $validators['file_validate_is_image'] = array();
119
  }
120

    
121
  $allow = $form_state['values']['allow_all_extensions'];
122
  if ($allow === 'empty_array') {
123
    $validators['file_validate_extensions'] = array();
124
  }
125
  elseif ($allow === 'empty_string') {
126
    $validators['file_validate_extensions'] = array('');
127
  }
128
  elseif (!empty($form_state['values']['extensions'])) {
129
    $validators['file_validate_extensions'] = array($form_state['values']['extensions']);
130
  }
131

    
132
  $file = file_save_upload('file_test_upload', $validators, $destination, $form_state['values']['file_test_replace']);
133
  if ($file) {
134
    $form_state['values']['file_test_upload'] = $file;
135
    drupal_set_message(t('File @filepath was uploaded.', array('@filepath' => $file->uri)));
136
    drupal_set_message(t('File name is @filename.', array('@filename' => $file->filename)));
137
    drupal_set_message(t('File MIME type is @mimetype.', array('@mimetype' => $file->filemime)));
138
    drupal_set_message(t('You WIN!'));
139
  }
140
  elseif ($file === FALSE) {
141
    drupal_set_message(t('Epic upload FAIL!'), 'error');
142
  }
143
}
144

    
145

    
146
/**
147
 * Reset/initialize the history of calls to the file_* hooks.
148
 *
149
 * @see file_test_get_calls()
150
 * @see file_test_reset()
151
 */
152
function file_test_reset() {
153
  // Keep track of calls to these hooks
154
  $results = array(
155
    'load' => array(),
156
    'validate' => array(),
157
    'download' => array(),
158
    'insert' => array(),
159
    'update' => array(),
160
    'copy' => array(),
161
    'move' => array(),
162
    'delete' => array(),
163
  );
164
  variable_set('file_test_results', $results);
165

    
166
  // These hooks will return these values, see file_test_set_return().
167
  $return = array(
168
    'validate' => array(),
169
    'download' => NULL,
170
  );
171
  variable_set('file_test_return', $return);
172
}
173

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

    
193
/**
194
 * Get an array with the calls for all hooks.
195
 *
196
 * @return
197
 *   An array keyed by hook name ('load', 'validate', 'download', 'insert',
198
 *   'update', 'copy', 'move', 'delete') with values being arrays of parameters
199
 *   passed to each call.
200
 */
201
function file_test_get_all_calls() {
202
  return variable_get('file_test_results', array());
203
}
204

    
205
/**
206
 * Store the values passed to a hook invocation.
207
 *
208
 * @param $op
209
 *   One of the hook_file_* operations: 'load', 'validate', 'download',
210
 *   'insert', 'update', 'copy', 'move', 'delete'.
211
 * @param $args
212
 *   Values passed to hook.
213
 *
214
 * @see file_test_get_calls()
215
 * @see file_test_reset()
216
 */
217
function _file_test_log_call($op, $args) {
218
  $results = variable_get('file_test_results', array());
219
  $results[$op][] = $args;
220
  variable_set('file_test_results', $results);
221
}
222

    
223
/**
224
 * Load the appropriate return value.
225
 *
226
 * @param $op
227
 *   One of the hook_file_[validate,download] operations.
228
 *
229
 * @return
230
 *   Value set by file_test_set_return().
231
 *
232
 * @see file_test_set_return()
233
 * @see file_test_reset()
234
 */
235
function _file_test_get_return($op) {
236
  $return = variable_get('file_test_return', array($op => NULL));
237
  return $return[$op];
238
}
239

    
240
/**
241
 * Assign a return value for a given operation.
242
 *
243
 * @param $op
244
 *   One of the hook_file_[validate,download] operations.
245
 * @param $value
246
 *   Value for the hook to return.
247
 *
248
 * @see _file_test_get_return()
249
 * @see file_test_reset()
250
 */
251
function file_test_set_return($op, $value) {
252
  $return = variable_get('file_test_return', array());
253
  $return[$op] = $value;
254
  variable_set('file_test_return', $return);
255
}
256

    
257
/**
258
 * Implements hook_file_load().
259
 */
260
function file_test_file_load($files) {
261
  foreach ($files as $file) {
262
    _file_test_log_call('load', array($file));
263
    // Assign a value on the object so that we can test that the $file is passed
264
    // by reference.
265
    $file->file_test['loaded'] = TRUE;
266
  }
267
}
268

    
269
/**
270
 * Implements hook_file_validate().
271
 */
272
function file_test_file_validate($file) {
273
  _file_test_log_call('validate', array($file));
274
  return _file_test_get_return('validate');
275
}
276

    
277
/**
278
 * Implements hook_file_download().
279
 */
280
function file_test_file_download($uri) {
281
  _file_test_log_call('download', array($uri));
282
  return _file_test_get_return('download');
283
}
284

    
285
/**
286
 * Implements hook_file_insert().
287
 */
288
function file_test_file_insert($file) {
289
  _file_test_log_call('insert', array($file));
290
}
291

    
292
/**
293
 * Implements hook_file_update().
294
 */
295
function file_test_file_update($file) {
296
  _file_test_log_call('update', array($file));
297
}
298

    
299
/**
300
 * Implements hook_file_copy().
301
 */
302
function file_test_file_copy($file, $source) {
303
  _file_test_log_call('copy', array($file, $source));
304
}
305

    
306
/**
307
 * Implements hook_file_move().
308
 */
309
function file_test_file_move($file, $source) {
310
  _file_test_log_call('move', array($file, $source));
311
}
312

    
313
/**
314
 * Implements hook_file_delete().
315
 */
316
function file_test_file_delete($file) {
317
  _file_test_log_call('delete', array($file));
318
}
319

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

    
334
    // Most CDNs don't support private file transfers without a lot of hassle,
335
    // so don't support this in the common case.
336
    $schemes = array('public');
337

    
338
    $scheme = file_uri_scheme($uri);
339

    
340
    // Only serve shipped files and public created files from the CDN.
341
    if (!$scheme || in_array($scheme, $schemes)) {
342
      // Shipped files.
343
      if (!$scheme) {
344
        $path = $uri;
345
      }
346
      // Public created files.
347
      else {
348
        $wrapper = file_stream_wrapper_get_instance_by_scheme($scheme);
349
        $path = $wrapper->getDirectoryPath() . '/' . file_uri_target($uri);
350
      }
351

    
352
      // Clean up Windows paths.
353
      $path = str_replace('\\', '/', $path);
354

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

    
382
      // Clean up Windows paths.
383
      $path = str_replace('\\', '/', $path);
384

    
385
      // Generate a root-relative URL.
386
      $uri = base_path() . '/' . $path;
387
    }
388
  }
389
  // Test alteration of file URLs to use protocol-relative URLs.
390
  elseif ($alter_mode == 'protocol-relative') {
391
    // Only serve shipped files and public created files with protocol-relative
392
    // URLs.
393
    $scheme = file_uri_scheme($uri);
394
    if (!$scheme || $scheme == 'public') {
395
      // Shipped files.
396
      if (!$scheme) {
397
        $path = $uri;
398
      }
399
      // Public created files.
400
      else {
401
        $wrapper = file_stream_wrapper_get_instance_by_scheme($scheme);
402
        $path = $wrapper->getDirectoryPath() . '/' . file_uri_target($uri);
403
      }
404

    
405
      // Clean up Windows paths.
406
      $path = str_replace('\\', '/', $path);
407

    
408
      // Generate a protocol-relative URL.
409
      $uri = '/' . base_path() . '/' . $path;
410
    }
411
  }
412
}
413

    
414
/**
415
 * Implements hook_file_mimetype_mapping_alter().
416
 */
417
function file_test_file_mimetype_mapping_alter(&$mapping) {
418
  // Add new mappings.
419
  $mapping['mimetypes']['file_test_mimetype_1'] = 'madeup/file_test_1';
420
  $mapping['mimetypes']['file_test_mimetype_2'] = 'madeup/file_test_2';
421
  $mapping['mimetypes']['file_test_mimetype_3'] = 'madeup/doc';
422
  $mapping['extensions']['file_test_1'] = 'file_test_mimetype_1';
423
  $mapping['extensions']['file_test_2'] = 'file_test_mimetype_2';
424
  $mapping['extensions']['file_test_3'] = 'file_test_mimetype_2';
425
  // Override existing mapping.
426
  $mapping['extensions']['doc'] = 'file_test_mimetype_3';
427
}
428

    
429
/**
430
 * Helper class for testing the stream wrapper registry.
431
 *
432
 * Dummy stream wrapper implementation (dummy://).
433
 */
434
class DrupalDummyStreamWrapper extends DrupalLocalStreamWrapper {
435
  function getDirectoryPath() {
436
    return variable_get('stream_public_path', 'sites/default/files');
437
  }
438

    
439
  /**
440
   * Override getInternalUri().
441
   *
442
   * Return a dummy path for testing.
443
   */
444
  function getInternalUri() {
445
    return '/dummy/example.txt';
446
  }
447

    
448
  /**
449
   * Override getExternalUrl().
450
   *
451
   * Return the HTML URI of a public file.
452
   */
453
  function getExternalUrl() {
454
    return '/dummy/example.txt';
455
  }
456
}
457

    
458
/**
459
 * Helper class for testing the stream wrapper registry.
460
 *
461
 * Dummy remote stream wrapper implementation (dummy-remote://).
462
 *
463
 * Basically just the public scheme but not returning a local file for realpath.
464
 */
465
class DrupalDummyRemoteStreamWrapper extends DrupalPublicStreamWrapper {
466
  function realpath() {
467
    return FALSE;
468
  }
469
}