Project

General

Profile

Revision 56aebcb7

Added by Assos Assos about 8 years ago

Weekly update of contrib modules

View differences:

drupal7/sites/all/modules/entityreference/entityreference.devel_generate.inc
19 19
  // Get all the entity that are referencable here.
20 20
  $referencable_entity = entityreference_get_selection_handler($field, $instance)->getReferencableEntities();
21 21
  if (is_array($referencable_entity) && !empty($referencable_entity)) {
22
    // Get a random key.
23
    foreach ($referencable_entity as $type => $eids) {
24
      $object_field['target_id'] = array_rand($eids);
22
    // $referencable_entity is keyed by bundle type.
23
    $random_bundle = array_rand($referencable_entity);
24
    if (!empty($random_bundle)) {
25
      $target_id = array_rand($referencable_entity[$random_bundle]);
26
      if (!empty($referencable_entity[$random_bundle][$target_id])) {
27
        $object_field['target_id'] = $target_id;
28
      }
25 29
    }
26 30
  }
27 31
  return $object_field;
drupal7/sites/all/modules/entityreference/entityreference.feeds.inc
125 125
          break;
126 126
        case 'label':
127 127
          $options = $handler->getReferencableEntities($value, '=');
128
          $options = reset($options);
129
          $etids = array_keys($options);
130
          // Use the first matching entity.
131
          $entity_id = reset($etids);
128
          if ($options) {
129
            $options = reset($options);
130
            $etids = array_keys($options);
131
            // Use the first matching entity.
132
            $entity_id = reset($etids);
133
          }
134
          else {
135
            $entity_id = NULL;
136
          }
132 137
          break;
133 138
      }
134 139
      /*
drupal7/sites/all/modules/entityreference/entityreference.info
1 1
name = Entity Reference
2 2
description = Provides a field that can reference other entities.
3
core = 7.x
4 3
package = Fields
4
core = 7.x
5

  
5 6
dependencies[] = entity
6 7
dependencies[] = ctools
7 8

  
9
test_dependencies[] = feeds
10
test_dependencies[] = views
11

  
8 12
; Migrate handler.
9 13
files[] = entityreference.migrate.inc
10 14

  
11
; Our plugins interfaces and abstract implementations.
15
; Plugins interfaces and abstract implementations.
12 16
files[] = plugins/selection/abstract.inc
13 17
files[] = plugins/selection/views.inc
14 18
files[] = plugins/behavior/abstract.inc
15 19

  
20
; Views integration.
16 21
files[] = views/entityreference_plugin_display.inc
17 22
files[] = views/entityreference_plugin_style.inc
18 23
files[] = views/entityreference_plugin_row_fields.inc
......
22 27
files[] = tests/entityreference.taxonomy.test
23 28
files[] = tests/entityreference.admin.test
24 29
files[] = tests/entityreference.feeds.test
30
files[] = tests/entityreference.entity_translation.test
25 31

  
26
; Information added by  packaging script on 2013-11-20
27
version = "7.x-1.1"
32
; Information added by Drupal.org packaging script on 2016-09-19
33
version = "7.x-1.2"
28 34
core = "7.x"
29 35
project = "entityreference"
30
datestamp = "1384973110"
36
datestamp = "1474306740"
31 37

  
drupal7/sites/all/modules/entityreference/entityreference.install
41 41
    }
42 42

  
43 43
    // Invoke the behaviors to allow them to change the schema.
44
    module_load_include('module', 'entityreference');
44 45
    foreach (entityreference_get_behavior_handlers($field) as $handler) {
45 46
      $handler->schema_alter($schema, $field);
46 47
    }
......
161 162
      'not null' => TRUE,
162 163
    ));
163 164
  }
164
}
165
}
drupal7/sites/all/modules/entityreference/entityreference.migrate.inc
1 1
<?php
2

  
3 2
/**
4 3
 * @file
5 4
 * Support for processing entity reference fields in Migrate.
6 5
 */
7 6

  
8 7
/**
9
 * Implement hook_migrate_api().
8
 * Implements hook_migrate_api().
10 9
 */
11 10
function entityreference_migrate_api() {
12 11
  return array(
......
15 14
  );
16 15
}
17 16

  
17
/**
18
 * Extended class for handling entityreference fields.
19
 */
