Projet

Général

Profil

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

root / drupal7 / sites / all / modules / entity / includes / entity.inc @ 651307cd

1
<?php
2

    
3
/**
4
 * @file
5
 * Provides a base class for entities.
6
 */
7

    
8
/**
9
 * Interface for class based entities.
10
 */
11
interface EntityInterface {
12

    
13
  /**
14
   * Returns the internal, numeric identifier.
15
   *
16
   * Returns the numeric identifier, even if the entity type has specified a
17
   * name key. In the latter case, the numeric identifier is supposed to be used
18
   * when dealing generically with entities or internally to refer to an entity,
19
   * i.e. in a relational database. If unsure, use Entity:identifier().
20
   */
21
  public function internalIdentifier();
22

    
23
  /**
24
   * Returns the entity identifier, i.e. the entities name or numeric id.
25
   *
26
   * @return
27
   *   The identifier of the entity. If the entity type makes use of a name key,
28
   *   the name is returned, else the numeric id.
29
   *
30
   * @see entity_id()
31
   */
32
  public function identifier();
33

    
34
  /**
35
   * Returns the info of the type of the entity.
36
   *
37
   * @see entity_get_info()
38
   */
39
  public function entityInfo();
40

    
41
  /**
42
   * Returns the type of the entity.
43
   */
44
  public function entityType();
45

    
46
  /**
47
   * Returns the bundle of the entity.
48
   *
49
   * @return
50
   *   The bundle of the entity. Defaults to the entity type if the entity type
51
   *   does not make use of different bundles.
52
   */
53
  public function bundle();
54

    
55
  /**
56
   * Returns the EntityMetadataWrapper of the entity.
57
   *
58
   * @return EntityDrupalWrapper
59
   *   An EntityMetadataWrapper containing the entity.
60
   */
61
  public function wrapper();
62

    
63
  /**
64
   * Returns the label of the entity.
65
   *
66
   * Modules may alter the label by specifying another 'label callback' using
67
   * hook_entity_info_alter().
68
   *
69
   * @see entity_label()
70
   */
71
  public function label();
72

    
73
  /**
74
   * Returns the uri of the entity just as entity_uri().
75
   *
76
   * Modules may alter the uri by specifying another 'uri callback' using
77
   * hook_entity_info_alter().
78
   *
79
   * @see entity_uri()
80
   */
81
  public function uri();
82

    
83
  /**
84
   * Checks if the entity has a certain exportable status.
85
   *
86
   * @param $status
87
   *   A status constant, i.e. one of ENTITY_CUSTOM, ENTITY_IN_CODE,
88
   *   ENTITY_OVERRIDDEN or ENTITY_FIXED.
89
   *
90
   * @return bool
91
   *   For exportable entities TRUE if the entity has the status, else FALSE.
92
   *   In case the entity is not exportable, NULL is returned.
93
   *
94
   * @see entity_has_status()
95
   */
96
  public function hasStatus($status);
97

    
98
  /**
99
   * Permanently saves the entity.
100
   *
101
   * @see entity_save()
102
   */
103
  public function save();
104

    
105
  /**
106
   * Permanently deletes the entity.
107
   *
108
   * @see entity_delete()
109
   */
110
  public function delete();
111

    
112
  /**
113
   * Exports the entity.
114
   *
115
   * @see entity_export()
116
   */
117
  public function export($prefix = '');
118

    
119
  /**
120
   * Generate an array for rendering the entity.
121
   *
122
   * @see entity_view()
123
   */
124
  public function view($view_mode = 'full', $langcode = NULL, $page = NULL);
125

    
126
  /**
127
   * Builds a structured array representing the entity's content.
128
   *
129
   * @see entity_build_content()
130
   */
131
  public function buildContent($view_mode = 'full', $langcode = NULL);
132

    
133
  /**
134
   * Gets the raw, translated value of a property or field.
135
   *
136
   * Supports retrieving field translations as well as i18n string translations.
137
   *
138
   * Note that this returns raw data values, which might not reflect what
139
   * has been declared for hook_entity_property_info() as no 'getter callbacks'
140
   * are invoked or no referenced entities are loaded. For retrieving values
141
   * reflecting the property info make use of entity metadata wrappers, see
142
   * entity_metadata_wrapper().
143
   *
144
   * @param $property
145
   *   The name of the property to return; e.g., 'title'.
146
   * @param $langcode
147
   *   (optional) The language code of the language to which the value should
148
   *   be translated. If set to NULL, the default display language is being
149
   *   used.
150
   *
151
   * @return
152
   *   The raw, translated property value; or the raw, un-translated value if no
153
   *   translation is available.
154
   *
155
   * @todo Implement an analogous setTranslation() method for updating.
156
   */
157
  public function getTranslation($property, $langcode = NULL);
158

    
159
  /**
160
   * Checks whether the entity is the default revision.
161
   *
162
   * @return Boolean
163
   *
164
   * @see entity_revision_is_default()
165
   */
166
  public function isDefaultRevision();
167

    
168
}
169

    
170
/**
171
 * A common class for entities.
172
 *
173
 * It's suggested, but not required, to extend this class and to override
174
 * __construct() in order to specify a fixed entity type.
175
 *
176
 * For providing an entity label and URI it is suggested to override the
177
 * defaultLabel() and defaultUri() methods, and to specify the
178
 * entity_class_label() and entity_class_uri() as respective callbacks in
179
 * hook_entity_info(). That way modules are able to override your defaults
180
 * by altering the hook_entity_info() callbacks, while $entity->label() and
181
 * $entity->uri() reflect this changes as well.
182
 *
183
 * Defaults for entity properties can be easily defined by adding class
184
 * properties, e.g.:
185
 * @code
186
 *   public $name = '';
187
 *   public $count = 0;
188
 * @endcode
189
 */
