Commit 44227b16 authored by alexpott's avatar alexpott

Issue #2609252 by eiriksm, Ginovski, lokapujya, toncic, Arla, Berdir, chx:...

Issue #2609252 by eiriksm, Ginovski, lokapujya, toncic, Arla, Berdir, chx: Boolean field with #access FALSE cause EntityStorageException
parent ef809cba
......@@ -1257,7 +1257,11 @@ protected function saveToDedicatedTables(ContentEntityInterface $entity, $update
foreach ($storage_definition->getColumns() as $column => $attributes) {
$column_name = $table_mapping->getFieldColumnName($storage_definition, $column);
// Serialize the value if specified in the column schema.
$record[$column_name] = !empty($attributes['serialize']) ? serialize($item->$column) : $item->$column;
$value = $item->$column;
if (!empty($attributes['serialize'])) {
$value = serialize($value);
}
$record[$column_name] = drupal_schema_get_field_value($attributes, $value);
}
$query->values($record);
if ($this->entityType->isRevisionable()) {
......
......@@ -20,7 +20,12 @@ class BooleanFieldTest extends WebTestBase {
*
* @var array
*/
public static $modules = array('entity_test', 'field_ui', 'options');
public static $modules = [
'entity_test',
'field_ui',
'options',
'field_test_boolean_access_denied',
];
/**
* A field to use in this test class.
......@@ -179,4 +184,66 @@ function testBooleanField() {
$this->assertFieldById('edit-settings-off-label', $off);
}
/**
* Test field access.
*/
public function testFormAccess() {
$on = 'boolean_on';
$off = 'boolean_off';
$label = 'boolean_label';
$field_name = 'boolean_name';
$this->fieldStorage = FieldStorageConfig::create([
'field_name' => $field_name,
'entity_type' => 'entity_test',
'type' => 'boolean',
]);
$this->fieldStorage->save();
$this->field = FieldConfig::create([
'field_name' => $field_name,
'entity_type' => 'entity_test',
'bundle' => 'entity_test',
'label' => $label,
'settings' => [
'on_label' => $on,
'off_label' => $off,
],
]);
$this->field->save();
// Create a form display for the default form mode.
entity_get_form_display('entity_test', 'entity_test', 'default')
->setComponent($field_name, [
'type' => 'boolean_checkbox',
])
->save();
// Create a display for the full view mode.
entity_get_display('entity_test', 'entity_test', 'full')
->setComponent($field_name, [
'type' => 'boolean',
])
->save();
// Display creation form.
$this->drupalGet('entity_test/add');
$this->assertFieldByName("{$field_name}[value]");
// Should be posted OK.
$this->drupalPostForm(NULL, [], t('Save'));
preg_match('|entity_test/manage/(\d+)|', $this->url, $match);
$id = $match[1];
$this->assertText(t('entity_test @id has been created.', ['@id' => $id]));
// Tell the test module to disable access to the field.
\Drupal::state()->set('field.test_boolean_field_access_field', $field_name);
$this->drupalGet('entity_test/add');
// Field should not be there anymore.
$this->assertNoFieldByName("{$field_name}[value]");
// Should still be able to post the form.
$this->drupalPostForm(NULL, [], t('Save'));
preg_match('|entity_test/manage/(\d+)|', $this->url, $match);
$id = $match[1];
$this->assertText(t('entity_test @id has been created.', ['@id' => $id]));
}
}
<?php
namespace Drupal\field_test\Plugin\Field\FieldType;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\TypedData\DataDefinition;
use Drupal\Core\Field\FieldItemBase;
/**
* Defines the 'test_object_field' entity field item.
*
* @FieldType(
* id = "test_object_field",
* label = @Translation("Test object field"),
* description = @Translation("Test field type that has an object to test serialization"),
* default_widget = "test_object_field_widget",
* default_formatter = "object_field_test_default"
* )
*/
class TestObjectItem extends FieldItemBase {
/**
* {@inheritdoc}
*/
public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
$properties['value'] = DataDefinition::create('any')
->setLabel(t('Value'))
->setRequired(TRUE);
return $properties;
}
/**
* {@inheritdoc}
*/
public static function schema(FieldStorageDefinitionInterface $field_definition) {
return [
'columns' => [
'value' => [
'description' => 'The object item value.',
'type' => 'blob',
'not null' => TRUE,
'serialize' => TRUE,
],
],
];
}
/**
* {@inheritdoc}
*/
public function setValue($values, $notify = TRUE) {
if (isset($values['value'])) {
// @todo Remove this in https://www.drupal.org/node/2788637.
if (is_string($values['value'])) {
$values['value'] = unserialize($values['value']);
}
}
parent::setValue($values, $notify);
}
}
name: 'Boolean field Test'
type: module
description: 'Support module for the field and entity display tests.'
core: 8.x
package: Testing
version: VERSION
dependencies:
- field
<?php
/**
* @file
* Module for testing denying access to boolean fields.
*/
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Session\AccountInterface;
/**
* Implements hook_entity_field_access().
*/
function field_test_boolean_access_denied_entity_field_access($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, FieldItemListInterface $items = NULL) {
return AccessResult::forbiddenIf($field_definition->getName() === \Drupal::state()->get('field.test_boolean_field_access_field'));
}
<?php
namespace Drupal\Tests\field\Kernel;
use Drupal\entity_test\Entity\EntityTest;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
/**
* Tests the serialization of an object.
*
* @group field
*/
class TestObjectItemTest extends FieldKernelTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('field_test');
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
// Create a 'test_field' field and storage for validation.
FieldStorageConfig::create(array(
'field_name' => 'field_test',
'entity_type' => 'entity_test',
'type' => 'test_object_field',
))->save();
FieldConfig::create([
'entity_type' => 'entity_test',
'field_name' => 'field_test',
'bundle' => 'entity_test',
])->save();
}
/**
* Tests the serialization of a field type that has an object.
*/
public function testTestObjectItem() {
$object = new \stdClass();
$object->foo = 'bar';
$entity = EntityTest::create();
$entity->field_test->value = $object;
$entity->save();
// Verify that the entity has been created properly.
$id = $entity->id();
$entity = EntityTest::load($id);
$this->assertTrue($entity->field_test->value instanceof \stdClass);
$this->assertEquals($object, $entity->field_test->value);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment