summaryrefslogtreecommitdiff
path: root/modules/field
diff options
context:
space:
mode:
Diffstat (limited to 'modules/field')
-rw-r--r--modules/field/field.api.php4
-rw-r--r--modules/field/field.form.inc4
-rw-r--r--modules/field/modules/field_sql_storage/field_sql_storage.module72
-rw-r--r--modules/field/modules/list/list.module2
-rw-r--r--modules/field/modules/list/tests/list.test17
-rw-r--r--modules/field/modules/text/text.test6
6 files changed, 76 insertions, 29 deletions
diff --git a/modules/field/field.api.php b/modules/field/field.api.php
index ba44c7356..3287dd555 100644
--- a/modules/field/field.api.php
+++ b/modules/field/field.api.php
@@ -1132,7 +1132,7 @@ function hook_field_attach_form($entity_type, $entity, &$form, &$form_state, $la
*
* See field_attach_load() for details and arguments.
*/
-function hook_field_attach_load($entity_type, &$entities, $age, $options) {
+function hook_field_attach_load($entity_type, $entities, $age, $options) {
// @todo Needs function body.
}
@@ -1580,7 +1580,7 @@ function hook_field_storage_details_alter(&$details, $field) {
* non-deleted fields. If unset or FALSE, only non-deleted fields should be
* loaded.
*/
-function hook_field_storage_load($entity_type, &$entities, $age, $fields, $options) {
+function hook_field_storage_load($entity_type, $entities, $age, $fields, $options) {
$field_info = field_info_field_by_ids();
$load_current = $age == FIELD_LOAD_CURRENT;
diff --git a/modules/field/field.form.inc b/modules/field/field.form.inc
index 845f04109..66d93e963 100644
--- a/modules/field/field.form.inc
+++ b/modules/field/field.form.inc
@@ -373,7 +373,7 @@ function field_default_form_errors($entity_type, $entity, $field, $instance, $la
* to return just the changed part of the form.
*/
function field_add_more_submit($form, &$form_state) {
- $button = $form_state['clicked_button'];
+ $button = $form_state['triggering_element'];
// Go one level up in the form, to the widgets container.
$element = drupal_array_get_nested_value($form, array_slice($button['#array_parents'], 0, -1));
@@ -398,7 +398,7 @@ function field_add_more_submit($form, &$form_state) {
* @see field_add_more_submit()
*/
function field_add_more_js($form, $form_state) {
- $button = $form_state['clicked_button'];
+ $button = $form_state['triggering_element'];
// Go one level up in the form, to the widgets container.
$element = drupal_array_get_nested_value($form, array_slice($button['#array_parents'], 0, -1));
diff --git a/modules/field/modules/field_sql_storage/field_sql_storage.module b/modules/field/modules/field_sql_storage/field_sql_storage.module
index 6f49167ec..10bae64b5 100644
--- a/modules/field/modules/field_sql_storage/field_sql_storage.module
+++ b/modules/field/modules/field_sql_storage/field_sql_storage.module
@@ -468,7 +468,6 @@ function field_sql_storage_field_storage_purge($entity_type, $entity, $field, $i
* Implements hook_field_storage_query().
*/
function field_sql_storage_field_storage_query(EntityFieldQuery $query) {
- $groups = array();
if ($query->age == FIELD_LOAD_CURRENT) {
$tablename_function = '_field_sql_storage_tablename';
$id_key = 'entity_id';
@@ -499,26 +498,12 @@ function field_sql_storage_field_storage_query(EntityFieldQuery $query) {
}
}
- // Add field conditions.
- foreach ($query->fieldConditions as $key => $condition) {
- $table_alias = $table_aliases[$key];
- $field = $condition['field'];
- // Add the specified condition.
- $sql_field = "$table_alias." . _field_sql_storage_columnname($field['field_name'], $condition['column']);
- $query->addCondition($select_query, $sql_field, $condition);
- // Add delta / language group conditions.
- foreach (array('delta', 'language') as $column) {
- if (isset($condition[$column . '_group'])) {
- $group_name = $condition[$column . '_group'];
- if (!isset($groups[$column][$group_name])) {
- $groups[$column][$group_name] = $table_alias;
- }
- else {
- $select_query->where("$table_alias.$column = " . $groups[$column][$group_name] . ".$column");
- }
- }
- }
- }
+ // Add field conditions. We need a fresh grouping cache.
+ drupal_static_reset('_field_sql_storage_query_field_conditions');
+ _field_sql_storage_query_field_conditions($query, $select_query, $query->fieldConditions, $table_aliases, '_field_sql_storage_columnname');
+
+ // Add field meta conditions.
+ _field_sql_storage_query_field_conditions($query, $select_query, $query->fieldMetaConditions, $table_aliases, '_field_sql_storage_query_columnname');
if (isset($query->deleted)) {
$select_query->condition("$field_base_table.deleted", (int) $query->deleted);
@@ -592,6 +577,51 @@ function _field_sql_storage_query_join_entity(SelectQuery $select_query, $entity
}
/**
+ * Adds field (meta) conditions to the given query objects respecting groupings.
+ *
+ * @param EntityFieldQuery $query
+ * The field query object to be processed.
+ * @param SelectQuery $select_query
+ * The SelectQuery that should get grouping conditions.
+ * @param condtions
+ * The conditions to be added.
+ * @param $table_aliases
+ * An associative array of table aliases keyed by field index.
+ * @param $column_callback
+ * A callback that should return the column name to be used for the field
+ * conditions. Accepts a field name and a field column name as parameters.
+ */
+function _field_sql_storage_query_field_conditions(EntityFieldQuery $query, SelectQuery $select_query, $conditions, $table_aliases, $column_callback) {
+ $groups = &drupal_static(__FUNCTION__, array());
+ foreach ($conditions as $key => $condition) {
+ $table_alias = $table_aliases[$key];
+ $field = $condition['field'];
+ // Add the specified condition.
+ $sql_field = "$table_alias." . $column_callback($field['field_name'], $condition['column']);
+ $query->addCondition($select_query, $sql_field, $condition);
+ // Add delta / language group conditions.
+ foreach (array('delta', 'language') as $column) {
+ if (isset($condition[$column . '_group'])) {
+ $group_name = $condition[$column . '_group'];
+ if (!isset($groups[$column][$group_name])) {
+ $groups[$column][$group_name] = $table_alias;
+ }
+ else {
+ $select_query->where("$table_alias.$column = " . $groups[$column][$group_name] . ".$column");
+ }
+ }
+ }
+ }
+}
+
+/**
+ * Field meta condition column callback.
+ */
+function _field_sql_storage_query_columnname($field_name, $column) {
+ return $column;
+}
+
+/**
* Implements hook_field_storage_delete_revision().
*
* This function actually deletes the data from the database.
diff --git a/modules/field/modules/list/list.module b/modules/field/modules/list/list.module
index 608679bbb..2518ebcfc 100644
--- a/modules/field/modules/list/list.module
+++ b/modules/field/modules/list/list.module
@@ -343,7 +343,7 @@ function list_allowed_values_string($values) {
function list_field_update_forbid($field, $prior_field, $has_data) {
if ($field['module'] == 'list' && $has_data) {
// Forbid any update that removes allowed values with actual data.
- $lost_keys = array_diff(array_keys($field['settings']['allowed_values']), array_keys($prior_field['settings']['allowed_values']));
+ $lost_keys = array_diff(array_keys($prior_field['settings']['allowed_values']), array_keys($field['settings']['allowed_values']));
if (_list_values_in_use($field, $lost_keys)) {
throw new FieldUpdateForbiddenException(t('Cannot update a list field to not include keys with existing data.'));
}
diff --git a/modules/field/modules/list/tests/list.test b/modules/field/modules/list/tests/list.test
index 941d2b4cb..dec09560f 100644
--- a/modules/field/modules/list/tests/list.test
+++ b/modules/field/modules/list/tests/list.test
@@ -55,6 +55,23 @@ class ListFieldTestCase extends FieldTestCase {
$this->assertTrue(!empty($form[$this->field_name][$langcode][2]), t('Option 2 exists'));
$this->assertTrue(!empty($form[$this->field_name][$langcode][3]), t('Option 3 exists'));
+ // Use one of the values in an actual entity, and check that this value
+ // cannot be removed from the list.
+ $entity = field_test_create_stub_entity();
+ $entity->{$this->field_name}[$langcode][0] = array('value' => 1);
+ field_test_entity_save($entity);
+ $this->field['settings']['allowed_values'] = array(2 => 'Two');
+ try {
+ field_update_field($this->field);
+ $this->fail(t('Cannot update a list field to not include keys with existing data.'));
+ }
+ catch (FieldException $e) {
+ $this->pass(t('Cannot update a list field to not include keys with existing data.'));
+ }
+ // Empty the value, so that we can actually remove the option.
+ $entity->{$this->field_name}[$langcode] = array();
+ field_test_entity_save($entity);
+
// Removed options do not appear.
$this->field['settings']['allowed_values'] = array(2 => 'Two');
field_update_field($this->field);
diff --git a/modules/field/modules/text/text.test b/modules/field/modules/text/text.test
index b42fed7e0..59369370e 100644
--- a/modules/field/modules/text/text.test
+++ b/modules/field/modules/text/text.test
@@ -464,7 +464,7 @@ class TextTranslationTestCase extends DrupalWebTestCase {
$node = $this->drupalGetNodeByTitle($edit['title']);
$this->drupalGet("node/$node->nid/translate");
$this->clickLink(t('add translation'));
- $this->assertFieldByXPath("//textarea[@name='body[fr][0][value]']", $body, t('The textfield widget is populated.'));
+ $this->assertFieldByXPath("//textarea[@name='body[$langcode][0][value]']", $body, t('The textfield widget is populated.'));
}
/**
@@ -484,17 +484,17 @@ class TextTranslationTestCase extends DrupalWebTestCase {
);
// Create an article with the first body input format set to "Full HTML".
- $langcode = 'en';
$title = $this->randomName();
$edit = array(
'title' => $title,
- 'language' => $langcode,
+ 'language' => 'en',
);
$this->drupalPost('node/add/article', $edit, t('Save'));
// Populate the body field: the first item gets the "Full HTML" input
// format, the second one "Filtered HTML".
$formats = array('full_html', 'filtered_html');
+ $langcode = LANGUAGE_NONE;
foreach ($body as $delta => $value) {
$edit = array(
"body[$langcode][$delta][value]" => $value,