entity_test.module 15.1 KB
Newer Older
1
2
3
4
<?php

/**
 * @file
5
 * Test module for the entity API providing several entity types for testing.
6
7
 */

8
use Drupal\Core\Entity\EntityInterface;
9
10
11
use Drupal\entity\Entity\EntityFormDisplay;
use Drupal\field\Entity\Field;
use Drupal\field\Entity\FieldInstance;
12

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
/**
 * Filter that limits test entity list to revisable ones.
 */
const ENTITY_TEST_TYPES_REVISABLE = 1;

/**
 * Filter that limits test entity list to multilingual ones.
 */
const ENTITY_TEST_TYPES_MULTILINGUAL = 2;

/**
 * Returns a list of test entity types.
 *
 * The returned entity types are one for each available entity storage type:
 * - The plain entity_test type supports neither revisions nor multilingual
 *   properties.
 * - The entity_test_mul type supports multilingual properties.
 * - The entity_test_rev type supports revisions.
 * - The entity_test_mulrev type supports both revisions and multilingual
 *   properties.
 *
 * @param int $filter
 *   Either ENTITY_TEST_TYPES_REVISABLE to only return revisable entity types or
 *   ENTITY_TEST_TYPES_MULTILINGUAL to only return multilingual ones. Defaults
 *   to NULL, which returns all.
 *
 * @return array
 *   List with entity_types.
 */
function entity_test_entity_types($filter = NULL) {
  $types = array();
  if ($filter == NULL) {
    $types[] = 'entity_test';
  }
  if ($filter != ENTITY_TEST_TYPES_REVISABLE) {
    $types[] = 'entity_test_mul';
  }
  if ($filter != ENTITY_TEST_TYPES_MULTILINGUAL) {
    $types[] = 'entity_test_rev';
  }
  $types[] = 'entity_test_mulrev';
  return drupal_map_assoc($types);
}
56

57
/**
58
 * Implements hook_entity_info_alter().
59
 */
60
function entity_test_entity_info_alter(&$info) {
61
  // Optionally specify a translation handler for testing translations.
62
  if (\Drupal::state()->get('entity_test.translation')) {
63
64
65
    foreach(entity_test_entity_types() as $entity_type) {
      $info[$entity_type]['translation'][$entity_type] = TRUE;
    }
66
  }
67
68
}

69
70
71
72
73
74
75
76
77
78
79
80
81
/**
 * Creates a new bundle for entity_test entities.
 *
 * @param string $bundle
 *   The machine-readable name of the bundle.
 * @param string $text
 *   (optional) The human-readable name of the bundle. If none is provided, the
 *   machine name will be used.
 * @param string $entity_type
 *   (optional) The entity type for which the bundle is created. Defaults to
 *   'entity_test'.
 */
function entity_test_create_bundle($bundle, $text = NULL, $entity_type = 'entity_test') {
82
  $bundles = \Drupal::state()->get($entity_type . '.bundles') ?: array('entity_test' => array('label' => 'Entity Test Bundle'));
83
  $bundles += array($bundle => array('label' => $text ? $text : $bundle));
84
  \Drupal::state()->set($entity_type . '.bundles', $bundles);
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100

  entity_invoke_bundle_hook('create', $entity_type, $bundle);
}

/**
 * Renames a bundle for entity_test entities.
 *
 * @param string $bundle_old
 *   The machine-readable name of the bundle to rename.
 * @param string $bundle_new
 *   The new machine-readable name of the bundle
 * @param string $entity_type
 *   (optional) The entity type for which the bundle is renamed. Defaults to
 *   'entity_test'.
 */
function entity_test_rename_bundle($bundle_old, $bundle_new, $entity_type = 'entity_test') {
101
  $bundles = \Drupal::state()->get($entity_type . '.bundles') ?: array('entity_test' => array('label' => 'Entity Test Bundle'));
102
103
  $bundles[$bundle_new] = $bundles[$bundle_old];
  unset($bundles[$bundle_old]);
104
  \Drupal::state()->set($entity_type . '.bundles', $bundles);
105
106
107
108
109
110
111
112
113
114
115
116
117
118

  entity_invoke_bundle_hook('rename', $entity_type, $bundle_old, $bundle_new);
}

/**
 * Deletes a bundle for entity_test entities.
 *
 * @param string $bundle
 *   The machine-readable name of the bundle to delete.
 * @param string $entity_type
 *   (optional) The entity type for which the bundle is deleted. Defaults to
 *   'entity_test'.
 */