18 20
class MigrateEntityReferenceFieldHandler extends MigrateSimpleFieldHandler {
21

  
22
  /**
23
   * Constructor.
24
   */
19 25
  public function __construct() {
20 26
    parent::__construct(array(
21 27
      'value_key' => 'target_id',
drupal7/sites/all/modules/entityreference/entityreference.module
220 220
  if ($ids) {
221 221
    $valid_ids = entityreference_get_selection_handler($field, $instance, $entity_type, $entity)->validateReferencableEntities(array_keys($ids));
222 222

  
223
    $invalid_entities = array_diff_key($ids, array_flip($valid_ids));
224
    if ($invalid_entities) {
225
      foreach ($invalid_entities as $id => $delta) {
226
        $errors[$field['field_name']][$langcode][$delta][] = array(
227
          'error' => 'entityreference_invalid_entity',
228
          'message' => t('The referenced entity (@type: @id) is invalid.', array('@type' => $field['settings']['target_type'], '@id' => $id)),
229
        );
223
    if (!empty($valid_ids)) {
224
      $invalid_entities = array_diff_key($ids, array_flip($valid_ids));
225
      if ($invalid_entities) {
226
        foreach ($invalid_entities as $id => $delta) {
227
          $errors[$field['field_name']][$langcode][$delta][] = array(
228
            'error' => 'entityreference_invalid_entity',
229
            'message' => t('The referenced entity (@type: @id) is invalid.', array('@type' => $field['settings']['target_type'], '@id' => $id)),
230
          );
231
        }
230 232
      }
231 233
    }
232 234
  }
......
1094 1096
      'settings' => array(
1095 1097
        'view_mode' => 'default',
1096 1098
        'links' => TRUE,
1099
        'use_content_language' => TRUE,
1097 1100
      ),
1098 1101
    ),
1099 1102
  );
......
1105 1108
function entityreference_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
1106 1109
  $display = $instance['display'][$view_mode];
1107 1110
  $settings = $display['settings'];
1111
  $element = array();
1108 1112

  
1109 1113
  if ($display['type'] == 'entityreference_label') {
1110 1114
    $element['link'] = array(
......
1136 1140
      '#title' => t('Show links'),
1137 1141
      '#default_value' => $settings['links'],
1138 1142
    );
1143

  
1144
    $element['use_content_language'] = array(
1145
      '#type' => 'checkbox',
1146
      '#title' => t('Use current content language'),
1147
      '#default_value' => $settings['use_content_language'],
1148
    );
1139 1149
  }
1140 1150

  
1141 1151
  return $element;
......
1162 1172
    }
1163 1173
    $summary[] = t('Rendered as @mode', array('@mode' => $view_mode_label));
1164 1174
    $summary[] = !empty($settings['links']) ? t('Display links') : t('Do not display links');
1175
    $summary[] = !empty($settings['use_content_language']) ? t('Use current content language') : t('Use field language');
1165 1176
  }
1166 1177

  
1167 1178
  return implode('<br />', $summary);
......
1195 1206

  
1196 1207
    foreach ($items[$id] as $delta => $item) {
1197 1208
      // Check whether the referenced entity could be loaded.
1198
      if (isset($target_entities[$item['target_id']])) {
1209
      if (isset($item['target_id']) && isset($target_entities[$item['target_id']])) {
1199 1210
        // Replace the instance value with the term data.
1200 1211
        $items[$id][$delta]['entity'] = $target_entities[$item['target_id']];
1201 1212
        // Check whether the user has access to the referenced entity.
......
1255 1266
      break;
1256 1267

  
1257 1268
    case 'entityreference_entity_view':
1269
      $target_langcode = $langcode;
1270
      if (!empty($settings['use_content_language']) && !empty($GLOBALS['language_content']->language)) {
1271
        $target_langcode = $GLOBALS['language_content']->language;
1272
      }
1273

  
1258 1274
      foreach ($items as $delta => $item) {
1259 1275
        // Protect ourselves from recursive rendering.
1260 1276
        static $depth = 0;
......
1263 1279
          throw new EntityReferenceRecursiveRenderingException(t('Recursive rendering detected when rendering entity @entity_type(@entity_id). Aborting rendering.', array('@entity_type' => $entity_type, '@entity_id' => $item['target_id'])));
1264 1280
        }
1265 1281

  
1266
        $entity = clone $item['entity'];
1267
        unset($entity->content);
1268
        $result[$delta] = entity_view($field['settings']['target_type'], array($item['target_id'] => $entity), $settings['view_mode'], $langcode, FALSE);
1282
        $target_entity = clone $item['entity'];
1283
        unset($target_entity->content);
1284
        $result[$delta] = entity_view($field['settings']['target_type'], array($item['target_id'] => $target_entity), $settings['view_mode'], $target_langcode, FALSE);
1269 1285

  
1270 1286
        if (empty($settings['links']) && isset($result[$delta][$field['settings']['target_type']][$item['target_id']]['links'])) {
1271 1287
          $result[$delta][$field['settings']['target_type']][$item['target_id']]['links']['#access'] = FALSE;
drupal7/sites/all/modules/entityreference/examples/entityreference_behavior_example/entityreference_behavior_example.info
4 4
package = Fields
5 5
dependencies[] = entityreference
6 6

  
7
; Information added by  packaging script on 2013-11-20
8
version = "7.x-1.1"
7
; Information added by Drupal.org packaging script on 2016-09-19
8
version = "7.x-1.2"
9 9
core = "7.x"
10 10
project = "entityreference"
11
datestamp = "1384973110"
11
datestamp = "1474306740"
12 12

  
drupal7/sites/all/modules/entityreference/plugins/selection/EntityReference_SelectionHandler_Generic.class.php
339 339
    // Join the known base-table.
340 340
    $target_type = $this->field['settings']['target_type'];
341 341
    $entity_info = entity_get_info($target_type);
342
    $target_type_base_table = $entity_info['base table'];
342 343
    $id = $entity_info['entity keys']['id'];
344

  
343 345
    // Return the alias of the table.
344
    return $query->innerJoin($target_type, NULL, "%alias.$id = $alias.entity_id");
346
    return $query->innerJoin($target_type_base_table, NULL, "%alias.$id = $alias.entity_id");
345 347
  }
346 348
}
347 349

  
......
543 545
      if ($vocabulary = taxonomy_vocabulary_machine_name_load($bundle)) {
544 546
        if ($terms = taxonomy_get_tree($vocabulary->vid, 0, NULL, TRUE)) {
545 547
          foreach ($terms as $term) {
546
            $options[$vocabulary->machine_name][$term->tid] = str_repeat('-', $term->depth) . check_plain($term->name);
548
            $options[$vocabulary->machine_name][$term->tid] = str_repeat('-', $term->depth) . check_plain(entity_label('taxonomy_term', $term));
547 549
          }
548 550
        }
549 551
      }
drupal7/sites/all/modules/entityreference/plugins/selection/EntityReference_SelectionHandler_Views.class.php
138 138
    if ($this->initializeView(NULL, 'CONTAINS', 0, $ids)) {
139 139
      // Get the results.
140 140
      $entities = $this->view->execute_display($display_name, $args);
141
      $result = array_keys($entities);
141
      if (!empty($entities)) {
142
        $result = array_keys($entities);
143
      }
142 144
    }
143 145
    return $result;
144 146
  }
drupal7/sites/all/modules/entityreference/tests/entityreference.admin.test
21 21
    parent::setUp(array('field_ui', 'entity', 'ctools', 'entityreference'));
22 22

  
23 23
    // Create test user.
24
    $this->admin_user = $this->drupalCreateUser(array('access content', 'administer content types'));
24
    $this->admin_user = $this->drupalCreateUser(array('access content', 'administer content types', 'administer fields'));
25 25
    $this->drupalLogin($this->admin_user);
26 26

  
27 27
    // Create content type, with underscores.
......
68 68
      'fields[_add_new_field][type]' => 'entityreference',
69 69
      'fields[_add_new_field][widget_type]' => 'entityreference_autocomplete',
70 70
    ), t('Save'));
71

  
71
    return;
72 72
    // Node should be selected by default.
73 73
    $this->assertFieldByName('field[settings][target_type]', 'node');
74 74
    // The base handler should be selected by default.
drupal7/sites/all/modules/entityreference/tests/entityreference.feeds.test
17 17
      'name' => 'Feeds integration (field mapper)',
18 18
      'description' => 'Test Feeds Mapper support for fields.',
19 19
      'group' => 'Entity Reference',
20
      'dependencies' => array('feeds'),
20 21
    );
