diff options
-rw-r--r-- | modules/field/field.attach.inc | 3 | ||||
-rw-r--r-- | modules/field/field.default.inc | 22 | ||||
-rw-r--r-- | modules/field/field.form.inc | 31 | ||||
-rw-r--r-- | modules/field/tests/field.test | 45 | ||||
-rw-r--r-- | modules/field/tests/field_test.entity.inc | 14 |
5 files changed, 86 insertions, 29 deletions
diff --git a/modules/field/field.attach.inc b/modules/field/field.attach.inc index 28a75fe90..3896e2134 100644 --- a/modules/field/field.attach.inc +++ b/modules/field/field.attach.inc @@ -555,6 +555,9 @@ function field_attach_form($entity_type, $entity, &$form, &$form_state, $langcod $form['#pre_render'][] = '_field_extra_weights_pre_render'; $form['#extra_fields'] = field_extra_fields($entity_type, $bundle); + // Save the original entity to allow later re-use. + $form_state['entity'] = $entity; + // Let other modules make changes to the form. // Avoid module_invoke_all() to let parameters be taken by reference. foreach (module_implements('field_attach_form') as $module) { diff --git a/modules/field/field.default.inc b/modules/field/field.default.inc index 0af3d06c6..62ab6178e 100644 --- a/modules/field/field.default.inc +++ b/modules/field/field.default.inc @@ -67,13 +67,23 @@ function field_default_validate($entity_type, $entity, $field, $instance, $langc function field_default_submit($entity_type, $entity, $field, $instance, $langcode, &$items, $form, &$form_state) { $field_name = $field['field_name']; - // Reorder items to account for drag-n-drop reordering. - if (field_behaviors_widget('multiple values', $instance) == FIELD_BEHAVIOR_DEFAULT) { - $items = _field_sort_items($field, $items); + if (isset($form_state['values'][$field_name][$langcode])) { + // Reorder items to account for drag-n-drop reordering. + if (field_behaviors_widget('multiple values', $instance) == FIELD_BEHAVIOR_DEFAULT) { + $items = _field_sort_items($field, $items); + } + // Filter out empty values. + $items = _field_filter_items($field, $items); + } + elseif (!empty($entity->revision) && isset($form_state['entity']->{$field_name}[$langcode])) { + // To ensure new revisions are created with all field values in all + // languages, populate values not included in the form with the ones from + // the original object. This covers: + // - partial forms including only a subset of the fields, + // - fields for which the user has no edit access, + // - languages not involved in the form. + $items = $form_state['entity']->{$field_name}[$langcode]; } - - // Filter out empty values. - $items = _field_filter_items($field, $items); } /** diff --git a/modules/field/field.form.inc b/modules/field/field.form.inc index 61a5833bc..32c4d3a9a 100644 --- a/modules/field/field.form.inc +++ b/modules/field/field.form.inc @@ -16,19 +16,10 @@ function field_default_form($entity_type, $entity, $field, $instance, $langcode, list($id, , ) = entity_extract_ids($entity_type, $entity); } + $addition = array(); $field_name = $field['field_name']; $addition[$field_name] = array(); - // Store field information in $form_state['storage']. - $form_state['field'][$field_name][$langcode] = array( - 'field' => $field, - 'instance' => $instance, - // This entry will be populated at form build time. - 'array_parents' => array(), - // This entry will be populated at form validation time. - 'errors' => array(), - ); - // Populate widgets with default values when creating a new entity. if (empty($items) && empty($id)) { $items = field_get_default_value($entity_type, $entity, $field, $instance, $langcode); @@ -79,6 +70,16 @@ function field_default_form($entity_type, $entity, $field, $instance, $langcode, } if ($elements) { + // Store field information in $form_state. + $form_state['field'][$field_name][$langcode] = array( + 'field' => $field, + 'instance' => $instance, + // This entry will be populated at form build time. + 'array_parents' => array(), + // This entry will be populated at form validation time. + 'errors' => array(), + ); + // Also aid in theming of field widgets by rendering a classified // container. $addition[$field_name] = array( @@ -93,16 +94,6 @@ function field_default_form($entity_type, $entity, $field, $instance, $langcode, '#weight' => $instance['widget']['weight'], ); } - else { - // The field is not accessible, or the widget did not return anything. Make - // sure the items are available in the submitted form values. - foreach ($items as $delta => $item) { - $elements[$delta] = array( - '#type' => 'value', - '#value' => $item, - ); - } - } // Populate the 'array_parents' information in $form_state['field'] after // the form is built, so that we catch changes in the form structure performed diff --git a/modules/field/tests/field.test b/modules/field/tests/field.test index 589d0b886..632e474ca 100644 --- a/modules/field/tests/field.test +++ b/modules/field/tests/field.test @@ -2878,6 +2878,51 @@ class FieldTranslationsTestCase extends FieldTestCase { $langcode = field_language($entity_type, $entity, $this->field_name, $requested_language); $this->assertTrue(isset($entity->{$this->field_name}[$langcode]) && $langcode != $requested_language, t('The display language for the (single) field %field_name is %language.', array('%field_name' => $field_name, '%language' => $langcode))); } + + /** + * Tests field translations when creating a new revision. + */ + function testFieldFormTranslationRevisions() { + $web_user = $this->drupalCreateUser(array('access field_test content', 'administer field_test content')); + $this->drupalLogin($web_user); + + // Prepare the field translations. + field_test_entity_info_translatable($this->entity_type, TRUE); + $eid = 1; + $entity = field_test_create_stub_entity($eid, $eid, $this->instance['bundle']); + $available_languages = array_flip(field_available_languages($this->entity_type, $this->field)); + unset($available_languages[LANGUAGE_NONE]); + $field_name = $this->field['field_name']; + + // Store the field translations. + $entity->is_new = TRUE; + foreach ($available_languages as $langcode => $value) { + $entity->{$field_name}[$langcode][0]['value'] = $value + 1; + } + field_test_entity_save($entity); + + // Create a new revision. + $langcode = field_valid_language(NULL); + $edit = array("{$field_name}[$langcode][0][value]" => $entity->{$field_name}[$langcode][0]['value'], 'revision' => TRUE); + $this->drupalPost('test-entity/' . $eid . '/edit', $edit, t('Save')); + + // Check translation revisions. + $this->checkTranslationRevisions($eid, $eid, $available_languages); + $this->checkTranslationRevisions($eid, $eid + 1, $available_languages); + } + + /** + * Check if the field translation attached to the entity revision identified + * by the passed arguments were correctly stored. + */ + private function checkTranslationRevisions($eid, $evid, $available_languages) { + $field_name = $this->field['field_name']; + $entity = field_test_entity_test_load($eid, $evid); + foreach ($available_languages as $langcode => $value) { + $passed = isset($entity->{$field_name}[$langcode]) && $entity->{$field_name}[$langcode][0]['value'] == $value + 1; + $this->assertTrue($passed, t('The @language translation for revision @revision was correctly stored', array('@language' => $langcode, '@revision' => $entity->ftvid))); + } + } } /** diff --git a/modules/field/tests/field_test.entity.inc b/modules/field/tests/field_test.entity.inc index 953b0a01c..cdd3b0c34 100644 --- a/modules/field/tests/field_test.entity.inc +++ b/modules/field/tests/field_test.entity.inc @@ -164,11 +164,19 @@ function field_test_create_stub_entity($id = 1, $vid = 1, $bundle = 'test_bundle function field_test_entity_test_load($ftid, $ftvid = NULL) { // Load basic strucure. $query = db_select('test_entity', 'fte', array()) - ->fields('fte') - ->condition('ftid', $ftid); + ->condition('fte.ftid', $ftid); + if ($ftvid) { - $query->condition('ftvid', $ftvid); + $query->join('test_entity_revision', 'fter', 'fte.ftid = fter.ftid'); + $query->addField('fte', 'ftid'); + $query->addField('fte', 'fttype'); + $query->addField('fter', 'ftvid'); + $query->condition('fter.ftvid', $ftvid); + } + else { + $query->fields('fte'); } + $entities = $query->execute()->fetchAllAssoc('ftid'); // Attach fields. |