Projet

Général

Profil

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

root / drupal7 / sites / all / modules / uuid / uuid_services / uuid_services.module @ e7101f36

1
<?php
2

    
3
/**
4
 * Implementation of hook_menu().
5
 */
6
function uuid_services_menu() {
7
  $items['admin/config/services/uuid-services'] = array(
8
    'title' => 'UUID Services',
9
    'description' => 'Configure settings for Module Filter.',
10
    'access arguments' => array('administer services'),
11
    'page callback' => 'drupal_get_form',
12
    'page arguments' => array('uuid_services_settings'),
13
    'file' => 'uuid_services.admin.inc'
14
  );
15
  return $items;
16
}
17

    
18
/**
19
 * Implements hook_services_resources_alter().
20
 *
21
 * Alter all resources that support UUIDs, to make use this functionality when
22
 * exposing them through Services.
23
 *
24
 * Since we are working with UUID enabled entities, the 'create' method is
25
 * redundant. Instead, clients should do a PUT to '<entity_type>/<uuid>'. This
26
 * will route through the 'update' method and create the entity if it doesn't
27
 * exist. This is the most logical thing to do, since it's up to the client to
28
 * generate and set the UUID on the entity.
29
 */
30
function uuid_services_services_resources_alter(&$resources, &$endpoint) {
31
  foreach (entity_get_info() as $entity_type => $entity_info) {
32
    if (isset($entity_info['uuid']) && $entity_info['uuid'] == TRUE && (isset($resources[$entity_type]) || variable_get('uuid_services_support_all_entity_types', FALSE))) {
33
      unset($resources[$entity_type]['operations']['create']);
34

    
35
      // Alter 'retrieve' method to use UUID enabled functions and arguments.
36
      $resources[$entity_type]['operations']['retrieve']['help'] = t('Retrieve %label entities based on UUID.', array('%label' => $entity_info['label']));
37
      $resources[$entity_type]['operations']['retrieve']['callback'] = '_uuid_services_entity_retrieve';
38
      $resources[$entity_type]['operations']['retrieve']['access callback'] = '_uuid_services_entity_access';
39
      $resources[$entity_type]['operations']['retrieve']['access arguments'] = array('view');
40
      $resources[$entity_type]['operations']['retrieve']['access arguments append'] = TRUE;
41
      $resources[$entity_type]['operations']['retrieve']['args'] = array(
42
        // This argument isn't exposed in the service, only used internally..
43
        array(
44
          'name' => 'entity_type',
45
          'description' => t('The entity type.'),
46
          'type' => 'string',
47
          'default value' => $entity_type,
48
          'optional' => TRUE,
49
        ),
50
        array(
51
          'name' => 'uuid',
52
          'description' => t('The %label UUID.', array('%label' => $entity_info['label'])),
53
          'type' => 'text',
54
          'source' => array('path' => 0),
55
        ),
56
      );
57

    
58
      // Alter 'update' method to use UUID enabled functions and arguments.
59
      $resources[$entity_type]['operations']['update']['help'] = t('Update or create %label entities based on UUID. The payload must be formatted according to the <a href="!url">OData protocol</a>.', array('%label' => $entity_info['label'], '!url' => 'http://www.odata.org/developers/protocols'));
60
      $resources[$entity_type]['operations']['update']['callback'] = '_uuid_services_entity_update';
61
      $resources[$entity_type]['operations']['update']['access callback'] = '_uuid_services_entity_access';
62
      $resources[$entity_type]['operations']['update']['access arguments'] = array('update');
63
      $resources[$entity_type]['operations']['update']['access arguments append'] = TRUE;
64
      $resources[$entity_type]['operations']['update']['args'] = array(
65
        // This argument isn't exposed in the service, only used internally..
66
        array(
67
          'name' => 'entity_type',
68
          'description' => t('The entity type.'),
69
          'type' => 'string',
70
          'default value' => $entity_type,
71
          'optional' => TRUE,
72
        ),
73
        array(
74
          'name' => 'uuid',
75
          'description' => t('The %label UUID.', array('%label' => $entity_info['label'])),
76
          'type' => 'text',
77
          'source' => array('path' => 0),
78
        ),
79
        array(
80
          'name' => 'entity',
81
          'description' => t('The %label entity object.', array('%label' => $entity_info['label'])),
82
          'type' => 'struct',
83
          'source' => 'data',
84
        ),
85
      );
86

    
87
      // Alter 'delete' method to use UUID enabled functions and arguments.
88
      $resources[$entity_type]['operations']['delete']['help'] = t('Delete %label entities based on UUID.', array('%label' => $entity_info['label']));
89
      $resources[$entity_type]['operations']['delete']['callback'] = '_uuid_services_entity_delete';
90
      $resources[$entity_type]['operations']['delete']['access callback'] = '_uuid_services_entity_access';
91
      $resources[$entity_type]['operations']['delete']['access arguments'] = array('delete');
92
      $resources[$entity_type]['operations']['delete']['access arguments append'] = TRUE;
93
      $resources[$entity_type]['operations']['delete']['args'] = array(
94
        // This argument isn't exposed in the service, only used internally..
95
        array(
96
          'name' => 'entity_type',
97
          'description' => t('The entity type.'),
98
          'type' => 'string',
99
          'default value' => $entity_type,
100
          'optional' => TRUE,
101
        ),
102
        array(
103
          'name' => 'uuid',
104
          'description' => t('The %label UUID.', array('%label' => $entity_info['label'])),
105
          'type' => 'text',
106
          'source' => array('path' => 0),
107
        ),
108
      );
109
    }
110
  }
111
}
112

    
113
/**
114
 * Callback for the 'retrieve' method.
115
 *
116
 * @see entity_uuid_load()
117
 */
