Projet

Général

Profil

Paste
Télécharger (11,9 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / views / includes / base.inc @ 13c3c9b4

1
<?php
2

    
3
/**
4
 * @file
5
 * Provides the basic object definitions used by plugins and handlers.
6
 */
7

    
8
/**
9
 * Basic definition for many views objects.
10
 */
11
class views_object {
12
  /**
13
   * Except for displays, options for the object will be held here.
14
   */
15
  var $options = array();
16

    
17
  /**
18
   * The top object of a view.
19
   *
20
   * @var view
21
   */
22
  var $view = NULL;
23

    
24
  /**
25
   * Handler's definition
26
   *
27
   * @var array
28
   */
29
  var $definition;
30

    
31
  /**
32
   * Information about options for all kinds of purposes will be held here.
33
   * @code
34
   * 'option_name' => array(
35
   *  - 'default' => default value,
36
   *  - 'translatable' => (optional) TRUE/FALSE (wrap in t() on export if true),
37
   *  - 'contains' => (optional) array of items this contains, with its own
38
   *      defaults, etc. If contains is set, the default will be ignored and
39
   *      assumed to be array().
40
   *  - 'bool' => (optional) TRUE/FALSE Is the value a boolean value. This will
41
   *      change the export format to TRUE/FALSE instead of 1/0.
42
   *  - 'export' => (optional) FALSE or a callback for special export handling
43
   *      if necessary.
44
   *  - 'unpack_translatable' => (optional) callback for special handling for
45
   *      translating data within the option, if necessary.
46
   *  ),
47
   *
48
   * @return array
49
   *   Returns the options of this handler/plugin.
50
   *
51
   * @see views_object::export_option()
52
   * @see views_object::export_option_always()
53
   * @see views_object::unpack_translatable()
54
   */
55
  function option_definition() { return array(); }
56

    
57
  /**
58
   * Views handlers use a special construct function so that we can more
59
   * easily construct them with variable arguments.
60
   */
61
  function construct() { $this->set_default_options(); }
62

    
63
  /**
64
   * Set default options on this object. Called by the constructor in a
65
   * complex chain to deal with backward compatibility.
66
   *
67
   * @deprecated since views2
68
   */
69
  function options(&$options) { }
70

    
71
  /**
72
   * Set default options.
73
   * For backward compatibility, it sends the options array; this is a
74
   * feature that will likely disappear at some point.
75
   */
76
  function set_default_options() {
77
    $this->_set_option_defaults($this->options, $this->option_definition());
78

    
79
    // Retained for complex defaults plus backward compatibility.
80
    $this->options($this->options);
81
  }
82

    
83
  function _set_option_defaults(&$storage, $options, $level = 0) {
84
    foreach ($options as $option => $definition) {
85
      if (isset($definition['contains']) && is_array($definition['contains'])) {
86
        $storage[$option] = array();
87
        $this->_set_option_defaults($storage[$option], $definition['contains'], $level++);
88
      }
89
      elseif (!empty($definition['translatable']) && !empty($definition['default'])) {
90
        $storage[$option] = t($definition['default']);
91
      }
92
      else {
93
        $storage[$option] = isset($definition['default']) ? $definition['default'] : NULL;
94
      }
95
    }
96
  }
97

    
98
  /**
99
   * Unpack options over our existing defaults, drilling down into arrays
100
   * so that defaults don't get totally blown away.
101
   */
102
  function unpack_options(&$storage, $options, $definition = NULL, $all = TRUE, $check = TRUE, $localization_keys = array()) {
103
    if ($check && !is_array($options)) {
104
      return;
105
    }
106

    
107
    if (!isset($definition)) {
108
      $definition = $this->option_definition();
109
    }
110

    
111
    if (!empty($this->view)) {
112
      // Ensure we have a localization plugin.
113
      $this->view->init_localization();
114

    
115
      // Set up default localization keys. Handlers and such set this for us
116
      if (empty($localization_keys) && isset($this->localization_keys)) {
117
        $localization_keys = $this->localization_keys;
118
      }
119
      // but plugins don't because there isn't a common init() these days.
120
      else if (!empty($this->is_plugin) && empty($localization_keys)) {
121
        if ($this->plugin_type != 'display') {
122
          $localization_keys = array($this->view->current_display);
123
          $localization_keys[] = $this->plugin_type;
124
        }
125
      }
126
    }
127

    
128
    foreach ($options as $key => $value) {
129
      if (is_array($value)) {
130
        // Ignore arrays with no definition.
131
        if (!$all && empty($definition[$key])) {
132
          continue;
133
        }
134

    
135
        if (!isset($storage[$key]) || !is_array($storage[$key])) {
136
          $storage[$key] = array();
137
        }
138

    
139
        // If we're just unpacking our known options, and we're dropping an
140
        // unknown array (as might happen for a dependent plugin fields) go
141
        // ahead and drop that in.
142
        if (!$all && isset($definition[$key]) && !isset($definition[$key]['contains'])) {
143
          $storage[$key] = $value;
144
          continue;
145
        }
146

    
147
        $this->unpack_options($storage[$key], $value, isset($definition[$key]['contains']) ? $definition[$key]['contains'] : array(), $all, FALSE, array_merge($localization_keys, array($key)));
148
      }
149
      // Don't localize strings during editing. When editing, we need to work with
150
      // the original data, not the translated version.
151
      else if (empty($this->view->editing) && !empty($definition[$key]['translatable']) && !empty($value) || !empty($definition['contains'][$key]['translatable']) && !empty($value)) {
152
        if (!empty($this->view) && $this->view->is_translatable()) {
153
          // Allow other modules to make changes to the string before it's
154
          // sent for translation.
155
          // The $keys array is built from the view name, any localization keys
156
          // sent in, and the name of the property being processed.
157
          $format = NULL;
158
          if (isset($definition[$key]['format_key']) && isset($options[$definition[$key]['format_key']])) {
159
            $format = $options[$definition[$key]['format_key']];
160
          }
161
          $translation_data = array(
162
            'value' => $value,
163
            'format' => $format,
164
            'keys' => array_merge(array($this->view->name), $localization_keys, array($key)),
165
          );
166
          $storage[$key] = $this->view->localization_plugin->translate($translation_data);
167
        }
168
        // Otherwise, this is a code-based string, so we can use t().
169
        else {
170
          $storage[$key] = t($value);
171
        }
172
      }
173
      else if ($all || !empty($definition[$key])) {
174
        $storage[$key] = $value;
175
      }
176
    }
177
  }
178

    
179
  /**
180
   * Let the handler know what its full definition is.
181
   */
182
  function set_definition($definition) {
183
    $this->definition = $definition;
184
    if (isset($definition['field'])) {
185
      $this->real_field = $definition['field'];
186
    }
187
  }
188

    
189
  function destroy() {
190
    if (isset($this->view)) {
191
      unset($this->view);
192
    }
193

    
194
    if (isset($this->display)) {
195
      unset($this->display);
196
    }
197

    
198
    if (isset($this->query)) {
199
      unset($this->query);
200
    }
201
  }
202

    
203
  function export_options($indent, $prefix) {
204
    $output = '';
205
    foreach ($this->option_definition() as $option => $definition) {
206
      $output .= $this->export_option($indent, $prefix, $this->options, $option, $definition, array());
207
    }
208

    
209
    return $output;
210
  }
211

    
212
  function export_option($indent, $prefix, $storage, $option, $definition, $parents) {
213
    // Do not export options for which we have no settings.
214
    if (!isset($storage[$option])) {
215
      return;
216
    }
217

    
218
    if (isset($definition['export'])) {
219
      if ($definition['export'] === FALSE) {
220
        return;
221
      }
222

    
223
      // Special handling for some items
224
      if (method_exists($this, $definition['export'])) {
225
        return $this->{$definition['export']}($indent, $prefix, $storage, $option, $definition, $parents);
226
      }
227
    }
228

    
229
    // Add the current option to the parents tree.
230
    $parents[] = $option;
231
    $output = '';
232

    
233
    // If it has child items, export those separately.
234
    if (isset($definition['contains'])) {
235
      foreach ($definition['contains'] as $sub_option => $sub_definition) {
236
        $output .= $this->export_option($indent, $prefix, $storage[$option], $sub_option, $sub_definition, $parents);
237
      }
238
    }
239
    // Otherwise export just this item.
240
    else {
241
      $default = isset($definition['default']) ? $definition['default'] : NULL;
242
      $value = $storage[$option];
243
      if (isset($definition['bool'])) {
244
        $value = (bool) $value;
245
      }
246

    
247
      if ($value !== $default) {
248
        $output .= $indent . $prefix . "['" . implode("']['", $parents) . "'] = ";
249
        if (isset($definition['bool'])) {
250
          $output .= empty($storage[$option]) ? 'FALSE' : 'TRUE';
251
        }
252
        else {
253
          $output .= views_var_export($storage[$option], $indent);
254
        }
255

    
256
        $output .= ";\n";
257
      }
258
    }
259
    return $output;
260
  }
261

    
262
  /**
263
   * Always exports the option, regardless of the default value.
264
   */
265
  function export_option_always($indent, $prefix, $storage, $option, $definition, $parents) {
266
    // If there is no default, the option will always be exported.
267
    unset($definition['default']);
268
    // Unset our export method to prevent recursion.
269
    unset($definition['export']);
270
    return $this->export_option($indent, $prefix, $storage, $option, $definition, $parents);
271
  }
272

    
273
  /**
274
   * Unpacks each handler to store translatable texts.
275
   */
276
  function unpack_translatables(&$translatable, $parents = array()) {
277
    foreach ($this->option_definition() as $option => $definition) {
278
      $this->unpack_translatable($translatable, $this->options, $option, $definition, $parents, array());
279
    }
280
  }
281

    
282
  /**
283
   * Unpack a single option definition.
284
   *
285
   * This function run's through all suboptions recursive.
286
   *
287
   * @param $translatable
288
   *   Stores all available translatable items.
289
   * @param $storage
290
   * @param $option
291
   * @param $definition
292
   * @param $parents
293
   * @param $keys
294
   */
295
  function unpack_translatable(&$translatable, $storage, $option, $definition, $parents, $keys = array()) {
296
    // Do not export options for which we have no settings.
297
    if (!isset($storage[$option])) {
298
      return;
299
    }
300

    
301
    // Special handling for some items
302
    if (isset($definition['unpack_translatable']) && method_exists($this, $definition['unpack_translatable'])) {
303
      return $this->{$definition['unpack_translatable']}($translatable, $storage, $option, $definition, $parents, $keys);
304
    }
305

    
306
    if (isset($definition['translatable'])) {
307
      if ($definition['translatable'] === FALSE) {
308
        return;
309
      }
310
    }
311

    
312
    // Add the current option to the parents tree.
313
    $parents[] = $option;
314

    
315
    // If it has child items, unpack those separately.
316
    if (isset($definition['contains'])) {
317
      foreach ($definition['contains'] as $sub_option => $sub_definition) {
318
        $translation_keys = array_merge($keys, array($sub_option));
319
        $this->unpack_translatable($translatable, $storage[$option], $sub_option, $sub_definition, $parents, $translation_keys);
320
      }
321
    }
322

    
323
    // @todo Figure out this double definition stuff.
324
    $options = $storage[$option];
325
    if (is_array($options)) {
326
      foreach ($options as $key => $value) {
327
        $translation_keys = array_merge($keys, array($key));
328
        if (is_array($value)) {
329
          $this->unpack_translatable($translatable, $options, $key, $definition, $parents, $translation_keys);
330
        }
331
        else if (!empty($definition[$key]['translatable']) && !empty($value)) {
332
          // Build source data and add to the array
333
          $format = NULL;
334
          if (isset($definition['format_key']) && isset($options[$definition['format_key']])) {
335
            $format = $options[$definition['format_key']];
336
          }
337
          $translatable[] = array(
338
            'value' => $value,
339
            'keys' => $translation_keys,
340
            'format' => $format,
341
          );
342
        }
343
      }
344
    }
345
    else if (!empty($definition['translatable']) && !empty($options)) {
346
      $value = $options;
347
      // Build source data and add to the array
348
      $format = NULL;
349
      if (isset($definition['format_key']) && isset($storage[$definition['format_key']])) {
350
        $format = $storage[$definition['format_key']];
351
      }
352
      $translatable[] = array(
353
        'value' => $value,
354
        'keys' => isset($translation_keys) ? $translation_keys : $parents,
355
        'format' => $format,
356
      );
357
    }
358
  }
359
}