Projet

Général

Profil

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

root / drupal7 / sites / all / modules / entity / entity.features.inc @ 5136ce55

1
<?php
2

    
3
/**
4
 * @file
5
 * Provides Features integration for entity types using the CRUD API.
6
 */
7

    
8
/**
9
 * Returns the configured entity features controller.
10
 *
11
 * @param string $type
12
 *   The entity type to get the controller for.
13
 *
14
 * @return EntityDefaultFeaturesController
15
 *   The configured entity features controller.
16
 */
17
function entity_features_get_controller($type) {
18
  $static = &drupal_static(__FUNCTION__);
19
  if (!isset($static[$type])) {
20
    $info = entity_get_info($type);
21
    $info += array('features controller class' => 'EntityDefaultFeaturesController');
22
    $static[$type] = $info['features controller class'] ? new $info['features controller class']($type) : FALSE;
23
  }
24
  return $static[$type];
25
}
26

    
27
/**
28
 * Default controller handling features integration.
29
 */
30
class EntityDefaultFeaturesController {
31

    
32
  protected $type, $info;
33

    
34
  public function __construct($type) {
35
    $this->type = $type;
36
    $this->info = entity_get_info($type);
37
    $this->info['entity keys'] += array('module' => 'module', 'status' => 'status');
38
    $this->statusKey = $this->info['entity keys']['status'];
39
    $this->moduleKey = $this->info['entity keys']['module'];
40
    if (!empty($this->info['bundle of'])) {
41
      $entity_info = entity_get_info($this->info['bundle of']);
42
      $this->bundleKey = $entity_info['bundle keys']['bundle'];
43
    }
44
  }
45

    
46
  /**
47
   * Defines the result for hook_features_api().
48
   */
49
  public function api() {
50
    return array(
51
      // The entity type has to be the features component name.
52
      $this->type => array(
53
        'name' => $this->info['label'],
54
        'feature_source' => TRUE,
55
        'default_hook' => isset($this->info['export']['default hook']) ? $this->info['export']['default hook'] : 'default_' . $this->type,
56
        // Use the provided component callbacks making use of the controller.
57
        'base' => 'entity',
58
        'file' => drupal_get_path('module', 'entity') . '/entity.features.inc',
59
      ),
60
    );
61
  }
62

    
63
  /**
64
   * Generates the result for hook_features_export_options().
65
   */
66
  public function export_options() {
67
    $options = array();
68
    foreach (entity_load_multiple_by_name($this->type, FALSE) as $name => $entity) {
69
      $options[$name] = entity_label($this->type, $entity);
70
    }
71
    return $options;
72
  }
73

    
74
  /**
75
   * Generates the result for hook_features_export().
76
   */
77
  public function export($data, &$export, $module_name = '') {
78
    $pipe = array();
79
    foreach (entity_load_multiple_by_name($this->type, $data) as $name => $entity) {
80
      // If this entity is provided by a different module, add it as dependency.
81
      if (($entity->{$this->statusKey} & ENTITY_IN_CODE) && $entity->{$this->moduleKey} != $module_name) {
82
        $module = $entity->{$this->moduleKey};
83
        $export['dependencies'][$module] = $module;
84
      }
85
      // Otherwise export the entity.
86
      else {
87
        $export['features'][$this->type][$name] = $name;
88

    
89
        // If this is a bundle of a fieldable entity, add its fields to the pipe.
90
        if (!empty($this->info['bundle of'])) {
91
          $fields = field_info_instances($this->info['bundle of'], $entity->{$this->bundleKey});
92
          foreach ($fields as $name => $field) {
93
            $pipe['field'][] = "{$field['entity_type']}-{$field['bundle']}-{$field['field_name']}";
94
          }
95
        }
96
      }
97
    }
98
    // Add the module providing the entity type as dependency.
99
    if ($data && !empty($this->info['module'])) {
100
      $export['dependencies'][$this->info['module']] = $this->info['module'];
101
      // In case entity is not already an indirect dependency, add it.
102
      // We can do so without causing redundant dependencies because,
103
      // if entity is an indirect dependency, Features will filter it out.
104
      $export['dependencies']['entity'] = 'entity';
105
    }
106
    return $pipe;
107
  }
108

    
109
  /**
110
   * Generates the result for hook_features_export_render().
111
   */
112
  function export_render($module, $data, $export = NULL) {
113
    $output = array();
114
    $output[] = '  $items = array();';
115
    foreach (entity_load_multiple_by_name($this->type, $data) as $name => $entity) {
116
      $export  = "  \$items['$name'] = entity_import('{$this->type}', '";
117
      // Make sure to escape the characters \ and '.
118
      $export .= addcslashes(entity_export($this->type, $entity, '  '), '\\\'');
119
      $export .= "');";
120
      $output[] = $export;
121
    }
122
    $output[] = '  return $items;';
123
    $output = implode("\n", $output);
124

    
125
    $hook = isset($this->info['export']['default hook']) ? $this->info['export']['default hook'] : 'default_' . $this->type;
126
    return array($hook => $output);
127
  }
128

    
129
  /**
130
   * Generates the result for hook_features_revert().
131
   */
132
  function revert($module = NULL) {
133
    if ($defaults = features_get_default($this->type, $module)) {
134
      foreach ($defaults as $name => $entity) {
135
        entity_delete($this->type, $name);
136
      }
137
    }
138
  }
139
}
140

    
141
/**
142
 * Implements of hook_features_api().
143
 */
144
function entity_features_api() {
145
  $items = array();
146
  foreach (entity_crud_get_info() as $type => $info) {
147
    if (!empty($info['exportable']) && $controller = entity_features_get_controller($type)) {
148
      $items += $controller->api();
149
    }
150
  }
151
  return $items;
152
}
153

    
154
/**
155
 * Implements hook_features_export_options().
156
 *
157
 * Features component callback.
158
 */
159
function entity_features_export_options($a1, $a2 = NULL) {
160
  // Due to a change in the Features API the first parameter might be a feature
161
  // object or an entity type, depending on the Features version. This check is
162
  // for backwards compatibility.
163
  $entity_type = is_string($a1) ? $a1 : $a2;
164
  return entity_features_get_controller($entity_type)->export_options();
165
}
166

    
167
/**
168
 * Implements hook_features_export().
169
 *
170
 * Features component callback.
171
 */
172
function entity_features_export($data, &$export, $module_name = '', $entity_type) {
173
  return entity_features_get_controller($entity_type)->export($data, $export, $module_name);
174
}
175

    
176
/**
177
 * Implements hook_features_export_render().
178
 *
179
 * Features component callback.
180
 */
181
function entity_features_export_render($module, $data, $export = NULL, $entity_type) {
182
  return entity_features_get_controller($entity_type)->export_render($module, $data, $export);
183
}
184

    
185
/**
186
 * Implements hook_features_revert().
187
 *
188
 * Features component callback.
189
 */
190
function entity_features_revert($module = NULL, $entity_type) {
191
  return entity_features_get_controller($entity_type)->revert($module);
192
}
193

    
194
/**
195
 * Implements hook_features_post_restore().
196
 *
197
 * Rebuild all defaults when a features rebuild is triggered - even the ones not
198
 * handled by features itself.
199
 */
200
function entity_features_post_restore($op, $items = array()) {
201
  if ($op == 'rebuild') {
202
    // Use features rebuild to rebuild the features independent exports too.
203
    entity_defaults_rebuild();
204
  }
205
}