function entity_test_delete_bundle($bundle, $entity_type = 'entity_test') {
119
  $bundles = \Drupal::state()->get($entity_type . '.bundles') ?: array('entity_test' => array('label' => 'Entity Test Bundle'));
120
  unset($bundles[$bundle]);
121
  \Drupal::state()->set($entity_type . '.bundles', $bundles);
122
123
124
125
126

  entity_invoke_bundle_hook('delete', $entity_type, $bundle);
}

/**
127
 * Implements hook_entity_bundle_info().
128
 */
129
130
function entity_test_entity_bundle_info() {
  $bundles = array();
131
  $entity_info = entity_get_info();
132
133
  foreach ($entity_info as $entity_type => $info) {
    if ($info['module'] == 'entity_test') {
134
      $bundles[$entity_type] = \Drupal::state()->get($entity_type . '.bundles') ?: array($entity_type => array('label' => 'Entity Test Bundle'));
135
136
    }
  }
137
  return $bundles;
138
139
}

140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/**
 * Implements hook_entity_view_mode_info_alter().
 */
function entity_test_entity_view_mode_info_alter(&$view_modes) {
  $entity_info = entity_get_info();
  foreach ($entity_info as $entity_type => $info) {
    if ($entity_info[$entity_type]['module'] == 'entity_test') {
      $view_modes[$entity_type] = array(
        'full' => array(
          'label' => t('Full object'),
          'status' => TRUE,
        ),
        'teaser' => array(
          'label' => t('Teaser'),
          'status' => TRUE,
        ),
      );
    }
  }
}

161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
/**
 * Implements hook_field_extra_fields().
 */
function entity_test_field_extra_fields() {
  $extra['entity_test']['entity_test'] = array(
    'display' => array(
      // Note: those extra fields do not currently display anything, they are
      // just used in \Drupal\entity\Tests\EntityDisplayTest to test the
      // behavior of entity display objects,
      'display_extra_field' => array(
        'label' => t('Display extra field'),
        'description' => t('An extra field on the display side.'),
        'weight' => 5,
        'visible' => TRUE,
      ),
      'display_extra_field_hidden' => array(
        'label' => t('Display extra field (hidden)'),
        'description' => t('An extra field on the display side, hidden by default.'),
        'visible' => FALSE,
      ),
    )
  );

  return $extra;
}

187
188
189
190
191
192
193
194
195
/**
 * Implements hook_permission().
 */
function entity_test_permission() {
  $permissions = array(
    'administer entity_test content' => array(
      'title' => t('Administer entity_test content'),
      'description' => t('Manage entity_test content'),
    ),
196
197
198
199
200
201
    'view test entity' => array(
      'title' => t('View test entities'),
    ),
    'view test entity translations' => array(
      'title' => t('View translations of test entities'),
    ),
202
203
204
205
206
207
208
209
210
211
  );
  return $permissions;
}

/**
 * Implements hook_menu().
 */
function entity_test_menu() {
  $items = array();

212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
  foreach(entity_test_entity_types() as $entity_type) {
    $items[$entity_type . '/add'] = array(
      'title' => 'Add an @type',
      'title arguments' => array('@type' => $entity_type),
      'page callback' => 'entity_test_add',
      'page arguments' => array($entity_type),
      'access arguments' => array('administer entity_test content'),
      'type' => MENU_NORMAL_ITEM,
    );

    $items[$entity_type . '/manage/%' . $entity_type] = array(
      'title' => 'Edit @type',
      'title arguments' => array('@type' => $entity_type),
      'page callback' => 'entity_test_edit',
      'page arguments' => array(2),
      'access arguments' => array('administer entity_test content'),
      'type' => MENU_NORMAL_ITEM,
    );

    $items[$entity_type . '/manage/%' . $entity_type . '/edit'] = array(
      'title' => 'Edit',
      'type' => MENU_DEFAULT_LOCAL_TASK,
    );
  }
236
237
238
239

  return $items;
}

240
241
242
243
244
/**
 * Implements hook_form_BASE_FORM_ID_alter().
 */
function entity_test_form_node_form_alter(&$form, &$form_state, $form_id) {
  $langcode = $form_state['controller']->getFormLangcode($form_state);
245
  \Drupal::state()->set('entity_test.form_langcode', $langcode);
246
247
}