190
class Entity implements EntityInterface {
191

    
192
  protected $entityType;
193
  protected $entityInfo;
194
  protected $idKey, $nameKey, $statusKey;
195
  protected $defaultLabel = FALSE;
196
  protected $wrapper;
197

    
198
  /**
199
   * {@inheritdoc}
200
   */
201
  public function __construct(array $values = array(), $entityType = NULL) {
202
    if (empty($entityType)) {
203
      throw new Exception('Cannot create an instance of Entity without a specified entity type.');
204
    }
205
    $this->entityType = $entityType;
206
    $this->setUp();
207
    // Set initial values.
208
    foreach ($values as $key => $value) {
209
      $this->$key = $value;
210
    }
211
  }
212

    
213
  /**
214
   * Set up the object instance on construction or unserializiation.
215
   */
216
  protected function setUp() {
217
    $this->entityInfo = entity_get_info($this->entityType);
218
    $this->idKey = $this->entityInfo['entity keys']['id'];
219
    $this->nameKey = isset($this->entityInfo['entity keys']['name']) ? $this->entityInfo['entity keys']['name'] : $this->idKey;
220
    $this->statusKey = empty($this->entityInfo['entity keys']['status']) ? 'status' : $this->entityInfo['entity keys']['status'];
221
  }
222

    
223
  /**
224
   * {@inheritdoc}
225
   */
226
  public function internalIdentifier() {
227
    return isset($this->{$this->idKey}) ? $this->{$this->idKey} : NULL;
228
  }
229

    
230
  /**
231
   * {@inheritdoc}
232
   */
233
  public function identifier() {
234
    return isset($this->{$this->nameKey}) ? $this->{$this->nameKey} : NULL;
235
  }
236

    
237
  /**
238
   * {@inheritdoc}
239
   */
240
  public function entityInfo() {
241
    return $this->entityInfo;
242
  }
243

    
244
  /**
245
   * {@inheritdoc}
246
   */
247
  public function entityType() {
248
    return $this->entityType;
249
  }
250

    
251
  /**
252
   * {@inheritdoc}
253
   */
254
  public function bundle() {
255
    return !empty($this->entityInfo['entity keys']['bundle']) ? $this->{$this->entityInfo['entity keys']['bundle']} : $this->entityType;
256
  }
257

    
258
  /**
259
   * {@inheritdoc}
260
   */
261
  public function wrapper() {
262
    if (empty($this->wrapper)) {
263
      $this->wrapper = entity_metadata_wrapper($this->entityType, $this);
264
    }
265
    elseif ($this->wrapper->value() !== $this) {
266
      // Wrapper has been modified outside, so let's better create a new one.
267
      $this->wrapper = entity_metadata_wrapper($this->entityType, $this);
268
    }
269
    return $this->wrapper;
270
  }
271

    
272
  /**
273
   * {@inheritdoc}
274
   */
275
  public function label() {
276
    // If the default label flag is enabled, this is being invoked recursively.
277
    // In this case we need to use our default label callback directly. This may
278
    // happen if a module provides a label callback implementation different
279
    // from ours, but then invokes Entity::label() or entity_class_label() from
280
    // there.
281
    if ($this->defaultLabel || (isset($this->entityInfo['label callback']) && $this->entityInfo['label callback'] == 'entity_class_label')) {
282
      return $this->defaultLabel();
283
    }
284
    $this->defaultLabel = TRUE;
285
    $label = entity_label($this->entityType, $this);
286
    $this->defaultLabel = FALSE;
287
    return $label;
288
  }
289

    
290
  /**
291
   * Defines the entity label if the 'entity_class_label' callback is used.
292
   *
293
   * Specify 'entity_class_label' as 'label callback' in hook_entity_info() to
294
   * let the entity label point to this method. Override this in order to
295
   * implement a custom default label.
296
   */
297
  protected function defaultLabel() {
298
    // Add in the translated specified label property.
299
    return $this->getTranslation($this->entityInfo['entity keys']['label']);
300
  }
301

    
302
  /**
303
   * {@inheritdoc}
304
   */
305
  public function uri() {
306
    if (isset($this->entityInfo['uri callback']) && $this->entityInfo['uri callback'] == 'entity_class_uri') {
307
      return $this->defaultUri();
308
    }
309
    return entity_uri($this->entityType, $this);
310
  }
311

    
312
  /**
313
   * Override this in order to implement a custom default URI and specify
314
   * 'entity_class_uri' as 'uri callback' hook_entity_info().
315
   */
316
  protected function defaultUri() {
317
    return array('path' => 'default/' . $this->identifier());
318
  }
319

    
320
  /**
321
   * {@inheritdoc}
322
   */
323
  public function hasStatus($status) {
324
    if (!empty($this->entityInfo['exportable'])) {
325
      return isset($this->{$this->statusKey}) && ($this->{$this->statusKey} & $status) == $status;
326
    }
327
  }
328

    
329
  /**
330
   * {@inheritdoc}
331
   */
332
  public function save() {
333
    return entity_get_controller($this->entityType)->save($this);
334
  }
335

    
336
  /**
337
   * {@inheritdoc}
338
   */
339
  public function delete() {
340
    $id = $this->identifier();
341
    if (isset($id)) {
342
      entity_get_controller($this->entityType)->delete(array($id));
343
    }
344
  }
345

    
346
  /**
347
   * {@inheritdoc}
348
   */
349
  public function export($prefix = '') {
350
    return entity_get_controller($this->entityType)->export($this, $prefix);
351
  }
352

    
353
  /**
354
   * {@inheritdoc}
355
   */
356
  public function view($view_mode = 'full', $langcode = NULL, $page = NULL) {
357
    return entity_get_controller($this->entityType)->view(array($this), $view_mode, $langcode, $page);
358
  }
359

    
360
  /**
361
   * {@inheritdoc}
362
   */
363
  public function buildContent($view_mode = 'full', $langcode = NULL) {
364
    return entity_get_controller($this->entityType)->buildContent($this, $view_mode, $langcode);
365
  }
366

    
367
  /**
368
   * {@inheritdoc}
369
   */
370
  public function getTranslation($property, $langcode = NULL) {
371
    $all_info = entity_get_all_property_info($this->entityType);
372
    // Assign by reference to avoid triggering notices if metadata is missing.
373
    $property_info = &$all_info[$property];
374

    
375
    if (!empty($property_info['translatable'])) {
376
      if (!empty($property_info['field'])) {
377
        return field_get_items($this->entityType, $this, $property, $langcode);
378
      }
379
      elseif (!empty($property_info['i18n string'])) {
380
        $name = $this->entityInfo['module'] . ':' . $this->entityType . ':' . $this->identifier() . ':' . $property;
381
        return entity_i18n_string($name, $this->$property, $langcode);
382
      }
383
    }
384
    return $this->$property;
385
  }
386

    
387
  /**
388
   * {@inheritdoc}
389
   */
390
  public function isDefaultRevision() {
391
    if (!empty($this->entityInfo['entity keys']['revision'])) {
392
      $key = !empty($this->entityInfo['entity keys']['default revision']) ? $this->entityInfo['entity keys']['default revision'] : 'default_revision';
393
      return !empty($this->$key);
394
    }
395
    return TRUE;
396
  }
397

    
398
  /**
399
   * Magic method to only serialize what's necessary.
400
   */
401
  public function __sleep() {
402
    $vars = get_object_vars($this);
403
    unset($vars['entityInfo'], $vars['idKey'], $vars['nameKey'], $vars['statusKey']);
404
    // Also key the returned array with the variable names so the method may
405
    // be easily overridden and customized.
406
    return drupal_map_assoc(array_keys($vars));
407
  }
408

    
409
  /**
410
   * Magic method to invoke setUp() on unserialization.
411
   */
412
  public function __wakeup() {
413
    $this->setUp();
414
  }
415
}
416

    
417
/**
418
 * These classes are deprecated by "Entity" and are only here for backward
419
 * compatibility reasons.
420
 */
421
class EntityDB extends Entity {}
422
class EntityExtendable extends Entity {}
423
class EntityDBExtendable extends Entity {}