21 22
  }
22 23

  
......
28 29
    module_enable(array('entityreference_feeds_test'), TRUE);
29 30
    $this->resetAll();
30 31

  
31
    if (!module_exists('feeds')) {
32
      return;
33
    }
34

  
35 32
    $permissions[] = 'access content';
36 33
    $permissions[] = 'administer site configuration';
37 34
    $permissions[] = 'administer content types';
......
157 154
   * Basic test loading a double entry CSV file.
158 155
   */
159 156
  public function test() {
160
    if (!module_exists('feeds')) {
161
      return;
162
    }
163

  
164 157
    $this->drupalLogin($this->admin_user);
165 158
    $this->drupalGet('admin/structure/types/manage/article/fields');
166 159
    $this->assertText('Ref - entity ID', t('Found Entity reference field %field.', array('%field' => 'field_er_id')));
drupal7/sites/all/modules/entityreference/tests/modules/entityreference_feeds_test/entityreference_feeds_test.info
8 8
dependencies[] = feeds_ui
9 9
dependencies[] = entityreference
10 10

  
11
; Information added by  packaging script on 2013-11-20
12
version = "7.x-1.1"
11
; Information added by Drupal.org packaging script on 2016-09-19
12
version = "7.x-1.2"
13 13
core = "7.x"
14 14
project = "entityreference"
15
datestamp = "1384973110"
15
datestamp = "1474306740"
16 16

  
drupal7/sites/all/modules/views_data_export/plugins/views_data_export_plugin_display_export.inc
238 238
    }
239 239

  
240 240
    // Try and get a batch context if possible.
241
    $eid = !empty($_GET['eid']) ? $_GET['eid'] :
242
            (!empty($this->batched_execution_state->eid) ? $this->batched_execution_state->eid : FALSE);
241

  
242
    if (!empty($_GET['eid']) && !empty($_GET['token']) && drupal_valid_token($_GET['token'], 'views_data_export/' . $_GET['eid'])) {
243
      $eid = $_GET['eid'];
244
    }
245
    elseif (!empty($this->batched_execution_state->eid)) {
246
      $eid = $this->batched_execution_state->eid;
247
    }
248
    else {
249
      $eid = FALSE;
250
    }
251

  
243 252
    if ($eid) {
244 253
      $this->batched_execution_state = views_data_export_get($eid);
245 254
    }
......
293 302
    $this->batched_execution_state = views_data_export_new($this->view->name, $this->view->current_display, $this->outputfile_create());