248
249
/**
 * Menu callback: displays the 'Add new entity_test' form.
250
 *
251
252
253
 * @param string $entity_type
 *   Name of the entity type for which a create form should be displayed.
 *
254
255
256
257
 * @return array
 *   The processed form for a new entity_test.
 *
 * @see entity_test_menu()
258
 */
259
260
261
function entity_test_add($entity_type) {
  drupal_set_title(t('Create an @type', array('@type' => $entity_type)));
  $entity = entity_create($entity_type, array());
262
  return \Drupal::entityManager()->getForm($entity);
263
264
265
266
}

/**
 * Menu callback: displays the 'Edit existing entity_test' form.
267
 *
268
 * @param \Drupal\Core\Entity\EntityInterface $entity
269
270
271
 *   The entity to be edited.
 *
 * @return array
272
 *   The processed form for the edited entity.
273
274
 *
 * @see entity_test_menu()
275
 */
276
function entity_test_edit(EntityInterface $entity) {
277
  drupal_set_title($entity->label(), PASS_THROUGH);
278
  return \Drupal::entityManager()->getForm($entity);
279
280
}

281
282
283
/**
 * Loads a test entity.
 *
284
 * @param int $id
285
 *   A test entity ID.
286
 * @param bool $reset
287
288
 *   A boolean indicating that the internal cache should be reset.
 *
289
 * @return \Drupal\entity_test\Entity\EntityTest
290
 *   The loaded entity object, or NULL if the entity cannot be loaded.
291
292
 */
function entity_test_load($id, $reset = FALSE) {
293
  return entity_load('entity_test', $id, $reset);
294
295
296
}

/**
297
 * Loads a test entity.
298
 *
299
300
 * @param int $id
 *   A test entity ID.
301
 * @param bool $reset
302
303
 *   A boolean indicating that the internal cache should be reset.
 *
304
 * @return \Drupal\entity_test\Entity\EntityTestRev
305
 *   The loaded entity object, or NULL if the entity cannot be loaded.
306
 */
307
308
function entity_test_rev_load($id, $reset = FALSE) {
  return entity_load('entity_test_rev', $id, $reset);
309
310
311
}

/**
312
313
314
315
316
317
 * Loads a test entity.
 *
 * @param int $id
 *   A test entity ID.
 * @param bool $reset
 *   A boolean indicating that the internal cache should be reset.
318
 *
319
 * @return \Drupal\entity_test\Entity\EntityTestMul
320
 *   The loaded entity object, or FALSE if the entity cannot be loaded.
321
 */
322
323
function entity_test_mul_load($id, $reset = FALSE) {
  return entity_load('entity_test_mul', $id, $reset);
324
}
325
326

/**
327
328
329
330
331
332
333
 * Loads a test entity.
 *
 * @param int $id
 *   A test entity ID.
 * @param bool $reset
 *   A boolean indicating that the internal cache should be reset.
 *
334
 * @return \Drupal\entity_test\Entity\EntityTestMulRev
335
 *   The loaded entity object, or NULL if the entity cannot be loaded.
336
 */
337
338
function entity_test_mulrev_load($id, $reset = FALSE) {
  return entity_load('entity_test_mulrev', $id, $reset);
339
}
340
341
342
343
344
345
346
347
348

/**
 * Implements hook_ENTITY_TYPE_insert().
 */
function entity_test_entity_test_insert($entity) {
  if ($entity->name->value == 'fail_insert') {
    throw new Exception("Test exception rollback.");
  }
}
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365

/**
 * Entity label callback.
 *
 * @param $entity_type
 *   The entity type.
 * @param $entity
 *   The entity object.
 * @param $langcocde
 *   (optional) The langcode.
 *
 * @return
 *   The label of the entity prefixed with "label callback".
 */
function entity_test_label_callback($entity_type, $entity, $langcode = NULL) {
  return 'label callback ' . $entity->name->value;
}
366

367
368
369
370
371
372
/**
 * Implements hook_entity_field_access().
 *
 * @see \Drupal\system\Tests\Entity\FieldAccessTest::testFieldAccess()
 */
function entity_test_entity_field_access($operation, $field, $account) {
373
374
375
376
377
378
379
  if ($field->getName() == 'field_test_text') {
    if ($field->value == 'no access value') {
      return FALSE;
    }
    elseif ($operation == 'delete' && $field->value == 'no delete access value') {
      return FALSE;
    }
380
381
382
383
384
385
386
387
388
389
390
391
392
393
  }
}

