Project

General

Profile

Paste
Download (5.91 KB) Statistics
| Branch: | Revision:

root / drupal7 / sites / all / modules / entity / entity.features.inc @ 7d7b5830

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
function entity_features_get_controller($type) {
12
  $static = &drupal_static(__FUNCTION__);
13
  if (!isset($static[$type])) {
14
    $info = entity_get_info($type);
15
    $info += array('features controller class' => 'EntityDefaultFeaturesController');
16
    $static[$type] = $info['features controller class'] ? new $info['features controller class']($type) : FALSE;
17
  }
18
  return $static[$type];
19
}
20

    
21
/**
22
 * Default controller handling features integration.
23
 */
24
class EntityDefaultFeaturesController {
25

    
26
  protected $type, $info;
27

    
28
  public function __construct($type) {
29
    $this->type = $type;
30
    $this->info = entity_get_info($type);
31
    $this->info['entity keys'] += array('module' => 'module', 'status' => 'status');
32
    $this->statusKey = $this->info['entity keys']['status'];
33
    $this->moduleKey = $this->info['entity keys']['module'];
34
    if (!empty($this->info['bundle of'])) {
35
      $entity_info = entity_get_info($this->info['bundle of']);
36
      $this->bundleKey = $entity_info['bundle keys']['bundle'];
37
    }
38
  }
39

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

    
57
  /**
58
   * Generates the result for hook_features_export_options().
59
   */
60
  public function export_options() {
61
    $options = array();
62
    foreach (entity_load_multiple_by_name($this->type, FALSE) as $name => $entity) {
63
      $options[$name] = entity_label($this->type, $entity);
64
    }
65
    return $options;
66
  }
67

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

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

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

    
119
    $hook = isset($this->info['export']['default hook']) ? $this->info['export']['default hook'] : 'default_' . $this->type;
120
    return array($hook => $output);
121
  }
122

    
123
  /**
124
   * Generates the result for hook_features_revert().
125
   */
126
  function revert($module = NULL) {
127
    if ($defaults = features_get_default($this->type, $module)) {
128
      foreach ($defaults as $name => $entity) {
129
        entity_delete($this->type, $name);
130
      }
131
    }
132
  }
133
}
134

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

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

    
159
/**
160
 * Features component callback.
161
 */
162
function entity_features_export($data, &$export, $module_name = '', $entity_type) {
163
  return entity_features_get_controller($entity_type)->export($data, $export, $module_name);
164
}
165

    
166
/**
167
 * Features component callback.
168
 */
169
function entity_features_export_render($module, $data, $export = NULL, $entity_type) {
170
  return entity_features_get_controller($entity_type)->export_render($module, $data, $export);
171
}
172

    
173
/**
174
 * Features component callback.
175
 */
176
function entity_features_revert($module = NULL, $entity_type) {
177
  return entity_features_get_controller($entity_type)->revert($module);
178
}