294 303
    views_data_export_view_store($this->batched_execution_state->eid, $this->view);
295 304

  
305
    // Record a usage of our file, so we can identify our exports later.
306
    file_usage_add(file_load($this->batched_execution_state->fid), 'views_data_export', 'eid', $this->batched_execution_state->eid);
307

  
296 308
    // We need to build the index right now, before we lose $_GET etc.
297 309
    $this->initialize_index();
298 310
    //$this->batched_execution_state->fid = $this->outputfile_create();
299 311

  
300
    // Initialize the progress counter
301
    $this->batched_execution_state->sandbox['max'] = db_query('SELECT COUNT(*) FROM {' . $this->index_tablename() . '}')->fetchField();
312
    // Initialize the progress counter.
313
    if (db_table_exists($this->index_tablename())) {
314
      $this->batched_execution_state->sandbox['max'] = db_query('SELECT COUNT(*) FROM {' . $this->index_tablename() . '}')->fetchField();
315
    }
316

  
302 317
    // Record the time we started.
303 318
    list($usec, $sec) = explode(' ', microtime());
304 319
    $this->batched_execution_state->sandbox['started'] = (float) $usec + (float) $sec;
305 320

  
321
    // Pop something into the session to ensure it stays aorund.
322
    $_SESSION['views_data_export'][$this->batched_execution_state->eid] = TRUE;
323

  
306 324
    // Build up our querystring for the final page callback.
307 325
    $querystring = array(
308 326
      'eid' => $this->batched_execution_state->eid,
327
      'token' => drupal_get_token('views_data_export/' . $this->batched_execution_state->eid),
309 328
      'return-url' => NULL,
310 329
    );
311 330

  
......
401 420
        break;
402 421

  
403 422
      case VIEWS_DATA_EXPORT_FOOTER:
423
        // Update the temporary file size, otherwise we would get a problematic
424
        // "Content-Length: 0" HTTP header, that may break the export download.
425
        $this->outputfile_update_size();
404 426
        $sandbox['finished'] = 1;
405 427
        $state->batch_state = VIEWS_DATA_EXPORT_FINISHED;
406 428
        break;
