Issue #1043198 by tim.plunkett, tstoeckler, swentel, larowlan: Convert view modes to ConfigEntity.

8.0.x
Alex Pott 2013-05-16 08:29:16 +01:00
parent f816c8919c
commit 6fa50c64eb
36 changed files with 303 additions and 177 deletions

View File

@ -30,46 +30,6 @@ function hook_entity_info(&$entity_info) {
$entity_info['node']['controllers']['form']['mymodule_foo'] = 'Drupal\mymodule\NodeFooFormController';
}
/**
* Describe the view modes for entity types.
*
* View modes let entities be displayed differently depending on the context.
* For instance, a node can be displayed differently on its own page ('full'
* mode), on the home page or taxonomy listings ('teaser' mode), or in an RSS
* feed ('rss' mode). Modules taking part in the display of the entity (notably
* the Field API) can adjust their behavior depending on the requested view
* mode. An additional 'default' view mode is available for all entity types.
* This view mode is not intended for actual entity display, but holds default
* display settings. For each available view mode, administrators can configure
* whether it should use its own set of field display settings, or just
* replicate the settings of the 'default' view mode, thus reducing the amount
* of display configurations to keep track of.
*
* @return array
* An associative array of all entity view modes, keyed by the entity
* type name, and then the view mode name, with the following keys:
* - label: The human-readable name of the view mode.
* - custom_settings: A boolean specifying whether the view mode should by
* default use its own custom field display settings. If FALSE, entities
* displayed in this view mode will reuse the 'default' display settings
* by default (e.g. right after the module exposing the view mode is
* enabled), but administrators can later use the Field UI to apply custom
* display settings specific to the view mode.
*
* @see entity_get_view_modes()
* @see hook_entity_view_mode_info_alter()
*/
function hook_entity_view_mode_info() {
$view_modes['user']['full'] = array(
'label' => t('User account'),
);
$view_modes['user']['compact'] = array(
'label' => t('Compact'),
'custom_settings' => TRUE,
);
return $view_modes;
}
/**
* Alter the view modes for entity types.
*
@ -80,7 +40,7 @@ function hook_entity_view_mode_info() {
* @see hook_entity_view_mode_info()
*/
function hook_entity_view_mode_info_alter(&$view_modes) {
$view_modes['user']['full']['custom_settings'] = TRUE;
$view_modes['user']['full']['status'] = TRUE;
}
/**

View File

@ -121,13 +121,10 @@ function entity_get_view_modes($entity_type = NULL) {
$view_modes = $cache->data;
}
else {
$view_modes = module_invoke_all('entity_view_mode_info');
foreach ($view_modes as $type => $entity_info) {
foreach ($entity_info as $view_mode => $view_mode_info) {
$view_modes[$type][$view_mode] += array(
'custom_settings' => FALSE,
);
}
$view_modes = array();
foreach (entity_load_multiple('view_mode') as $view_mode) {
list($view_mode_entity_type, $view_mode_name) = explode('.', $view_mode->id(), 2);
$view_modes[$view_mode_entity_type][$view_mode_name] = (array) $view_mode;
}
drupal_alter('entity_view_mode_info', $view_modes);
cache()->set("entity_view_mode_info:$langcode", $view_modes, CacheBackendInterface::CACHE_PERMANENT, array('entity_info' => TRUE));
@ -704,7 +701,7 @@ function entity_get_render_display(EntityInterface $entity, $view_mode) {
// configuration of the view mode for this bundle, this will be either the
// display associated to the view mode, or the 'default' display.
$view_mode_settings = field_view_mode_settings($entity_type, $bundle);
$render_view_mode = !empty($view_mode_settings[$view_mode]['custom_settings']) ? $view_mode : 'default';
$render_view_mode = !empty($view_mode_settings[$view_mode]['status']) ? $view_mode : 'default';
$display = entity_get_display($entity_type, $bundle, $render_view_mode);
$display->originalViewMode = $view_mode;

View File

@ -0,0 +1,4 @@
id: custom_block.full
label: Full
status: '0'
targetEntityType: custom_block

View File

@ -185,16 +185,6 @@ function custom_block_entity_bundle_info() {
return $bundles;
}
/**
* Implements hook_entity_view_mode_info().
*/
function custom_block_entity_view_mode_info() {
$view_modes['custom_block']['full'] = array(
'label' => t('Full'),
);
return $view_modes;
}
/**
* Adds the default body field to a custom block type.
*

View File

@ -255,17 +255,6 @@ function book_admin_paths() {
}
}
/**
* Implements hook_entity_view_mode_info().
*/
function book_entity_view_mode_info() {
// Add the 'Print' view mode for nodes.
$view_modes['node']['print'] = array(
'label' => t('Print'),
);
return $view_modes;
}
/**
* Returns an array of all books.
*

View File

@ -0,0 +1,4 @@
id: node.print
label: Print
status: '0'
targetEntityType: node

View File

@ -97,16 +97,6 @@ function comment_help($path, $arg) {
}
}
/**
* Implements hook_entity_view_mode_info().
*/
function comment_entity_view_mode_info() {
$view_modes['comment']['full'] = array(
'label' => t('Full comment'),
);
return $view_modes;
}
/**
* Implements hook_entity_bundle_info().
*/

