diff --git a/core/lib/Drupal/Core/Entity/Annotation/ConfigEntityType.php b/core/lib/Drupal/Core/Entity/Annotation/ConfigEntityType.php index b99e47214f7..7126eff2378 100644 --- a/core/lib/Drupal/Core/Entity/Annotation/ConfigEntityType.php +++ b/core/lib/Drupal/Core/Entity/Annotation/ConfigEntityType.php @@ -19,4 +19,18 @@ class ConfigEntityType extends EntityType { */ public $entity_type_class = 'Drupal\Core\Config\Entity\ConfigEntityType'; + /** + * {@inheritdoc} + */ + public $group = 'configuration'; + + /** + * {@inheritdoc} + */ + public function get() { + $this->definition['group_label'] = $this->t('Configuration', array(), array('context' => 'Entity type group')); + + return parent::get(); + } + } diff --git a/core/lib/Drupal/Core/Entity/Annotation/ContentEntityType.php b/core/lib/Drupal/Core/Entity/Annotation/ContentEntityType.php index e9ae8522ace..ddf05c90c00 100644 --- a/core/lib/Drupal/Core/Entity/Annotation/ContentEntityType.php +++ b/core/lib/Drupal/Core/Entity/Annotation/ContentEntityType.php @@ -19,4 +19,18 @@ class ContentEntityType extends EntityType { */ public $entity_type_class = 'Drupal\Core\Entity\ContentEntityType'; + /** + * {@inheritdoc} + */ + public $group = 'content'; + + /** + * {@inheritdoc} + */ + public function get() { + $this->definition['group_label'] = $this->t('Content', array(), array('context' => 'Entity type group')); + + return parent::get(); + } + } diff --git a/core/lib/Drupal/Core/Entity/Annotation/EntityType.php b/core/lib/Drupal/Core/Entity/Annotation/EntityType.php index 76e51e4048f..6301f8014b1 100644 --- a/core/lib/Drupal/Core/Entity/Annotation/EntityType.php +++ b/core/lib/Drupal/Core/Entity/Annotation/EntityType.php @@ -8,6 +8,7 @@ namespace Drupal\Core\Entity\Annotation; use Drupal\Component\Annotation\Plugin; +use Drupal\Core\StringTranslation\StringTranslationTrait; /** * Defines an Entity type annotation object. @@ -24,6 +25,8 @@ use Drupal\Component\Annotation\Plugin; */ class EntityType extends Plugin { + use StringTranslationTrait; + /** * The class used to represent the entity type. * @@ -33,6 +36,20 @@ class EntityType extends Plugin { */ public $entity_type_class = 'Drupal\Core\Entity\EntityType'; + /** + * The group machine name. + */ + public $group = 'default'; + + /** + * The group label. + * + * @var \Drupal\Core\Annotation\Translation + * + * @ingroup plugin_translatable + */ + public $group_label = ''; + /** * {@inheritdoc} */ diff --git a/core/lib/Drupal/Core/Entity/EntityManager.php b/core/lib/Drupal/Core/Entity/EntityManager.php index fb1a78636c1..bc3e5638748 100644 --- a/core/lib/Drupal/Core/Entity/EntityManager.php +++ b/core/lib/Drupal/Core/Entity/EntityManager.php @@ -22,6 +22,7 @@ use Drupal\Core\Plugin\Discovery\AlterDecorator; use Drupal\Core\Plugin\Discovery\CacheDecorator; use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery; use Drupal\Core\Plugin\Discovery\InfoHookDecorator; +use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\StringTranslation\TranslationInterface; use Drupal\Core\TypedData\TranslatableInterface; use Symfony\Component\DependencyInjection\ContainerAwareInterface; @@ -44,6 +45,7 @@ use Symfony\Component\DependencyInjection\ContainerAwareTrait; class EntityManager extends PluginManagerBase implements EntityManagerInterface, ContainerAwareInterface { use ContainerAwareTrait; + use StringTranslationTrait; /** * Extra fields by bundle. @@ -638,10 +640,28 @@ class EntityManager extends PluginManagerBase implements EntityManagerInterface, /** * {@inheritdoc} */ - public function getEntityTypeLabels() { + public function getEntityTypeLabels($group = FALSE) { $options = array(); - foreach ($this->getDefinitions() as $entity_type => $definition) { - $options[$entity_type] = $definition->getLabel(); + $definitions = $this->getDefinitions(); + + foreach ($definitions as $entity_type_id => $definition) { + if ($group) { + $options[$definition->getGroupLabel()][$entity_type_id] = $definition->getLabel(); + } + else { + $options[$entity_type_id] = $definition->getLabel(); + } + } + + if ($group) { + foreach ($options as &$group_options) { + // Sort the list alphabetically by group label. + array_multisort($group_options, SORT_ASC, SORT_NATURAL); + } + + // Make sure that the 'Content' group is situated at the top. + $content = $this->t('Content', array(), array('context' => 'Entity type group')); + $options = array($content => $options[$content]) + $options; } return $options; diff --git a/core/lib/Drupal/Core/Entity/EntityManagerInterface.php b/core/lib/Drupal/Core/Entity/EntityManagerInterface.php index 7ee02553609..7d2c54770ca 100644 --- a/core/lib/Drupal/Core/Entity/EntityManagerInterface.php +++ b/core/lib/Drupal/Core/Entity/EntityManagerInterface.php @@ -17,10 +17,14 @@ interface EntityManagerInterface extends PluginManagerInterface { /** * Builds a list of entity type labels suitable for a Form API options list. * + * @param bool $group + * (optional) Whether to group entity types by plugin group (e.g. 'content', + * 'config'). Defaults to FALSE. + * * @return array * An array of entity type labels, keyed by entity type name. */ - public function getEntityTypeLabels(); + public function getEntityTypeLabels($group = FALSE); /** * Gets the base field definitions for a content entity type. diff --git a/core/lib/Drupal/Core/Entity/EntityType.php b/core/lib/Drupal/Core/Entity/EntityType.php index 653864743e6..438266533ca 100644 --- a/core/lib/Drupal/Core/Entity/EntityType.php +++ b/core/lib/Drupal/Core/Entity/EntityType.php @@ -10,12 +10,15 @@ namespace Drupal\Core\Entity; use Drupal\Component\Utility\String; use Drupal\Component\Utility\Unicode; use Drupal\Core\Entity\Exception\EntityTypeIdLengthException; +use Drupal\Core\StringTranslation\StringTranslationTrait; /** * Provides an implementation of an entity type and its metadata. */ class EntityType implements EntityTypeInterface { + use StringTranslationTrait; + /** * Indicates whether entities should be statically cached. * @@ -179,6 +182,16 @@ class EntityType implements EntityTypeInterface { */ protected $uri_callback; + /** + * The machine name of the entity type group. + */ + protected $group; + + /** + * The human-readable name of the entity type group. + */ + protected $group_label; + /** * Constructs a new EntityType. * @@ -610,4 +623,19 @@ class EntityType implements EntityTypeInterface { return $this; } + /** + * {@inheritdoc} + */ + public function getGroup() { + return $this->group; + } + + + /** + * {@inheritdoc} + */ + public function getGroupLabel() { + return !empty($this->group_label) ? $this->group_label : $this->t('Other', array(), array('context' => 'Entity type group')); + } + } diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/ConfigurableEntityReferenceItem.php b/core/modules/entity_reference/lib/Drupal/entity_reference/ConfigurableEntityReferenceItem.php index 4757302198a..e5ad209d8e3 100644 --- a/core/modules/entity_reference/lib/Drupal/entity_reference/ConfigurableEntityReferenceItem.php +++ b/core/modules/entity_reference/lib/Drupal/entity_reference/ConfigurableEntityReferenceItem.php @@ -163,7 +163,7 @@ class ConfigurableEntityReferenceItem extends EntityReferenceItem implements All $element['target_type'] = array( '#type' => 'select', '#title' => t('Type of item to reference'), - '#options' => \Drupal::entityManager()->getEntityTypeLabels(), + '#options' => \Drupal::entityManager()->getEntityTypeLabels(TRUE), '#default_value' => $this->getSetting('target_type'), '#required' => TRUE, '#disabled' => $has_data, diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAdminTest.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAdminTest.php index 8466bf242de..60d55ba81ff 100644 --- a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAdminTest.php +++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAdminTest.php @@ -127,7 +127,7 @@ class EntityReferenceAdminTest extends WebTestBase { if ($fields) { $field = $fields[0]; $options = $this->getAllOptionsList($field); - return $this->assertIdentical($options, $expected_options); + return $this->assertIdentical(sort($options), sort($expected_options)); } else { return $this->fail('Unable to find field ' . $name); diff --git a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php index 20fb54f5105..340b5556a60 100644 --- a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php +++ b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php @@ -3141,7 +3141,7 @@ abstract class WebTestBase extends TestBase { // Input element with correct value. $found = TRUE; } - elseif (isset($field->option)) { + elseif (isset($field->option) || isset($field->optgroup)) { // Select element found. $selected = $this->getSelectedItem($field); if ($selected === FALSE) {