Project

General

Profile

Paste
Download (8.56 KB) Statistics
| Branch: | Revision:

root / drupal7 / sites / all / modules / views_data_export / views_data_export.module @ 56aebcb7

1
<?php
2

    
3
/**
4
 * @file
5
 * Provides the ability to export to specific
6
 */
7

    
8
define('VIEWS_DATA_EXPORT_HEADER', 'header');
9
define('VIEWS_DATA_EXPORT_BODY', 'body');
10
define('VIEWS_DATA_EXPORT_FOOTER', 'footer');
11
define('VIEWS_DATA_EXPORT_FINISHED', 'finished');
12

    
13
define('VIEWS_DATA_EXPORT_INDEX_TABLE_PREFIX', 'views_data_export_index_');
14

    
15
/**
16
 * Implements hook_init().
17
 */
18
function views_data_export_init() {
19
  // We have to include our theme preprocessors here until:
20
  // http://drupal.org/node/1096770 is fixed.
21
  module_load_include('inc', 'views_data_export', 'theme/views_data_export.theme');
22
}
23

    
24
/**
25
 * Implementation of hook_views_api().
26
 */
27
function views_data_export_views_api() {
28
  return array(
29
    'api' => 2,
30
  );
31
}
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

    
52
/**
53
 * Implementation of hook_theme().
54
 */
55
function views_data_export_theme() {
56
  // Make sure that views picks up the preprocess functions.
57
  module_load_include('inc', 'views_data_export', 'theme/views_data_export.theme');
58
  $hooks = array();
59
  $hooks['views_data_export_feed_icon'] = array(
60
    'pattern' => 'views_data_export_feed_icon__',
61
    'variables' => array(
62
      'image_path' => NULL,
63
      'url' => NULL,
64
      'query' => '',
65
      'text' => '',
66
    ),
67
    'file' => 'theme/views_data_export.theme.inc',
68
  );
69

    
70
  $hooks['views_data_export_complete_page'] = array (
71
    'variables' => array(
72
      'file' => '',
73
      'errors' => array(),
74
      'return_url'=> '',
75
    ),
76
    'file' => 'theme/views_data_export.theme.inc',
77
  );
78

    
79
  $hooks['views_data_export_message'] = array (
80
    'variables' => array(
81
      'message' => '',
82
      'type' => 'info',
83
    ),
84
    'file' => 'theme/views_data_export.theme.inc',
85
  );
86

    
87
  return $hooks;
88
}
89

    
90

    
91
/**
92
 * Implementation of hook_cron().
93
 */
94
function views_data_export_cron() {
95
  views_data_export_garbage_collect();
96
}
97

    
98
/**
99
 * Removes any temporary index tables that have been left
100
 * behind. This is caused by batch processes which are
101
 * started but never finished.
102
 *
103
 * Removes all trace of exports from the database that
104
 * were created more than $expires seconds ago
105
 *
106
 * @param $expires
107
 *   Seconds ago. Defaults to that given in the settings.
108
 * @param $chunk
109
 *   The number of tables to test for and delete.
110
 *   Defaults to that given in the settings. Pass -1
111
 *   for this setting to remove any restriction and to
112
 *   garbage collect all exports.
113
 */
114
function views_data_export_garbage_collect($expires = NULL, $chunk = NULL) {
115
  if (lock_acquire('views_data_export_gc')) {
116
    if (!isset($expires)) {
117
      $expires = variable_get('views_data_export_gc_expires', 604800); // one week
118
    }
119
    if (!isset($chunk)) {
120
      $chunk = variable_get('views_data_export_gc_chunk', 30);
121
    }
122

    
123
    if ($chunk == -1) {
124
      $result = db_query("SELECT eid FROM {views_data_export} WHERE time_stamp <= :timestamp ORDER BY time_stamp ASC", array(':timestamp' => REQUEST_TIME - $expires));
125
    }
126
    else {
127
      $result = db_query_range("SELECT eid FROM {views_data_export} WHERE time_stamp <= :timestamp ORDER BY time_stamp ASC", 0, $chunk, array(':timestamp' => REQUEST_TIME - $expires));
128
    }
129

    
130
    $eids_to_clear = array();
131
    foreach ($result as $row) {
132
      $eids_to_clear[] = $row->eid;
133
    }
134

    
135
    // We do two things to exports we want to garbage collect
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.
140
    if (count($eids_to_clear)) {
141
      foreach ($eids_to_clear as $eid) {
142
        // 1. Delete index table, if it is still around for some reason
143
        $table = VIEWS_DATA_EXPORT_INDEX_TABLE_PREFIX . $eid;
144
        if (db_table_exists($table)) {
145
          db_drop_table($table);
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
        }
152
      }
153

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

    
159
      // 4. Clear the cached views
160
      views_data_export_view_clear($eids_to_clear);
161
    }
162

    
163
    lock_release('views_data_export_gc');
164
  }
165
}
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

    
186

    
187
/**
188
 * Batch API callback.
189
 * Handles all batching operations by executing the appropriate view.
190
 */