118
function _uuid_services_entity_retrieve($entity_type, $uuid) {
119
  try {
120
    $entities = entity_uuid_load($entity_type, array($uuid));
121
    $entity = reset($entities);
122
    return $entity;
123
  }
124
  catch (Exception $exception) {
125
    watchdog_exception('uuid_services', $exception);
126
    return services_error($exception, 406, $uuid);
127
  }
128
}
129

    
130
/**
131
 * Callback for the 'update' method.
132
 *
133
 * @see entity_uuid_save()
134
 */
135
function _uuid_services_entity_update($entity_type, $uuid, $entity) {
136
  try {
137
    $controller = entity_get_controller($entity_type);
138
    if ($controller instanceof EntityAPIControllerInterface) {
139
      $entity = $controller->create($entity);
140
    }
141
    else {
142
      $entity = (object) $entity;
143
    }
144
    $entity->uuid_services = TRUE;
145
    entity_uuid_save($entity_type, $entity);
146
    return $entity;
147
  }
148
  catch (Exception $exception) {
149
    watchdog_exception('uuid_services', $exception);
150
    return services_error($exception, 406, $entity);
151
  }
152
}
153

    
154
/**
155
 * Callback for the 'delete' method.
156
 *
157
 * @see entity_uuid_delete()
158
 */
159
function _uuid_services_entity_delete($entity_type, $uuid) {
160
  try {
161
    $return = entity_uuid_delete($entity_type, array($uuid));
162
    return $return;
163
  }
164
  catch (Exception $exception) {
165
    watchdog_exception('uuid_services', $exception);
166
    return services_error($exception, 406, $uuid);
167
  }
168
}
169

    
170
/**
171
 * Access callback.
172
 *
173
 * @param $op
174
 *   The operation we are trying to do on the entity. Can only be:
175
 *   - "view"
176
 *   - "update"
177
 *   - "delete"
178
 *   See 'uuid_services_services_resources_alter()' for an explanation why
179
 *   'create' is missing.
180
 * @param $args
181
 *   The arguments passed to the method. The keys are holding the following:
182
 *   0. <entity_type>
183
 *   1. <uuid>
184
 *   2. <entity> (only available if $op == 'update')
185
 */
186
function _uuid_services_entity_access($op, $args) {
187
  try {
188
    // Fetch the information we have to work with.
189
    $entity_type = $args[0];
190
    // Load functions always deal with multiple entities. So does this lookup
191
    // function. But in practice this will always only be one id.
192
    $entity_ids = entity_get_id_by_uuid($entity_type, array($args[1]));
193
    $entity = NULL;
194
    if (!empty($args[2])) {
195
      $entity = entity_create($entity_type, $args[2]);
196
      // We have to make the entity local (i.e. only have local references), for
197
      // access functions to work on it.
198
      entity_make_entity_local($entity_type, $entity);
199
    }
200
    // Fetch the local entity if we've got an id.
201
    elseif (!empty($entity_ids)) {
202
      $entities = entity_load($entity_type, $entity_ids);
203
      $entity = reset($entities);
204
    }
205

    
206
    // If we've been routed to the 'update' method and the entity we are
207
    // operating on doesn't exist yet, that should be reflected.
208
    if ($op == 'update' && empty($entity_ids)) {
209
      $op = 'create';
210
    }
211
    // Taxonomy and Comment module uses 'edit' instead of 'update'.
212
    // Oh, how I love Drupal consistency.
213
    if (($entity_type == 'taxonomy_term' || $entity_type == 'comment') && $op == 'update') {
214
      $op = 'edit';
215
    }
216
    // The following code is taken from entity_access() with some extra logic
217
    // to handle the case where an entity type is not defining an access
218
    // callback. With this logic, it's important that all entity types that
219
    // needs access control have an access callback defined.
220
    if (($info = entity_get_info()) && isset($info[$entity_type]['access callback'])) {
221
      return $info[$entity_type]['access callback']($op, $entity, NULL, $entity_type);
222
    }
223
    return TRUE;
224
  }
225
  catch (Exception $exception) {
226
    watchdog_exception('uuid_services', $exception);
227
    return services_error($exception, 406, $entity_type);
228
  }
229
}
230

    
231
/**
232
 * Implements hook_services_resources().
233
 */
234
function uuid_services_services_resources() {
235
  module_load_include('inc', 'uuid_services', 'resources/field_collection.resource');
236

    
237
  $resources = array(
238
    '#api_version' => 3002,
239
  );
240

    
241
  $resources += _field_collection_resource_definition();
242

    
243
  return $resources;
244
}