ContentTranslationSyncImageTest.php 9.91 KB
Newer Older
1 2 3 4
<?php

/**
 * @file
5
 * Contains \Drupal\entity\Tests\ContentTranslationSyncImageTest.
6 7
 */

8
namespace Drupal\content_translation\Tests;
9 10 11 12 13

use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Language\Language;

/**
14
 * Tests the Content Translation image field synchronization capability.
15
 */
16
class ContentTranslationSyncImageTest extends ContentTranslationTestBase {
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36

  /**
   * The cardinality of the image field.
   *
   * @var int
   */
  protected $cardinality;

  /**
   * The test image files.
   *
   * @var array
   */
  protected $files;

  /**
   * Modules to enable.
   *
   * @var array
   */
37
  public static $modules = array('language', 'content_translation', 'entity_test', 'image', 'field_ui');
38 39 40 41 42

  public static function getInfo() {
    return array(
      'name' => 'Image field synchronization',
      'description' => 'Tests the field synchronization behavior for the image field.',
43
      'group' => 'Content Translation UI',
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
    );
  }

  function setUp() {
    parent::setUp();
    $this->files = $this->drupalGetTestFiles('image');
  }

  /**
   * Creates the test image field.
   */
  protected function setupTestFields() {
    $this->fieldName = 'field_test_et_ui_image';
    $this->cardinality = 3;

59
    entity_create('field_entity', array(
60 61
      'name' => $this->fieldName,
      'entity_type' => $this->entityType,
62 63 64
      'type' => 'image',
      'cardinality' => $this->cardinality,
      'translatable' => TRUE,
65
    ))->save();
66

67
    entity_create('field_instance', array(
68 69 70 71 72 73 74 75 76 77 78
      'entity_type' => $this->entityType,
      'field_name' => $this->fieldName,
      'bundle' => $this->entityType,
      'label' => 'Test translatable image field',
      'settings' => array(
        'translation_sync' => array(
          'file' => FALSE,
          'alt' => 'alt',
          'title' => 'title',
        ),
      ),
79
    ))->save();
80 81
  }

82 83 84 85 86 87 88 89
  /**
   * {@inheritdoc}
   */
  protected function getEditorPermissions() {
    // Every entity-type-specific test needs to define these.
    return array('administer entity_test_mul fields', 'administer languages', 'administer content translation');
  }

90 91 92 93
  /**
   * Tests image field field synchronization.
   */
  function testImageFieldSync() {
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
    // Check that the alt and title fields are enabled for the image field.
    $this->drupalLogin($this->editor);
    $this->drupalGet('entity_test_mul/structure/' . $this->entityType . '/fields/' . $this->entityType . '.' . $this->entityType . '.' . $this->fieldName);
    $this->assertFieldChecked('edit-instance-settings-translation-sync-alt');
    $this->assertFieldChecked('edit-instance-settings-translation-sync-title');
    $edit = array(
      'instance[settings][translation_sync][alt]' => FALSE,
      'instance[settings][translation_sync][title]' => FALSE,
    );
    $this->drupalPostForm(NULL, $edit, t('Save settings'));

    // Check that the content translation settings page reflects the changes
    // performed in the field edit page.
    $this->drupalGet('admin/config/regional/content-language');
    $this->assertNoFieldChecked('edit-settings-entity-test-mul-entity-test-mul-columns-field-test-et-ui-image-alt');
    $this->assertNoFieldChecked('edit-settings-entity-test-mul-entity-test-mul-columns-field-test-et-ui-image-title');
    $edit = array(
      'settings[entity_test_mul][entity_test_mul][columns][field_test_et_ui_image][alt]' => TRUE,
      'settings[entity_test_mul][entity_test_mul][columns][field_test_et_ui_image][title]' => TRUE,
    );
    $this->drupalPostForm('admin/config/regional/content-language', $edit, t('Save'));
    $this->assertFieldChecked('edit-settings-entity-test-mul-entity-test-mul-columns-field-test-et-ui-image-alt');
    $this->assertFieldChecked('edit-settings-entity-test-mul-entity-test-mul-columns-field-test-et-ui-image-title');
    $this->drupalLogin($this->translator);

119 120 121 122
    $default_langcode = $this->langcodes[0];
    $langcode = $this->langcodes[1];

    // Populate the required contextual values.
123
    $attributes = $this->container->get('request')->attributes;
124 125 126 127 128 129 130 131
    $attributes->set('source_langcode', $default_langcode);

    // Populate the test entity with some random initial values.
    $values = array(
      'name' => $this->randomName(),
      'user_id' => mt_rand(1, 128),
      'langcode' => $default_langcode,
    );
132
    $entity = entity_create($this->entityType, $values);
133 134 135 136 137 138 139 140 141 142 143

    // Create some file entities from the generated test files and store them.
    $values = array();
    for ($delta = 0; $delta < $this->cardinality; $delta++) {
      // For the default language use the same order for files and field items.
      $index = $delta;

      // Create the file entity for the image being processed and record its
      // identifier.
      $field_values = array(
        'uri' => $this->files[$index]->uri,
144
        'uid' => $GLOBALS['user']->id(),
145 146 147 148 149 150 151 152 153 154
        'status' => FILE_STATUS_PERMANENT,
      );
      $file = entity_create('file', $field_values);
      $file->save();
      $fid = $file->id();
      $this->files[$index]->fid = $fid;

      // Generate the item for the current image file entity and attach it to
      // the entity.
      $item = array(
155
        'target_id' => $fid,
156 157
        'alt' => $default_langcode . '_' . $fid . '_' . $this->randomName(),
        'title' => $default_langcode . '_' . $fid . '_' . $this->randomName(),
158
      );
159
      $entity->{$this->fieldName}->offsetGet($delta)->setValue($item);
160 161 162 163 164 165 166 167 168 169

      // Store the generated values keying them by fid for easier lookup.
      $values[$default_langcode][$fid] = $item;
    }
    $entity = $this->saveEntity($entity);

    // Create some field translations for the test image field. The translated
    // items will be one less than the original values to check that only the
    // translated ones will be preserved. In fact we want the same fids and
    // items order for both languages.
170
    $translation = $entity->getTranslation($langcode);
171 172 173 174 175 176 177 178 179 180
    for ($delta = 0; $delta < $this->cardinality - 1; $delta++) {
      // Simulate a field reordering: items are shifted of one position ahead.
      // The modulo operator ensures we start from the beginning after reaching
      // the maximum allowed delta.
      $index = ($delta + 1) % $this->cardinality;

      // Generate the item for the current image file entity and attach it to
      // the entity.
      $fid = $this->files[$index]->fid;
      $item = array(
181
        'target_id' => $fid,
182 183
        'alt' => $langcode . '_' . $fid . '_' . $this->randomName(),
        'title' => $langcode . '_' . $fid . '_' . $this->randomName(),
184
      );
185
      $translation->{$this->fieldName}->offsetGet($delta)->setValue($item);
186 187 188 189 190 191

      // Again store the generated values keying them by fid for easier lookup.
      $values[$langcode][$fid] = $item;
    }

    // Perform synchronization: the translation language is used as source,
192 193 194
    // while the default language is used as target.
    $entity = $this->saveEntity($translation);
    $translation = $entity->getTranslation($langcode);
195 196

    // Check that one value has been dropped from the original values.
197
    $assert = count($entity->{$this->fieldName}) == 2;
198 199 200 201 202
    $this->assertTrue($assert, 'One item correctly removed from the synchronized field values.');

    // Check that fids have been synchronized and translatable column values
    // have been retained.
    $fids = array();
203
    foreach ($entity->{$this->fieldName} as $delta => $item) {
204
      $value = $values[$default_langcode][$item->target_id];
205
      $source_item = $translation->{$this->fieldName}->offsetGet($delta);
206 207 208
      $assert = $item->target_id == $source_item->target_id && $item->alt == $value['alt'] && $item->title == $value['title'];
      $this->assertTrue($assert, format_string('Field item @fid has been successfully synchronized.', array('@fid' => $item->target_id)));
      $fids[$item->target_id] = TRUE;
209 210 211 212 213 214 215 216
    }

    // Check that the dropped value is the right one.
    $removed_fid = $this->files[0]->fid;
    $this->assertTrue(!isset($fids[$removed_fid]), format_string('Field item @fid has been correctly removed.', array('@fid' => $removed_fid)));

    // Add back an item for the dropped value and perform synchronization again.
    $values[$langcode][$removed_fid] = array(
217
      'target_id' => $removed_fid,
218 219
      'alt' => $langcode . '_' . $removed_fid . '_' . $this->randomName(),
      'title' => $langcode . '_' . $removed_fid . '_' . $this->randomName(),
220
    );
221
    $translation->{$this->fieldName}->setValue(array_values($values[$langcode]));
222 223
    // When updating an entity we do not have a source language defined.
    $attributes->remove('source_langcode');
224 225
    $entity = $this->saveEntity($translation);
    $translation = $entity->getTranslation($langcode);
226 227

    // Check that the value has been added to the default language.
228
    $assert = count($entity->{$this->fieldName}->getValue()) == 3;
229 230
    $this->assertTrue($assert, 'One item correctly added to the synchronized field values.');

231
    foreach ($entity->{$this->fieldName} as $delta => $item) {
232 233 234
      // When adding an item its value is copied over all the target languages,
      // thus in this case the source language needs to be used to check the
      // values instead of the target one.
235 236
      $fid_langcode = $item->target_id != $removed_fid ? $default_langcode : $langcode;
      $value = $values[$fid_langcode][$item->target_id];
237
      $source_item = $translation->{$this->fieldName}->offsetGet($delta);
238 239
      $assert = $item->target_id == $source_item->target_id && $item->alt == $value['alt'] && $item->title == $value['title'];
      $this->assertTrue($assert, format_string('Field item @fid has been successfully synchronized.', array('@fid' => $item->target_id)));
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254
    }
  }

  /**
   * Saves the passed entity and reloads it, enabling compatibility mode.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The entity to be saved.
   *
   * @return \Drupal\Core\Entity\EntityInterface
   *   The saved entity.
   */
  protected function saveEntity(EntityInterface $entity) {
    $entity->save();
    $entity = entity_test_mul_load($entity->id(), TRUE);
255
    return $entity;
256 257 258
  }

}