191
function _views_data_export_batch_process($export_id, $display_id, $exposed_input, &$context) {
192
  // Don't show the admin menu on batch page, some people don't like it.
193
  if (module_exists('admin_menu')) {
194
    module_invoke('admin_menu', 'suppress');
195
  }
196

    
197
  // Fetch the view in question from our cache
198
  $view = views_data_export_view_retrieve($export_id);
199
  $view->set_display($display_id);
200
  if (!empty($exposed_input)) {
201
    $view->set_exposed_input($exposed_input);
202
  }
203
  // Inform the data_export display which export it corresponds to and execute
204
  if (!isset($view->display_handler->batched_execution_state)) {
205
    $view->display_handler->batched_execution_state = new stdClass();
206
  }
207
  $view->display_handler->batched_execution_state->eid = $export_id;
208
  $view->display_handler->views_data_export_cached_view_loaded = TRUE;
209
  $view->execute_display($display_id);
210

    
211
  // Update batch api progress information
212
  $sandbox = $view->display_handler->batched_execution_state->sandbox;
213
  $context['finished'] = $sandbox['finished'];
214
  $context['message'] = $sandbox['message'];
215

    
216
  views_data_export_view_store($export_id, $view);
217
}
218

    
219

    
220

    
221
/**********/
222
/** CRUD **/
223
/**********/
224

    
225
/**
226
 * Save a new export into the database.
227
 */
228
function views_data_export_new($view_name, $view_display_id, $file) {
229
  // Insert new row into exports table
230
  $record = (object) array(
231
    'view_name' => $view_name,
232
    'view_display_id' => $view_display_id,
233
    'time_stamp' => REQUEST_TIME,
234
    'fid' => $file,
235
    'batch_state' => VIEWS_DATA_EXPORT_HEADER,
236
    'sandbox' => array(),
237
  );
238
  drupal_write_record('views_data_export', $record);
239
  return $record;
240
}
241

    
242

    
243
/**
244
 * Update an export row in the database
245
 */
246
function views_data_export_update($state) {
247
  // Note, drupal_write_record handles serializing
248
  // the sandbox field as per our schema definition
249
  drupal_write_record('views_data_export', $state, 'eid');
250
}
251

    
252

    
253

    
254
/**
255
 * Get the information about a previous export.
256
 */
257
function views_data_export_get($export_id) {
258
  $object = db_query("SELECT * FROM {views_data_export} WHERE eid = :eid", array(':eid' => (int)$export_id))->fetch();
259
  if ($object) {
260
    $object->sandbox = unserialize($object->sandbox);
261
  }
262
  return $object;
263
}
264

    
265
/**
266
 * Remove the information about an export.
267
 */
268
function views_data_export_clear($export_id) {
269
  db_delete('views_data_export')
270
    ->condition('eid', $export_id)
271
    ->execute();
272
  views_data_export_view_clear($export_id);
273
}
274

    
275

    
276
/**
277
 * Store a view in the object cache.
278
 */
279
function views_data_export_view_store($export_id, $view) {
280
  // Store a clean copy of the view.
281
  $_view = $view->clone_view();
282

    
283
  views_data_export_view_clear($export_id);
284
  $record = array(
285
    'eid' => $export_id,
286
    'data' => $_view,
287
    'updated' => REQUEST_TIME,
288
  );
289
  drupal_write_record('views_data_export_object_cache', $record);
290
}
291

    
292
/**
293
 * Retrieve a view from the object cache.
294
 */
295
function views_data_export_view_retrieve($export_id) {
296
  views_include('view');
297
  $data = db_query("SELECT * FROM {views_data_export_object_cache} WHERE eid = :eid", array(':eid' => $export_id))->fetch();
298
  if ($data) {
299
    $view = unserialize($data->data);
300
  }
301
  return $view;
302
}
303

    
304
/**
305
 * Clear a view from the object cache.
306
 *
307
 * @param $export_id
308
 *   An export ID or an array of export IDs to clear from the object cache.
309
 */
310
function views_data_export_view_clear($export_id) {
311
  db_delete('views_data_export_object_cache')
312
    ->condition('eid', $export_id)
313
    ->execute();
314
}