diff --git a/core/lib/Drupal/Core/Entity/EntityManager.php b/core/lib/Drupal/Core/Entity/EntityManager.php index 6c8e48b..7cb3f26 100644 --- a/core/lib/Drupal/Core/Entity/EntityManager.php +++ b/core/lib/Drupal/Core/Entity/EntityManager.php @@ -128,27 +128,6 @@ * - access callback: As in hook_menu(). 'user_access' will be assumed if * no value is provided. * - access arguments: As in hook_menu(). - * - view_modes: An array describing the view modes for the entity type. 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. Keys of the array are view mode names. Each view mode is - * described by an array with the following key/value pairs: - * - 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. * - menu_base_path: (optional) The base menu router path to which the entity * administration user interface responds. It can be used to generate UI * links and to attach additional router items to the entity UI in a generic @@ -270,15 +249,24 @@ protected function processDefinition(&$definition, $plugin_id) { parent::processDefinition($definition, $plugin_id); // @todo Remove this check once http://drupal.org/node/1780396 is resolved. - if (!module_exists($definition['module'])) { + if ($definition['module'] != 'Core' && !module_exists($definition['module'])) { $definition = NULL; return; } - foreach ($definition['view_modes'] as $view_mode => $view_mode_info) { - $definition['view_modes'][$view_mode] += array( - 'custom_settings' => FALSE, - ); + // Add view modes. + // We cannot use entity_load_multiple() as that leads to recursion. + $view_modes = drupal_container()->get('config.storage')->listAll('view_mode.'); + $config_factory = drupal_container()->get('config.factory'); + foreach ($view_modes as $config_name) { + $view_mode = $config_factory->get($config_name)->load()->get(); + if ($view_mode['targetEntityType'] == $plugin_id) { + $entity_type = strtok($view_mode['id'], '.'); + $definition['view_modes'][strtok('.')] = array( + 'label' => check_plain($view_mode['label']), + 'custom_settings' => $view_mode['hasSettings'], + ); + } } // If no bundle key is provided, assume a single bundle, named after @@ -286,6 +274,7 @@ protected function processDefinition(&$definition, $plugin_id) { if (empty($definition['entity_keys']['bundle']) && empty($definition['bundles'])) { $definition['bundles'] = array($plugin_id => array('label' => $definition['label'])); } + // Prepare entity schema fields SQL info for // Drupal\Core\Entity\DatabaseStorageControllerInterface::buildQuery(). if (isset($definition['base_table'])) { diff --git a/core/lib/Drupal/Core/Entity/ViewMode/EntityViewModeStorageController.php b/core/lib/Drupal/Core/Entity/ViewMode/EntityViewModeStorageController.php new file mode 100644 index 0000000..5d6b193 --- /dev/null +++ b/core/lib/Drupal/Core/Entity/ViewMode/EntityViewModeStorageController.php @@ -0,0 +1,33 @@ +name, '.'); + return strtok('.'); + } + +} diff --git a/core/modules/book/book.module b/core/modules/book/book.module index 062097a..e48b548 100644 --- a/core/modules/book/book.module +++ b/core/modules/book/book.module @@ -246,17 +246,6 @@ function book_admin_paths() { } /** - * Implements hook_entity_info(). - */ -function book_entity_info(&$info) { - // Add the 'Print' view mode for nodes. - $info['node']['view_modes']['print'] = array( - 'label' => t('Print'), - 'custom_settings' => FALSE, - ); -} - -/** * Implements hook_block_info(). */ function book_block_info() { diff --git a/core/modules/book/config/view_mode.node.print.yml b/core/modules/book/config/view_mode.node.print.yml new file mode 100644 index 0000000..c1290fd --- /dev/null +++ b/core/modules/book/config/view_mode.node.print.yml @@ -0,0 +1,5 @@ +id: node.print +label: Print +hasSettings: '0' +targetEntityType: node +locked: '1' diff --git a/core/modules/comment/config/view_mode.comment.full.yml b/core/modules/comment/config/view_mode.comment.full.yml new file mode 100644 index 0000000..1549c46 --- /dev/null +++ b/core/modules/comment/config/view_mode.comment.full.yml @@ -0,0 +1,5 @@ +id: comment.full +label: Full comment +hasSettings: '0' +targetEntityType: comment +locked: '1' diff --git a/core/modules/comment/lib/Drupal/comment/Plugin/Core/Entity/Comment.php b/core/modules/comment/lib/Drupal/comment/Plugin/Core/Entity/Comment.php index e0bbfd9..e3b31a0 100644 --- a/core/modules/comment/lib/Drupal/comment/Plugin/Core/Entity/Comment.php +++ b/core/modules/comment/lib/Drupal/comment/Plugin/Core/Entity/Comment.php @@ -34,12 +34,6 @@ * "bundle" = "node_type", * "label" = "subject", * "uuid" = "uuid" - * }, - * view_modes = { - * "full" = { - * "label" = "Full comment", - * "custom_settings" = FALSE - * } * } * ) */ diff --git a/core/modules/field_ui/field_ui.module b/core/modules/field_ui/field_ui.module index a04c0dd..babb0b4 100644 --- a/core/modules/field_ui/field_ui.module +++ b/core/modules/field_ui/field_ui.module @@ -1,9 +1,12 @@ set('menu_rebuild_needed', TRUE); +} + +/** + * Implements hook_view_mode_delete(). + */ +function field_ui_view_mode_delete(EntityViewMode $view_mode) { + state()->set('menu_rebuild_needed', TRUE); +} + diff --git a/core/modules/file/config/view_mode.file.full.yml b/core/modules/file/config/view_mode.file.full.yml new file mode 100644 index 0000000..743e2d1 --- /dev/null +++ b/core/modules/file/config/view_mode.file.full.yml @@ -0,0 +1,5 @@ +id: file.full +label: File default +hasSettings: '0' +targetEntityType: file +locked: '1' diff --git a/core/modules/file/lib/Drupal/file/Plugin/Core/Entity/File.php b/core/modules/file/lib/Drupal/file/Plugin/Core/Entity/File.php index bc54514..d7f2a6b 100644 --- a/core/modules/file/lib/Drupal/file/Plugin/Core/Entity/File.php +++ b/core/modules/file/lib/Drupal/file/Plugin/Core/Entity/File.php @@ -26,12 +26,6 @@ * "id" = "fid", * "label" = "filename", * "uuid" = "uuid" - * }, - * view_modes = { - * "full" = { - * "label" = "File default", - * "custom_settings" = FALSE - * } * } * ) */ diff --git a/core/modules/node/config/view_mode.node.full.yml b/core/modules/node/config/view_mode.node.full.yml new file mode 100644 index 0000000..e3fe426 --- /dev/null +++ b/core/modules/node/config/view_mode.node.full.yml @@ -0,0 +1,5 @@ +id: node.full +label: Full content +hasSettings: '0' +targetEntityType: node +locked: '1' diff --git a/core/modules/node/config/view_mode.node.rss.yml b/core/modules/node/config/view_mode.node.rss.yml new file mode 100644 index 0000000..5b29601 --- /dev/null +++ b/core/modules/node/config/view_mode.node.rss.yml @@ -0,0 +1,5 @@ +id: node.rss +label: RSS +hasSettings: '0' +targetEntityType: node +locked: '1' diff --git a/core/modules/node/config/view_mode.node.teaser.yml b/core/modules/node/config/view_mode.node.teaser.yml new file mode 100644 index 0000000..8d83192 --- /dev/null +++ b/core/modules/node/config/view_mode.node.teaser.yml @@ -0,0 +1,5 @@ +id: node.teaser +label: Teaser +hasSettings: '1' +targetEntityType: node +locked: '1' diff --git a/core/modules/node/lib/Drupal/node/Plugin/Core/Entity/Node.php b/core/modules/node/lib/Drupal/node/Plugin/Core/Entity/Node.php index 1fd8fc8..1267f3a 100644 --- a/core/modules/node/lib/Drupal/node/Plugin/Core/Entity/Node.php +++ b/core/modules/node/lib/Drupal/node/Plugin/Core/Entity/Node.php @@ -38,20 +38,6 @@ * }, * bundle_keys = { * "bundle" = "type" - * }, - * view_modes = { - * "full" = { - * "label" = "Full content", - * "custom_settings" = FALSE - * }, - * "teaser" = { - * "label" = "Teaser", - * "custom_settings" = TRUE - * }, - * "rss" = { - * "label" = "RSS", - * "custom_settings" = FALSE - * } * } * ) */ diff --git a/core/modules/node/node.module b/core/modules/node/node.module index 08d7810..83d5627 100644 --- a/core/modules/node/node.module +++ b/core/modules/node/node.module @@ -182,19 +182,6 @@ function node_entity_info(&$info) { $info['node']['translation']['node'] = TRUE; } - // 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')) { - $info['node']['view_modes']['search_index'] = array( - 'label' => t('Search index'), - 'custom_settings' => FALSE, - ); - $info['node']['view_modes']['search_result'] = array( - 'label' => t('Search result'), - 'custom_settings' => FALSE, - ); - } - // Bundles must provide a human readable name so we can create help and error // messages, and the path to attach Field admin pages to. node_type_cache_reset(); diff --git a/core/modules/rest/lib/Drupal/rest/Tests/RESTTestBase.php b/core/modules/rest/lib/Drupal/rest/Tests/RESTTestBase.php index acf4802..09e1e09 100644 --- a/core/modules/rest/lib/Drupal/rest/Tests/RESTTestBase.php +++ b/core/modules/rest/lib/Drupal/rest/Tests/RESTTestBase.php @@ -116,6 +116,8 @@ protected function entityCreate($entity_type) { return entity_create('node', array('title' => $this->randomString())); case 'user': return entity_create('user', array('name' => $this->randomName())); + case 'view_mode': + return entity_create('view_mode', array('name' => $this->randomName(), 'machineName' => 'node.test')); default: return entity_create($entity_type, array()); } diff --git a/core/modules/search/config/view_mode.node.search_index.yml b/core/modules/search/config/view_mode.node.search_index.yml new file mode 100644 index 0000000..cd98947 --- /dev/null +++ b/core/modules/search/config/view_mode.node.search_index.yml @@ -0,0 +1,5 @@ +id: node.search_index +label: Search index +hasSettings: '0' +targetEntityType: node +locked: '1' diff --git a/core/modules/search/config/view_mode.node.search_result.yml b/core/modules/search/config/view_mode.node.search_result.yml new file mode 100644 index 0000000..ab6fe86 --- /dev/null +++ b/core/modules/search/config/view_mode.node.search_result.yml @@ -0,0 +1,5 @@ +id: node.search_result +label: Search result +hasSettings: '0' +targetEntityType: node +locked: '1' diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/FilledStandardUpgradePathTest.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/FilledStandardUpgradePathTest.php index e1df73e..4147c27 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/FilledStandardUpgradePathTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/FilledStandardUpgradePathTest.php @@ -96,5 +96,14 @@ public function testFilledStandardUpgrade() { $blog_type = node_type_load('blog'); $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'."); + + // Verify all core view modes have been converted to config. + $entity_info = entity_get_info(); + foreach ($entity_info as $type => $info) { + if (!empty($info['fieldable'])) { + $this->assertTrue(!empty($info['view_modes']), format_string('View modes for @entity_type have been converted', array('@entity_type' => $info['label']))); + } + } + } } diff --git a/core/modules/system/system.install b/core/modules/system/system.install index 9d823ca..8c0f129 100644 --- a/core/modules/system/system.install +++ b/core/modules/system/system.install @@ -2232,6 +2232,57 @@ function system_update_8036() { } /** + * Moves entity view modes to config. + * + * @ingroup config_upgrade + */ +function system_update_8037() { + // 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', + ), + '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) { + $custom = ($key == 'teaser'); + config('view_mode.' . $entity_type . '.' . $key) + ->set('machineName', $entity_type . '.' . $key) + ->set('name', $name) + ->set('targetEntityType', $entity_type) + ->set('locked', TRUE) + ->set('custom', $custom) + ->save(); + } + } +} + +/** * @} End of "defgroup updates-7.x-to-8.x". * The next series of updates should start at 9000. */ diff --git a/core/modules/taxonomy/config/view_mode.taxonomy_term.full.yml b/core/modules/taxonomy/config/view_mode.taxonomy_term.full.yml new file mode 100644 index 0000000..4203a25 --- /dev/null +++ b/core/modules/taxonomy/config/view_mode.taxonomy_term.full.yml @@ -0,0 +1,5 @@ +id: taxonomy_term.full +label: Taxonomy term page +hasSettings: '0' +targetEntityType: taxonomy_term +locked: '1' diff --git a/core/modules/taxonomy/config/view_mode.taxonomy_vocabulary.full.yml b/core/modules/taxonomy/config/view_mode.taxonomy_vocabulary.full.yml new file mode 100644 index 0000000..1f8cfd9 --- /dev/null +++ b/core/modules/taxonomy/config/view_mode.taxonomy_vocabulary.full.yml @@ -0,0 +1,5 @@ +id: vocabulary.full +label: Taxonomy vocabulary +hasSettings: '0' +targetEntityType: taxonomy_vocabulary +locked: '1' diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Core/Entity/Term.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Core/Entity/Term.php index 51468af..7d9ce49 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Core/Entity/Term.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Core/Entity/Term.php @@ -37,12 +37,6 @@ * bundle_keys = { * "bundle" = "machine_name" * }, - * view_modes = { - * "full" = { - * "label" = "Taxonomy term page", - * "custom_settings" = FALSE - * } - * }, * menu_base_path = "taxonomy/term/%taxonomy_term" * ) */ diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Core/Entity/Vocabulary.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Core/Entity/Vocabulary.php index 0ecbae8..beee8d1 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Core/Entity/Vocabulary.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Core/Entity/Vocabulary.php @@ -26,12 +26,6 @@ * entity_keys = { * "id" = "vid", * "label" = "name" - * }, - * view_modes = { - * "full" = { - * "label" = "Taxonomy vocabulary", - * "custom_settings" = FALSE - * } * } * ) */ diff --git a/core/modules/user/config/view_mode.user.full.yml b/core/modules/user/config/view_mode.user.full.yml new file mode 100644 index 0000000..cd81d36 --- /dev/null +++ b/core/modules/user/config/view_mode.user.full.yml @@ -0,0 +1,5 @@ +id: user.full +label: User account +hasSettings: '0' +targetEntityType: user +locked: '1' diff --git a/core/modules/user/lib/Drupal/user/Plugin/Core/Entity/User.php b/core/modules/user/lib/Drupal/user/Plugin/Core/Entity/User.php index dbedf89..da41eaa 100644 --- a/core/modules/user/lib/Drupal/user/Plugin/Core/Entity/User.php +++ b/core/modules/user/lib/Drupal/user/Plugin/Core/Entity/User.php @@ -42,12 +42,6 @@ * "access arguments" = {"administer users"} * } * } - * }, - * view_modes = { - * "full" = { - * "label" = "User account", - * "custom_settings" = FALSE - * } * } * ) */