......
418 440
  function execute_final() {
419 441
    // Should we download the file.
420 442
    if (!empty($_GET['download'])) {
443
      // Clean up our session, if we need to.
444
      if (isset($_SESSION)) {
445
        unset($_SESSION['views_data_export'][$this->batched_execution_state->eid]);
446
        if (empty($_SESSION['views_data_export'])) {
447
          unset($_SESSION['views_data_export']);
448
        }
449
      }
421 450
      // This next method will exit.
422 451
      $this->transfer_file();
423 452
    }
......
526 555
    $query = array(
527 556
      'download' => 1,
528 557
      'eid' => $this->batched_execution_state->eid,
558
      'token' => drupal_get_token('views_data_export/' . $this->batched_execution_state->eid),
529 559
    );
530 560

  
531 561
    return theme('views_data_export_complete_page', array(
......
573 603
    }
574 604
    // Set the headers.
575 605
    $this->add_http_headers();
576
    file_transfer($this->outputfile_path(), array());
606
    $headers = array(
607
      'Content-Length' => $this->outputfile_entity()->filesize,
608
    );
609
    file_transfer($this->outputfile_path(), $headers);
577 610
  }
578 611

  
579 612
  /**
......
666 699
  }
667 700

  
668 701
  /**
669
   * Get the output file path.
702
   * Get the output file entity.
670 703
   */
671
  function outputfile_path() {
704
  public function outputfile_entity() {
672 705
    if (empty($this->_output_file)) {
673 706
      if (!empty($this->batched_execution_state->fid)) {
674 707
        // Return the filename associated with this file.
......
678 711
        return NULL;
679 712
      }
680 713
    }
681
    return $this->_output_file->uri;
714
    return $this->_output_file;
715
  }
716

  
717
  /**
718
   * Get the output file path.
719
   */
720
  public function outputfile_path() {
721
    if ($file = $this->outputfile_entity()) {
722
      return $file->uri;
723
    }
682 724
  }
683 725

  
684 726
  /**
......
700 742
    // Save the file into the DB.
701 743
    $file = $this->file_save_file($path);
702 744

  
745
    // Make sure the file is marked as temporary.
746
    // There is no FILE_STATUS_TEMPORARY constant.
747
    $file->status = 0;
748
    file_save($file);
749

  
703 750
    return $file->fid;
704 751
  }
705 752

  
......
713 760
    }
714 761
  }
715 762

  
763
  /**
764
   * Updates the file size in the file entity.
765
   */
766
  protected function outputfile_update_size() {
767
    if ($file = $this->outputfile_entity()) {
768
      $file->filesize = filesize($file->uri);
769
      file_save($file);
770
    }
771
  }
772

  
716 773
  function abort_export($errors) {
717 774
    // Just cause the next batch to do the clean-up
718 775
    if (!is_array($errors)) {
drupal7/sites/all/modules/views_data_export/tests/access.test
1
<?php
2

  
3
/**
4
 * Test class for access checks for VDE downloads.
5
 *
6
 * Views Data Export enforces that a previously exported file may only be
7
 * re-downloaded by the user that created the export. We test for that with
8
 * this class.
9
 */
10
class ViewsDataExportAccessTest extends ViewsDataExportBaseTest {
11

  
12
  protected $profile = 'testing';
13

  
14
  public static function getInfo() {
15
    return array(
16
      'name' => 'Access to temp files',
17
      'description' => 'Check access to created export files.',
18
      'group' => 'Views Data Export',
19
    );
20
  }
21

  
22
  /**
23
   * Test that VDE export can only be downloaded by the user that created them.
24
   */
25
  public function testExportedTempFileAccess() {
26
    $this->admin_user1 = $this->drupalCreateUser();
27
    $this->admin_user2 = $this->drupalCreateUser();
28

  
29
    // Run a batched export.
30
    $path = 'vde_test/' . $this->randomName();
31
    list($view, $expected) = $this->getExportView($path);
32
    $display = &$view->display['vde_test']->handler;
33
    // Set this view to be batched.
34
    $display->override_option('use_batch', 'batch');
35
    // Save this view so we can hit the path.
36
    $view->save();
37
    // Ensure that the menu router system is rebuilt on the next page load.
38
    variable_set('menu_rebuild_needed', TRUE);
39

  
40
    $this->drupalLogin($this->admin_user1);
41
    // Catpure the session_id as the redirects in the request ditch it.
42
    $session_id = $this->session_id;
43
    $this->assertBatchedExportEqual($path, $expected, 'Batched access export matched expected output.');
44

  
45
    // Remove all the test data, so future exports will be different.
46
    db_truncate('views_test')->execute();
47
    $this->resetAll();
48

  
49
    // Assert that we can re-download directly when supplying the token.
50
    // We rely on this being the first export in this test class.
51
    // Restore the session_id from above so we can use drupalGetToken.
52
    $this->session_id = $session_id;
53
    $token = $this->drupalGetToken('views_data_export/1');
54
    $this->drupalGet($path, array('query' => array('eid' => 1, 'download' => 1, 'token' => $token)));
55
    $output = $this->drupalGetContent();
56
    $this->assertEqual($this->normaliseString($output), $expected, 'Re-download of export file by original user is possible with session token.');
57

  
58
    // Assert that we cannot re-download directly without supplying the token.
59
    // We rely on this being the first export in this test class.
60
    $this->drupalGet($path, array('query' => array('eid' => 1, 'download' => 1)));
61
    $output = $this->drupalGetContent();
62
    $this->assertEqual($this->normaliseString($output), '', 'Re-download of export file by original user is not possible.');
63

  
64
    // Assert that someone else can't download our file.
65
    // We rely on this being the first export in this test class.
66
    $this->drupalLogin($this->admin_user2);
67
    $this->drupalGet($path, array('query' => array('eid' => 1, 'download' => 1, 'token' => $token)));
68
    $output = $this->drupalGetContent();
69
    $this->assertEqual($this->normaliseString($output), '', 'Re-download of export file by different user is not possible.');
70
  }
71

  
72
  /**
73
   * Overrides DrupalWebTestCase::drupalGetToken() to support the hash salt.
74
   *
75
   * @todo Remove when http://drupal.org/node/1555862 is fixed in core.
76
   */
77
  protected function drupalGetToken($value = '') {
78
    $private_key = drupal_get_private_key();
79
    return drupal_hmac_base64($value, $this->session_id . $private_key . drupal_get_hash_salt());
80
  }
81

  
82
  /**
83
   * Build and return a basic view of the views_test table.
84
   *
85
   * @return view
86
   */
87
  protected function getBasicExportView() {
88
    views_include('view');
89

  
90
    // Create the basic view.
91
    $view = new view();
92
    $view->vid = 'new';
93
    $view->base_table = 'views_test';
94

  
95
    // Set up the fields we need.
96
    $display = $view->new_display('default', 'Master', 'default');
97

  
98
    $display->override_option('fields', array(
99
      'id' => array(
100
        'id' => 'id',
101
        'table' => 'views_test',
102
        'field' => 'id',
103
        'relationship' => 'none',
104
      ),
105
      'name' => array(
106
        'id' => 'name',
107
        'table' => 'views_test',
108
        'field' => 'name',
109
        'relationship' => 'none',
110
      ),
111
      'age' => array(
112
        'id' => 'age',
113
        'table' => 'views_test',
114
        'field' => 'age',
115
        'relationship' => 'none',
116
      ),
117
    ));
118

  
119
    // Set up the sort order.
120
    $display->override_option('sorts', array(
121
      'id' => array(
122
        'order' => 'ASC',
123
        'id' => 'id',
124
        'table' => 'views_test',
125
        'field' => 'id',
126
        'relationship' => 'none',
127
      ),
128
    ));
129

  
130
    // Set up the pager.
131
    $display->override_option('pager', array(
132
      'type' => 'none',
133
      'options' => array('offset' => 0),
134
    ));
135

  
136
    return $view;
137
  }
138

  
139
  protected function getStylePluginName() {
140
    return 'views_data_export_txt';
141
  }
142

  
143
  protected function getExportView($path = 'vde_test') {
144
    // Create the basic view.
145
    $view = $this->getBasicExportView();
146

  
147
    $display = $view->new_display('views_data_export', 'Data export', 'vde_test');
148
    $display->override_option('style_plugin', $this->getStylePluginName());
149
    $display->override_option('path', $path);
150

  
151
    $expected = '[ID]
152

  
153
1
154
[Name]
155

  
156
John
157
[Age]
158

  
159
25
160
----------------------------------------
161

  
162
[ID]
163

  
164
2
165
[Name]
166

  
167
George
168
[Age]
169

  
170
27
171
----------------------------------------
172

  
173
[ID]
174

  
175
3
176
[Name]
177

  
178
Ringo
179
[Age]
180

  
181
28
182
----------------------------------------
183

  
184
[ID]
185

  
186
4
187
[Name]
188

  
189
Paul
190
[Age]
191

  
192
26
193
----------------------------------------
194

  
195
[ID]
196

  
197
5
198
[Name]
199

  
200
Meredith
201
[Age]
202

  
203
30
204
----------------------------------------';
205

  
206
    return array(&$view, $expected);
207
  }
208
}
drupal7/sites/all/modules/views_data_export/tests/garbagecollection.test
1
<?php
2

  
3
/**
4
 * Test class for garbage collection of VDE export data.
5
 */
6
class ViewsDataExportGarbageCollectionTest extends ViewsDataExportBaseTest {
7

  
8
  protected $profile = 'testing';
9

  
10
  public static function getInfo() {
11
    return array(
12
      'name' => 'Garbage collection',
13
      'description' => 'Checks garbage collection of batched exports',
14
      'group' => 'Views Data Export',
15
    );
16
  }
17

  
18
  /**
19
   * Test that VDE export can only be downloaded by the user that created them.
20
   */
21
  public function testExportedGarbageCollection() {
22
    // Run a batched export.
23
    $path = 'vde_test/' . $this->randomName();
24
    list($view, $expected) = $this->getExportView($path);
25
    $display = &$view->display['vde_test']->handler;
26
    // Set this view to be batched.
27
    $display->override_option('use_batch', 'batch');
28
    // Save this view so we can hit the path.
29
    $view->save();
30
    // Ensure that the menu router system is rebuilt on the next page load.
31
    variable_set('menu_rebuild_needed', TRUE);
32
    $exports = $this->getNumberOfStoredExports();
33
    $files = $this->getNumberOfFiles();
34
    $this->assertBatchedExportEqual($path, $expected, 'Batched access export matched expected output.');
35
    // We should have created a new export and file.
36
    $this->assertEqual($this->getNumberOfStoredExports(), $exports + 1, 'A single new batched export was created');
37
    $this->assertEqual($this->getNumberOfFiles(), $files + 1, 'A single new temporary file was created');
38

  
39
    $middle_timestamp = time();
40
    sleep(1);
41
    $this->assertBatchedExportEqual($path, $expected, 'Batched access export matched expected output.');
42
    // We should have created a new export and file.
43
    $this->assertEqual($this->getNumberOfStoredExports(), $exports + 2, 'A single new batched export was created');
44
    $this->assertEqual($this->getNumberOfFiles(), $files + 2, 'A single new temporary file was created');
45

  
46
    // Garbage collect the first export only.
47
    views_data_export_garbage_collect(REQUEST_TIME - $middle_timestamp);
48
    $this->assertEqual($this->getNumberOfStoredExports(), $exports + 1, 'Garbage collection removed 1 old export');
49
    $this->assertEqual($this->getNumberOfFiles(), $files + 1, 'Garbage collection removed 1 old temporary file');
50
  }
51

  
52
  protected function getNumberOfStoredExports() {
53
    return (int) db_select('views_data_export')->countQuery()->execute()->fetchField();
54
  }
55

  
56
  protected function getNumberOfFiles() {
57
    return (int) db_select('file_managed')->countQuery()->execute()->fetchField();
58
  }
59

  
60

  
61
  /**
62
   * Build and return a basic view of the views_test table.
63
   *
64
   * @return view
65
   */
66
  protected function getBasicExportView() {
67
    views_include('view');
68

  
69
    // Create the basic view.
70
    $view = new view();
71
    $view->vid = 'new';
72
    $view->base_table = 'views_test';
73

  
74
    // Set up the fields we need.
75
    $display = $view->new_display('default', 'Master', 'default');
76

  
77
    $display->override_option('fields', array(
78
      'id' => array(
79
        'id' => 'id',
80
        'table' => 'views_test',
81
        'field' => 'id',
82
        'relationship' => 'none',
83
      ),
84
      'name' => array(
85
        'id' => 'name',
86
        'table' => 'views_test',
87
        'field' => 'name',
88
        'relationship' => 'none',
89
      ),
90
      'age' => array(
91
        'id' => 'age',
92
        'table' => 'views_test',
93
        'field' => 'age',
94
        'relationship' => 'none',
95
      ),
96
    ));
97

  
98
    // Set up the sort order.
99
    $display->override_option('sorts', array(
100
      'id' => array(
101
        'order' => 'ASC',
102
        'id' => 'id',
103
        'table' => 'views_test',
104
        'field' => 'id',
105
        'relationship' => 'none',
106
      ),
107
    ));
108

  
109
    // Set up the pager.
110
    $display->override_option('pager', array(
111
      'type' => 'none',
112
      'options' => array('offset' => 0),
113
    ));
114

  
115
    return $view;
116
  }
117

  
118
  protected function getStylePluginName() {
119
    return 'views_data_export_txt';
120
  }
121

  
122
  protected function getExportView($path = 'vde_test') {
123
    // Create the basic view.
124
    $view = $this->getBasicExportView();
125

  
126
    $display = $view->new_display('views_data_export', 'Data export', 'vde_test');
127
    $display->override_option('style_plugin', $this->getStylePluginName());
128
    $display->override_option('path', $path);
129

  
130
    $expected = '[ID]
131

  
132
1
133
[Name]
134

  
135
John
136
[Age]
137

  
138
25
139
----------------------------------------
140

  
141
[ID]
142

  
143
2
144
[Name]
145

  
146
George
147
[Age]
148

  
149
27
150
----------------------------------------
151

  
152
[ID]
153

  
154
3
155
[Name]
156

  
157
Ringo
158
[Age]
159

  
160
28
161
----------------------------------------
162

  
163
[ID]
164

  
165
4
166
[Name]
167

  
168
Paul
169
[Age]
170

  
171
26
172
----------------------------------------
173

  
174
[ID]
175

  
176
5
177
[Name]
178

  
179
Meredith
180
[Age]
181

  
182
30
183
----------------------------------------';
184

  
185
    return array(&$view, $expected);
186
  }
187
}
drupal7/sites/all/modules/views_data_export/theme/views_data_export.theme.inc
259 259
  _views_data_export_body_shared_preprocess($vars);
260 260
}
261 261

  
262
/**
263
 * Implements hook_preprocess_views_data_export_doc_body().
264
 */
262 265
function template_preprocess_views_data_export_doc_body(&$vars) {
263 266
  // Pass through the generic MS Office preprocess.
264 267
  template_preprocess_views_data_export_msoffice_body($vars);
265 268
}
266 269

  
270
/**
271
 * Implements hook_preprocess_views_data_export_xls_body().
272
 */
267 273
function template_preprocess_views_data_export_xls_body(&$vars) {
268 274
  // Pass through the generic MS Office preprocess.
269 275
  template_preprocess_views_data_export_msoffice_body($vars);
......
272 278
function template_preprocess_views_data_export_msoffice_body(&$vars) {
273 279
  _views_data_export_header_shared_preprocess($vars);
274 280
  _views_data_export_body_shared_preprocess($vars);
281
}
282

  
283
/**
284
 * Implements hook_process_views_data_export_doc_body().
285
 */
286
function template_process_views_data_export_doc_body(&$vars) {
287
  // Pass through the generic MS Office process.
288
  template_process_views_data_export_msoffice_body($vars);
289
}
290

  
291
/**
292
 * Implements hook_process_views_data_export_xls_body().
293
 */
294
function template_process_views_data_export_xls_body(&$vars) {
295
  // Pass through the generic MS Office process.
296
  template_process_views_data_export_msoffice_body($vars);
297
}
298

  
299
function template_process_views_data_export_msoffice_body(&$vars) {
275 300

  
276 301
  $output = '';
277 302

  
drupal7/sites/all/modules/views_data_export/views_data_export.drush.inc
17 17
      'output_file' => 'The file to write the results to - will be overwritten if it already exists',
18 18
    ),
19 19
    'options' => array (
20
      '--arguments' => 'Comma separated list of arguments to be passed to the view.',
21
      '--format' => 'csv,doc,txt,xls or xml. These options are ignored if the display_id passed is a "views_data_export" display.',
22
      '--separator' => 'csv only: What character separates the fields (default:,)',
23
      '--trim-whitespace' => 'csv only: Trim whitespace from either side of fields (default:1)',
24
      '--header-row' => 'csv only: Make the first row a row of headers (default:1)',
25
      '--quote-values' => 'csv only: Surround each field in quotes (default:1)',
20
      'arguments' => 'Comma separated list of arguments to be passed to the view.',
21
      'format' => 'csv,doc,txt,xls or xml. These options are ignored if the display_id passed is a "views_data_export" display.',
22
      'separator' => 'csv only: What character separates the fields (default:,)',
23
      'trim-whitespace' => 'csv only: Trim whitespace from either side of fields (default:1)',
24
      'header-row' => 'csv only: Make the first row a row of headers (default:1)',
25
      'quote-values' => 'csv only: Surround each field in quotes (default:1)',
26 26
    ),
27 27
    'examples' => array (
28 28
      'drush views-data-export myviewname views_data_export_1 output.csv' => 'Export myviewname:views_data_export_1 and write the output to output.csv in the current directory',
......
168 168
    $options['output_file'] = realpath(drush_get_context('DRUSH_OLDCWD', getcwd())) . '/' . $output_file;
169 169
  }
170 170

  
171
  $arguments = drush_get_option('arguments', '');
172
  $arguments = explode(',', $arguments);
171 173

  
172 174
  if ($view->display_handler->is_batched()) {
173 175
    // This is a batched export, and needs to be handled as such.
174 176
    _drush_views_data_export_override_batch($view_name, $display_id, $options);
175 177

  
176
    $arguments = drush_get_option('arguments', '');
177
    $arguments = explode(',', $arguments);
178 178
    $view->execute_display($display_id, $arguments);
179 179
  }
180 180
  else {
181 181
    // This export isn't batched.
182 182
    ob_start();
183
    $view->execute_display($display_id);
183
    $view->execute_display($display_id, $arguments);
184 184
    // Get the results, and clean the output buffer.
185 185
    $result = ob_get_contents();
186 186
    // Clean the buffer.
drupal7/sites/all/modules/views_data_export/views_data_export.info
14 14

  
15 15
; Tests
16 16
files[] = "tests/base.test"
17
files[] = "tests/access.test"
18
files[] = "tests/garbagecollection.test"
17 19
files[] = "tests/csv_export.test"
18 20
files[] = "tests/doc_export.test"
19 21
files[] = "tests/txt_export.test"
20 22
files[] = "tests/xls_export.test"
21 23
files[] = "tests/xml_export.test"
22 24

  
23
; Information added by Drupal.org packaging script on 2015-10-26
24
version = "7.x-3.0-beta9"
25
; Information added by Drupal.org packaging script on 2016-09-20
26
version = "7.x-3.1"
25 27
core = "7.x"
26 28
project = "views_data_export"
27
datestamp = "1445842742"
29
datestamp = "1474360174"
28 30

  
drupal7/sites/all/modules/views_data_export/views_data_export.module
30 30
  );
31 31
}
32 32

  
33
/**
34
/**
35
 * Checks whether the passed URI identifies an export file.
36
 *
37
 * @param string $uri
38
 *   A file URI.
39
 *
40
 * @return bool
41
 *   TRUE if the URI identifies an export file, FALSE otherwise.
42
 */
43
function views_data_export_is_export_file($uri) {
44
  foreach (entity_load('file', FALSE, array('uri' => $uri)) as $file) {
45
    // See if this is an export file.
46
    $usages = file_usage_list($file);
47
    return !empty($usages['views_data_export']['eid']);
48
  }
49
  return FALSE;
50
}
51

  
33 52
/**
34 53
 * Implementation of hook_theme().
35 54
 */
......
114 133
    }
115 134

  
116 135
    // We do two things to exports we want to garbage collect
117
    // 1. Delete the index table for it, if it is still around
118
    // 2. Delete the row from the exports table
119
    // 3. Delete the view from the object_cache
136
    // 1. Delete the index table for it, if it is still around.
137
    // 2. Delete the files used during the export.
138
    // 3. Delete the row from the exports table.
139
    // 4. Delete the view from the object_cache.
120 140
    if (count($eids_to_clear)) {
121 141
      foreach ($eids_to_clear as $eid) {
122 142
        // 1. Delete index table, if it is still around for some reason
......
124 144
        if (db_table_exists($table)) {
125 145
          db_drop_table($table);
126 146
        }
147

  
148
        // 2. Delete the files used during the export.
149
        foreach (views_data_export_export_list_files($eid) as $file) {
150
          file_delete($file, TRUE);
151
        }
127 152
      }
128 153

  
129
      // 2. Delete the entries in the exports table.
154
      // 3. Delete the entries in the exports table.
130 155
      db_delete('views_data_export')
131 156
        ->condition('eid', $eids_to_clear, 'IN')
132 157
        ->execute();
133 158

  
134
      // 3. Clear the cached views
159
      // 4. Clear the cached views
135 160
      views_data_export_view_clear($eids_to_clear);
136 161
    }
137 162

  
......
139 164
  }
140 165
}
141 166

  
167
/**
168
 * Determines where a file is used.
169
 *
170
 * @param $eid
171
 *   The ID of a Views Data Export.
172
 *
173
 * @return array
174
 *   An array of loaded files objects used by the specified export.
175
 */
176
function views_data_export_export_list_files($eid) {
177
  $result = db_select('file_usage', 'f')
178
    ->fields('f', array('fid'))
179
    ->condition('id', $eid)
180
    ->condition('type', 'eid')
181
    ->condition('module', 'views_data_export')
182
    ->execute();
183
  return file_load_multiple($result->fetchCol());
184
}
185

  
142 186

  
143 187
/**
144 188
 * Batch API callback.
......
268 312
    ->condition('eid', $export_id)
269 313
    ->execute();
270 314
}
271

  
272
/**
273
 * Implements hook_file_presave().
274
 */
275
function views_data_export_file_presave($file) {
276
  // Ensure temporary files really are temporary.
277
  // @see: https://drupal.org/node/2198399
278
  if (strpos($file->filename, 'views_data_export') === 0) {
279
    // There is no FILE_STATUS_TEMPORARY.
280
    $file->status = 0;
281
  }
282
}

Also available in: Unified diff