Projet

Général

Profil

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

root / drupal7 / sites / all / modules / views_bulk_operations / views / views_bulk_operations_handler_field_operations.inc @ 9df8b457

1
<?php
2

    
3
/**
4
* @file
5
* Views field handler. Contains all relevant VBO options and related logic.
6
* Implements the Views Form API.
7
*/
8

    
9
class views_bulk_operations_handler_field_operations extends views_handler_field {
10
  var $revision = FALSE;
11

    
12
  function init(&$view, &$options) {
13
    parent::init($view, $options);
14

    
15
    // Update old settings
16
    if (!empty($options['vbo']) && empty($this->options['vbo_operations'])) {
17
      $this->options['vbo_operations'] = $options['vbo']['operations'];
18
      unset($options['vbo']['operations']);
19
      $this->options['vbo_settings'] = $options['vbo'] + $this->options['vbo_settings'];
20
    }
21
    // When updating old Views it is possible for this value to stay empty.
22
    if (empty($this->options['vbo_settings']['entity_load_capacity'])) {
23
      $this->options['vbo_settings']['entity_load_capacity'] = 10;
24
    }
25

    
26
    foreach ($this->options['vbo_operations'] as $operation_id => &$operation_options) {
27
      // Prefix all un-prefixed operations.
28
      if (strpos($operation_id, '::') === FALSE) {
29
        $operations = views_bulk_operations_get_operation_info();
30
        // Basically, guess.
31
        foreach (array('action', 'rules_component') as $operation_type) {
32
          $new_operation_id = $operation_type . '::' . $operation_id;
33
          if (isset($operations[$new_operation_id])) {
34
            $this->options['vbo_operations'][$new_operation_id] = $operation_options;
35
            break;
36
          }
37
        }
38

    
39
        // Remove the old operation in any case.
40
        unset($this->options['vbo_operations'][$operation_id]);
41
      }
42

    
43
      // Rename the use_queue setting.
44
      if (isset($operation_options['use_queue']) && !isset($operation_options['postpone_processing'])) {
45
        $operation_options['postpone_processing'] = $operation_options['use_queue'];
46
        unset($operation_options['use_queue']);
47
      }
48
    }
49
  }
50

    
51
  function option_definition() {
52
    $options = parent::option_definition();
53

    
54
    $options['vbo_settings'] = array(
55
      'contains' => array(
56
        'display_type' => array('default' => 0),
57
        'enable_select_all_pages' => array('default' => TRUE),
58
        'row_clickable' => array('default' => TRUE),
59
        'force_single' => array('default' => FALSE),
60
        'entity_load_capacity' => array('default' => 10),
61
        'skip_batching' => array('default' => 0),
62
      ),
63
    );
64
    $options['vbo_operations'] = array(
65
      'default' => array(),
66
      'unpack_translatable' => 'unpack_operations',
67
      'export' => 'export_vbo_operations',
68
    );
69

    
70
    return $options;
71
  }
72

    
73
  function export_vbo_operations($indent, $prefix, $storage, $option, $definition, $parents) {
74
    // Anti-recursion, since we use the parent export helper.
75
    unset($definition['export']);
76

    
77
    // Find and remove all unselected/disabled operations.
78
    foreach ($storage['vbo_operations'] as $operation_id => $operation) {
79
      if (empty($operation['selected'])) {
80
        unset($storage['vbo_operations'][$operation_id]);
81
      }
82
    }
83

    
84
    return parent::export_option($indent, $prefix, $storage, $option, $definition, $parents);
85
  }
86

    
87
  function unpack_operations(&$translatable, $storage, $option, $definition, $parents, $keys) {
88
    $translatable[] = array(
89
      'value' => t('- Choose an operation -'),
90
      'keys' => array_merge($keys, array('noop')),
91
    );
92
    foreach ($storage[$option] as $key => $operation) {
93
      if (!empty($operation['override_label']) && !empty($operation['label'])) {
94
        $translatable[] = array(
95
          'value' => $operation['label'],
96
          'keys' => array_merge($keys, array($key)),
97
        );
98
      }
99
    }
100
  }
101

    
102
  function options_form(&$form, &$form_state) {
103
    parent::options_form($form, $form_state);
104

    
105
    $form['vbo_settings'] = array(
106
      '#type' => 'fieldset',
107
      '#title' => t('Bulk operations settings'),
108
      '#collapsible' => TRUE,
109
      '#collapsed' => TRUE,
110
    );
111
    $form['vbo_settings']['display_type'] = array(
112
      '#type' => 'radios',
113
      '#title' => t('Display operations as'),
114
      '#default_value' => $this->options['vbo_settings']['display_type'],
115
      '#options' => array(
116
        t('Dropdown selectbox with Submit button'),
117
        t('Each action as a separate button'),
118
      ),
119
    );
120
    $form['vbo_settings']['enable_select_all_pages'] = array(
121
      '#type' => 'checkbox',
122
      '#title' => t('Enable "Select all items on all pages"'),
123
      '#default_value' => $this->options['vbo_settings']['enable_select_all_pages'],
124
      '#description' => t('Check this box to enable the ability to select all items on all pages.'),
125
    );
126
    $form['vbo_settings']['row_clickable'] = array(
127
      '#type' => 'checkbox',
128
      '#title' => t('Make the whole row clickable'),
129
      '#default_value' => $this->options['vbo_settings']['row_clickable'],
130
      '#description' => t('Check this box to select an item when its row has been clicked. Requires JavaScript.'),
131
    );
132
    $form['vbo_settings']['force_single'] = array(
133
      '#type' => 'checkbox',
134
      '#title' => t('Force single'),
135
      '#default_value' => $this->options['vbo_settings']['force_single'],
136
      '#description' => t('Check this box to restrict selection to a single value.'),
137
    );
138
    $form['vbo_settings']['entity_load_capacity'] = array(
139
      '#type' => 'textfield',
140
      '#title' => t('Number of entities to load at once'),
141
      '#description' => t("Improve execution performance at the cost of memory usage. Set to '1' if you're having problems."),
142
      '#default_value' => $this->options['vbo_settings']['entity_load_capacity'],
143
    );
144
    $form['vbo_settings']['skip_batching'] = array(
145
      '#type' => 'checkbox',
146
      '#title' => t('Skip batching'),
147
      '#default_value' => $this->options['vbo_settings']['skip_batching'],
148
      '#description' => '<b>' . t('Warning:') . '</b> ' . t('This will cause timeouts for larger amounts of selected items.'),
149
    );
150

    
151
    // Display operations and their settings.
152
    $form['vbo_operations'] = array(
153
      '#tree' => TRUE,
154
      '#type' => 'fieldset',
155
      '#title' => t('Selected bulk operations'),
156
      '#collapsible' => TRUE,
157
      '#collapsed' => FALSE,
158
    );
159

    
160
    $entity_type = $this->get_entity_type();
161
    $options = $this->options['vbo_operations'];
162
    foreach (views_bulk_operations_get_applicable_operations($entity_type, $options) as $operation_id => $operation) {
163
      $operation_options = !empty($options[$operation_id]) ? $options[$operation_id] : array();
164

    
165
      $dom_id = 'edit-options-vbo-operations-' . str_replace(array('_', ':'), array('-', ''), $operation_id);
166
      $form['vbo_operations'][$operation_id]['selected'] = array(
167
        '#type' => 'checkbox',
168
        '#title' => $operation->adminLabel(),
169
        '#default_value' => !empty($operation_options['selected']),
170
      );
171
      if (!$operation->aggregate()) {
172
        $form['vbo_operations'][$operation_id]['postpone_processing'] = array(
173
          '#type' => 'checkbox',
174
          '#title' => t('Enqueue the operation instead of executing it directly'),
175
          '#default_value' => !empty($operation_options['postpone_processing']),
176
          '#dependency' => array(
177
            $dom_id . '-selected' => array(1),
178
          ),
179
        );
180
      }
181
      $form['vbo_operations'][$operation_id]['skip_confirmation'] = array(
182
        '#type' => 'checkbox',
183
        '#title' => t('Skip confirmation step'),
184
        '#default_value' => !empty($operation_options['skip_confirmation']),
185
        '#dependency' => array(
186
          $dom_id . '-selected' => array(1),
187
        ),
188
      );
189

    
190
      $form['vbo_operations'][$operation_id] += $operation->adminOptionsForm($dom_id, $this);
191
    }
192
  }
193

    
194
  function options_validate(&$form, &$form_state) {
195
    parent::options_validate($form, $form_state);
196

    
197
    $entity_type = $this->get_entity_type();
198
    foreach ($form_state['values']['options']['vbo_operations'] as $operation_id => &$options) {
199
      if (empty($options['selected'])) {
200
        continue;
201
      }
202

    
203
      $operation = views_bulk_operations_get_operation($operation_id, $entity_type, $options);
204
      $fake_form = $form['vbo_operations'][$operation_id];
205
      $fake_form_state = array('values' => &$options);
206
      $error_element_base = 'vbo_operations][' . $operation_id . '][';
207
      $operation->adminOptionsFormValidate($fake_form, $fake_form_state, $error_element_base);
208
    }
209
  }
210

    
211
  function options_submit(&$form, &$form_state) {
212
    parent::options_submit($form, $form_state);
213

    
214
    $entity_type = $this->get_entity_type();
215
    foreach ($form_state['values']['options']['vbo_operations'] as $operation_id => &$options) {
216
      if (empty($options['selected'])) {
217
        continue;
218
      }
219

    
220
      $operation = views_bulk_operations_get_operation($operation_id, $entity_type, $options);
221
      $fake_form = $form['vbo_operations'][$operation_id];
222
      $fake_form_state = array('values' => &$options);
223
      $operation->adminOptionsFormSubmit($fake_form, $fake_form_state);
224
    }
225
  }
226

    
227
  /**
228
   * Returns the value of a vbo option.
229
   */
230
  function get_vbo_option($key, $default = NULL) {
231
    return isset($this->options['vbo_settings'][$key]) ? $this->options['vbo_settings'][$key] : $default;
232
  }
233

    
234
  /**
235
   * If the view is using a table style, provide a
236
   * placeholder for a "select all" checkbox.
237
   */
238
  function label() {
239
    if (!empty($this->view->style_plugin) && $this->view->style_plugin instanceof views_plugin_style_table && !$this->options['vbo_settings']['force_single']) {
240
      return '<!--views-bulk-operations-select-all-->';
241
    }
242
    else {
243
      return parent::label();
244
    }
245
  }
246

    
247
  function render($values) {
248
    return '<!--form-item-' . $this->options['id'] . '--' . $this->view->row_index . '-->';
249
  }
250

    
251
  /**
252
   * The form which replaces the placeholder from render().
253
   */
254
  function views_form(&$form, &$form_state) {
255
    // The view is empty, abort.
256
    if (empty($this->view->result)) {
257
      return;
258
    }
259

    
260
    $form[$this->options['id']] = array(
261
      '#tree' => TRUE,
262
    );
263
    // At this point, the query has already been run, so we can access the results
264
    // in order to get the base key value (for example, nid for nodes).
265
    foreach ($this->view->result as $row_index => $row) {
266
      $entity_id = $this->get_value($row);
267

    
268
      if ($this->options['vbo_settings']['force_single']) {
269
        $form[$this->options['id']][$row_index] = array(
270
          '#type' => 'radio',
271
          '#parents' => array($this->options['id']),
272
          '#return_value' => $entity_id,
273
        );
274
      }
275
      else {
276
        $form[$this->options['id']][$row_index] = array(
277
          '#type' => 'checkbox',
278
          '#return_value' => $entity_id,
279
          '#default_value' => FALSE,
280
          '#attributes' => array('class' => array('vbo-select')),
281
        );
282
      }
283
    }
284
  }
285

    
286
  public function get_selected_operations() {
287
    global $user;
288
    $selected = drupal_static(__FUNCTION__);
289
    if (!isset($selected)) {
290
      $entity_type = $this->get_entity_type();
291
      $selected = array();
292
      foreach ($this->options['vbo_operations'] as $operation_id => $options) {
293
        if (empty($options['selected'])) {
294
          continue;
295
        }
296

    
297
        $operation = views_bulk_operations_get_operation($operation_id, $entity_type, $options);
298
        if (!$operation || !$operation->access($user)) {
299
          continue;
300
        }
301
        $selected[$operation_id] = $operation;
302
      }
303
    }
304

    
305
    return $selected;
306
  }
307

    
308
  /**
309
   * Returns the options stored for the provided operation id.
310
   */
311
  public function get_operation_options($operation_id) {
312
    $options = $this->options['vbo_operations'];
313
    return isset($options[$operation_id]) ? $options[$operation_id] : array();
314
  }
315

    
316
  /**
317
   * Determine the base table of the VBO field, and then use it to determine
318
   * the entity type that VBO is operating on.
319
   */
320
  public function get_entity_type() {
321
    $base_table = $this->view->base_table;
322

    
323
    // If the current field is under a relationship you can't be sure that the
324
    // base table of the view is the base table of the current field.
325
    // For example a field from a node author on a node view does have users as base table.
326
    if (!empty($this->options['relationship']) && $this->options['relationship'] != 'none') {
327
      $relationships = $this->view->display_handler->get_option('relationships');
328
      $options = $relationships[$this->options['relationship']];
329
      $data = views_fetch_data($options['table']);
330
      $base_table = $data[$options['field']]['relationship']['base'];
331
    }
332
    // The base table is now known, use it to determine the entity type.
333
    foreach (entity_get_info() as $entity_type => $info) {
334
      if (isset($info['base table']) && $info['base table'] == $base_table) {
335
        return $entity_type;
336
      }
337
      elseif (isset($info['revision table']) && $info['revision table'] == $base_table) {
338
        $this->revision = TRUE;
339
        return $entity_type;
340
      }
341
    }
342
    // This should never happen.
343
    _views_bulk_operations_report_error("Could not determine the entity type for VBO field on views base table %table", array('%table' => $base_table));
344
    return FALSE;
345
  }
346
}