View File

@ -0,0 +1,4 @@
id: comment.full
label: Full comment
status: '0'
targetEntityType: comment

View File

@ -0,0 +1,17 @@
<?php
/**
* @file
* Contains \Drupal\entity\EntityViewModeInterface.
*/
namespace Drupal\entity;
use Drupal\Core\Config\Entity\ConfigEntityInterface;
/**
* Provides an interface defining an entity view mode entity.
*/
interface EntityViewModeInterface extends ConfigEntityInterface {
}

View File

@ -0,0 +1,32 @@
<?php
/**
* @file
* Contains \Drupal\entity\EntityViewModeStorageController.
*/
namespace Drupal\entity;
use Drupal\Core\Config\Entity\ConfigStorageController;
use Drupal\Core\Entity\EntityInterface;
/**
* Defines the storage controller class for entity view modes.
*/
class EntityViewModeStorageController extends ConfigStorageController {
/**
* {@inheritdoc}
*/
protected function preSave(EntityInterface $view_mode) {
entity_info_cache_clear();
}
/**
* {@inheritdoc}
*/
protected function preDelete($view_modes) {
entity_info_cache_clear();
}
}

View File

@ -0,0 +1,94 @@
<?php
/**
* @file
* Contains \Drupal\entity\Plugin\Core\Entity\EntityViewMode.
*/
namespace Drupal\entity\Plugin\Core\Entity;
use Drupal\Core\Config\Entity\ConfigEntityBase;
use Drupal\Core\Entity\Annotation\EntityType;
use Drupal\Core\Annotation\Translation;
use Drupal\entity\EntityViewModeInterface;
/**
* Defines the view mode configuration entity class.
*
* View modes let entities be displayed differently depending on the context.
* For instance, a node can be displayed differently on its own page ('full'
* mode), on the home page or taxonomy listings ('teaser' mode), or in an RSS
* feed ('rss' mode). Modules taking part in the display of the entity (notably
* the Field API) can adjust their behavior depending on the requested view
* mode. An additional 'default' view mode is available for all entity types.
* This view mode is not intended for actual entity display, but holds default
* display settings. For each available view mode, administrators can configure
* whether it should use its own set of field display settings, or just
* replicate the settings of the 'default' view mode, thus reducing the amount
* of display configurations to keep track of.
*
* @see entity_get_view_modes()
* @see hook_entity_view_mode_info_alter()
*
* @EntityType(
* id = "view_mode",
* label = @Translation("View mode"),
* module = "entity",
* controllers = {
* "storage" = "Drupal\entity\EntityViewModeStorageController"
* },
* config_prefix = "entity.view_mode",
* entity_keys = {
* "id" = "id",
* "label" = "label",
* "uuid" = "uuid"
* }
* )
*/
class EntityViewMode extends ConfigEntityBase implements EntityViewModeInterface {
/**
* The ID of the view mode.
*
* @var string
*/
public $id;
/**
* The UUID of the view mode.
*
* @var string
*/
public $uuid;
/**
* The human-readable name of the view mode.
*
* @var string
*/
public $label;
/**
* The entity type this view mode is used for.
*
* This is not to be confused with EntityViewMode::entityType which is
* inherited from Entity::entityType and equals 'view_mode' for any view mode
* entity.
*
* @var string
*/
public $targetEntityType;
/**
* Whether or not this view mode has custom settings by default.
*
* If FALSE, entities displayed in this view mode will reuse the 'default'
* display settings by default (e.g. right after the module exposing the view
* mode is enabled), but administrators can later use the Field UI to apply
* custom display settings specific to the view mode.
*
* @var bool
*/
public $status = FALSE;
}