/**
 * Implements hook_entity_field_access_alter().
 *
 * @see \Drupal\system\Tests\Entity\FieldAccessTest::testFieldAccess()
 */
function entity_test_entity_field_access_alter(array &$grants, array $context) {
  $field = $context['field'];
  if ($field->getName() == 'field_test_text' && $field->value == 'access alter value') {
    $grants[':default'] = FALSE;
  }
}
394
395
396
397
398
399
400
401
402
403
404
405
406

/**
 * Implements hook_entity_form_display_alter().
 */
function entity_test_entity_form_display_alter(EntityFormDisplay $form_display, $context) {
  // Make the field_test_text field 42 characters for entity_test_mul.
  if ($context['entity_type'] == 'entity_test') {
    if ($component_options = $form_display->getComponent('field_test_text')) {
      $component_options['settings']['size'] = 42;
      $form_display->setComponent('field_test_text', $component_options);
    }
  }
}
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424

/**
 * Implements hook_entity_presave()
 */
function entity_test_entity_presave(EntityInterface $entity) {
  if (isset($GLOBALS['entity_test_throw_exception'])) {
    throw new Exception('Entity presave exception', 1);
  }
}

/**
 * Implements hook_entity_predelete()
 */
function entity_test_entity_predelete(EntityInterface $entity) {
  if (isset($GLOBALS['entity_test_throw_exception'])) {
    throw new Exception('Entity predelete exception', 2);
  }
}
425
426
427
428
429
430
431

/**
 * Implements hook_entity_operation_alter().
 */
function entity_test_entity_operation_alter(array &$operations, EntityInterface $entity) {
  $uri = $entity->uri();
  $operations['test_operation'] = array(
432
    'title' => format_string('Test Operation: @label', array('@label' => $entity->label())),
433
434
435
436
    'href' => $uri['path'] . '/test_operation',
    'weight' => 50,
  );
}
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470

/**
 * Implements hook_entity_translation_insert().
 */
function entity_test_entity_translation_insert(EntityInterface $translation) {
  _entity_test_record_hooks('entity_translation_insert', $translation->language()->id);
}

/**
 * Implements hook_entity_translation_delete().
 */
function entity_test_entity_translation_delete(EntityInterface $translation) {
  _entity_test_record_hooks('entity_translation_delete', $translation->language()->id);
}

/**
 * Implements hook_ENTITY_TYPE_translation_insert().
 */
function entity_test_entity_test_mul_translation_insert(EntityInterface $translation) {
  _entity_test_record_hooks('entity_test_mul_translation_insert', $translation->language()->id);
}

/**
 * Implements hook_ENTITY_TYPE_translation_delete().
 */
function entity_test_entity_test_mul_translation_delete(EntityInterface $translation) {
  _entity_test_record_hooks('entity_test_mul_translation_delete', $translation->language()->id);
}

/**
 * Field default value callback.
 *
 * @param \Drupal\Core\Entity\EntityInterface $entity
 *   The entity the field belongs to.
471
 * @param \Drupal\field\Entity\Field $field
472
 *   The field for which default values should be provided.
473
 * @param \Drupal\field\Entity\FieldInstance $instance
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
 *   The field instance for which default values should be provided.
 * @param string $langcode
 *   The field language code to fill-in with the default value.
 */
function entity_test_field_default_value(EntityInterface $entity, Field $field, FieldInstance $instance, $langcode) {
  return array(array('value' => $field['field_name'] . '_' . $langcode));
}

/**
 * Helper function to be used to record hook invocations.
 *
 * @param string $hook
 *   The hook name.
 * @param mixed $data
 *   Arbitrary data associated to the hook invocation.
 */
function _entity_test_record_hooks($hook, $data) {
  $state = \Drupal::state();
  $key = 'entity_test.hooks';
  $hooks = $state->get($key);
  $hooks[$hook] = $data;
  $state->set($key, $hooks);
}
497
498
499
500
501
502

/**
 * Implements hook_entity_prepare_view().
 */
function entity_test_entity_prepare_view($entity_type, array $entities, array $displays) {
  // Add a dummy field item attribute on field_test_text if it exists.
503
  if ($entity_type == 'entity_test_render') {
504
505
506
507
508
509
510
511
512
    foreach ($entities as $entity) {
      if ($entity->getPropertyDefinition('field_test_text')) {
        foreach ($entity->get('field_test_text') as $item) {
          $item->_attributes += array('data-field-item-attr' => 'foobar');
        }
      }
    }
  }
}