Issue #2204325 followup by Arla: Fixed The "rendered entity" formatter breaks for entity types with out a ViewBuilder.

8.0.x
Alex Pott 2014-08-18 13:47:16 +01:00
parent 093ea79442
commit c2a74e6531
6 changed files with 143 additions and 8 deletions

View File

@ -112,10 +112,11 @@ class FormatterPluginManager extends DefaultPluginManager {
$plugin_id = $configuration['type'];
// Switch back to default formatter if either:
// - $type_info doesn't exist (the widget type is unknown),
// - the field type is not allowed for the widget.
// - the configuration does not specify a formatter class
// - the field type is not allowed for the formatter
// - the formatter is not applicable to the field definition.
$definition = $this->getDefinition($configuration['type'], FALSE);
if (!isset($definition['class']) || !in_array($field_type, $definition['field_types'])) {
if (!isset($definition['class']) || !in_array($field_type, $definition['field_types']) || !$definition['class']::isApplicable($field_definition)) {
// Grab the default widget for the field type.
$field_type_definition = $this->fieldTypeManager->getDefinition($field_type);
if (empty($field_type_definition['default_formatter'])) {

View File

@ -98,10 +98,11 @@ class WidgetPluginManager extends DefaultPluginManager {
$plugin_id = $configuration['type'];
// Switch back to default widget if either:
// - $type_info doesn't exist (the widget type is unknown),
// - the field type is not allowed for the widget.
// - the configuration does not specify a widget class
// - the field type is not allowed for the widget
// - the widget is not applicable to the field definition.
$definition = $this->getDefinition($configuration['type'], FALSE);
if (!isset($definition['class']) || !in_array($field_type, $definition['field_types'])) {
if (!isset($definition['class']) || !in_array($field_type, $definition['field_types']) || !$definition['class']::isApplicable($field_definition)) {
// Grab the default widget for the field type.
$field_type_definition = $this->fieldTypeManager->getDefinition($field_type);
if (empty($field_type_definition['default_widget'])) {

View File

@ -0,0 +1,52 @@
<?php
/**
* @file
* Contains \Drupal\field\Tests\FormatterPluginManagerTest.
*/
namespace Drupal\field\Tests;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Field\FormatterPluginManager;
/**
* Tests the field formatter plugin manager.
*
* @group field
*/
class FormatterPluginManagerTest extends FieldUnitTestBase {
/**
* Tests that getInstance falls back on default if current is not applicable.
*
* @see \Drupal\field\Tests\WidgetPluginManagerTest::testNotApplicableFallback()
*/
public function testNotApplicableFallback() {
/** @var FormatterPluginManager $formatter_plugin_manager */
$formatter_plugin_manager = \Drupal::service('plugin.manager.field.formatter');
$base_field_definition = BaseFieldDefinition::create('test_field')
// Set a name that will make isApplicable() return TRUE.
->setName('field_test_field');
$formatter_options = array(
'field_definition' => $base_field_definition,
'view_mode' => 'default',
'configuration' => array(
'type' => 'field_test_applicable',
),
);
$instance = $formatter_plugin_manager->getInstance($formatter_options);
$this->assertEqual($instance->getPluginId(), 'field_test_applicable');
// Now set name to something that makes isApplicable() return FALSE.
$base_field_definition->setName('deny_applicable');
$instance = $formatter_plugin_manager->getInstance($formatter_options);
// Instance should be default widget.
$this->assertNotEqual($instance->getPluginId(), 'field_test_applicable');
$this->assertEqual($instance->getPluginId(), 'field_test_default');
}
}

View File

@ -2,10 +2,12 @@
/**
* @file
* Contains \Drupal\field\Tests\WidgetManagerTest.
* Contains \Drupal\field\Tests\WidgetPluginManagerTest.
*/
namespace Drupal\field\Tests;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Field\WidgetPluginManager;
/**
* Tests the field widget manager.
@ -20,8 +22,42 @@ class WidgetPluginManagerTest extends FieldUnitTestBase {
function testWidgetDefinitionAlter() {
$widget_definition = \Drupal::service('plugin.manager.field.widget')->getDefinition('test_field_widget_multiple');
// Test if hook_field_widget_info_alter is beïng called.
// Test if hook_field_widget_info_alter is being called.
$this->assertTrue(in_array('test_field', $widget_definition['field_types']), "The 'test_field_widget_multiple' widget is enabled for the 'test_field' field type in field_test_field_widget_info_alter().");
}
/**
* Tests that getInstance falls back on default if current is not applicable.
*
* @see \Drupal\field\Tests\FormatterPluginManagerTest::testNotApplicableFallback()
*/
public function testNotApplicableFallback() {
/** @var WidgetPluginManager $widget_plugin_manager */
$widget_plugin_manager = \Drupal::service('plugin.manager.field.widget');
$base_field_definition = BaseFieldDefinition::create('test_field')
// Set a name that will make isApplicable() return TRUE.
->setName('field_multiwidgetfield');
$widget_options = array(
'field_definition' => $base_field_definition,
'form_mode' => 'default',
'configuration' => array(
'type' => 'test_field_widget_multiple',
),
);
$instance = $widget_plugin_manager->getInstance($widget_options);
$this->assertEqual($instance->getPluginId(), 'test_field_widget_multiple');
// Now do the same but with machine name field_onewidgetfield, because that
// makes isApplicable() return FALSE.
$base_field_definition->setName('field_onewidgetfield');
$instance = $widget_plugin_manager->getInstance($widget_options);
// Instance should be default widget.
$this->assertNotEqual($instance->getPluginId(), 'test_field_widget_multiple');
$this->assertEqual($instance->getPluginId(), 'test_field_widget');
}
}

View File

@ -0,0 +1,44 @@
<?php
/**
* @file
* Contains \Drupal\field_test\Plugin\Field\FieldFormatter\TestFieldApplicableFormatter.
*/
namespace Drupal\field_test\Plugin\Field\FieldFormatter;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\FormatterBase;
/**
* Plugin implementation of the 'field_test_applicable' formatter.
*
* It is applicable to test_field fields unless their name is 'deny_applicable'.
*
* @FieldFormatter(
* id = "field_test_applicable",
* label = @Translation("Applicable"),
* description = @Translation("Applicable formatter"),
* field_types = {
* "test_field"
* },
* weight = 15,
* )
*/
class TestFieldApplicableFormatter extends FormatterBase {
/**
* {@inheritdoc}
*/
public static function isApplicable(FieldDefinitionInterface $field_definition) {
return $field_definition->getName() != 'deny_applicable';
}
/**
* {@inheritdoc}
*/
public function viewElements(FieldItemListInterface $items) {
return array('#markup' => 'Nothing to see here');
}
}

View File

@ -66,6 +66,7 @@ class ManageDisplayTest extends FieldUiTestBase {
'field_test_default',
'field_test_multiple',
'field_test_with_prepare_view',
'field_test_applicable',
'hidden',
);
$this->assertEqual($options, $expected_options, 'The expected formatter ordering is respected.');