View File

@ -574,9 +574,9 @@ function _field_sort_items_value_helper($a, $b) {
* elements:
* - view_modes: An associative array keyed by view mode, with the following
* key/value pairs:
* - custom_settings: Boolean specifying whether the view mode uses a
* dedicated set of display options (TRUE), or the 'default' options
* (FALSE). Defaults to FALSE.
* - status: Boolean specifying whether the view mode uses a dedicated set
* of display options (TRUE), or the 'default' options (FALSE). Defaults
* to FALSE.
* - extra_fields: An associative array containing the form and display
* settings for extra fields (also known as pseudo-fields):
* - form: An associative array whose keys are the names of extra fields,
@ -623,9 +623,9 @@ function field_bundle_settings($entity_type, $bundle, $settings = NULL) {
*
* @return
* An array keyed by view mode, with the following key/value pairs:
* - custom_settings: Boolean specifying whether the view mode uses a
* dedicated set of display options (TRUE), or the 'default' options
* (FALSE). Defaults to FALSE.
* - status: Boolean specifying whether the view mode uses a dedicated set of
* display options (TRUE), or the 'default' options (FALSE). Defaults to
* FALSE.
*/
function field_view_mode_settings($entity_type, $bundle) {
$cache = &drupal_static(__FUNCTION__, array());
@ -638,8 +638,8 @@ function field_view_mode_settings($entity_type, $bundle) {
// settings by default.
$view_modes = entity_get_view_modes($entity_type);
foreach ($view_modes as $view_mode => $view_mode_info) {
if (!isset($settings[$view_mode]['custom_settings']) && $view_mode_info['custom_settings']) {
$settings[$view_mode]['custom_settings'] = TRUE;
if (!isset($settings[$view_mode]['status']) && $view_mode_info['status']) {
$settings[$view_mode]['status'] = TRUE;
}
}
$cache[$entity_type][$bundle] = $settings;

View File

@ -38,11 +38,11 @@ function field_test_entity_view_mode_info_alter(&$view_modes) {
$view_modes[$entity_type] = array(
'full' => array(
'label' => t('Full object'),
'custom_settings' => TRUE,
'status' => TRUE,
),
'teaser' => array(
'label' => t('Teaser'),
'custom_settings' => TRUE,
'status' => TRUE,
),
);
}

View File

@ -1,9 +1,12 @@
<?php
/**
* @file
* Allows administrators to attach custom fields to fieldable types.
*/
use Drupal\entity\EntityViewModeInterface;
/**
* Implements hook_help().
*/
@ -347,3 +350,17 @@ function field_ui_library_info() {
return $libraries;
}
/**
* Implements hook_view_mode_presave().
*/
function field_ui_view_mode_presave(EntityViewModeInterface $view_mode) {
state()->set('menu_rebuild_needed', TRUE);
}
/**
* Implements hook_view_mode_delete().
*/
function field_ui_view_mode_delete(EntityViewModeInterface $view_mode) {
state()->set('menu_rebuild_needed', TRUE);
}

View File

@ -32,7 +32,7 @@ class ViewModeAccessCheck implements AccessCheckInterface {
$view_mode = $request->attributes->get('view_mode');
$view_mode_settings = field_view_mode_settings($entity_type, $bundle);
$visibility = ($view_mode == 'default') || !empty($view_mode_settings[$view_mode]['custom_settings']);
$visibility = ($view_mode == 'default') || !empty($view_mode_settings[$view_mode]['status']);
if ($visibility) {
$permission = $route->getRequirement('_field_ui_view_mode_access');
return user_access($permission);

View File

@ -361,7 +361,7 @@ class DisplayOverview extends OverviewBase {
$view_mode_settings = field_view_mode_settings($this->entity_type, $this->bundle);
foreach ($view_modes as $view_mode_name => $view_mode_info) {
$options[$view_mode_name] = $view_mode_info['label'];
if (!empty($view_mode_settings[$view_mode_name]['custom_settings'])) {
if (!empty($view_mode_settings[$view_mode_name]['status'])) {
$default[] = $view_mode_name;
}
}
@ -476,7 +476,7 @@ class DisplayOverview extends OverviewBase {
$view_mode_settings = field_view_mode_settings($this->entity_type, $this->bundle);
foreach ($form_values['view_modes_custom'] as $view_mode => $value) {
if (!empty($value) && empty($view_mode_settings[$view_mode]['custom_settings'])) {
if (!empty($value) && empty($view_mode_settings[$view_mode]['status'])) {
// If no display exists for the newly enabled view mode, initialize
// it with those from the 'default' view mode, which were used so
// far.
@ -489,7 +489,7 @@ class DisplayOverview extends OverviewBase {
$path = $this->entityManager->getAdminPath($this->entity_type, $this->bundle) . "/display/$view_mode";
drupal_set_message(t('The %view_mode mode now uses custom display settings. You might want to <a href="@url">configure them</a>.', array('%view_mode' => $view_mode_label, '@url' => url($path))));
}
$bundle_settings['view_modes'][$view_mode]['custom_settings'] = !empty($value);
$bundle_settings['view_modes'][$view_mode]['status'] = !empty($value);
}
// Save updated bundle settings.

View File

@ -0,0 +1,4 @@
id: file.full
label: File default
status: '0'
targetEntityType: file

View File

@ -90,16 +90,6 @@ function file_element_info() {
return $types;
}
/**
* Implements hook_entity_view_mode_info().
*/
function file_entity_view_mode_info() {
$view_modes['file']['full'] = array(
'label' => t('File default'),
);
return $view_modes;
}
/**
* Loads file entities from the database.
*

View File

@ -0,0 +1,4 @@
id: node.full
label: Full content
status: '0'
targetEntityType: node

View File

@ -0,0 +1,4 @@
id: node.rss
label: RSS
status: '0'
targetEntityType: node

View File

@ -0,0 +1,4 @@
id: node.teaser
label: Teaser
status: '1'
targetEntityType: node

View File

@ -180,33 +180,6 @@ function node_theme() {
);
}
/**
* Implements hook_entity_view_mode_info().
*/
function node_entity_view_mode_info() {
$view_modes['node']['full'] = array(
'label' => t('Full content'),
);
$view_modes['node']['teaser'] = array(
'label' => t('Teaser'),
'custom_settings' => TRUE,
);
$view_modes['node']['rss'] = array(
'label' => t('RSS'),
);
// Search integration is provided by node.module, so search-related
// view modes for nodes are defined here and not in search.module.
if (module_exists('search')) {
$view_modes['node']['search_index'] = array(
'label' => t('Search index'),
);
$view_modes['node']['search_result'] = array(
'label' => t('Search result'),
);
}
return $view_modes;
}
/**
* Implements hook_entity_bundle_info().
*/

View File

@ -0,0 +1,4 @@
id: node.search_index
label: Search index
status: '0'
targetEntityType: node

View File

@ -0,0 +1,4 @@
id: node.search_result
label: Search result
status: '0'
targetEntityType: node

View File

@ -99,6 +99,13 @@ class FilledStandardUpgradePathTest extends UpgradePathTestBase {
$this->assertEqual($blog_type->module, 'node', "Content type 'blog' has been reassigned from the blog module to the node module.");
$this->assertEqual($blog_type->base, 'node_content', "The base string used to construct callbacks corresponding to content type 'Blog' has been reassigned to 'node_content'.");
// Each entity type has a 'full' view mode, ensure it was migrated.
$all_view_modes = entity_get_view_modes();
$this->assertTrue(!empty($all_view_modes), 'The view modes have been migrated.');
foreach ($all_view_modes as $entity_view_modes) {
$this->assertTrue(isset($entity_view_modes['full']));
}
// Check that user data has been migrated correctly.
$query = db_query('SELECT * FROM {users_data}');

View File

@ -2141,6 +2141,57 @@ function system_update_8055() {
}
}
/**
* Moves entity view modes to config.
*
* @ingroup config_upgrade
*/
function system_update_8056() {
// We cannot call entity_get_info() in an update hook, so we hardcode the view
// modes. Only the node entity type's teaser view mode is set to custom by
// default, we check specifically for that below. The only way to add custom
// view modes in Drupal 7 was hook_entity_info_alter(), which still works in
// Drupal 8.
$entity_view_modes = array(
'node' => array(
'full' => 'Full content',
'teaser' => 'Teaser',
'rss' => 'RSS',
'search_index' => 'Search index',
'search_result' => 'Search result',
'print' => 'Print',
),
'file' => array(
'full' => 'File default',
),
'comment' => array(
'full' => 'Full comment',
),
'user' => array(
'full' => 'User account',
'compact' => 'Compact',
),
'taxonomy_term' => array(
'full' => 'Taxonomy term page',
),
'taxonomy_vocabulary' => array(
'full' => 'Taxonomy vocabulary',
),
);
foreach ($entity_view_modes as $entity_type => $view_modes) {
foreach ($view_modes as $key => $name) {
$status = in_array($key, array('teaser', 'compact'));
config("entity.view_mode.$entity_type.$key")
->set('id', "$entity_type.$key")
->set('label', $name)
->set('targetEntityType', $entity_type)
->set('status', $status)
->save();
}
}
}
/**
* @} End of "defgroup updates-7.x-to-8.x".
* The next series of updates should start at 9000.

View File

@ -0,0 +1,4 @@
id: entity_test_render.full
label: Full
status: '0'
targetEntityType: entity_test_render

View File

@ -0,0 +1,4 @@
id: entity_test_render.test
label: Test
status: '0'
targetEntityType: entity_test_render

View File

@ -338,20 +338,6 @@ function entity_test_label_callback($entity_type, $entity, $langcode = NULL) {
return 'label callback ' . $entity->name->value;
}
/**
* Implements hook_entity_view_mode_info().
*/
function entity_test_entity_view_mode_info() {
$view_modes['entity_test_render']['full'] = array(
'label' => t('Full'),
);
$view_modes['entity_test_render']['test'] = array(
'label' => t('Test'),
);
return $view_modes;
}
/**
* Implements hook_entity_field_access().
*

View File

@ -12,19 +12,19 @@
$value = array(
'view_modes' => array(
'teaser' => array(
'custom_settings' => 1,
'status' => 1,
),
'full' => array(
'custom_settings' => 0,
'status' => 0,
),
'rss' => array(
'custom_settings' => 0,
'status' => 0,
),
'search_index' => array(
'custom_settings' => 0,
'status' => 0,
),
'search_result' => array(
'custom_settings' => 0,
'status' => 0,
),
),
'extra_fields' => array(

View File

@ -0,0 +1,4 @@
id: taxonomy_term.full
label: Taxonomy term page
status: '0'
targetEntityType: taxonomy_term

View File

@ -0,0 +1,4 @@
id: vocabulary.full
label: Taxonomy vocabulary
status: '0'
targetEntityType: taxonomy_vocabulary

View File

@ -105,19 +105,6 @@ function taxonomy_permission() {
return $permissions;
}
/**
* Implements hook_entity_view_mode_info().
*/
function taxonomy_entity_view_mode_info() {
$view_modes['taxonomy_term']['full'] = array(
'label' => t('Taxonomy term page'),
);
$view_modes['taxonomy_vocabulary']['full'] = array(
'label' => t('Taxonomy vocabulary'),
);
return $view_modes;
}
/**
* Implements hook_entity_bundle_info().
*/

View File

@ -0,0 +1,4 @@
id: user.compact
label: Compact
status: '1'
targetEntityType: user

View File

@ -0,0 +1,4 @@
id: user.full
label: User account
status: '0'
targetEntityType: user

View File

@ -121,20 +121,6 @@ function user_page_build(&$page) {
$page['#attached']['css'][$path . '/user.css'] = array('every_page' => TRUE);
}
/**
* Implements hook_entity_view_mode_info().
*/
function user_entity_view_mode_info() {
$view_modes['user']['full'] = array(
'label' => t('User account'),
);
$view_modes['user']['compact'] = array(
'label' => t('Compact'),
'custom_settings' => TRUE,
);
return $view_modes;
}
/**
* Implements hook_entity_bundle_info().
*/