Projet

Général

Profil

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

root / drupal7 / sites / all / modules / entity / entity.features.inc @ b42754b9

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
            $pipe['field_instance'][] = "{$field['entity_type']}-{$field['bundle']}-{$field['field_name']}";
95
          }
96
        }
97
      }
98
    }
99
    // Add the module providing the entity type as dependency.
100
    if ($data && !empty($this->info['module'])) {
101
      $export['dependencies'][$this->info['module']] = $this->info['module'];
102
      // In case entity is not already an indirect dependency, add it.
103
      // We can do so without causing redundant dependencies because,
104
      // if entity is an indirect dependency, Features will filter it out.
105
      $export['dependencies']['entity'] = 'entity';
106
    }
107
    return $pipe;
108
  }
109

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

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

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

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

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

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

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

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

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