Projet

Général

Profil

Paste
Télécharger (51,5 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / field_collection / field_collection.test @ 5e632cae

1 31a5a6d6 Assos Assos
<?php
2
3
/**
4
 * @file
5
 * field_collections tests.
6
 */
7
8
/**
9
 * Test basics.
10
 */
11
class FieldCollectionBasicTestCase extends DrupalWebTestCase {
12
13
  public static function getInfo() {
14
    return array(
15
      'name' => 'Field collection',
16
      'description' => 'Tests creating and using field collections.',
17
      'group' => 'Field types',
18
    );
19
  }
20
21
  function setUp() {
22
    parent::setUp('field_collection', 'entity_crud_hook_test');
23
24
    // Create a field_collection field to use for the tests.
25
    $this->field_name = 'field_test_collection';
26 950416da Assos Assos
    $this->field = array(
27
      'field_name' => $this->field_name,
28
      'type' => 'field_collection',
29
      'cardinality' => 4,
30
    );
31 31a5a6d6 Assos Assos
    $this->field = field_create_field($this->field);
32
    $this->field_id = $this->field['id'];
33
34
    $this->instance = array(
35
      'field_name' => $this->field_name,
36
      'entity_type' => 'node',
37
      'bundle' => 'article',
38 5e632cae Assos Assos
      'label' => self::randomName() . '_label',
39
      'description' => self::randomName() . '_description',
40
      'weight' => random_int(0, 127),
41 31a5a6d6 Assos Assos
      'settings' => array(),
42
      'widget' => array(
43
        'type' => 'hidden',
44
        'label' => 'Test',
45
        'settings' => array(),
46
      ),
47
    );
48
    $this->instance = field_create_instance($this->instance);
49
  }
50
51
  /**
52
   * Pass if the message $text was set by one of the CRUD hooks in
53
   * entity_crud_hook_test.module, i.e., if the $text is an element of
54
   * $_SESSION['entity_crud_hook_test'].
55
   *
56
   * @see EntityCrudHookTestCase::assertHookMessage()
57
   * @see FieldCollectionBasicTestCase::assertNoHookMessage()
58
   * @see FieldCollectionBasicTestCase::clearHookMessages()
59
   *
60
   * @param $text
61
   *   Plain text to look for.
62
   * @param $message
63
   *   Message to display.
64
   * @param $group
65
   *   The group this message belongs to, defaults to 'Other'.
66
   * @return
67
   *   TRUE on pass, FALSE on fail.
68
   */
69
  protected function assertHookMessage($text, $message = NULL, $group = 'Other') {
70
    if (!isset($message)) {
71
      $message = $text;
72
    }
73 a1cafe7e Assos Assos
    return $this->assertTrue(in_array($text, $_SESSION['entity_crud_hook_test']), $message, $group);
74 31a5a6d6 Assos Assos
  }
75
76
  /**
77
   * Fail if the message $text was set by one of the CRUD hooks in
78
   * entity_crud_hook_test.module, i.e., if the $text is an element of
79
   * $_SESSION['entity_crud_hook_test'].
80
   *
81
   * @see FieldCollectionBasicTestCase::assertHookMessage()
82
   * @see FieldCollectionBasicTestCase::clearHookMessages()
83
   *
84
   * @param $text
85
   *   Plain text to look for.
86
   * @param $message
87
   *   Message to display.
88
   * @param $group
89
   *   The group this message belongs to, defaults to 'Other'.
90 950416da Assos Assos
   *
91
   * @return bool
92 31a5a6d6 Assos Assos
   *   TRUE on pass, FALSE on fail.
93
   */
94
  protected function assertNoHookMessage($text, $message = NULL, $group = 'Other') {
95
    if (!isset($message)) {
96
      $message = $text;
97
    }
98 a1cafe7e Assos Assos
    return $this->assertFalse(in_array($text, $_SESSION['entity_crud_hook_test']), $message, $group);
99 31a5a6d6 Assos Assos
  }
100
101
  /**
102
   * Clear hook messages recorded by entity_crud_hook_test.
103
   *
104
   * @see FieldCollectionBasicTestCase::assertHookMessage()
105
   * @see FieldCollectionBasicTestCase::assertNoHookMessage()
106
   */
107
  protected function clearHookMessages() {
108
    $_SESSION['entity_crud_hook_test'] = array();
109
  }
110
111
  /**
112
   * Helper for creating a new node with a field collection item.
113
   */
114
  protected function createNodeWithFieldCollection() {
115
    $node = $this->drupalCreateNode(array('type' => 'article'));
116
    // Manually create a field_collection.
117
    $entity = entity_create('field_collection_item', array('field_name' => $this->field_name));
118
    $entity->setHostEntity('node', $node);
119
    $entity->save();
120
121
    return array($node, $entity);
122
  }
123
124
  /**
125
   * Tests CRUD.
126
   */
127
  function testCRUD() {
128
    list ($node, $entity) = $this->createNodeWithFieldCollection();
129
    $node = node_load($node->nid, NULL, TRUE);
130
    $this->assertEqual($entity->item_id, $node->{$this->field_name}[LANGUAGE_NONE][0]['value'], 'A field_collection has been successfully created and referenced.');
131
    $this->assertEqual($entity->revision_id, $node->{$this->field_name}[LANGUAGE_NONE][0]['revision_id'], 'A field_collection has been successfully created and referenced.');
132
133
    // Test adding an additional field_collection during node edit.
134
    $entity2 = entity_create('field_collection_item', array('field_name' => $this->field_name));
135
    $node->{$this->field_name}[LANGUAGE_NONE][] = array('entity' => $entity2);
136
    node_save($node);
137
138
    $node = node_load($node->nid, NULL, TRUE);
139
    $this->assertTrue(!empty($entity2->item_id) && !empty($entity2->revision_id), 'Field_collection has been saved.');
140
    $this->assertEqual($entity->item_id, $node->{$this->field_name}[LANGUAGE_NONE][0]['value'], 'Existing reference has been kept during update.');
141
    $this->assertEqual($entity->revision_id, $node->{$this->field_name}[LANGUAGE_NONE][0]['revision_id'], 'Existing reference has been kept during update (revision).');
142
    $this->assertEqual($entity2->item_id, $node->{$this->field_name}[LANGUAGE_NONE][1]['value'], 'New field_collection has been properly referenced');
143
    $this->assertEqual($entity2->revision_id, $node->{$this->field_name}[LANGUAGE_NONE][1]['revision_id'], 'New field_collection has been properly referenced (revision)');
144
145
    // Make sure deleting the field_collection removes the reference.
146
    $this->clearHookMessages();
147
    $entity2->delete();
148
    $this->assertHookMessage('entity_crud_hook_test_entity_presave called for type node');
149
    $node = node_load($node->nid, NULL, TRUE);
150
    $this->assertTrue(!isset($node->{$this->field_name}[LANGUAGE_NONE][1]), 'Reference correctly deleted.');
151
152
    // Make sure field_collections are removed during deletion of the host.
153
    $this->clearHookMessages();
154
    node_delete($node->nid);
155
    $this->assertNoHookMessage('entity_crud_hook_test_entity_presave called for type node');
156 a1cafe7e Assos Assos
    $this->assertTrue(entity_load('field_collection_item') === array(), 'Field collections are deleted when the host is deleted.');
157 31a5a6d6 Assos Assos
158
    // Try deleting nodes with collections without any values.
159
    $node = $this->drupalCreateNode(array('type' => 'article'));
160
    node_delete($node->nid);
161
    $this->assertTrue(node_load($node->nid, NULL, TRUE) == FALSE, 'Node without collection values deleted.');
162
163
    // Test creating a field collection entity with a not-yet saved host entity.
164
    $node = entity_create('node', array('type' => 'article'));
165
    $entity = entity_create('field_collection_item', array('field_name' => $this->field_name));
166
    $entity->setHostEntity('node', $node);
167
    $entity->save();
168
    // Now the node should have been saved with the collection and the link
169
    // should have been established.
170
    $this->assertTrue(!empty($node->nid), 'Node has been saved with the collection.');
171
    $this->assertTrue(count($node->{$this->field_name}[LANGUAGE_NONE]) == 1 && !empty($node->{$this->field_name}[LANGUAGE_NONE][0]['value']) && !empty($node->{$this->field_name}[LANGUAGE_NONE][0]['revision_id']), 'Link has been established.');
172
173
    // Again, test creating a field collection with a not-yet saved host entity,
174
    // but this time save both entities via the host.
175
    $node = entity_create('node', array('type' => 'article'));
176
    $entity = entity_create('field_collection_item', array('field_name' => $this->field_name));
177
    $entity->setHostEntity('node', $node);
178
    node_save($node);
179
    $this->assertTrue(!empty($entity->item_id) && !empty($entity->revision_id), 'Collection has been saved with the host.');
180
    $this->assertTrue(count($node->{$this->field_name}[LANGUAGE_NONE]) == 1 && !empty($node->{$this->field_name}[LANGUAGE_NONE][0]['value']) && !empty($node->{$this->field_name}[LANGUAGE_NONE][0]['revision_id']), 'Link has been established.');
181
182
    // Test Revisions.
183
    list ($node, $item) = $this->createNodeWithFieldCollection();
184
    $entity2 = entity_create('field_collection_item', array('field_name' => $this->field_name));
185
    $node->{$this->field_name}[LANGUAGE_NONE][] = array('entity' => $entity2);
186
    node_save($node);
187
    $this->assertEqual($entity2->archived, FALSE, 'New field collection item with new content revision is not archived.');
188
189
    // Test saving a new revision of a node.
190
    $node->revision = TRUE;
191
    node_save($node);
192
    $item_updated = field_collection_item_load($node->{$this->field_name}[LANGUAGE_NONE][0]['value']);
193
    $this->assertNotEqual($item->revision_id, $item_updated->revision_id, 'Creating a new host entity revision creates a new field collection revision.');
194
195
    // Test saving a new revision with a new field collection item.
196
    $node->revision = TRUE;
197
198
    // Test saving the node without creating a new revision.
199
    $item = $item_updated;
200
    $node->revision = FALSE;
201
    node_save($node);
202
    $item_updated = field_collection_item_load($node->{$this->field_name}[LANGUAGE_NONE][0]['value']);
203
    $this->assertEqual($item->revision_id, $item_updated->revision_id, 'Updating a new host entity  without creating a new revision does not create a new field collection revision.');
204
205
    // Create a new revision of the node, such we have a non default node and
206
    // field collection revision. Then test using it.
207
    $vid = $node->vid;
208
    $item_revision_id = $item_updated->revision_id;
209
    $node->revision = TRUE;
210
    node_save($node);
211
212
    $item_updated = field_collection_item_load($node->{$this->field_name}[LANGUAGE_NONE][0]['value']);
213
    $this->assertNotEqual($item_revision_id, $item_updated->revision_id, 'Creating a new host entity revision creates a new field collection revision.');
214
    $this->assertTrue($item_updated->isDefaultRevision(), 'Field collection of default host entity revision is default too.');
215
    $this->assertEqual($item_updated->hostEntityId(), $node->nid, 'Can access host entity ID of default field collection revision.');
216
    $this->assertEqual($item_updated->hostEntity()->vid, $node->vid, 'Loaded default host entity revision.');
217
218
    $item = entity_revision_load('field_collection_item', $item_revision_id);
219
    $this->assertFalse($item->isDefaultRevision(), 'Field collection of non-default host entity is non-default too.');
220
    $this->assertEqual($item->hostEntityId(), $node->nid, 'Can access host entity ID of non-default field collection revision.');
221
    $this->assertEqual($item->hostEntity()->vid, $vid, 'Loaded non-default host entity revision.');
222
223
    // Delete the non-default revision and make sure the field collection item
224
    // revision has been deleted too.
225
    entity_revision_delete('node', $vid);
226
    $this->assertFalse(entity_revision_load('node', $vid), 'Host entity revision deleted.');
227
    $this->assertFalse(entity_revision_load('field_collection_item', $item_revision_id), 'Field collection item revision deleted.');
228
229
    // Test having archived field collections, i.e. collections referenced only
230
    // in non-default revisions.
231
    list ($node, $item) = $this->createNodeWithFieldCollection();
232
    // Create two revisions.
233
    $node_vid = $node->vid;
234
    $node->revision = TRUE;
235
    node_save($node);
236
237
    $node_vid2 = $node->vid;
238
    $node->revision = TRUE;
239
    node_save($node);
240
241
    // Now delete the field collection item for the default revision.
242
    $item = field_collection_item_load($node->{$this->field_name}[LANGUAGE_NONE][0]['value']);
243
    $item_revision_id = $item->revision_id;
244
    $item->deleteRevision();
245
    $node = node_load($node->nid);
246
    $this->assertTrue(!isset($node->{$this->field_name}[LANGUAGE_NONE][0]), 'Field collection item revision removed from host.');
247
    $this->assertFalse(field_collection_item_revision_load($item->revision_id), 'Field collection item default revision deleted.');
248
249
    $item = field_collection_item_load($item->item_id);
250
    $this->assertNotEqual($item->revision_id, $item_revision_id, 'Field collection default revision has been updated.');
251
    $this->assertTrue($item->archived, 'Field collection item has been archived.');
252
    $this->assertFalse($item->isInUse(), 'Field collection item specified as not in use.');
253
    $this->assertTrue($item->isDefaultRevision(), 'Field collection of non-default host entity is default (but archived).');
254
    $this->assertEqual($item->hostEntityId(), $node->nid, 'Can access host entity ID of non-default field collection revision.');
255
    $this->assertEqual($item->hostEntity()->nid, $node->nid, 'Loaded non-default host entity revision.');
256
257
    // Test deleting a revision of an archived field collection.
258
    $node_revision2 = node_load($node->nid, $node_vid2);
259
    $item = field_collection_item_revision_load($node_revision2->{$this->field_name}[LANGUAGE_NONE][0]['revision_id']);
260
    $item->deleteRevision();
261
    // There should be one revision left, so the item should still exist.
262
    $item = field_collection_item_load($item->item_id);
263
    $this->assertTrue($item->archived, 'Field collection item is still archived.');
264
    $this->assertFalse($item->isInUse(), 'Field collection item specified as not in use.');
265
266
    // Test that deleting the first node revision deletes the whole field
267
    // collection item as it contains its last revision.
268
    node_revision_delete($node_vid);
269
    $this->assertFalse(field_collection_item_load($item->item_id), 'Archived field collection deleted when last revision deleted.');
270
271
    // Test that removing a field-collection item also deletes it.
272
    list ($node, $item) = $this->createNodeWithFieldCollection();
273
274
    $node->{$this->field_name}[LANGUAGE_NONE] = array();
275
    $node->revision = FALSE;
276
    node_save($node);
277
    $this->assertFalse(field_collection_item_load($item->item_id), 'Removed field collection item has been deleted.');
278
279
    // Test removing a field-collection item while creating a new host revision.
280
    list ($node, $item) = $this->createNodeWithFieldCollection();
281
    $node->{$this->field_name}[LANGUAGE_NONE] = array();
282
    $node->revision = TRUE;
283
    node_save($node);
284
    // Item should not be deleted but archived now.
285
    $item = field_collection_item_load($item->item_id);
286
    $this->assertTrue($item, 'Removed field collection item still exists.');
287
    $this->assertTrue($item->archived, 'Removed field collection item is archived.');
288
289
    // Test removing an old node revision. Make sure that the field collection
290 950416da Assos Assos
    // is not removed.
291 31a5a6d6 Assos Assos
    list ($node, $item) = $this->createNodeWithFieldCollection();
292
    $node_vid = $node->vid;
293
    $node->revision = TRUE;
294
    node_save($node);
295
    $node_vid2 = $node->vid;
296
    $item_vid2 = $node->{$this->field_name}[LANGUAGE_NONE][0]['revision_id'];
297
    node_revision_delete($node_vid);
298
    $item2 = field_collection_item_revision_load($item_vid2);
299
    $item_id2 = isset($item2->item_id) ? $item2->item_id : -1;
300
    $this->assertEqual($item_id2, $item->item_id, 'Removing an old node revision does not delete newer field collection revisions');
301
302
  }
303
304
  /**
305
   * Make sure the basic UI and access checks are working.
306
   */
307
  function testBasicUI() {
308
    // Add a field to the collection.
309
    $field = array(
310
      'field_name' => 'field_text',
311
      'type' => 'text',
312
      'cardinality' => 1,
313
      'translatable' => FALSE,
314
    );
315
    field_create_field($field);
316
    $instance = array(
317
      'entity_type' => 'field_collection_item',
318
      'field_name' => 'field_text',
319
      'bundle' => $this->field_name,
320
      'label' => 'Test text field',
321
      'widget' => array(
322
        'type' => 'text_textfield',
323
      ),
324
    );
325
    field_create_instance($instance);
326
327
    $user = $this->drupalCreateUser();
328
    $node = $this->drupalCreateNode(array('type' => 'article'));
329
330
    $this->drupalLogin($user);
331
    // Make sure access is denied.
332
    $path = 'field-collection/field-test-collection/add/node/' . $node->nid;
333
    $this->drupalGet($path);
334
    $this->assertText(t('Access denied'), 'Access has been denied.');
335
336
    $user_privileged = $this->drupalCreateUser(array('access content', 'edit any article content'));
337
    $this->drupalLogin($user_privileged);
338
    $this->drupalGet("node/$node->nid");
339
    $this->assertLinkByHref($path, 0, 'Add link is shown.');
340
    $this->drupalGet($path);
341
    $this->assertText(t('Test text field'), 'Add form is shown.');
342
343 5e632cae Assos Assos
    $edit['field_text[und][0][value]'] = self::randomName();
344 31a5a6d6 Assos Assos
    $this->drupalPost($path, $edit, t('Save'));
345
    $this->assertText(t('The changes have been saved.'), 'Field collection saved.');
346
347 a1cafe7e Assos Assos
    $this->assertText($edit['field_text[und][0][value]'], 'Added field value is shown.');
348 31a5a6d6 Assos Assos
349 5e632cae Assos Assos
    $edit['field_text[und][0][value]'] = self::randomName();
350 31a5a6d6 Assos Assos
    $this->drupalPost('field-collection/field-test-collection/1/edit', $edit, t('Save'));
351
    $this->assertText(t('The changes have been saved.'), 'Field collection saved.');
352 a1cafe7e Assos Assos
    $this->assertText($edit['field_text[und][0][value]'], 'Field collection has been edited.');
353 31a5a6d6 Assos Assos
354
    $this->drupalGet('field-collection/field-test-collection/1');
355 a1cafe7e Assos Assos
    $this->assertText($edit['field_text[und][0][value]'], 'Field collection can be viewed.');
356 31a5a6d6 Assos Assos
357
    // Add further 3 items, so we have reached 4 == maxium cardinality.
358
    $this->drupalPost($path, $edit, t('Save'));
359
    $this->drupalPost($path, $edit, t('Save'));
360
    $this->drupalPost($path, $edit, t('Save'));
361
    // Make sure adding doesn't work any more as we have restricted cardinality
362
    // to 1.
363
    $this->drupalGet($path);
364 5e632cae Assos Assos
    $this->assertResponse(403);
365 31a5a6d6 Assos Assos
366
    $this->drupalPost('field-collection/field-test-collection/1/delete', array(), t('Delete'));
367
    $this->drupalGet($path);
368
    // Add form is shown again.
369
    $this->assertText(t('Test text field'), 'Field collection item has been deleted.');
370
371
    // Test the viewing a revision. There should be no links to change it.
372
    $vid = $node->vid;
373
    $node = node_load($node->nid, NULL, TRUE);
374
    $node->revision = TRUE;
375
    node_save($node);
376
377
    $this->drupalGet("node/$node->nid/revisions/$vid/view");
378
    $this->assertResponse(403, 'Access to view revision denied');
379
    // Login in as admin and try again.
380
    $user = $this->drupalCreateUser(array('administer nodes', 'bypass node access'));
381
    $this->drupalLogin($user);
382
    $this->drupalGet("node/$node->nid/revisions/$vid/view");
383
    $this->assertNoResponse(403, 'Access to view revision granted');
384
385
    $this->assertNoLinkByHref($path, 'No links on revision view.');
386
    $this->assertNoLinkByHref('field-collection/field-test-collection/2/edit', 'No links on revision view.');
387
    $this->assertNoLinkByHref('field-collection/field-test-collection/2/delete', 'No links on revision view.');
388
389
    $this->drupalGet("node/$node->nid/revisions");
390
  }
391
392
  /**
393
   * Make sure that field_collection-entities are copied when host-entities do.
394
   */
395
  public function testCopyingEntities() {
396
    list($node, $entity) = $this->createNodeWithFieldCollection();
397
398
    // Create a copy of that node.
399
    $node->nid = NULL;
400
    $node->vid = NULL;
401
    $node->is_new = TRUE;
402
403
    node_save($node);
404
    $item = $node->{$this->field_name}[LANGUAGE_NONE][0];
405
    $this->assertNotEqual($entity->item_id, $item['value']);
406
407
    // Do a php clone to the $node object and save it.
408
    $node2 = clone $node;
409
    $node2->nid = NULL;
410
    $node2->is_new = TRUE;
411
    $node2->vid = NULL;
412
    node_save($node2);
413
414
    $item2 = $node2->{$this->field_name}[LANGUAGE_NONE][0];
415
    $this->assertNotEqual($item2['value'], $item['value']);
416
417
    // Create another copy this time (needlessly) forcing a new revision.
418
    $node->nid = NULL;
419
    $node->vid = NULL;
420
    $node->is_new = TRUE;
421
    $node->revision = TRUE;
422
    node_save($node);
423
    $item3 = $node->{$this->field_name}[LANGUAGE_NONE][0];
424
    $this->assertNotEqual($item['value'], $item3['value']);
425
  }
426
427
}
428
429
430
/**
431
 * Test using field collection with Rules.
432
 */
433
class FieldCollectionRulesIntegrationTestCase extends DrupalWebTestCase {
434
435
  public static function getInfo() {
436
    return array(
437
      'name' => 'Field collection Rules integration',
438
      'description' => 'Tests using field collections with rules.',
439
      'group' => 'Field types',
440
      'dependencies' => array('rules'),
441
    );
442
  }
443
444
  function setUp() {
445
    parent::setUp(array('field_collection', 'rules'));
446
    variable_set('rules_debug_log', 1);
447
  }
448
449
  protected function createFields($cardinality = 4) {
450
    // Create a field_collection field to use for the tests.
451
    $this->field_name = 'field_test_collection';
452
    $this->field = array('field_name' => $this->field_name, 'type' => 'field_collection', 'cardinality' => $cardinality);
453
    $this->field = field_create_field($this->field);
454
    $this->field_id = $this->field['id'];
455
456
    $this->instance = array(
457
      'field_name' => $this->field_name,
458
      'entity_type' => 'node',
459
      'bundle' => 'article',
460 5e632cae Assos Assos
      'label' => self::randomName() . '_label',
461
      'description' => self::randomName() . '_description',
462
      'weight' => random_int(0, 127),
463 31a5a6d6 Assos Assos
      'settings' => array(),
464
      'widget' => array(
465
        'type' => 'hidden',
466
        'label' => 'Test',
467
        'settings' => array(),
468
      ),
469
    );
470
    $this->instance = field_create_instance($this->instance);
471
    // Add a field to the collection.
472
    $field = array(
473
      'field_name' => 'field_text',
474
      'type' => 'text',
475
      'cardinality' => 1,
476
      'translatable' => FALSE,
477
    );
478
    field_create_field($field);
479
    $instance = array(
480
      'entity_type' => 'field_collection_item',
481
      'field_name' => 'field_text',
482
      'bundle' => $this->field_name,
483
      'label' => 'Test text field',
484
      'widget' => array(
485
        'type' => 'text_textfield',
486
      ),
487
    );
488
    field_create_instance($instance);
489
  }
490
491
  /**
492
   * Test creation field collection items.
493
   */
494
  function testCreation() {
495
    $this->createFields();
496
497
    $node = $this->drupalCreateNode(array('type' => 'article'));
498
    // Create a field collection.
499
    $action_set = rules_action_set(array('node' => array('type' => 'node', 'bundle' => 'article')));
500
    $action_set->action('entity_create', array(
501
      'type' => 'field_collection_item',
502
      'param_field_name' => $this->field_name,
503
      'param_host_entity:select' => 'node',
504
    ));
505
    $action_set->action('data_set', array('data:select' => 'entity-created:field-text', 'value' => 'foo'));
506
    $action_set->execute($node);
507
508
    $node = node_load($node->nid, NULL, TRUE);
509
    $this->assertTrue(!empty($node->{$this->field_name}[LANGUAGE_NONE][0]['value']), 'A field_collection has been successfully created.');
510
    $this->assertTrue(!empty($node->{$this->field_name}[LANGUAGE_NONE][0]['revision_id']), 'A field_collection has been successfully created (revision).');
511
512
    // Now try making use of the field collection in rules.
513
    $action_set = rules_action_set(array('node' => array('type' => 'node', 'bundle' => 'article')));
514
    $action_set->action('drupal_message', array('message:select' => 'node:field-test-collection:0:field-text'));
515
    $action_set->execute($node);
516
517
    $msg = drupal_get_messages();
518
    $this->assertEqual(array_pop($msg['status']), 'foo', 'Field collection can be used.');
519
    RulesLog::logger()->checkLog();
520
  }
521
522
  /**
523
   * Test using field collection items via the host while they are being created.
524
   */
525
  function testUsageDuringCreation() {
526
    // Test using a single-cardinality field collection.
527
    $this->createFields(1);
528
529
    $node = $this->drupalCreateNode(array('type' => 'article'));
530
    $entity = entity_create('field_collection_item', array('field_name' => $this->field_name));
531
    $entity->setHostEntity('node', $node);
532
    // Now the field collection is linked to the host, but not yet saved.
533
534
    // Test using the wrapper on it.
535
    $wrapper = entity_metadata_wrapper('node', $node);
536
    $wrapper->get($this->field_name)->field_text->set('foo');
537
    $this->assertEqual($entity->field_text[LANGUAGE_NONE][0]['value'], 'foo', 'Field collection item used during creation via the wrapper.');
538
539
    // Now test it via Rules, which should save our changes.
540
    $set = rules_action_set(array('node' => array('type' => 'node', 'bundle' => 'article')));
541
    $set->action('data_set', array('data:select' => 'node:' . $this->field_name . ':field-text', 'value' => 'bar'));
542
    $set->execute($node);
543
    $this->assertEqual($entity->field_text[LANGUAGE_NONE][0]['value'], 'bar', 'Field collection item used during creation via Rules.');
544
    $this->assertTrue(!empty($entity->item_id) && !empty($entity->revision_id), 'Field collection item has been saved by Rules and the host entity.');
545
    RulesLog::logger()->checkLog();
546
  }
547
}
548
549
/**
550
 * Test using field collection with content that gets translated.
551
 */
552
class FieldCollectionContentTranslationTestCase extends DrupalWebTestCase {
553
554
  public static function getInfo() {
555
    return array(
556
      'name' => 'Field collection content translation',
557
      'description' => 'Tests using content under translation.',
558
      'group' => 'Field types',
559
      'dependencies' => array('translation'),
560
    );
561
  }
562
563
  public function setUp() {
564
    parent::setUp(array('field_collection', 'translation'));
565
    // Create a field_collection field to use for the tests.
566
    $this->field_name = 'field_test_collection';
567
    $this->field = array('field_name' => $this->field_name, 'type' => 'field_collection', 'cardinality' => 4);
568
    $this->field = field_create_field($this->field);
569
    $this->field_id = $this->field['id'];
570
571
    $this->instance = array(
572
      'field_name' => $this->field_name,
573
      'entity_type' => 'node',
574
      'bundle' => 'article',
575 5e632cae Assos Assos
      'label' => self::randomName() . '_label',
576
      'description' => self::randomName() . '_description',
577
      'weight' => random_int(0, 127),
578 31a5a6d6 Assos Assos
      'settings' => array(),
579
      'widget' => array(
580
        'type' => 'field_collection_embed',
581
        'label' => 'Test',
582
        'settings' => array(),
583
      ),
584
    );
585
    $this->instance = field_create_instance($this->instance);
586
587
    // Add a field to the collection.
588
    $field = array(
589
      'field_name' => 'field_text',
590
      'type' => 'text',
591
      'cardinality' => 1,
592
      'translatable' => FALSE,
593
    );
594
    field_create_field($field);
595
    $instance = array(
596
      'entity_type' => 'field_collection_item',
597
      'field_name' => 'field_text',
598
      'bundle' => $this->field_name,
599
      'label' => 'Test text field',
600
      'widget' => array(
601
        'type' => 'text_textfield',
602
      ),
603
    );
604
    field_create_instance($instance);
605
606
    $admin_user = $this->drupalCreateUser(array('administer languages', 'administer content types', 'access administration pages', 'create article content', 'edit any article content', 'translate content'));
607
608
    $this->drupalLogin($admin_user);
609
    // Add German language.
610
    locale_add_language('de');
611
612
    // Set "Article" content type to use multilingual support.
613
    variable_set('language_content_type_article', TRANSLATION_ENABLED);
614
  }
615
616
  /**
617
   * Ensure field collections are cloned to new entities on content translation.
618
   */
619
  public function testContentTranslation() {
620
    // Create "Article" content.
621 5e632cae Assos Assos
    $edit['title'] = self::randomName();
622
    $edit['body[' . LANGUAGE_NONE . '][0][value]'] = self::randomName();
623 31a5a6d6 Assos Assos
    $edit['language'] = 'en';
624
    $field_collection_name = 'field_test_collection[' . LANGUAGE_NONE . '][0][field_text][' . LANGUAGE_NONE . '][0][value]';
625 5e632cae Assos Assos
    $edit[$field_collection_name] = self::randomName();
626 31a5a6d6 Assos Assos
627
    $this->drupalPost('node/add/article', $edit, t('Save'));
628
    $this->assertRaw(t('Article %title has been created.', array('%title' => $edit['title'])), 'Article created.');
629
    $node1 = $this->drupalGetNodeByTitle($edit['title']);
630
631
    $this->drupalGet('node/' . $node1->nid . '/edit');
632
    $this->drupalGet('node/' . $node1->nid . '/translate');
633
    $this->drupalGet('node/add/article', array('query' => array('translation' => $node1->nid, 'target' => 'de')));
634
635
    // Suffix translations with the langcode.
636
    unset($edit['language']);
637
    $edit['title'] .= 'DE';
638
    $edit[$field_collection_name] .= 'DE';
639
    $this->drupalPost('node/add/article', $edit, t('Save'), array('query' => array('translation' => $node1->nid, 'target' => 'de')));
640
    $node2 = $this->drupalGetNodeByTitle($edit['title']);
641
642
    // Ensure that our new node is the translation of the first one.
643
    $this->assertEqual($node1->nid, $node2->tnid, 'Succesfully created translation.');
644
    // And check to see that their field collections are different.
645
    $this->assertNotEqual($node1->field_test_collection, $node2->field_test_collection, 'Field collections between translation source and translation differ.');
646
  }
647
648
}
649
650
/**
651
 * Test using field collection with content that gets translated with Entity Translation.
652
 */
653
class FieldCollectionEntityTranslationTestCase extends DrupalWebTestCase {
654
  const TRANS_FIELD_EN = 'Translatable EN';
655
  const TRANS_FIELD_DE = 'Translatable DE';
656
  const TRANS_FIELD_DE_MOD = 'Translatable DE Mod';
657
  const UNTRANS_FIELD_EN = 'Untranslatable EN';
658
  const UNTRANS_FIELD_DE = 'Untranslatable DE';
659
  const UNTRANS_FIELD_DE_MOD = 'Untranslatable DE Mod';
660
  const NUM_VALUES = 4;
661
662
  public static function getInfo() {
663
    return array(
664
      'name' => 'Field collection entity translation',
665
      'description' => 'Tests using content under translation with Entity Translation.',
666
      'group' => 'Field types',
667
      'dependencies' => array('entity_translation'),
668
    );
669
  }
670
671
  /**
672
   * Login the given user only if she has not changed.
673
   */
674
  function login($user) {
675
    if (!isset($this->current_user) || $this->current_user->uid != $user->uid) {
676
      $this->current_user = $user;
677
      $this->drupalLogin($user);
678
    }
679
  }
680
681
  /**
682
   * Returns a user with administration rights.
683
   *
684
   * @param $permissions
685
   *   Additional permissions for administrative user.
686
   */
687
  function getAdminUser(array $permissions = array()) {
688
    if (!isset($this->admin_user)) {
689
      $this->admin_user = $this->drupalCreateUser(array_merge(array(
690
        'bypass node access',
691
        'administer nodes',
692
        'administer languages',
693
        'administer content types',
694
        'administer blocks',
695
        'access administration pages',
696
        'administer site configuration',
697
        'administer entity translation',
698
      ), $permissions));
699
    }
700
    return $this->admin_user;
701
  }
702
703
  /**
704
   * Returns a user with minimal translation rights.
705
   *
706
   * @param $permissions
707
   *   Additional permissions for administrative user.
708
   */
709
  function getTranslatorUser(array $permissions = array()) {
710
    if (!isset($this->translator_user)) {
711
      $this->translator_user = $this->drupalCreateUser(array_merge(array(
712
        'create page content',
713
        'edit own page content',
714
        'delete own page content',
715
        'translate any entity',
716
      ), $permissions));
717
    }
718
    return $this->translator_user;
719
  }
720
721
  /**
722 950416da Assos Assos
   * Install a specified language if it has not been already, otherwise make
723
   * sure that the language is enabled.
724 31a5a6d6 Assos Assos
   *
725 950416da Assos Assos
   * @param string $langcode
726 31a5a6d6 Assos Assos
   *   The language code to check.
727
   */
728
  function addLanguage($langcode) {
729
    // Check to make sure that language has not already been installed.
730
    $this->drupalGet('admin/config/regional/language');
731
732
    if (strpos($this->drupalGetContent(), 'enabled[' . $langcode . ']') === FALSE) {
733
      // Doesn't have language installed so add it.
734
      $edit = array();
735
      $edit['langcode'] = $langcode;
736
      $this->drupalPost('admin/config/regional/language/add', $edit, t('Add language'));
737
738
      // Make sure we are not using a stale list.
739
      drupal_static_reset('language_list');
740 a1cafe7e Assos Assos
      $languages = language_list();
741 31a5a6d6 Assos Assos
      $this->assertTrue(array_key_exists($langcode, $languages), t('Language was installed successfully.'));
742
743
      if (array_key_exists($langcode, $languages)) {
744
        $this->assertRaw(t('The language %language has been created and can now be used. More information is available on the <a href="@locale-help">help screen</a>.', array('%language' => $languages[$langcode]->name, '@locale-help' => url('admin/help/locale'))), t('Language has been created.'));
745
      }
746
    }
747
    elseif ($this->xpath('//input[@type="checkbox" and @name=:name and @checked="checked"]', array(':name' => 'enabled[' . $langcode . ']'))) {
748
      // It is installed and enabled. No need to do anything.
749
      $this->assertTrue(TRUE, 'Language [' . $langcode . '] already installed and enabled.');
750
    }
751
    else {
752
      // It is installed but not enabled. Enable it.
753
      $this->assertTrue(TRUE, 'Language [' . $langcode . '] already installed.');
754
      $this->drupalPost(NULL, array('enabled[' . $langcode . ']' => TRUE), t('Save configuration'));
755
      $this->assertRaw(t('Configuration saved.'), t('Language successfully enabled.'));
756
    }
757
  }
758
759
  public function setUp() {
760
    parent::setUp(array('field_collection', 'entity_translation'));
761
    $language_none = LANGUAGE_NONE;
762
    // Login with an admin user.
763
    $this->login($this->getAdminUser());
764
    // Add English and German languages.
765
    $this->addLanguage('en');
766
    $this->addLanguage('de');
767
768
    // Set "Article" content type to use multilingual support with translation.
769
    $edit = array();
770
    $edit['language_content_type'] = ENTITY_TRANSLATION_ENABLED;
771
    $this->drupalPost('admin/structure/types/manage/page', $edit, t('Save content type'));
772
    $this->assertRaw(t('The content type %type has been updated.', array('%type' => 'Basic page')), t('Basic page content type has been updated.'));
773
774
    // Create a field collection field to use for the tests.
775
    $this->field_name = 'field_test_collection';
776
    $this->field_base = "{$this->field_name}[$language_none]";
777
    $this->field = array(
778
      'field_name' => $this->field_name,
779
      'type' => 'field_collection',
780
      'cardinality' => -1,
781
      'translatable' => TRUE,
782
    );
783
    $this->field = field_create_field($this->field);
784
    $this->field_id = $this->field['id'];
785
786
    $this->instance = array(
787
      'field_name' => $this->field_name,
788
      'entity_type' => 'node',
789
      'bundle' => 'page',
790 5e632cae Assos Assos
      'label' => self::randomName() . '_label',
791
      'description' => self::randomName() . '_description',
792
      'weight' => random_int(0, 127),
793 31a5a6d6 Assos Assos
      'settings' => array(),
794
      'widget' => array(
795
        'type' => 'field_collection_embed',
796
        'label' => 'Test',
797
        'settings' => array(),
798
      ),
799
    );
800
    $this->instance = field_create_instance($this->instance);
801
802
    // Enable entity translation of field collections.
803
    $this->drupalGet('admin/config/regional/entity_translation');
804
    $this->drupalPost('admin/config/regional/entity_translation', array('entity_translation_entity_types[field_collection_item]' => TRUE), t('Save configuration'));
805
    $this->assertRaw(t('The configuration options have been saved.'), t('Entity translation of field collections enabled.'));
806
807
    // Add an untraslatable field to the collection.
808
    $this->field_untrans_name = 'field_text_untrans';
809
    $this->field_untrans_base = "[{$this->field_untrans_name}][$language_none][0][value]";
810
    $field = array(
811
      'field_name' => $this->field_untrans_name,
812
      'type' => 'text',
813
      'cardinality' => 1,
814
      'translatable' => FALSE,
815
    );
816
    field_create_field($field);
817
    $instance = array(
818
      'entity_type' => 'field_collection_item',
819
      'field_name' => $this->field_untrans_name,
820
      'bundle' => $this->field_name,
821
      'label' => 'Test untranslatable text field',
822
      'widget' => array(
823
        'type' => 'text_textfield',
824
      ),
825
    );
826
    field_create_instance($instance);
827
828
    // Add a translatable field to the collection.
829
    $this->field_trans_name = 'field_text_trans';
830
    $this->field_trans_base = "[{$this->field_trans_name}][$language_none][0][value]";
831
    $this->field_trans_dest = "[{$this->field_trans_name}][de][0][value]";
832
    $field = array(
833
      'field_name' => $this->field_trans_name,
834
      'type' => 'text',
835
      'cardinality' => 1,
836
      'translatable' => TRUE,
837
    );
838
    field_create_field($field);
839
    $instance = array(
840
      'entity_type' => 'field_collection_item',
841
      'field_name' => $this->field_trans_name,
842
      'bundle' => $this->field_name,
843
      'label' => 'Test translatable text field',
844
      'widget' => array(
845
        'type' => 'text_textfield',
846
      ),
847
    );
848
    field_create_instance($instance);
849
850
    $this->login($this->getTranslatorUser());
851
  }
852
853
  /**
854
   * Creates a basic page with a value in the field collection.
855
   *
856
   *  @param integer $num_values
857
   *    The number of values to include in the field collection.
858
   *  @param string $langcode
859
   *    Language for the node.
860
   */
861
  protected function createPage($num_values, $langcode = 'en') {
862
    // Check if num_values is greater than the field cardinality.
863
    if ($num_values > self::NUM_VALUES) {
864
      $num_values = self::NUM_VALUES;
865
    }
866
867 5e632cae Assos Assos
    $title = self::randomName();
868 31a5a6d6 Assos Assos
869
    $this->drupalGet('node/add/page');
870
871
    $edit = array();
872
    $edit['title'] = $title;
873
    for ($i = 0; $i < $num_values; $i++) {
874
      if ($i != 0) {
875
        $this->drupalPost(NULL, array(), t('Add another item'));
876
      }
877
      $edit[$this->field_base . '[' . $i . ']' . $this->field_untrans_base] = self::UNTRANS_FIELD_EN . '_' . $i;
878
      $edit[$this->field_base . '[' . $i . ']' . $this->field_trans_base] = self::TRANS_FIELD_EN . '_' . $i;
879
    }
880
881
    $edit['language'] = $langcode;
882
    $this->drupalPost(NULL, $edit, t('Save'));
883
    $this->assertRaw(t('Basic page %title has been created.', array('%title' => $title)), t('Basic page created.'));
884
885
    // Check to make sure the node was created.
886
    $node = $this->drupalGetNodeByTitle($title);
887
    $this->assertTrue($node, t('Node found in database.'));
888
889
    return $node;
890
891
  }
892
893
  /**
894
   * Create a translation using the Entity Translation Form.
895
   *
896 950416da Assos Assos
   * @param mixed $node
897 31a5a6d6 Assos Assos
   *   Node of the basic page to create translation for.
898 950416da Assos Assos
   * @param string $langcode
899 31a5a6d6 Assos Assos
   *   The language code of the translation.
900 950416da Assos Assos
   * @param string $source_langcode
901 31a5a6d6 Assos Assos
   *   The original language code.
902
   */
903
  protected function createTranslationForm($node, $langcode, $source_langcode = 'en') {
904
    $language_none = LANGUAGE_NONE;
905
    $edit = array();
906
907
    $this->drupalGet('node/' . $node->nid . '/edit/add/' . $source_langcode . '/' .$langcode);
908
909
    // Get the field collection in the original language.
910
    $fc_values = $node->{$this->field_name}[$source_langcode];
911
912
    // Check if all the fields were populated and fill it with the new value.
913
    foreach ($fc_values as $delta => $fc_value) {
914
      // Load the field collection item.
915
      $fc_item_array = entity_load('field_collection_item', array($fc_value['value']));
916
      $fc_item = reset($fc_item_array);
917
      $fc_untrans_key = "{$this->field_name}[$langcode][$delta]{$this->field_untrans_base}";
918
      $fc_trans_key = "{$this->field_name}[$langcode][$delta]{$this->field_trans_dest}";
919
      $this->assertFieldByXPath(
920
          "//input[@name='$fc_untrans_key']",
921
          $fc_item->{$this->field_untrans_name}[LANGUAGE_NONE][0]['value'],
922
          'Original value of untranslatable field correctly populated'
923
              );
924
      $this->assertFieldByXPath(
925
          "//input[@name='$fc_trans_key']",
926
          $fc_item->{$this->field_trans_name}['en'][0]['value'],
927
          'Original value of translatable field correctly populated'
928
              );
929
930
      $edit[$fc_untrans_key] = self::UNTRANS_FIELD_DE . '_' . $delta;
931
      $edit[$fc_trans_key] = self::TRANS_FIELD_DE . '_' . $delta;
932
    }
933
934
    // Save the translation.
935
    $this->drupalPost(NULL, $edit, t('Save'));
936
    $this->drupalGet('node/' . $node->nid . '/translate');
937
    $this->assertLinkByHref('node/' . $node->nid . '/edit/' . $langcode, 0, t('Translation edit link found. Translation created.'));
938
939
    // Reload the node.
940
    $node = node_load($node->nid, NULL, TRUE);
941
942
    // Check the values of the translated field.
943
    $this->checkFieldCollectionContent($node, $langcode);
944
945
    // Check the values of the field in the original language.
946
    $this->checkFieldCollectionContent($node, $source_langcode);
947
948
    return $node;
949
  }
950
951
  /**
952
   * Removes a translation using the entity translation form.
953
   *
954
   * @param mixed $node
955
   *   The node to remove the translation from.
956 950416da Assos Assos
   * @param string $langcode
957 31a5a6d6 Assos Assos
   *   The language of the translation to remove.
958 950416da Assos Assos
   * @param string $source_langcode
959 31a5a6d6 Assos Assos
   *   The source language of the node.
960
   */
961
  protected function removeTranslationForm($node, $langcode, $source_langcode) {
962
    // Number of field collection items in the source language.
963
    $num_original_fc_items = count($node->{$this->field_name}[$source_langcode]);
964
965
    // Fetch the translation edit form.
966
    $this->drupalGet('node/' . $node->nid . '/edit/' . $langcode);
967
968
    // Remove the translation.
969
    $this->drupalPost(NULL, array(), t('Delete translation'));
970
    // Confirm deletion.
971
    $this->drupalPost(NULL, array(), t('Delete'));
972
973
    // Reload the node.
974
    $node = node_load($node->nid, NULL, TRUE);
975
976
    // Check that the translation is removed.
977
    $this->drupalGet('node/' . $node->nid . '/translate');
978
    $this->assertLinkByHref('node/' . $node->nid . '/edit/add/' . $source_langcode . '/' . $langcode, 0, 'The add translation link appears');
979
    $this->assert(empty($node->{$this->field_name}[$langcode]));
980
981
    // Check that the field collection in the original language has not changed.
982
    $num_fc_items = count($node->{$this->field_name}[$source_langcode]);
983
    $this->assertEqual($num_original_fc_items, $num_fc_items, 'The number of field collection items in the original language has not changed.');
984
    $this->checkFieldCollectionContent($node, $source_langcode);
985
  }
986
987
  /**
988
   * Creates a translation programmatically using Entity Translation.
989
   *
990 950416da Assos Assos
   * @param mixed $node
991 31a5a6d6 Assos Assos
   *   Node of the basic page to create translation for.
992 950416da Assos Assos
   * @param string $langcode
993 31a5a6d6 Assos Assos
   *   The language code of the translation.
994
   */
995
  protected function createTranslation($node, $langcode) {
996
    $source_langcode = $node->language;
997
998
    // Get the Entity Translation Handler.
999
    $handler = entity_translation_get_handler('node', $node, TRUE);
1000
    // Variable to hold the fields values.
1001
    $values = array();
1002
    // Translation settings.
1003
    $translation = array(
1004
      'translate' => 0,
1005
      'status' => 1,
1006
      'language' => $langcode,
1007
      'source' => $source_langcode,
1008
      'uid' => $node->uid,
1009
    );
1010
    // Copy field values.
1011
    foreach (field_info_instances('node', $node->type) as $instance) {
1012
      $field_name = $instance['field_name'];
1013
      $field = field_info_field($field_name);
1014
      $field_value = array();
1015
      // Copy the value of the translated field if it's translatable.
1016 a1cafe7e Assos Assos
      if ($field['translatable']
1017
        && isset($node->{$field_name}[$node->language])) {
1018
        $field_value = $node->{$field_name}[$source_langcode];
1019
        $values[$field_name][$langcode] = $field_value;
1020
        $node->{$field_name}[$langcode] = $field_value;
1021 31a5a6d6 Assos Assos
      }
1022
    }
1023
1024
    $handler->setTranslation($translation, $values);
1025
    $handler->saveTranslations();
1026
    field_attach_update('node', $node);
1027
1028
    // Reload an return the node.
1029 950416da Assos Assos
    $node = node_load($node->nid, NULL, TRUE);
1030 31a5a6d6 Assos Assos
    return $node;
1031
  }
1032
1033
  /**
1034
   * Removes a translation programmatically using the entity translation api.
1035
   *
1036
   * @param mixed $node
1037
   *   The node to remove the translation from.
1038 950416da Assos Assos
   * @param string $langcode
1039 31a5a6d6 Assos Assos
   *   The language of the translation to remove.
1040
   */
1041
  protected function removeTranslation($node, $langcode) {
1042
    // Get a translation entity handler.
1043
    $handler = entity_translation_get_handler('node', $node, TRUE);
1044
1045
    // Remove the translation.
1046
    $handler->removeTranslation($langcode);
1047
    node_save($node);
1048
1049
    // Reload and return the node.
1050 950416da Assos Assos
    $node = node_load($node->nid, NULL, TRUE);
1051 31a5a6d6 Assos Assos
1052
    return $node;
1053
  }
1054
1055
  /**
1056
   * Creates a new revision of the node and checks the result.
1057
   *
1058 950416da Assos Assos
   * @param mixed $node
1059
   *   The node to remove the translation from.
1060
   * @param string $langcode
1061
   *   The language of the translation to remove.
1062
   * @param string $source_langcode
1063
   *   The source language of the node.
1064
   *
1065
   * @return mixed
1066 31a5a6d6 Assos Assos
   *   The new revision of the node.
1067
   */
1068
  protected function createRevision($node, $langcode, $source_langcode) {
1069
    $node_original_revision = $node->vid;
1070
    // The original entries of the translated field.
1071
    $original_fc_item_ids = $node->{$this->field_name}[$langcode];
1072
1073
    // Create the revision.
1074
    $node->revision = TRUE;
1075
    node_save($node);
1076
1077
    // The new entries of the translated field.
1078
    $new_fc_item_ids = $node->{$this->field_name}[$langcode];
1079
1080
    // Check that the field collection items are the same and a new revision of
1081
    // each one has been created.
1082
    foreach ($original_fc_item_ids as $delta => $value) {
1083
      $this->assertEqual($value['value'], $new_fc_item_ids[$delta]['value'], t('We have the same field collection item'));
1084
      $this->assertNotEqual($value['revision_id'], $new_fc_item_ids[$delta]['revision_id'], t('We have a new revision of the field collection item'));
1085
    }
1086
1087
    return $node;
1088
  }
1089
1090
  /**
1091
   * Check the content of the field collection for a specified language.
1092
   *
1093
   * @param mixed $node
1094
   *   The node to check.
1095
   * @param string $langcode
1096
   *   The language to check.
1097
   */
1098
  protected function checkFieldCollectionContent($node, $langcode) {
1099 950416da Assos Assos
    switch ($langcode) {
1100 31a5a6d6 Assos Assos
      case 'en':
1101
        $untrans_field = self::UNTRANS_FIELD_EN;
1102
        $trans_field = self::TRANS_FIELD_EN;
1103
        break;
1104 950416da Assos Assos
1105 31a5a6d6 Assos Assos
      case 'de':
1106
        $untrans_field = self::UNTRANS_FIELD_DE;
1107
        $trans_field = self::TRANS_FIELD_DE;
1108
        break;
1109
    }
1110
    // Get the field collection in the specified language.
1111
    $fc_values = $node->{$this->field_name}[$langcode];
1112
1113
    foreach ($fc_values as $delta => $fc_value) {
1114
      // Load the field collection item.
1115
      $fc_item_array = entity_load('field_collection_item', array($fc_value['value']));
1116
      $fc_item = reset($fc_item_array);
1117
      $fc_untrans_key = "{$this->field_name}[$langcode][$delta]{$this->field_untrans_base}";
1118
      $fc_trans_key = "{$this->field_name}[$langcode][$delta]{$this->field_trans_base}";
1119
1120
      $this->assertEqual($untrans_field . '_' . $delta, $fc_item->{$this->field_untrans_name}[LANGUAGE_NONE][0]['value']);
1121
      $this->assertEqual($trans_field . '_' . $delta, $fc_item->{$this->field_trans_name}[$langcode][0]['value']);
1122
    }
1123
  }
1124
1125
  /**
1126
   * Returns the text field values of an specified node, language and delta.
1127
   *
1128
   * @param mixed $node
1129
   * @param string $langcode
1130
   * @param integer $delta
1131
   * @return array
1132
   */
1133
  protected function getFieldValues($node, $langcode, $delta) {
1134
    $return = array();
1135
1136
    if (isset($node->{$this->field_name}[$langcode][$delta]['value'])) {
1137
      $fc_item_id = $node->{$this->field_name}[$langcode][$delta]['value'];
1138
      // Load the field collection.
1139
      $fc_item_array = entity_load('field_collection_item', array($fc_item_id));
1140
      $fc_item = reset($fc_item_array);
1141
1142
      $return = array(
1143
        'field_untrans' => $fc_item->{$this->field_untrans_name}[LANGUAGE_NONE][0]['value'],
1144
        'field_trans' => $fc_item->{$this->field_trans_name}[$langcode][0]['value'],
1145
      );
1146
    }
1147
1148
    return $return;
1149
  }
1150
1151
  /**
1152
   * Ensures the right behaviour in all Entity Translation use cases.
1153
   */
1154
  public function testEntityTranslation() {
1155
    $source_langcode = 'en';
1156
    $translation_langcode = 'de';
1157
1158
    /*
1159
     * Test with a page with only one value in the field collection
1160
     */
1161
    // Create an article in the original language with only one field collection
1162
    // value.
1163
    $node = $this->createPage(1, $source_langcode);
1164
1165
    // Create a traslation of the page through the entity translation form.
1166
    $node = $this->createTranslationForm($node, $translation_langcode, $source_langcode);
1167
1168
    /*
1169
     * Test with a page with multiple values in the field collection.
1170
     */
1171
    $num_values = 4;
1172
    // Create a page in the original language with multiple field collection
1173
    // values.
1174
    $node = $this->createPage($num_values, $source_langcode);
1175
1176
    // Create a traslation of the page through the entity translation form.
1177
    $node = $this->createTranslationForm($node, $translation_langcode, $source_langcode);
1178
1179
    // Assign a new field collection item to an existing node.
1180
    $values = array();
1181
    $values['field_name'] = $this->field_name;
1182
    $fc_entity = entity_create('field_collection_item', $values);
1183
    $fc_entity->setHostEntity('node', $node, $translation_langcode);
1184
1185
    $fc_entity->{$this->field_untrans_name}[LANGUAGE_NONE][0]['value'] = self::UNTRANS_FIELD_DE_MOD;
1186
    $fc_entity->{$this->field_trans_name}['de'][0]['value'] = self::TRANS_FIELD_DE_MOD;
1187
    $fc_entity->save(TRUE);
1188
1189
    node_save($node);
1190
1191
    // Reload the node to check it.
1192
    $node = node_load($node->nid, NULL, TRUE);
1193
    // Check that there is a new element in the translation.
1194
    $this->assertEqual($num_values + 1, count($node->{$this->field_name}[$translation_langcode]), t('We have one item more in translation.'));
1195
    // Check that the new element is correctly saved.
1196
    $fc_item_values = $this->getFieldValues($node, $translation_langcode, $num_values);
1197
    $this->assertEqual($fc_item_values['field_untrans'], self::UNTRANS_FIELD_DE_MOD);
1198
    $this->assertEqual($fc_item_values['field_trans'], self::TRANS_FIELD_DE_MOD);
1199
    // Check that we have the same items in the original language.
1200
    $this->assertEqual($num_values, count($node->{$this->field_name}[$source_langcode]), t('We have same items in the original language.'));
1201
1202
    // Remove a field collection item from the translation.
1203
    $fc_item_id = $node->{$this->field_name}[$translation_langcode][0]['value'];
1204
    unset($node->{$this->field_name}[$translation_langcode][0]);
1205
    node_save($node);
1206
    // Reload the node.
1207
    $node = node_load($node->nid, NULL, TRUE);
1208
    // Check that we have one item less in the translation.
1209
    // We should take into account that we added a field one step before.
1210
    $this->assertEqual($num_values, count($node->{$this->field_name}[$translation_langcode]), t('We have one item less in translation.'));
1211
    // Check that we have the same items in the original language.
1212
    $this->assertEqual($num_values, count($node->{$this->field_name}[$source_langcode]), t('We have same items in the original language.'));
1213
    // Check that the field collection is removed from the database.
1214
    $fc_items = entity_load('field_collection_item', array($fc_item_id));
1215
    $this->assert(empty($fc_items), t('The field collection item has been removed from the database.'));
1216
1217
    // Delete the translation.
1218
    $this->removeTranslationForm($node, $translation_langcode, $source_langcode);
1219
1220
    /*
1221
     * Check the revisioning of an entity with translations.
1222
     */
1223
    $num_values = 4;
1224
    // Create a page in the original language with multiple field collection
1225
    // values.
1226
    $node_rev = $this->createPage($num_values, $source_langcode);
1227
1228
    // Create a traslation of the page.
1229
    $node_rev = $this->createTranslationForm($node_rev, $translation_langcode, $source_langcode);
1230
1231
    $original_revision = $node_rev->vid;
1232
1233
    // Create a new revision of the node.
1234
    $node_rev = $this->createRevision($node_rev, $translation_langcode, $source_langcode);
1235
1236
    /*
1237
     * Test creating programmatically.
1238
     */
1239
    $num_values = 4;
1240
    // Create a page in the original language.
1241
    $node_prog = $this->createPage($num_values, $source_langcode);
1242
1243
    // Create programmatically a translation of the page.
1244
    $node_prog = $this->createTranslation($node_prog, $translation_langcode);
1245
1246
    $orig_fc_items = $node_prog->{$this->field_name}[$source_langcode];
1247
    $trans_fc_items = $node_prog->{$this->field_name}[$translation_langcode];
1248
1249
    $orig_fc_item_ids = array();
1250
    $trans_fc_item_ids = array();
1251
1252
    // Check each item.
1253
    foreach ($orig_fc_items as $delta => $value) {
1254
      $orig_fc_item_ids[] = $value['value'];
1255
      $trans_fc_item_ids[] = $trans_fc_items[$delta]['value'];
1256
1257
      // Check if we have new items for the translation.
1258
      $this->assertNotEqual($value['value'], $trans_fc_items[$delta]['value'], t('New item generated for translation.'));
1259
    }
1260
1261
    // Check that the original item still exists in the database.
1262
    $fc_items = entity_load('field_collection_item', $orig_fc_item_ids);
1263
    $this->assert(!empty($fc_items), t('Field Collections in the source language still exist.'));
1264
    // Check that the translated item exists in the database.
1265
    $fc_items = entity_load('field_collection_item', $trans_fc_item_ids);
1266
    $this->assert(!empty($fc_items), t('Translations for the Field Collection exist.'));
1267
1268
    // Remove the translation and check that the original field collection items
1269
    // are still there.
1270
    $node_prog = $this->removeTranslation($node, $translation_langcode);
1271
1272
    // Check the content in the source language.
1273
    $this->checkFieldCollectionContent($node_prog, $source_langcode);
1274
1275
    // Check that the field translated content has been removed.
1276
    $this->assert(empty($node->{$this->field_name}[$translation_langcode]), t('Translated content removed.'));
1277
  }
1278
1279
}