Projet

Général

Profil

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

root / drupal7 / sites / all / modules / views_data_export / plugins / views_data_export_plugin_style_export.inc @ f0456308

1
<?php
2
/**
3
 * @file
4
 * Plugin include file for export style plugin.
5
 */
6

    
7
/**
8
 * Generalized style plugin for export plugins.
9
 *
10
 * @ingroup views_style_plugins
11
 */
12
class views_data_export_plugin_style_export extends views_plugin_style {
13

    
14
  /**
15
   * Set options fields and default values.
16
   *
17
   * @return
18
   * An array of options information.
19
   */
20
  function option_definition() {
21
    $options = parent::option_definition();
22

    
23
    $options['attach_text'] = array(
24
      'default' => $this->definition['export feed text'],
25
      'translatable' => TRUE,
26
    );
27
    $options['provide_file'] = array(
28
      'default' => FALSE,
29
      'translatable' => FALSE,
30
    );
31
    $options['filename'] = array(
32
      'default' => $this->definition['export feed file'],
33
      'translatable' => FALSE,
34
    );
35
    $options['parent_sort'] = array(
36
      'default' => FALSE,
37
      'translatable' => FALSE,
38
    );
39
    return $options;
40
  }
41

    
42
  /**
43
   * Options form mini callback.
44
   *
45
   * @param $form
46
   * Form array to add additional fields to.
47
   * @param $form_state
48
   * State of the form.
49
   * @return
50
   * None.
51
   */
52
  function options_form(&$form, &$form_state) {
53
    $form['attach_text'] = array(
54
      '#type' => 'textfield',
55
      '#title' => t('Attach text'),
56
      '#default_value' => $this->options['attach_text'],
57
      '#description' => t('This text is used in building the feed link. By default it is the "alt" text for the feed image.'),
58
    );
59
    $form['provide_file'] = array(
60
      '#type' => 'checkbox',
61
      '#title' => t('Provide as file'),
62
      '#default_value' => $this->options['provide_file'],
63
      '#description' => t('By deselecting this, the xml file will be provided as a feed instead of a file for download.'),
64
    );
65
    $form['filename'] = array(
66
      '#type' => 'textfield',
67
      '#title' => t('Filename'),
68
      '#default_value' => $this->options['filename'],
69
      '#description' => t('The filename that will be suggested to the browser for downloading purposes. You may include replacement patterns from the list below.'),
70
      '#process' => array('ctools_dependent_process'),
71
      '#dependency' => array(
72
        'edit-style-options-provide-file' => array(TRUE),
73
      ),
74
    );
75

    
76
    // General token replacement.
77
    $output = t('<p>The following substitution patterns are available for this display. Use the pattern shown on the left to display the value indicated on the right.</p>');
78
    $items = array(
79
      '%view == ' . t('View name'),
80
      '%display == ' . t('Display name'),
81
    );
82

    
83
    $output .= theme('item_list', array('items' => $items));
84

    
85
    // Get a list of the available arguments for token replacement.
86
    $options = array();
87

    
88
    $count = 0; // This lets us prepare the key as we want it printed.
89
    foreach ($this->view->display_handler->get_handlers('argument') as $arg => $handler) {
90
      $options[t('Arguments')]['%' . ++$count . '-title'] = t('@argument title', array('@argument' => $handler->ui_name()));
91
      $options[t('Arguments')]['%' . $count . '-value'] = t('@argument value', array('@argument' => $handler->ui_name()));
92
    }
93

    
94
    // Append the list with exposed filters stuff.
95
    $options[t('Exposed filters')]['%exposed'] = t('effective exposed filters, like <em>filter1_foo-filter2_bar</em>');
96

    
97
    // ...and datestamp.
98
    $time = REQUEST_TIME;
99
    $parts = array(
100
      'full' => 'Y-m-d\TH-i-s',
101
      'yy' => 'y',
102
      'yyyy' => 'Y',
103
      'mm' => 'm',
104
      'mmm' => 'M',
105
      'dd' => 'd',
106
      'ddd' => 'D',
107
      'hh' => 'H',
108
      'ii' => 'i',
109
      'ss' => 's',
110
    );
111
    foreach ($parts as $part => $format) {
112
      $options[t('Timestamp')]['%timestamp-' . $part] = format_date($time, 'custom', $format);
113
    }
114

    
115
    // We have some options, so make a list.
116
    if (!empty($options)) {
117
      foreach (array_keys($options) as $type) {
118
        if (!empty($options[$type])) {
119
          $items = array();
120
          foreach ($options[$type] as $key => $value) {
121
            $items[] = $key . ' == ' . $value;
122
          }
123
          $output .= theme('item_list', array('items' => $items, 'title' => $type));
124
        }
125
      }
126
    }
127
    $form['help'] = array(
128
      '#type' => 'fieldset',
129
      '#title' => t('Replacement patterns'),
130
      '#collapsible' => TRUE,
131
      '#collapsed' => TRUE,
132
      '#value' => $output,
133
      '#dependency' => array(
134
        'edit-style-options-provide-file' => array(1),
135
      ),
136
    );
137
    $form['parent_sort'] = array(
138
      '#type' => 'checkbox',
139
      '#title' => t('Parent sort'),
140
      '#default_value' => $this->options['parent_sort'],
141
      '#description' => t('Try to apply any additional sorting from the attached display like table sorting to the exported feed.'),
142
    );
143
  }
144

    
145
  /**
146
   * Attach this view to another display as a feed.
147
   *
148
   * Provide basic functionality for all export style views like attaching a
149
   * feed image link.
150
   */
151
  function attach_to($display_id, $path, $title) {
152
    if ($this->display->handler->access()) {
153
      $type = $this->definition['export feed type'];
154
      $theme_pattern = array(
155
        'views_data_export_feed_icon__' . $this->view->name . '__' . $display_id . '__' . $type,
156
        'views_data_export_feed_icon__' . $this->view->name . '__' . $display_id,
157
        'views_data_export_feed_icon__' . $this->view->name . '__' . $type,
158
        'views_data_export_feed_icon__' . $display_id . '__' . $type,
159
        'views_data_export_feed_icon__' . $display_id,
160
        'views_data_export_feed_icon__' . $type,
161
        'views_data_export_feed_icon',
162
      );
163
      $query = $this->view->get_exposed_input();
164
      // Stash the display id we're coming form in the url so we can hijack it later.
165
      if ($this->options['parent_sort']) {
166
        $query['attach'] = $display_id;
167
      }
168
      if (!isset($this->view->feed_icon)) {
169
        $this->view->feed_icon = '';
170
      }
171
      $this->view->feed_icon .= theme($theme_pattern, array(
172
          'image_path' => $this->definition['export feed icon'],
173
          'url' => $this->view->get_url(NULL, $path),
174
          'query' => $query,
175
          'text' => $this->options['attach_text'],
176
        )
177
      );
178
    }
179
  }
180

    
181
  function build_sort() {
182

    
183
    // Bypass doing any sort of testing if parent sorting is disabled.
184
    if (!$this->options['parent_sort']) {
185
      return parent::build_sort();
186
    }
187

    
188
    $displays = $this->display->handler->get_option('displays');
189

    
190
    // Here is later. We can get the passed argument and use it to know which
191
    // display we can from and then do some addition processing.
192
    // If the display exists and is attached these two tests will succeed.
193
    if (isset($_GET['attach']) && isset($displays[$_GET['attach']]) && $displays[$_GET['attach']]) {
194
      // Setup the second style we're going to be using to sort on.
195
      $plugin_id = $displays[$_GET['attach']];
196
      $parent_display = $this->view->display[$plugin_id];
197
      $style_name = $parent_display->handler->get_option('style_plugin');
198
      $style_options = $parent_display->handler->get_option('style_options');
199
      $this->extra_style = views_get_plugin('style', $style_name);
200
      $this->extra_style->init($this->view, $parent_display, $style_options);
201

    
202
      // Call the second styles sort funciton and return the value.
203
      return $this->extra_style->build_sort();
204
    }
205
  }
206

    
207
  function build_sort_post() {
208
    // If we found an extra style plugin earlier, pass off the build_sort_post call to it.
209
    if (isset($this->extra_style)) {
210
      return $this->extra_style->build_sort_post();
211
    }
212
    else {
213
      return parent::build_sort_post();
214
    }
215
  }
216

    
217
  /**
218
   * Render the display in this style.
219
   */
220
  function render() {
221
    if ($this->uses_row_plugin() && empty($this->row_plugin)) {
222
      vpr('views_plugin_style_default: Missing row plugin');
223
      return;
224
    }
225

    
226
    $output = '';
227
    $rows['header'] = $this->render_header();
228
    $rows['body'] = $this->render_body();
229
    $rows['footer'] = $this->render_footer();
230
    $title = '';
231
    $output .= theme($this->theme_functions(), array('view' => $this->view, 'options' => $this->options, 'rows' => $rows, 'title' => $title));
232
    return $output;
233
  }
234

    
235
  function render_header() {
236
    $rows = array();
237
    $title = '';
238
    $output = '';
239
    $output .= theme($this->theme_functions($this->definition['additional themes base'] . '_header'), array('view' => $this->view, 'options' => $this->options, 'rows' => $rows, 'title' => $title));
240
    return $output;
241
  }
242

    
243
  function render_footer() {
244
    $rows = array();
245
    $title = '';
246
    $output = '';
247
    $output .= theme($this->theme_functions($this->definition['additional themes base'] . '_footer'), array('view' => $this->view, 'options' => $this->options, 'rows' => $rows, 'title' => $title));
248

    
249
    return $output;
250
  }
251

    
252
  function render_body() {
253
    if ($this->uses_row_plugin() && empty($this->row_plugin)) {
254
      vpr('views_plugin_style_default: Missing row plugin');
255
      return;
256
    }
257

    
258
    // Group the rows according to the grouping field, if specified.
259
    $sets = $this->render_grouping($this->view->result, $this->options['grouping']);
260

    
261
    // Render each group separately and concatenate.  Plugins may override this
262
    // method if they wish some other way of handling grouping.
263
    $output = '';
264
    foreach ($sets as $title => $records) {
265
      if ($this->uses_row_plugin()) {
266
        $rows = array();
267
        foreach ($records as $row_index => $row) {
268
          $this->view->row_index = $row_index;
269
          $rows[] = $this->row_plugin->render($row);
270
        }
271
      }
272
      else {
273
        $rows = $records;
274
      }
275

    
276
      $title = '';
277
      $output .= theme($this->theme_functions($this->definition['additional themes base'] . '_body'), array('view' => $this->view, 'options' => $this->options, 'rows' => $rows, 'title' => $title));
278
    }
279
    unset($this->view->row_index);
280
    return $output;
281

    
282
  }
283

    
284
  /**
285
   * Provide a full list of possible theme templates used by this style.
286
   */
287
  function theme_functions($hook = NULL) {
288
    if (is_null($hook)) {
289
      $hook = $this->definition['theme'];
290
    }
291
    return views_theme_functions($hook, $this->view, $this->display);
292
  }
293

    
294
  /**
295
   * Add any HTTP headers that this style plugin wants to.
296
   */
297
  function add_http_headers() {
298

    
299
    drupal_add_http_header('Cache-Control', 'max-age=60, must-revalidate');
300

    
301
    if (!empty($this->definition['export headers'])) {
302
      foreach ($this->definition['export headers'] as $name => $value) {
303
        drupal_add_http_header($name, $value);
304
      }
305
    }
306

    
307
    if (isset($this->options['filename']) && !empty($this->options['provide_file'])) {
308
      $filename = $this->generate_filename();
309

    
310
      if ($filename) {
311
        drupal_add_http_header('Content-Disposition', 'attachment; filename="'. $filename .'"');
312
      }
313
    }
314
  }
315

    
316
  /**
317
   * Generate the filename for the export.
318
   */
319
  function generate_filename() {
320
    $view = $this->view;
321
    $filename = '';
322

    
323
    if (isset($this->options['filename']) && !empty($this->options['provide_file'])) {
324
      // General tokens.
325
      $tokens = array(
326
        '%view' => check_plain($view->name),
327
        '%display' => check_plain($view->current_display),
328
      );
329
      // Argument tokens.
330
      $count = 0;
331
      foreach ($view->display_handler->get_handlers('argument') as $arg => $handler) {
332
        $token = '%' . ++$count;
333
        $tokens[$token . '-title'] = $handler->get_title();
334
        $tokens[$token . '-value'] = isset($view->args[$count - 1]) ? check_plain($view->args[$count - 1]) : '';
335
      }
336

    
337
      // Effective exposed filters token.
338
      $exposed = array();
339
      foreach ($view->display_handler->get_handlers('filter') as $arg => $handler) {
340
        if (!$handler->options['exposed']) {
341
          continue;
342
        }
343
        if (!empty($view->exposed_input[$handler->options['expose']['identifier']])) {
344
          $identifier = $handler->options['expose']['identifier'];
345
          $option = $view->exposed_input[$identifier];
346
          // The option may be a string or an array, depending on whether the
347
          // widget is a text box/area or a select box.
348
          if (is_array($option)) {
349
            $option = implode('--', $option);
350
          }
351
          $exposed[] = check_plain($identifier) . '_' . check_plain($option);
352
        }
353
      }
354
      if (!empty($exposed)) {
355
        $tokens['%exposed'] = implode('-', $exposed);
356
      }
357
      else {
358
        $tokens['%exposed'] = 'default' ;
359
      }
360

    
361
      // Timestamp token.
362
      $time = REQUEST_TIME;
363
      $parts = array(
364
        'full' => 'Y-m-d\TH-i-s',
365
        'yy' => 'y',
366
        'yyyy' => 'Y',
367
        'mm' => 'm',
368
        'mmm' => 'M',
369
        'dd' => 'd',
370
        'ddd' => 'D',
371
        'hh' => 'H',
372
        'ii' => 'i',
373
        'ss' => 's',
374
      );
375
      foreach ($parts as $part => $format) {
376
        $tokens['%timestamp-' . $part] = format_date($time, 'custom', $format);
377
      }
378

    
379
      $filename = strtr($this->options['filename'], $tokens);
380
    }
381

    
382
    return $filename;
383
  }
384
}