summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwebchick <webchick@24967.no-reply.drupal.org>2012-05-12 18:26:43 -0700
committerwebchick <webchick@24967.no-reply.drupal.org>2012-05-12 18:26:43 -0700
commit2b8686151f2c2a32a77eca726c36c9b72260acd0 (patch)
tree9c36e8b46e83e38d61ff9eb565bde4caee387a19
parentfffeb72bfd2802e8b5d4f0b514870d4b7fb23a29 (diff)
downloadbrdo-2b8686151f2c2a32a77eca726c36c9b72260acd0.tar.gz
brdo-2b8686151f2c2a32a77eca726c36c9b72260acd0.tar.bz2
Issue #1302228 by xjm, yched, chx: Fixed Change notice for: field_has_data() returns inconsistent results – possible data loss.
-rw-r--r--modules/field/field.module4
-rw-r--r--modules/field/modules/field_sql_storage/field_sql_storage.module7
-rw-r--r--modules/node/node.test95
3 files changed, 105 insertions, 1 deletions
diff --git a/modules/field/field.module b/modules/field/field.module
index dedf8470c..4e39a0397 100644
--- a/modules/field/field.module
+++ b/modules/field/field.module
@@ -972,6 +972,10 @@ function field_has_data($field) {
->fieldCondition($field)
->range(0, 1)
->count()
+ // Neutralize the 'entity_field_access' query tag added by
+ // field_sql_storage_field_storage_query(). The result cannot depend on the
+ // access grants of the current user.
+ ->addTag('DANGEROUS_ACCESS_CHECK_OPT_OUT')
->execute();
}
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 2ed783507..a75619427 100644
--- a/modules/field/modules/field_sql_storage/field_sql_storage.module
+++ b/modules/field/modules/field_sql_storage/field_sql_storage.module
@@ -512,7 +512,12 @@ function field_sql_storage_field_storage_query(EntityFieldQuery $query) {
}
else {
$select_query = db_select($tablename, $table_alias);
- $select_query->addTag('entity_field_access');
+ // Allow queries internal to the Field API to opt out of the access
+ // check, for situations where the query's results should not depend on
+ // the access grants for the current user.
+ if (!isset($query->tags['DANGEROUS_ACCESS_CHECK_OPT_OUT'])) {
+ $select_query->addTag('entity_field_access');
+ }
$select_query->addMetaData('base_table', $tablename);
$select_query->fields($table_alias, array('entity_type', 'entity_id', 'revision_id', 'bundle'));
$field_base_table = $table_alias;
diff --git a/modules/node/node.test b/modules/node/node.test
index f46d2a108..6e458bb47 100644
--- a/modules/node/node.test
+++ b/modules/node/node.test
@@ -6,6 +6,26 @@
*/
/**
+ * Defines a base class for testing the Node module.
+ */
+class NodeWebTestCase extends DrupalWebTestCase {
+ function setUp() {
+ $modules = func_get_args();
+ if (isset($modules[0]) && is_array($modules[0])) {
+ $modules = $modules[0];
+ }
+ $modules[] = 'node';
+ parent::setUp($modules);
+
+ // Create Basic page and Article node types.
+ if ($this->profile != 'standard') {
+ $this->drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page'));
+ $this->drupalCreateContentType(array('type' => 'article', 'name' => 'Article'));
+ }
+ }
+}
+
+/**
* Test the node_load_multiple() function.
*/
class NodeLoadMultipleTestCase extends DrupalWebTestCase {
@@ -2493,3 +2513,78 @@ class NodeAccessPagerTestCase extends DrupalWebTestCase {
$this->assertNoRaw('page=2', t('No third page exists.'));
}
}
+
+
+/**
+ * Tests the interaction of the node access system with fields.
+ */
+class NodeAccessFieldTestCase extends NodeWebTestCase {
+
+ public static function getInfo() {
+ return array(
+ 'name' => 'Node access and fields',
+ 'description' => 'Tests the interaction of the node access system with fields.',
+ 'group' => 'Node',
+ );
+ }
+
+ public function setUp() {
+ parent::setUp('node_access_test', 'field_ui');
+ node_access_rebuild();
+
+ // Create some users.
+ $this->admin_user = $this->drupalCreateUser(array('access content', 'bypass node access'));
+ $this->content_admin_user = $this->drupalCreateUser(array('access content', 'administer content types'));
+
+ // Add a custom field to the page content type.
+ $this->field_name = drupal_strtolower($this->randomName() . '_field_name');
+ $this->field = field_create_field(array('field_name' => $this->field_name, 'type' => 'text'));
+ $this->instance = field_create_instance(array(
+ 'field_name' => $this->field_name,
+ 'entity_type' => 'node',
+ 'bundle' => 'page',
+ ));
+ }
+
+ /**
+ * Tests administering fields when node access is restricted.
+ */
+ function testNodeAccessAdministerField() {
+ // Create a page node.
+ $langcode = LANGUAGE_NONE;
+ $field_data = array();
+ $value = $field_data[$langcode][0]['value'] = $this->randomName();
+ $node = $this->drupalCreateNode(array($this->field_name => $field_data));
+
+ // Log in as the administrator and confirm that the field value is present.
+ $this->drupalLogin($this->admin_user);
+ $this->drupalGet("node/{$node->nid}");
+ $this->assertText($value, 'The saved field value is visible to an administrator.');
+
+ // Log in as the content admin and try to view the node.
+ $this->drupalLogin($this->content_admin_user);
+ $this->drupalGet("node/{$node->nid}");
+ $this->assertText('Access denied', 'Access is denied for the content admin.');
+
+ // Modify the field default as the content admin.
+ $edit = array();
+ $default = 'Sometimes words have two meanings';
+ $edit["{$this->field_name}[$langcode][0][value]"] = $default;
+ $this->drupalPost(
+ "admin/structure/types/manage/page/fields/{$this->field_name}",
+ $edit,
+ t('Save settings')
+ );
+
+ // Log in as the administrator.
+ $this->drupalLogin($this->admin_user);
+
+ // Confirm that the existing node still has the correct field value.
+ $this->drupalGet("node/{$node->nid}");
+ $this->assertText($value, 'The original field value is visible to an administrator.');
+
+ // Confirm that the new default value appears when creating a new node.
+ $this->drupalGet('node/add/page');
+ $this->assertRaw($default, 'The updated default value is displayed when creating a new node.');
+ }
+}