diff --git a/sites/all/modules/contrib/admin/admin_toolbar/CHANGELOG.txt b/sites/all/modules/contrib/admin/admin_toolbar/CHANGELOG.txt index 3078d5f3b..12f4450ae 100644 --- a/sites/all/modules/contrib/admin/admin_toolbar/CHANGELOG.txt +++ b/sites/all/modules/contrib/admin/admin_toolbar/CHANGELOG.txt @@ -1,7 +1,30 @@ -Admin Toolbar 8.1.22, 2017-XX-XX +Admin Toolbar 8.1.23, 2018-02-06 +-------------------------------- +Changes since 8.1.22: + +- #2924266 by sunlix, romainj, adriancid, samerali: Add a menu link for the + media module. +- #2941184 by daniel.nitsche, adriancid: Remove unwanted comment from + admin.toolbar.css. +- #2912503 by Amsteri, m.abdulqader: Right to left language direction support. +- #2937982 by romainj, adriancid: Auto-generation of menu links conflicts with + other modules. +- #2932873 by vaplas, saravanaprasanth, adriancid: Horizontal mode only works if + the page is loaded in horizontal mode. +- #2935311 by romainj, adriancid: Use the $entityTypeManager variable instead of + the \Drupal::entityTypeManager service. +- #2935449 by adriancid: Add the release information for the 1.22 version in the + CHANGELOG.txt. +- #2932476 by romainj: toolbar.tree library should have a dependency to the + core/drupal library. +- #2931503 by K3vin_nl: Admin toolbar generates invalid class names. + +Admin Toolbar 8.1.22, 2018-01-02 -------------------------------- Changes since 8.1.21: +- #2929053 by kkuhnen, eme, adriancid: admin_toolbar.js should use Drupal + behaviors. - #2929061 by romainj, dsnopek, adriancid: admin_toolbar_links_access_filter doesn't do anything unless admin_toolbar is enabled. - #2928836 by eme: One extra pixel line under the admin toolbar. diff --git a/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar.info.yml b/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar.info.yml index 6f8a5e9ed..900077c7b 100644 --- a/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar.info.yml +++ b/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar.info.yml @@ -8,8 +8,8 @@ type: module dependencies: - drupal:toolbar -# Information added by Drupal.org packaging script on 2018-01-02 -version: '8.x-1.22' +# Information added by Drupal.org packaging script on 2018-02-06 +version: '8.x-1.23' core: '8.x' project: 'admin_toolbar' -datestamp: 1514888588 +datestamp: 1517936588 diff --git a/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar.libraries.yml b/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar.libraries.yml index 0a3ab1f5e..85b322a4e 100644 --- a/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar.libraries.yml +++ b/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar.libraries.yml @@ -7,3 +7,4 @@ toolbar.tree: js/admin_toolbar.js: {} dependencies: - core/jquery + - core/drupal diff --git a/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar.module b/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar.module index d42df2c12..a9199e91a 100644 --- a/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar.module +++ b/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar.module @@ -8,6 +8,7 @@ use Drupal\Core\Menu\MenuTreeParameters; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Url; +use Drupal\Component\Utility\Html; /** * Implements hook_toolbar_alter(). @@ -90,7 +91,7 @@ function toolbar_tools_menu_navigation_links(array $tree) { $element->options['attributes']['class'][] = 'toolbar-icon'; $string = strtolower(str_replace(['.', ' ', '_'], ['-', '-', '-'], $definition['id'])); - $element->options['attributes']['class'][] = 'toolbar-icon-' . $string; + $element->options['attributes']['class'][] = Html::cleanCssIdentifier('toolbar-icon-' . $string); $element->options['attributes']['title'] = $link->getDescription(); } return $tree; diff --git a/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar_links_access_filter/admin_toolbar_links_access_filter.info.yml b/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar_links_access_filter/admin_toolbar_links_access_filter.info.yml index 771c011e2..355a40cac 100644 --- a/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar_links_access_filter/admin_toolbar_links_access_filter.info.yml +++ b/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar_links_access_filter/admin_toolbar_links_access_filter.info.yml @@ -1,13 +1,15 @@ name: Admin Toolbar Links Access Filter description: Provides a workaround for the common problem that users with 'Use the administration pages and help' permission see menu links they don't have access permission for. Once the issue https://www.drupal.org/node/296693 be solved, this module will be deprecated. package: Administration -dependencies: - - admin_toolbar:admin_toolbar + type: module # core: 8.x -# Information added by Drupal.org packaging script on 2018-01-02 -version: '8.x-1.22' +dependencies: + - admin_toolbar:admin_toolbar + +# Information added by Drupal.org packaging script on 2018-02-06 +version: '8.x-1.23' core: '8.x' project: 'admin_toolbar' -datestamp: 1514888588 +datestamp: 1517936588 diff --git a/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar_tools/admin_toolbar_tools.info.yml b/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar_tools/admin_toolbar_tools.info.yml index 82051f62c..8166fe66e 100644 --- a/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar_tools/admin_toolbar_tools.info.yml +++ b/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar_tools/admin_toolbar_tools.info.yml @@ -8,8 +8,8 @@ type: module dependencies: - admin_toolbar:admin_toolbar -# Information added by Drupal.org packaging script on 2018-01-02 -version: '8.x-1.22' +# Information added by Drupal.org packaging script on 2018-02-06 +version: '8.x-1.23' core: '8.x' project: 'admin_toolbar' -datestamp: 1514888588 +datestamp: 1517936588 diff --git a/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar_tools/admin_toolbar_tools.module b/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar_tools/admin_toolbar_tools.module index f67573933..d08141db4 100644 --- a/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar_tools/admin_toolbar_tools.module +++ b/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar_tools/admin_toolbar_tools.module @@ -273,7 +273,7 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) { 'weight' => -5, ]; // Add node links for each content type. - foreach (\Drupal::entityTypeManager()->getStorage('node_type')->loadMultiple() as $type) { + foreach ($entityTypeManager->getStorage('node_type')->loadMultiple() as $type) { $links['node.add.' . $type->id()] = [ 'title' => t($type->label()), 'route_name' => 'node.add', @@ -418,7 +418,7 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) { 'weight' => '-1', ]; if ($moduleHandler->moduleExists('webprofiler')) { - $links['admin_menu_tools.devel.webprofiler'] = [ + $links['admin_toolbar_tools.devel.webprofiler'] = [ 'title' => t('Web Profiler settings'), 'route_name' => 'webprofiler.settings', 'menu_name' => 'admin', @@ -478,20 +478,33 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) { 'menu_name' => 'admin', 'parent' => 'admin_development', ]; + // Menu link for the Toolbar module. + $links['admin_toolbar_tools.toolbar.settings'] = [ + 'title' => t('Toolbar settings'), + 'route_name' => 'devel.toolbar.settings_form', + 'menu_name' => 'admin', + 'parent' => 'devel.admin_settings', + ]; } // If module Views Ui enabled. if ($moduleHandler->moduleExists('views_ui')) { - $links['views_ui.add'] = [ + $links['admin_toolbar_tools.views_ui.add'] = [ 'title' => t('Add new view'), 'route_name' => 'views_ui.add', 'menu_name' => 'admin', 'parent' => 'entity.view.collection', 'weight' => -5, ]; + $links['admin_toolbar_tools.views_ui.field_list'] = [ + 'title' => t('Used in views'), + 'route_name' => 'views_ui.reports_fields', + 'menu_name' => 'admin', + 'parent' => 'entity.field_storage_config.collection', + ]; } - $links['system.theme_settings_'] = [ + $links['admin_toolbar_tools.system.theme_settings'] = [ 'title' => t('Settings'), 'route_name' => 'system.theme_settings', 'menu_name' => 'admin', @@ -499,13 +512,14 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) { ]; if ($moduleHandler->moduleExists('webprofiler')) { - $links['admin_menu_tools.devel.webprofiler'] = [ + $links['admin_toolbar_tools.devel.webprofiler'] = [ 'title' => t('Webprofiler settings'), 'route_name' => 'webprofiler.settings', 'menu_name' => 'admin', 'parent' => 'admin_development', ]; } + if ($moduleHandler->moduleExists('update')) { $links['update.theme_install_'] = [ 'title' => t('Install new theme'), @@ -534,122 +548,52 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) { } } - // Add menu links for local tasks that sit below any admin menu link routes. - $manager = \Drupal::service('plugin.manager.menu.local_task'); - foreach ($links as $key => $link) { + // If module Language enabled. + if ($moduleHandler->moduleExists('language')) { + $links['admin_toolbar_tools.language.negotiation'] = [ + 'title' => t('Detection and selection'), + 'route_name' => 'language.negotiation', + 'menu_name' => 'admin', + 'parent' => 'entity.configurable_language.collection', + ]; + } - // Ignore menu links that have no route name. - if (empty($link['route_name'])) { - continue; - } - - // Ignore links that are not in the admin menu, include parents in the - // check as they inherit the menu name from the parent if not set. - $link_to_check = $link; - do { - // @todo Use configuration for admin menu name once added in - // https://www.drupal.org/node/1869638. - if (isset($link_to_check['menu_name'])) { - // If the link belongs to the admin menu, then skip this loop and - // look for local tasks. - if ($link_to_check['menu_name'] === 'admin') { - break; - } - else { - // If it is explicitly not in the admin menu, skip. - continue 2; - } - } - - if (!empty($link_to_check['parent']) && isset($links[$link_to_check['parent']])) { - $link_to_check = $links[$link_to_check['parent']]; - } - else { - // No parent and we found no menu_name, skip. - continue 2; - } - } while ($link_to_check); - - $route = $link['route_name']; - $route_local_tasks = $manager->getLocalTasksForRoute($route); - if (empty($route_local_tasks[0])) { - continue; - } - - foreach ($route_local_tasks[0] as $task_plugin) { - $definition = $task_plugin->getPluginDefinition(); - $local_route = $definition['route_name']; - if (empty($local_route)) { - continue; - } - $exists = FALSE; - $param = FALSE; - if (isset($link['route_parameters'])) { - $param = $link['route_parameters']; - } - // Check if local task has an already registered link in toolbar. - foreach ($links as $link2) { - // Route_name that could be a 'class'. - if (!(isset($link2['route_name']) && ($link2['route_name'] == $local_route))) { - continue; - } - // If route are equal, the parameters could be different. - // @todo: check if this is true. - if ($param) { - if (isset($link2['route_parameters']) && ($param == $link2['route_parameters'])) { - $exists = TRUE; - break; - } - } - else { - $exists = TRUE; - break; - } - } - $parent = FALSE; - - if ($exists) { - continue; - } - - $title = $definition['title']; - $title = $param ? $title . ' ' . $link['title'] : $title; - - // The following code is to choose the parent of the added link. - // If the parent of the current tab also has the tab as local task - // for example: "Content" has "File" as task" and and - // "Content>Comment" also has "File" as a tab then we decide to - // set this one as parent of the added link if not the current tab - // will be the parent. - if (!empty($link['parent']) && isset($links[$link['parent']])) { - $parentlink = $links[$link['parent']]; - $parentlink_route = $parentlink['route_name']; - $parent_primary = $manager->getLocalTasks($parentlink_route, 0); - foreach ($parent_primary['tabs'] as $parent_tab) { - if ($parent_tab['#link']['url']) { - $parent_route = $parent_tab['#link']['url']->getRouteName(); - if ($parent_route == $local_route) { - $parent = $link['parent']; - break; - } - } - } - } - $parent = $parent ? $parent : $key; - // Make sure the key of the route is unique. - $links[$key . '_' . $local_route] = [ - 'title' => $title, - 'route_name' => $local_route, - 'menu_name' => 'admin', - 'parent' => $parent, - 'att' => TRUE, + // If module Media enabled. + if ($moduleHandler->moduleExists('media')) { + $links['admin_toolbar_tools.add_media'] = [ + 'title' => t('Add media'), + 'route_name' => 'entity.media.add_page', + 'menu_name' => 'admin', + 'parent' => 'system.admin_content', + ]; + // Add node links for each media type. + foreach (\Drupal::entityTypeManager()->getStorage('media_type')->loadMultiple() as $type) { + $links['node.add.' . $type->id()] = [ + 'title' => t($type->label()), + 'route_name' => 'entity.media.add_form', + 'parent' => 'admin_toolbar_tools.add_media', + 'route_parameters' => ['media_type' => $type->id()], ]; - if ($param) { - $links[$key . '_' . $local_route]['route_parameters'] = $param; - } } } + // If module Config enabled. + if ($moduleHandler->moduleExists('config')) { + $links['admin_toolbar_tools.config.import'] = [ + 'title' => t('Import'), + 'route_name' => 'config.import_full', + 'menu_name' => 'admin', + 'parent' => 'config.sync', + 'weight' => 1, + ]; + $links['admin_toolbar_tools.config.export'] = [ + 'title' => t('Export'), + 'route_name' => 'config.export_full', + 'menu_name' => 'admin', + 'parent' => 'config.sync', + 'weight' => 2, + ]; + } } /** diff --git a/sites/all/modules/contrib/admin/admin_toolbar/css/admin.toolbar.css b/sites/all/modules/contrib/admin/admin_toolbar/css/admin.toolbar.css index 44d97919d..d848b90ef 100644 --- a/sites/all/modules/contrib/admin/admin_toolbar/css/admin.toolbar.css +++ b/sites/all/modules/contrib/admin/admin_toolbar/css/admin.toolbar.css @@ -1,4 +1,3 @@ -/*---------------------- menu horizontal hover---- Krout Fethi FrontEnd Developer-----*/ .toolbar-tray-horizontal .menu-item:hover { background: #fff; } @@ -105,32 +104,79 @@ display: block; } -[dir="rtl"] .toolbar-tray-horizontal .toolbar .level-2 > ul { +[dir="rtl"] .toolbar-tray-horizontal .menu-item:hover { + background: #fff; +} + +[dir="rtl"] .toolbar-tray-horizontal .menu-item a:focus { + background: #abeae4; +} + +[dir="rtl"] .toolbar-tray-horizontal .toolbar-menu:not(:first-child) li.menu-item--expanded > a:focus { + background-position: center right; + background-image: url('../misc/icons/0074bd/chevron-right.svg'); + background-repeat: no-repeat; +} + +[dir="rtl"] .toolbar-tray-horizontal .menu-item--expanded .menu { + background: #fff; + width: auto; + height: auto; +} + +[dir="rtl"] .toolbar-tray-horizontal .menu-item--expanded { + background-color: #f5f5f2; +} + +[dir="rtl"] .toolbar-tray-horizontal ul li li.menu-item { + border-top: none transparent; + border-right: 1px solid #dddddd; + border-bottom: 1px solid #dddddd; + border-left: 1px solid #dddddd; +} + +[dir="rtl"] .toolbar .toolbar-tray-horizontal .menu-item:last-child { + border-left: 1px solid #dddddd; + border-right: 1px solid #dddddd; +} + +[dir="rtl"] .toolbar .toolbar-tray-horizontal ul ul li.menu-item:first-child { + border-top: 1px solid #dddddd; +} + +[dir="rtl"] .toolbar-tray-horizontal li.menu-item--expanded.hover-intent ul ul, +[dir="rtl"] .toolbar-tray-horizontal li.menu-item--expanded.hover-intent ul ul ul, +[dir="rtl"] .toolbar-tray-horizontal li.menu-item--expanded.hover-intent ul ul ul ul, +[dir="rtl"] .toolbar-tray-horizontal li.menu-item--expanded.hover-intent ul ul ul ul ul { + display: none; + left: -999em; /* LTR */ +} + +/* Lists nested under hovered list items */ +[dir="rtl"] .toolbar-tray-horizontal li.menu-item--expanded.hover-intent ul, +[dir="rtl"] .toolbar-tray-horizontal li li.menu-item--expanded.hover-intent ul, +[dir="rtl"] .toolbar-tray-horizontal li li li.menu-item--expanded.hover-intent ul, +[dir="rtl"] .toolbar-tray-horizontal li li li li.menu-item--expanded.hover-intent ul, +[dir="rtl"] .toolbar-tray-horizontal li li li li li.menu-item--expanded.hover-intent ul { + display: block; + left: auto; /* LTR */ +} + +[dir="rtl"] .toolbar-tray-horizontal .menu ul li a, +[dir="rtl"] .toolbar-tray-horizontal .menu ul .toolbar-icon { + padding: 12px 15px 12px 12px; +} + +[dir="rtl"] .toolbar-tray-horizontal ul li.menu-item--expanded.hover-intent ul { + display: block; position: absolute; - padding-top: 0; - top: 0; - right: 200px; width: 200px; + box-shadow: 2px 2px 3px hsla(0, 0%, 0%, 0.4); + z-index: 1; } -[dir="rtl"] .toolbar-tray-horizontal li:hover ul li { - float: none !important; -} - -[dir="rtl"] .toolbar-tray-horizontal li:focus ul li { - float: none !important; -} - -[dir="rtl"] .toolbar .toolbar-menu ul .toolbar-icon { - padding-left: 1.3333em; -} - -[dir="rtl"] .toolbar-tray-horizontal ul li.menu-item--expanded .menu-item:hover ul { - margin: -40px 197px 0 0; -} - -[dir="rtl"] .toolbar-tray-horizontal ul li.menu-item--expanded .menu-item:focus ul { - margin: -40px 197px 0 0; +[dir="rtl"] .toolbar-tray-horizontal ul li.menu-item--expanded .menu-item > ul { + display: none; } [dir="rtl"] .toolbar-tray-horizontal ul li.menu-item--expanded ul li.menu-item--expanded { @@ -138,3 +184,28 @@ background-image: url('../misc/icons/0074bd/chevron-left.svg'); background-repeat: no-repeat; } + +[dir="rtl"] .toolbar-tray-horizontal ul li.menu-item--expanded .menu-item.hover-intent ul { + display: block; + margin: -40px 197px 0 0; +} + +[dir="rtl"] .toolbar-tray-horizontal li:hover ul li { + float: none; +} + +[dir="rtl"] .toolbar-tray-horizontal li.hover-intent ul li { + float: none; +} + +[dir="rtl"] .toolbar-tray-horizontal .toolbar .level-2 > ul { + position: absolute; + padding-top: 0; + top: 0; + left: 200px; + width: 200px; +} + +[dir="rtl"] .toolbar .toolbar-tray-vertical li.open > ul.toolbar-menu.clearfix { + display: block; +} diff --git a/sites/all/modules/contrib/admin/admin_toolbar/js/admin_toolbar.js b/sites/all/modules/contrib/admin/admin_toolbar/js/admin_toolbar.js index ec322f200..96dfa829a 100644 --- a/sites/all/modules/contrib/admin/admin_toolbar/js/admin_toolbar.js +++ b/sites/all/modules/contrib/admin/admin_toolbar/js/admin_toolbar.js @@ -1,10 +1,10 @@ -(function ($) { +(function ($, Drupal) { Drupal.behaviors.adminToolbar = { attach: function (context, settings) { $('a.toolbar-icon', context).removeAttr('title'); - - $('.toolbar-tray-horizontal li.menu-item--expanded, .toolbar-tray-horizontal ul li.menu-item--expanded .menu-item', context).hoverIntent({ + + $('.toolbar-tray li.menu-item--expanded, .toolbar-tray ul li.menu-item--expanded .menu-item', context).hoverIntent({ over: function () { // At the current depth, we should delete all "hover-intent" classes. // Other wise we get unwanted behaviour where menu items are expanded while already in hovering other ones. @@ -16,13 +16,13 @@ }, timeout: 250 }); - + // Make the toolbar menu navigable with keyboard. $('ul.toolbar-menu li.menu-item--expanded a', context).on('focusin', function () { $('li.menu-item--expanded', context).removeClass('hover-intent'); $(this).parents('li.menu-item--expanded').addClass('hover-intent'); }); - + $('ul.toolbar-menu li.menu-item a', context).keydown(function (e) { if ((e.shiftKey && (e.keyCode || e.which) == 9)) { if ($(this).parent('.menu-item').prev().hasClass('menu-item--expanded')) { @@ -30,15 +30,15 @@ } } }); - + $('.toolbar-menu:first-child > .menu-item:not(.menu-item--expanded) a, .toolbar-tab > a', context).on('focusin', function () { $('.menu-item--expanded').removeClass('hover-intent'); }); - + $('.toolbar-menu:first-child > .menu-item', context).on('hover', function () { - $(this,'a').css("background: #fff;"); + $(this, 'a').css("background: #fff;"); }); - + $('ul:not(.toolbar-menu)', context).on({ mousemove: function () { $('li.menu-item--expanded').removeClass('hover-intent'); @@ -50,4 +50,4 @@ } }; -})(jQuery); +})(jQuery, Drupal); diff --git a/sites/all/modules/contrib/admin/domain/.travis.yml b/sites/all/modules/contrib/admin/domain/.travis.yml index b77fae3a0..05414bc2f 100644 --- a/sites/all/modules/contrib/admin/domain/.travis.yml +++ b/sites/all/modules/contrib/admin/domain/.travis.yml @@ -4,6 +4,8 @@ sudo: false matrix: fast_finish: true include: + - env: DRUPAL=8.4.x + php: 7.1 - env: DRUPAL=8.4.x php: 7.0 - env: DRUPAL=8.4.x diff --git a/sites/all/modules/contrib/admin/domain/CHANGELOG.md b/sites/all/modules/contrib/admin/domain/CHANGELOG.md index 687fc5135..c9b637433 100644 --- a/sites/all/modules/contrib/admin/domain/CHANGELOG.md +++ b/sites/all/modules/contrib/admin/domain/CHANGELOG.md @@ -13,6 +13,8 @@ Changelog 23-APR-2017 8.x-1.0-alpha9 01-DEC-2017 8.x-1.0-alpha10 19-DEC-2017 8.x-1.0-alpha11 +12-FEB-2018 8.x-1.0-alpha12 +07-MAR-2018 8.x.1.0-alpha13 Status ==== @@ -108,13 +110,17 @@ marked with [x] are considered complete. - [x] Check loader logic in Domain Access `node_access` - [x] Check id logic in Domain Alias list controller - [x] Check domain responses on configuration forms -- [ ] Remove deprecated `entity_get_form_display` -- [ ] Implement theme functions or twig templates where proper +- [x] Remove deprecated `entity_get_form_display` +- [x] Implement theme functions or twig templates where proper - [ ] Advanced drush integration / complete labelled tasks +- [ ] Add filter options to domain_access and domain_source views - [ ] Test cron handling - [ ] Caching strategies in DomainNegotiator - [ ] Caching strategies in DomainConfigOverrides - [ ] Cache in the DomainAccessManager +- [ ] Add filter options to domain_access and domain_source views +- [ ] Proper handling of default node values +- [ ] Do not allow actions to be edited? - [o] Recreate the Domain Theme module -- see https://www.drupal.org/project/domain_theme_switch # Final @@ -124,3 +130,4 @@ marked with [x] are considered complete. - [x] Remove calls to deprecated methods / classes - [ ] Remove unnecessary use statements - [ ] Support Tour module +- [ ] Views schema fails -- see https://www.drupal.org/project/drupal/issues/2834801 diff --git a/sites/all/modules/contrib/admin/domain/domain/domain.info.yml b/sites/all/modules/contrib/admin/domain/domain/domain.info.yml index 04fa37fe4..a0ce87aa2 100644 --- a/sites/all/modules/contrib/admin/domain/domain/domain.info.yml +++ b/sites/all/modules/contrib/admin/domain/domain/domain.info.yml @@ -8,8 +8,8 @@ dependencies: - options configure: domain.admin -# Information added by Drupal.org packaging script on 2017-12-19 -version: '8.x-1.0-alpha11' +# Information added by Drupal.org packaging script on 2018-03-08 +version: '8.x-1.0-alpha13' core: '8.x' project: 'domain' -datestamp: 1513718589 +datestamp: 1520519900 diff --git a/sites/all/modules/contrib/admin/domain/domain/domain.install b/sites/all/modules/contrib/admin/domain/domain/domain.install index 9f986a5ad..8175c2483 100644 --- a/sites/all/modules/contrib/admin/domain/domain/domain.install +++ b/sites/all/modules/contrib/admin/domain/domain/domain.install @@ -27,12 +27,11 @@ function domain_update_8001() { * Configures user form display to checkboxes widget for domain admin field. */ function _domain_configure_field() { - // @TODO: This function is deprecated, but using the OO syntax is causing - // test fails. - entity_get_form_display('user', 'user', 'default') - ->setComponent(DOMAIN_ADMIN_FIELD, array( + if ($display = \Drupal::entityTypeManager()->getStorage('entity_form_display')->load('user.user.default')) { + $display->setComponent(DOMAIN_ADMIN_FIELD, [ 'type' => 'options_buttons', 'weight' => 50, - )) + ]) ->save(); + } } diff --git a/sites/all/modules/contrib/admin/domain/domain/migration_templates/d7_domain.yml b/sites/all/modules/contrib/admin/domain/domain/migrations/d7_domain.yml similarity index 90% rename from sites/all/modules/contrib/admin/domain/domain/migration_templates/d7_domain.yml rename to sites/all/modules/contrib/admin/domain/domain/migrations/d7_domain.yml index ced2c7198..52e31b119 100644 --- a/sites/all/modules/contrib/admin/domain/domain/migration_templates/d7_domain.yml +++ b/sites/all/modules/contrib/admin/domain/domain/migrations/d7_domain.yml @@ -15,3 +15,4 @@ process: status: valid destination: plugin: entity:domain + destination_module: domain diff --git a/sites/all/modules/contrib/admin/domain/domain/src/DomainElementManager.php b/sites/all/modules/contrib/admin/domain/domain/src/DomainElementManager.php index 3779e5212..2c1cb4e1b 100644 --- a/sites/all/modules/contrib/admin/domain/domain/src/DomainElementManager.php +++ b/sites/all/modules/contrib/admin/domain/domain/src/DomainElementManager.php @@ -188,7 +188,6 @@ class DomainElementManager implements DomainElementManagerInterface { */ public function listDisallowed(array $disallowed) { $domains = $this->domainStorage->loadMultiple($disallowed); - // @TODO: Proper theme function here. $string = $this->t('The following domains are currently assigned and cannot be changed:'); foreach ($domains as $domain) { $items[] = $domain->label(); diff --git a/sites/all/modules/contrib/admin/domain/domain/src/DomainNegotiator.php b/sites/all/modules/contrib/admin/domain/domain/src/DomainNegotiator.php index a45644448..950787b9b 100644 --- a/sites/all/modules/contrib/admin/domain/domain/src/DomainNegotiator.php +++ b/sites/all/modules/contrib/admin/domain/domain/src/DomainNegotiator.php @@ -204,7 +204,7 @@ class DomainNegotiator implements DomainNegotiatorInterface { return TRUE; } // Check for registered alias matches. - $values = array('hostname' => $httpHost); + $values = array('hostname' => $hostname); /** @var \Drupal\domain\Entity\DomainInterface $domain */ $domain = $this->domainStorage->create($values); $domain->setMatchType(self::DOMAIN_MATCH_NONE); diff --git a/sites/all/modules/contrib/admin/domain/domain/src/Plugin/Block/DomainServerBlock.php b/sites/all/modules/contrib/admin/domain/domain/src/Plugin/Block/DomainServerBlock.php index 6929c273a..16c88940d 100644 --- a/sites/all/modules/contrib/admin/domain/domain/src/Plugin/Block/DomainServerBlock.php +++ b/sites/all/modules/contrib/admin/domain/domain/src/Plugin/Block/DomainServerBlock.php @@ -27,8 +27,6 @@ class DomainServerBlock extends DomainBlockBase { /** * Build the output. - * - * @TODO: abstract or theme this function? */ public function build() { /** @var \Drupal\domain\DomainInterface $domain */ @@ -47,10 +45,14 @@ class DomainServerBlock extends DomainBlockBase { $domain->getResponse(); $check = \Drupal::service('entity_type.manager')->getStorage('domain')->loadByHostname($_SERVER['HTTP_HOST']); $match = $this->t('Exact match'); + // This value is not translatable. + $environment = 'default'; if (!$check) { // Specific check for Domain Alias. if (isset($domain->alias)) { $match = $this->t('ALIAS: Using alias %id', array('%id' => $domain->alias->getPattern())); + // Get the environment. + $environment = $domain->alias->getEnvironment(); } else { $match = $this->t('FALSE: Using default domain.'); @@ -60,6 +62,23 @@ class DomainServerBlock extends DomainBlockBase { $this->t('Domain match'), $match, ); + $rows[] = [ + $this->t('Environment'), + $environment, + ]; + $rows[] = [ + $this->t('Canonical hostname'), + $domain->getCanonical(), + ]; + $rows[] = [ + $this->t('Base path'), + $domain->getPath(), + ]; + $rows[] = [ + $this->t('Current URL'), + $domain->getUrl(), + ]; + $www = \Drupal::config('domain.settings')->get('www_prefix'); $rows[] = array( $this->t('Strip www prefix'), diff --git a/sites/all/modules/contrib/admin/domain/domain/src/Plugin/Block/DomainSwitcherBlock.php b/sites/all/modules/contrib/admin/domain/domain/src/Plugin/Block/DomainSwitcherBlock.php index 1f45c9f0d..5e8a4cf66 100644 --- a/sites/all/modules/contrib/admin/domain/domain/src/Plugin/Block/DomainSwitcherBlock.php +++ b/sites/all/modules/contrib/admin/domain/domain/src/Plugin/Block/DomainSwitcherBlock.php @@ -25,8 +25,6 @@ class DomainSwitcherBlock extends DomainBlockBase { /** * Build the output. - * - * @TODO: abstract or theme this function? */ public function build() { /** @var \Drupal\domain\DomainInterface $active_domain */ diff --git a/sites/all/modules/contrib/admin/domain/domain/src/Plugin/Block/DomainTokenBlock.php b/sites/all/modules/contrib/admin/domain/domain/src/Plugin/Block/DomainTokenBlock.php index f8f9965fc..ceb4485c0 100644 --- a/sites/all/modules/contrib/admin/domain/domain/src/Plugin/Block/DomainTokenBlock.php +++ b/sites/all/modules/contrib/admin/domain/domain/src/Plugin/Block/DomainTokenBlock.php @@ -27,8 +27,6 @@ class DomainTokenBlock extends DomainBlockBase { /** * Build the output. - * - * @TODO: abstract or theme this function? */ public function build() { /** @var \Drupal\domain\DomainInterface $domain */ @@ -49,7 +47,7 @@ class DomainTokenBlock extends DomainBlockBase { /** * Generates available tokens for printing. * - * @param Drupal\domain\DomainInterface $domain + * @param \Drupal\domain\DomainInterface $domain * The active domain request. * @return array * An array keyed by token name, with value of replacement value. diff --git a/sites/all/modules/contrib/admin/domain/domain/src/Plugin/migrate/source/d7/DomainRecord.php b/sites/all/modules/contrib/admin/domain/domain/src/Plugin/migrate/source/d7/DomainRecord.php index 4ceaa42f2..2ce6f96fe 100644 --- a/sites/all/modules/contrib/admin/domain/domain/src/Plugin/migrate/source/d7/DomainRecord.php +++ b/sites/all/modules/contrib/admin/domain/domain/src/Plugin/migrate/source/d7/DomainRecord.php @@ -8,7 +8,8 @@ use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase; * Drupal 7 Domain source from database. * * @MigrateSource( - * id = "d7_domain" + * id = "d7_domain", + * source_module = "domain" * ) */ class DomainRecord extends DrupalSqlBase { diff --git a/sites/all/modules/contrib/admin/domain/domain/tests/modules/domain_test/domain_test.info.yml b/sites/all/modules/contrib/admin/domain/domain/tests/modules/domain_test/domain_test.info.yml index a7bb7e659..3fe6b8e43 100644 --- a/sites/all/modules/contrib/admin/domain/domain/tests/modules/domain_test/domain_test.info.yml +++ b/sites/all/modules/contrib/admin/domain/domain/tests/modules/domain_test/domain_test.info.yml @@ -9,8 +9,8 @@ hidden: TRUE dependencies: - domain -# Information added by Drupal.org packaging script on 2017-12-19 -version: '8.x-1.0-alpha11' +# Information added by Drupal.org packaging script on 2018-03-08 +version: '8.x-1.0-alpha13' core: '8.x' project: 'domain' -datestamp: 1513718589 +datestamp: 1520519900 diff --git a/sites/all/modules/contrib/admin/domain/domain/tests/src/Functional/DomainEntityReferenceTest.php b/sites/all/modules/contrib/admin/domain/domain/tests/src/Functional/DomainEntityReferenceTest.php index fc697715e..5bbd8d952 100644 --- a/sites/all/modules/contrib/admin/domain/domain/tests/src/Functional/DomainEntityReferenceTest.php +++ b/sites/all/modules/contrib/admin/domain/domain/tests/src/Functional/DomainEntityReferenceTest.php @@ -150,11 +150,9 @@ class DomainEntityReferenceTest extends DomainTestBase { $field_config->save(); // Tell the form system how to behave. - entity_get_form_display('node', 'article', 'default') - ->setComponent($name, array( - 'type' => 'options_buttons', - )) - ->save(); + if ($display = \Drupal::entityTypeManager()->getStorage('entity_form_display')->load('node.article.default')) { + $display->setComponent($name, ['type' => 'options_buttons'])->save(); + } } } diff --git a/sites/all/modules/contrib/admin/domain/domain_access/config/schema/domain_access.views.schema.yml b/sites/all/modules/contrib/admin/domain/domain_access/config/schema/domain_access.views.schema.yml new file mode 100644 index 000000000..e489a9227 --- /dev/null +++ b/sites/all/modules/contrib/admin/domain/domain_access/config/schema/domain_access.views.schema.yml @@ -0,0 +1,63 @@ +# Schema for the domain access plugins. + +views.access.domain_access_admin: + type: mapping + label: 'Domain Access: Administer domain editors' +views.access.domain_access_editor: + type: mapping + label: 'Domain Access: Edit domain content' +views.argument.domain_access_argument: + type: views_argument + label: 'Domain Access' +views.field.domain_access_field: + type: views_field + label: 'Domain Access' + mapping: + click_sort_column: + type: string + label: 'Column used for click sorting' + type: + type: string + label: 'Formatter' + settings: + label: 'Settings' + type: field.formatter.settings.[%parent.type] + group_column: + type: string + label: 'Group by column' + group_columns: + type: sequence + label: 'Group by columns' + sequence: + type: string + label: 'Column' + group_rows: + type: boolean + label: 'Display all values in the same row' + delta_limit: + type: integer + label: 'Field' + delta_offset: + type: integer + label: 'Offset' + delta_reversed: + type: boolean + label: 'Reversed' + delta_first_last: + type: boolean + label: 'First and last only' + multi_type: + type: string + label: 'Display type' + separator: + type: label + label: 'Separator' + field_api_classes: + type: boolean + label: 'Use field template' +views.filter.domain_access_current_all_filter: + type: views_filter + label: 'Current Domain or All Domains' +views.filter.domain_access_filter: + type: views.filter.in_operator + label: 'Domain Access' diff --git a/sites/all/modules/contrib/admin/domain/domain_access/domain_access.info.yml b/sites/all/modules/contrib/admin/domain/domain_access/domain_access.info.yml index 2a6f1bac6..a2a58096a 100644 --- a/sites/all/modules/contrib/admin/domain/domain_access/domain_access.info.yml +++ b/sites/all/modules/contrib/admin/domain/domain_access/domain_access.info.yml @@ -8,8 +8,8 @@ dependencies: - domain - node -# Information added by Drupal.org packaging script on 2017-12-19 -version: '8.x-1.0-alpha11' +# Information added by Drupal.org packaging script on 2018-03-08 +version: '8.x-1.0-alpha13' core: '8.x' project: 'domain' -datestamp: 1513718589 +datestamp: 1520519900 diff --git a/sites/all/modules/contrib/admin/domain/domain_access/domain_access.module b/sites/all/modules/contrib/admin/domain/domain_access/domain_access.module index b27340b46..7fb3fc57d 100755 --- a/sites/all/modules/contrib/admin/domain/domain_access/domain_access.module +++ b/sites/all/modules/contrib/admin/domain/domain_access/domain_access.module @@ -343,7 +343,7 @@ function domain_access_node_access(NodeInterface $node, $op, AccountInterface $a } // Check to see that we have a valid active domain. // Without one, we cannot assert an opinion about access. - if (empty($active_domain->getDomainId())) { + if (!$active_domain || empty($active_domain->getDomainId())) { return AccessResult::neutral(); } @@ -560,19 +560,16 @@ function domain_access_confirm_fields($entity_type, $bundle, $text = array()) { $field_config->save(); } // Tell the form system how to behave. Default to radio buttons. - // @TODO: This function is deprecated, but using the OO syntax is causing - // test fails. - entity_get_form_display($entity_type, $bundle, 'default') - ->setComponent(DOMAIN_ACCESS_FIELD, array( + if ($display = \Drupal::entityTypeManager()->getStorage('entity_form_display')->load($entity_type . '.' . $bundle . '.default')) { + $display->setComponent(DOMAIN_ACCESS_FIELD, [ 'type' => 'options_buttons', 'weight' => 40, - )) - ->setComponent(DOMAIN_ACCESS_ALL_FIELD, array( + ])->setComponent(DOMAIN_ACCESS_ALL_FIELD, [ 'type' => 'boolean_checkbox', - 'settings' => array('display_label' => 1), + 'settings' => ['display_label' => 1], 'weight' => 41, - )) - ->save(); + ])->save(); + } } catch (Exception $e) { \Drupal::logger('domain_access')->notice('Field installation failed.'); diff --git a/sites/all/modules/contrib/admin/domain/domain_access/src/Plugin/views/argument/DomainAccessArgument.php b/sites/all/modules/contrib/admin/domain/domain_access/src/Plugin/views/argument/DomainAccessArgument.php index f1f95a837..21ee9b425 100644 --- a/sites/all/modules/contrib/admin/domain/domain_access/src/Plugin/views/argument/DomainAccessArgument.php +++ b/sites/all/modules/contrib/admin/domain/domain_access/src/Plugin/views/argument/DomainAccessArgument.php @@ -5,7 +5,7 @@ namespace Drupal\domain_access\Plugin\views\argument; use Drupal\views\Plugin\views\argument\StringArgument; /** - * Field handler to present the link an entity on a domain. + * Argument handler to find nodes by domain assignment. * * @ViewsArgument("domain_access_argument") */ diff --git a/sites/all/modules/contrib/admin/domain/domain_access/tests/modules/domain_access_test/domain_access_test.info.yml b/sites/all/modules/contrib/admin/domain/domain_access/tests/modules/domain_access_test/domain_access_test.info.yml index 5e85d249f..efa074180 100644 --- a/sites/all/modules/contrib/admin/domain/domain_access/tests/modules/domain_access_test/domain_access_test.info.yml +++ b/sites/all/modules/contrib/admin/domain/domain_access/tests/modules/domain_access_test/domain_access_test.info.yml @@ -11,8 +11,8 @@ dependencies: - domain_access - taxonomy -# Information added by Drupal.org packaging script on 2017-12-19 -version: '8.x-1.0-alpha11' +# Information added by Drupal.org packaging script on 2018-03-08 +version: '8.x-1.0-alpha13' core: '8.x' project: 'domain' -datestamp: 1513718589 +datestamp: 1520519900 diff --git a/sites/all/modules/contrib/admin/domain/domain_access/tests/src/Functional/DomainAccessFieldTest.php b/sites/all/modules/contrib/admin/domain/domain_access/tests/src/Functional/DomainAccessFieldTest.php index 339942937..327d01067 100644 --- a/sites/all/modules/contrib/admin/domain/domain_access/tests/src/Functional/DomainAccessFieldTest.php +++ b/sites/all/modules/contrib/admin/domain/domain_access/tests/src/Functional/DomainAccessFieldTest.php @@ -151,10 +151,12 @@ class DomainAccessFieldTest extends DomainTestBase { // Create a new content type and test that the fields are created. // Create a content type programmatically. $type = $this->drupalCreateContentType(); - $type_exists = (bool) NodeType::load($type->id()); $this->assertTrue($type_exists, 'The new content type has been created in the database.'); + // The test is not passing to domain_access_node_type_insert() properly. + domain_access_confirm_fields('node', $type->id()); + // Visit the article creation page. $this->drupalGet('node/add/' . $type->id()); $this->assertResponse(200, $type->id() . ' creation found.'); diff --git a/sites/all/modules/contrib/admin/domain/domain_alias/domain_alias.info.yml b/sites/all/modules/contrib/admin/domain/domain_alias/domain_alias.info.yml index d4d57d043..457aa530c 100644 --- a/sites/all/modules/contrib/admin/domain/domain_alias/domain_alias.info.yml +++ b/sites/all/modules/contrib/admin/domain/domain_alias/domain_alias.info.yml @@ -7,8 +7,8 @@ package: Domain dependencies: - domain -# Information added by Drupal.org packaging script on 2017-12-19 -version: '8.x-1.0-alpha11' +# Information added by Drupal.org packaging script on 2018-03-08 +version: '8.x-1.0-alpha13' core: '8.x' project: 'domain' -datestamp: 1513718589 +datestamp: 1520519900 diff --git a/sites/all/modules/contrib/admin/domain/domain_alpha/domain_alpha.info.yml b/sites/all/modules/contrib/admin/domain/domain_alpha/domain_alpha.info.yml index 201f1540a..963db3fa7 100644 --- a/sites/all/modules/contrib/admin/domain/domain_alpha/domain_alpha.info.yml +++ b/sites/all/modules/contrib/admin/domain/domain_alpha/domain_alpha.info.yml @@ -7,8 +7,8 @@ package: Domain dependencies: - domain -# Information added by Drupal.org packaging script on 2017-12-19 -version: '8.x-1.0-alpha11' +# Information added by Drupal.org packaging script on 2018-03-08 +version: '8.x-1.0-alpha13' core: '8.x' project: 'domain' -datestamp: 1513718589 +datestamp: 1520519900 diff --git a/sites/all/modules/contrib/admin/domain/domain_config/domain_config.info.yml b/sites/all/modules/contrib/admin/domain/domain_config/domain_config.info.yml index 8271c474c..49901e3c0 100644 --- a/sites/all/modules/contrib/admin/domain/domain_config/domain_config.info.yml +++ b/sites/all/modules/contrib/admin/domain/domain_config/domain_config.info.yml @@ -7,8 +7,8 @@ package: Domain dependencies: - domain -# Information added by Drupal.org packaging script on 2017-12-19 -version: '8.x-1.0-alpha11' +# Information added by Drupal.org packaging script on 2018-03-08 +version: '8.x-1.0-alpha13' core: '8.x' project: 'domain' -datestamp: 1513718589 +datestamp: 1520519900 diff --git a/sites/all/modules/contrib/admin/domain/domain_config/tests/modules/domain_config_middleware_test/domain_config_middleware_test.info.yml b/sites/all/modules/contrib/admin/domain/domain_config/tests/modules/domain_config_middleware_test/domain_config_middleware_test.info.yml index 09be4495d..9c2203ba3 100644 --- a/sites/all/modules/contrib/admin/domain/domain_config/tests/modules/domain_config_middleware_test/domain_config_middleware_test.info.yml +++ b/sites/all/modules/contrib/admin/domain/domain_config/tests/modules/domain_config_middleware_test/domain_config_middleware_test.info.yml @@ -10,8 +10,8 @@ dependencies: - domain - domain_config -# Information added by Drupal.org packaging script on 2017-12-19 -version: '8.x-1.0-alpha11' +# Information added by Drupal.org packaging script on 2018-03-08 +version: '8.x-1.0-alpha13' core: '8.x' project: 'domain' -datestamp: 1513718589 +datestamp: 1520519900 diff --git a/sites/all/modules/contrib/admin/domain/domain_config/tests/modules/domain_config_test/domain_config_test.info.yml b/sites/all/modules/contrib/admin/domain/domain_config/tests/modules/domain_config_test/domain_config_test.info.yml index 7438443d0..3d84ed4fd 100644 --- a/sites/all/modules/contrib/admin/domain/domain_config/tests/modules/domain_config_test/domain_config_test.info.yml +++ b/sites/all/modules/contrib/admin/domain/domain_config/tests/modules/domain_config_test/domain_config_test.info.yml @@ -10,8 +10,8 @@ dependencies: - domain - domain_config -# Information added by Drupal.org packaging script on 2017-12-19 -version: '8.x-1.0-alpha11' +# Information added by Drupal.org packaging script on 2018-03-08 +version: '8.x-1.0-alpha13' core: '8.x' project: 'domain' -datestamp: 1513718589 +datestamp: 1520519900 diff --git a/sites/all/modules/contrib/admin/domain/domain_content/config/optional/views.view.domain_content.yml b/sites/all/modules/contrib/admin/domain/domain_content/config/optional/views.view.domain_content.yml index 4eff610de..a902c0c96 100644 --- a/sites/all/modules/contrib/admin/domain/domain_content/config/optional/views.view.domain_content.yml +++ b/sites/all/modules/contrib/admin/domain/domain_content/config/optional/views.view.domain_content.yml @@ -326,17 +326,17 @@ display: click_sort_column: target_id type: entity_reference_label settings: - link: 1 + link: true group_column: target_id group_columns: { } - group_rows: 1 - delta_limit: '0' - delta_offset: '0' - delta_reversed: 0 - delta_first_last: 0 + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false multi_type: separator separator: ', ' - field_api_classes: 0 + field_api_classes: false plugin_id: domain_access_field field_domain_all_affiliates: id: field_domain_all_affiliates @@ -770,7 +770,7 @@ display: operation: view multiple: 0 access: false - bundles: null + bundles: { } glossary: false limit: 0 case: none @@ -1213,10 +1213,7 @@ display: group_type: group admin_label: '' operator: '=' - value: - min: '' - max: '' - value: '1' + value: '1' group: 1 exposed: false expose: @@ -1269,7 +1266,7 @@ display: authenticated: authenticated anonymous: '0' administrator: '0' - reduce: 0 + reduce: false is_grouped: false group_info: label: '' diff --git a/sites/all/modules/contrib/admin/domain/domain_content/config/optional/views.view.domain_content_editors.yml b/sites/all/modules/contrib/admin/domain/domain_content/config/optional/views.view.domain_content_editors.yml index 0dbc4c89c..bb00616dc 100644 --- a/sites/all/modules/contrib/admin/domain/domain_content/config/optional/views.view.domain_content_editors.yml +++ b/sites/all/modules/contrib/admin/domain/domain_content/config/optional/views.view.domain_content_editors.yml @@ -402,17 +402,17 @@ display: click_sort_column: target_id type: entity_reference_label settings: - link: 0 + link: false group_column: target_id group_columns: { } - group_rows: 1 - delta_limit: '0' - delta_offset: '0' - delta_reversed: 0 - delta_first_last: 0 + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false multi_type: separator separator: ', ' - field_api_classes: 0 + field_api_classes: false plugin_id: domain_access_field field_domain_all_affiliates: id: field_domain_all_affiliates @@ -1080,7 +1080,7 @@ display: operation: view multiple: 0 access: false - bundles: null + bundles: { } glossary: false limit: 0 case: none @@ -1381,7 +1381,7 @@ display: authenticated: authenticated anonymous: '0' administrator: '0' - reduce: 0 + reduce: false is_grouped: false group_info: label: '' diff --git a/sites/all/modules/contrib/admin/domain/domain_content/config/schema/domain_content.views.schema.yml b/sites/all/modules/contrib/admin/domain/domain_content/config/schema/domain_content.views.schema.yml new file mode 100644 index 000000000..16f223546 --- /dev/null +++ b/sites/all/modules/contrib/admin/domain/domain_content/config/schema/domain_content.views.schema.yml @@ -0,0 +1,8 @@ +# Schema for the domain content plugins. + +views.access.domain_content_admin: + type: mapping + label: 'Domain Content: View domain-specific editors' +views.access.domain_content_editor: + type: mapping + label: 'Domain Content: View domain-specific content' diff --git a/sites/all/modules/contrib/admin/domain/domain_content/domain_content.info.yml b/sites/all/modules/contrib/admin/domain/domain_content/domain_content.info.yml index 50c86ce06..7abe615de 100644 --- a/sites/all/modules/contrib/admin/domain/domain_content/domain_content.info.yml +++ b/sites/all/modules/contrib/admin/domain/domain_content/domain_content.info.yml @@ -11,8 +11,8 @@ dependencies: - user - views -# Information added by Drupal.org packaging script on 2017-12-19 -version: '8.x-1.0-alpha11' +# Information added by Drupal.org packaging script on 2018-03-08 +version: '8.x-1.0-alpha13' core: '8.x' project: 'domain' -datestamp: 1513718589 +datestamp: 1520519900 diff --git a/sites/all/modules/contrib/admin/domain/domain_content/src/Controller/DomainContentController.php b/sites/all/modules/contrib/admin/domain/domain_content/src/Controller/DomainContentController.php index ead35f356..4e7e61147 100644 --- a/sites/all/modules/contrib/admin/domain/domain_content/src/Controller/DomainContentController.php +++ b/sites/all/modules/contrib/admin/domain/domain_content/src/Controller/DomainContentController.php @@ -32,7 +32,7 @@ class DomainContentController extends ControllerBase { ]; if ($account->hasPermission($options['all_permission'])) { $build['#rows'][] = [ - Link::fromTextAndUrl($this->t('All affiliates'), Url::fromUri('internal:/admin/content/' . $options['path'] . '/' . '/all_affiliates')), + Link::fromTextAndUrl($this->t('All affiliates'), Url::fromUri('internal:/admin/content/' . $options['path'] . '/all_affiliates')), $this->getCount($options['type']), ]; } diff --git a/sites/all/modules/contrib/admin/domain/domain_source/config/schema/domain_source.views.schema.yml b/sites/all/modules/contrib/admin/domain/domain_source/config/schema/domain_source.views.schema.yml new file mode 100644 index 000000000..5ce71d584 --- /dev/null +++ b/sites/all/modules/contrib/admin/domain/domain_source/config/schema/domain_source.views.schema.yml @@ -0,0 +1,9 @@ +views.field.domain_source: + type: views_field + label: 'Domain source' +views.filter.domain_source: + type: views.filter.in_operator + label: 'Domain source' +views.filter_value.domain_source: + type: views.filter_value.in_operator + label: 'Domain source' diff --git a/sites/all/modules/contrib/admin/domain/domain_source/domain_source.info.yml b/sites/all/modules/contrib/admin/domain/domain_source/domain_source.info.yml index 24ae2905b..0f56a0029 100644 --- a/sites/all/modules/contrib/admin/domain/domain_source/domain_source.info.yml +++ b/sites/all/modules/contrib/admin/domain/domain_source/domain_source.info.yml @@ -8,8 +8,8 @@ dependencies: - domain - node -# Information added by Drupal.org packaging script on 2017-12-19 -version: '8.x-1.0-alpha11' +# Information added by Drupal.org packaging script on 2018-03-08 +version: '8.x-1.0-alpha13' core: '8.x' project: 'domain' -datestamp: 1513718589 +datestamp: 1520519900 diff --git a/sites/all/modules/contrib/admin/domain/domain_source/domain_source.module b/sites/all/modules/contrib/admin/domain/domain_source/domain_source.module index d87e2360e..863dd524d 100644 --- a/sites/all/modules/contrib/admin/domain/domain_source/domain_source.module +++ b/sites/all/modules/contrib/admin/domain/domain_source/domain_source.module @@ -54,14 +54,12 @@ function domain_source_confirm_fields($entity_type, $bundle) { } // Tell the form system how to behave. Default to radio buttons. - // @TODO: This function is deprecated, but using the OO syntax is causing - // test fails. - entity_get_form_display($entity_type, $bundle, 'default') - ->setComponent(DOMAIN_SOURCE_FIELD, array( + if ($display = \Drupal::entityTypeManager()->getStorage('entity_form_display')->load($entity_type . '.' . $bundle . '.default')) { + $display->setComponent(DOMAIN_SOURCE_FIELD, [ 'type' => 'options_select', 'weight' => 42, - )) - ->save(); + ])->save(); + } } /** @@ -130,12 +128,20 @@ function domain_source_form_alter(&$form, &$form_state, $form_id) { function domain_source_form_validate($element, \Drupal\Core\Form\FormStateInterface $form_state) { $values = $form_state->getValues(); // This is only run if Domain Access is present. - $access_values = $values[DOMAIN_ACCESS_FIELD]; - $source_value = current($values[DOMAIN_SOURCE_FIELD]); + if (isset($values[DOMAIN_SOURCE_FIELD]) && is_array($values[DOMAIN_SOURCE_FIELD]) && isset($values[DOMAIN_ACCESS_FIELD])) { + $access_values = $values[DOMAIN_ACCESS_FIELD]; + $source_value = current($values[DOMAIN_SOURCE_FIELD]); + } // If no value is selected, that's acceptable. Else run through a check. + // Note that the _none selection returns as [FALSE]. $source_set = empty($source_value); foreach ($access_values as $value) { - if ($value == $source_value) { + // Core is inconsistent depending on the field order. + // See https://www.drupal.org/project/domain/issues/2945771#comment-12493199 + if (is_array($value) && $value == $source_value) { + $source_set = TRUE; + } + elseif (is_string($value) && !empty($source_value['target_id']) && $value == $source_value['target_id']) { $source_set = TRUE; } } diff --git a/sites/all/modules/contrib/admin/domain/domain_source/tests/src/Functional/DomainSourceElementTest.php b/sites/all/modules/contrib/admin/domain/domain_source/tests/src/Functional/DomainSourceElementTest.php index 2dac3aba0..cf5384676 100644 --- a/sites/all/modules/contrib/admin/domain/domain_source/tests/src/Functional/DomainSourceElementTest.php +++ b/sites/all/modules/contrib/admin/domain/domain_source/tests/src/Functional/DomainSourceElementTest.php @@ -76,6 +76,10 @@ class DomainSourceElementTest extends DomainTestBase { $this->pressButton('edit-submit'); $this->assertSession()->statusCodeEquals(200); + // Check the URL. + $url = $this->geturl(); + $this->assert(strpos($url, 'node/1/edit') === FALSE, 'Form submitted.'); + // Edit the node. $this->drupalGet('node/1/edit'); $this->assertSession()->statusCodeEquals(200); @@ -90,5 +94,33 @@ class DomainSourceElementTest extends DomainTestBase { // Check the URL. $url = $this->geturl(); $this->assert(strpos($url, 'node/1/edit') > 0, 'Form not submitted.'); + + // Set the field properly and save again. + $this->selectFieldOption($locator, 'one_example_com'); + + // Save the form. + $this->pressButton('edit-submit'); + $this->assertSession()->statusCodeEquals(200); + + // Check the URL. + $url = $this->geturl(); + $this->assert(strpos($url, 'node/1/edit') === FALSE, 'Form submitted.'); + + // Save with no source. + + // Edit the node. + $this->drupalGet('node/1/edit'); + $this->assertSession()->statusCodeEquals(200); + + // Set the domain source field to an unselected domain. + $this->selectFieldOption($locator, '_none'); + + // Save the form. + $this->pressButton('edit-submit'); + $this->assertSession()->statusCodeEquals(200); + + // Check the URL. + $url = $this->geturl(); + $this->assert(strpos($url, 'node/1/edit') === FALSE, 'Form submitted.'); } } diff --git a/sites/all/modules/contrib/admin/features/composer.json b/sites/all/modules/contrib/admin/features/composer.json index 9de2a5c6b..1b7a61d37 100644 --- a/sites/all/modules/contrib/admin/features/composer.json +++ b/sites/all/modules/contrib/admin/features/composer.json @@ -1,8 +1,10 @@ { - "name": "drupal/features", - "description": "Enables administrators to package configuration into modules.", - "type": "drupal-module", + "description": "Enables administrators to package configuration into modules", "license": "GPL-2.0+", "minimum-stability": "dev", - "require": { } + "name": "drupal/features", + "require": { + "drupal/config_update": "^1.4" + }, + "type": "drupal-module" } diff --git a/sites/all/modules/contrib/admin/features/config/schema/features.schema.yml b/sites/all/modules/contrib/admin/features/config/schema/features.schema.yml index 7d515d18d..3d53f1d9f 100644 --- a/sites/all/modules/contrib/admin/features/config/schema/features.schema.yml +++ b/sites/all/modules/contrib/admin/features/config/schema/features.schema.yml @@ -38,7 +38,7 @@ features.bundle.*: type: boolean label: "Is install profile" -features.assignment.*: +features.assignment.settings: type: mapping label: "Assignment settings" mapping: @@ -49,16 +49,13 @@ features.assignment.*: type: integer label: "Weight" +features.assignment.*: + type: features.assignment.settings + features.assignment.base: - type: mapping + type: features.assignment.settings label: "Base type" mapping: - enabled: - type: boolean - label: "Enabled" - weight: - type: integer - label: "Weight" types: type: mapping label: "Types" @@ -75,15 +72,9 @@ features.assignment.base: type: string features.assignment.core: - type: mapping + type: features.assignment.settings label: "Core type" mapping: - enabled: - type: boolean - label: "Enabled" - weight: - type: integer - label: "Weight" types: type: mapping label: "Types" @@ -95,15 +86,9 @@ features.assignment.core: type: string features.assignment.exclude: - type: mapping + type: features.assignment.settings label: "Exclude" mapping: - enabled: - type: boolean - label: "Enabled" - weight: - type: integer - label: "Weight" types: type: mapping label: "Types" @@ -134,15 +119,9 @@ features.assignment.exclude: label: "Don't exclude ANY configuration by namespace" features.assignment.optional: - type: mapping + type: features.assignment.settings label: "Optional" mapping: - enabled: - type: boolean - label: "Enabled" - weight: - type: integer - label: "Weight" types: type: mapping label: "Types" @@ -154,15 +133,9 @@ features.assignment.optional: type: string features.assignment.profile: - type: mapping + type: features.assignment.settings label: "Profile" mapping: - enabled: - type: boolean - label: "Enabled" - weight: - type: integer - label: "Weight" curated: type: boolean label: "Add commonly-needed configuration" @@ -187,15 +160,9 @@ features.assignment.profile: type: string features.assignment.site: - type: mapping + type: features.assignment.settings label: "Site" mapping: - enabled: - type: boolean - label: "Enabled" - weight: - type: integer - label: "Weight" types: type: mapping label: "Types" @@ -205,3 +172,17 @@ features.assignment.site: label: "Configuration Types" sequence: type: string + +features.assignment.alter: + type: features.assignment.settings + label: "Alter" + mapping: + core: + type: boolean + label: "Core" + uuid: + type: boolean + label: "UUID" + user_permissions: + type: boolean + label: "User permissions" diff --git a/sites/all/modules/contrib/admin/features/drush.services.yml b/sites/all/modules/contrib/admin/features/drush.services.yml new file mode 100644 index 000000000..16b0f29c8 --- /dev/null +++ b/sites/all/modules/contrib/admin/features/drush.services.yml @@ -0,0 +1,11 @@ +services: + features.commands: + class: \Drupal\features\Commands\FeaturesCommands + arguments: + - '@features_assigner' + - '@features.manager' + - '@features_generator' + - '@config_update.config_diff' + - '@config.storage' + tags: + - { name: drush.command } diff --git a/sites/all/modules/contrib/admin/features/drush/features.drush.inc b/sites/all/modules/contrib/admin/features/drush/features.drush8.inc similarity index 100% rename from sites/all/modules/contrib/admin/features/drush/features.drush.inc rename to sites/all/modules/contrib/admin/features/drush/features.drush8.inc diff --git a/sites/all/modules/contrib/admin/features/features.info.yml b/sites/all/modules/contrib/admin/features/features.info.yml index ed60a6e00..197574cbd 100644 --- a/sites/all/modules/contrib/admin/features/features.info.yml +++ b/sites/all/modules/contrib/admin/features/features.info.yml @@ -7,8 +7,8 @@ dependencies: - config - config_update -# Information added by Drupal.org packaging script on 2017-03-07 -version: '8.x-3.5' +# Information added by Drupal.org packaging script on 2018-02-27 +version: '8.x-3.7' core: '8.x' project: 'features' -datestamp: 1488908587 +datestamp: 1519763291 diff --git a/sites/all/modules/contrib/admin/features/modules/features_ui/features_ui.info.yml b/sites/all/modules/contrib/admin/features/modules/features_ui/features_ui.info.yml index deec8eff8..a5d3cbd89 100644 --- a/sites/all/modules/contrib/admin/features/modules/features_ui/features_ui.info.yml +++ b/sites/all/modules/contrib/admin/features/modules/features_ui/features_ui.info.yml @@ -7,8 +7,8 @@ configure: features.assignment dependencies: - features -# Information added by Drupal.org packaging script on 2017-03-07 -version: '8.x-3.5' +# Information added by Drupal.org packaging script on 2018-02-27 +version: '8.x-3.7' core: '8.x' project: 'features' -datestamp: 1488908587 +datestamp: 1519763291 diff --git a/sites/all/modules/contrib/admin/features/modules/features_ui/src/Form/FeaturesEditForm.php b/sites/all/modules/contrib/admin/features/modules/features_ui/src/Form/FeaturesEditForm.php index c4b6c3343..ae52e2613 100644 --- a/sites/all/modules/contrib/admin/features/modules/features_ui/src/Form/FeaturesEditForm.php +++ b/sites/all/modules/contrib/admin/features/modules/features_ui/src/Form/FeaturesEditForm.php @@ -641,16 +641,15 @@ class FeaturesEditForm extends FormBase { foreach (array('excluded', 'required') as $constraint) { $this->{$constraint} = array(); $info = !empty($this->package->{'get' . $constraint}()) ? $this->package->{'get' . $constraint}() : array(); - if (($constraint == 'required') && (empty($info) || !is_array($info))) { - // If required is True or empty array, add all config as required - $info = $this->package->getConfigOrig(); - } - foreach ($info as $item_name) { - if (!isset($config[$item_name])) { - continue; + // $info may be boolean. + if (is_array($info)) { + foreach ($info as $item_name) { + if (!isset($config[$item_name])) { + continue; + } + $item = $config[$item_name]; + $this->{$constraint}[$item->getType()][$item->getShortName()] = $item->getLabel(); } - $item = $config[$item_name]; - $this->{$constraint}[$item->getType()][$item->getShortName()] = $item->getLabel(); } } diff --git a/sites/all/modules/contrib/admin/features/modules/features_ui/src/Form/FeaturesExportForm.php b/sites/all/modules/contrib/admin/features/modules/features_ui/src/Form/FeaturesExportForm.php index 45a555e2c..d2ffeedd3 100644 --- a/sites/all/modules/contrib/admin/features/modules/features_ui/src/Form/FeaturesExportForm.php +++ b/sites/all/modules/contrib/admin/features/modules/features_ui/src/Form/FeaturesExportForm.php @@ -133,10 +133,7 @@ class FeaturesExportForm extends FormBase { // Add in un-packaged configuration items. $this->addUnpackaged($packages, $config_collection); - // Filter packages on bundle if selected. - if (!$current_bundle->isDefault()) { - $packages = $this->featuresManager->filterPackages($packages, $current_bundle->getMachineName(), TRUE); - } + $packages = $this->featuresManager->filterPackages($packages, $current_bundle->getMachineName()); // Pass the packages and bundle data for use in the form pre_render // callback. diff --git a/sites/all/modules/contrib/admin/features/modules/features_ui/src/Tests/FeaturesBundleUITest.php b/sites/all/modules/contrib/admin/features/modules/features_ui/src/Tests/FeaturesBundleUITest.php index bdbcf087d..091c55e22 100644 --- a/sites/all/modules/contrib/admin/features/modules/features_ui/src/Tests/FeaturesBundleUITest.php +++ b/sites/all/modules/contrib/admin/features/modules/features_ui/src/Tests/FeaturesBundleUITest.php @@ -51,7 +51,7 @@ class FeaturesBundleUITest extends WebTestBase { * The features bundle. */ protected function defaultBundle() { - return $this->bundleStorage->load('default'); + return $this->bundleStorage->load(FeaturesBundleInterface::DEFAULT_BUNDLE); } /** diff --git a/sites/all/modules/contrib/admin/features/src/Commands/FeaturesCommands.php b/sites/all/modules/contrib/admin/features/src/Commands/FeaturesCommands.php new file mode 100644 index 000000000..79807b635 --- /dev/null +++ b/sites/all/modules/contrib/admin/features/src/Commands/FeaturesCommands.php @@ -0,0 +1,1052 @@ + NULL, + ]; + + const OPTIONS_ADD = self::OPTIONS; + + const OPTIONS_COMPONENTS = self::OPTIONS + [ + 'exported' => NULL, + 'format' => 'table', + 'not-exported' => NULL, + ]; + + const OPTIONS_DIFF = self::OPTIONS + [ + 'ctypes' => NULL, + 'lines' => NULL, + ]; + + const OPTIONS_EXPORT = self::OPTIONS + [ + 'add-profile' => NULL, + ]; + + const OPTIONS_IMPORT = self::OPTIONS + [ + 'force' => NULL, + ]; + + const OPTIONS_IMPORT_ALL = self::OPTIONS; + + const OPTIONS_LIST = self::OPTIONS + [ + 'format' => 'table', + ]; + + const OPTIONS_STATUS = self::OPTIONS; + + /** + * The features_assigner service. + * + * @var \Drupal\features\FeaturesAssignerInterface + */ + protected $assigner; + + /** + * The features.manager service. + * + * @var \Drupal\features\FeaturesManagerInterface + */ + protected $manager; + + /** + * The features_generator service. + * + * @var \Drupal\features\FeaturesGeneratorInterface + */ + protected $generator; + + /** + * The config_update.config_diff service. + * + * @var \Drupal\config_update\ConfigDiffInterface + */ + protected $configDiff; + + /** + * The config.storage service. + * + * @var \Drupal\Core\Config\StorageInterface + */ + protected $configStorage; + + /** + * FeaturesCommands constructor. + * + * @param \Drupal\features\FeaturesAssignerInterface $assigner + * The features_assigner service. + * @param \Drupal\features\FeaturesManagerInterface $manager + * The features.manager service. + * @param \Drupal\features\FeaturesGeneratorInterface $generator + * The features_generator service. + * @param \Drupal\config_update\ConfigDiffInterface $configDiff + * The config_update.config_diff service. + * @param \Drupal\Core\Config\StorageInterface $configStorage + * The config.storage service. + */ + public function __construct( + FeaturesAssignerInterface $assigner, + FeaturesManagerInterface $manager, + FeaturesGeneratorInterface $generator, + ConfigDiffInterface $configDiff, + StorageInterface $configStorage + ) { + parent::__construct(); + $this->assigner = $assigner; + $this->configDiff = $configDiff; + $this->configStorage = $configStorage; + $this->generator = $generator; + $this->manager = $manager; + } + + /** + * Applies global options for Features drush commands, including the bundle. + * + * The option --name="bundle_name" sets the bundle namespace. + * + * @return \Drupal\features\FeaturesAssignerInterface + * The features.assigner with options applied. + */ + protected function featuresOptions(array $options) { + $bundleName = $this->getOption($options, 'bundle'); + if (!empty($bundleName)) { + $bundle = $this->assigner->applyBundle($bundleName); + if ($bundle->getMachineName() !== $bundleName) { + $this->logger()->warning('Bundle {name} not found. Using default.', [ + 'name' => $bundleName, + ]); + } + } + else { + $this->assigner->assignConfigPackages(); + } + return $this->assigner; + } + + /** + * Get the value of an option. + * + * @param array $options + * The options array. + * @param string $name + * The option name. + * @param mixed $default + * The default value of the option. + * + * @return mixed|null + * The option value, defaulting to NULL. + */ + protected function getOption(array $options, $name, $default = NULL) { + return isset($options[$name]) + ? $options[$name] + : $default; + } + + /** + * Display current Features settings. + * + * @param string $keys + * A possibly empty, comma-separated, list of config information to display. + * + * @command features:status + * + * @option bundle Use a specific bundle namespace. + * + * @aliases fs,features-status + */ + public function status($keys = NULL, array $options = self::OPTIONS_STATUS) { + $this->featuresOptions($options); + + $currentBundle = $this->assigner->getBundle(); + $export_settings = $this->manager->getExportSettings(); + $methods = $this->assigner->getEnabledAssigners(); + $output = $this->output(); + if ($currentBundle->isDefault()) { + $output->writeln(dt('Current bundle: none')); + } + else { + $output->writeln(dt('Current bundle: @name (@machine_name)', [ + '@name' => $currentBundle->getName(), + '@machine_name' => $currentBundle->getMachineName(), + ])); + } + $output->writeln(dt('Export folder: @folder', [ + '@folder' => $export_settings['folder'], + ])); + $output + ->writeln(dt('The following assignment methods are enabled:')); + $output->writeln(dt(' @methods', [ + '@methods' => implode(', ', array_keys($methods)), + ])); + + if (!empty($keys)) { + $config = $this->manager->getConfigCollection(); + $keys = StringUtils::csvToArray($keys); + $data = count($keys) > 1 + ? array_keys($config) + : $config[$keys[0]]; + $output->writeln(print_r($data, TRUE)); + } + } + + /** + * Display a list of all generate-able existing features and packages. + * + * If a package name is provided as an argument, then all of the configuration + * objects assigned to that package will be listed. + * + * @param string $package_name + * The package to list. Optional; if specified, lists all configuration + * objects assigned to that package. If no package is specified, lists all + * of the features. + * + * @return \Consolidation\OutputFormatters\StructuredData\RowsOfFields|bool + * The command output, or FALSE if a requested package was not found. + * + * @command features:list:packages + * + * @option bundle Use a specific bundle namespace. + * + * @usage drush features:list:packages + * Display a list of all existing features and packages available to be + * generated. + * @usage drush features:list:packages 'example_article' + * Display a list of all configuration objects assigned to the + * 'example_article' package. + * + * @field-labels + * config: Config + * name: Name + * machine_name: Machine name + * status: Status + * version: Version + * state: State + * + * @aliases fl,features-list-packages + */ + public function listPackages($package_name = NULL, $options = self::OPTIONS_LIST) { + $assigner = $this->featuresOptions($options); + $current_bundle = $assigner->getBundle(); + $namespace = $current_bundle->isDefault() ? '' : $current_bundle->getMachineName(); + + $manager = $this->manager; + $packages = $manager->getPackages(); + + $packages = $manager->filterPackages($packages, $namespace); + $result = []; + + // If no package was specified, list all packages. + if (empty($package_name)) { + foreach ($packages as $package) { + $overrides = $manager->detectOverrides($package); + $state = $package->getState(); + if (!empty($overrides) && ($package->getStatus() != FeaturesManagerInterface::STATUS_NO_EXPORT)) { + $state = FeaturesManagerInterface::STATE_OVERRIDDEN; + } + + $packageState = ($state != FeaturesManagerInterface::STATE_DEFAULT) + ? $manager->stateLabel($state) + : ''; + + $result[$package->getMachineName()] = [ + 'name' => $package->getName(), + 'machine_name' => $package->getMachineName(), + 'status' => $manager->statusLabel($package->getStatus()), + 'version' => $package->getVersion(), + 'state' => $packageState, + ]; + } + return new RowsOfFields($result); + } + + // A valid package was listed. + $package = $this->manager->findPackage($package_name); + + // If no matching package found, return an error. + if (empty($package)) { + $this->logger()->warning(dt('Package "@package" not found.', [ + '@package' => $package_name, + ])); + return FALSE; + } + + // This is a valid package, list its configuration. + $config = array_map(function ($name) { + return ['config' => $name]; + }, $package->getConfig()); + + return new RowsOfFields($config); + } + + /** + * Import module config from all installed features. + * + * @command features:import:all + * + * @option bundle Use a specific bundle namespace. + * + * @usage drush features-import-all + * Import module config from all installed features. + * + * @aliases fra,fia,fim-all,features-import-all + */ + public function importAll($options = self::OPTIONS_IMPORT_ALL) { + $assigner = $this->featuresOptions($options); + $currentBundle = $assigner->getBundle(); + $namespace = $currentBundle->isDefault() ? '' : $currentBundle->getMachineName(); + + $manager = $this->manager; + $packages = $manager->getPackages(); + $packages = $manager->filterPackages($packages, $namespace); + $overridden = []; + + foreach ($packages as $package) { + $overrides = $manager->detectOverrides($package); + $missing = $manager->detectMissing($package); + if ((!empty($missing) || !empty($overrides)) && ($package->getStatus() == FeaturesManagerInterface::STATUS_INSTALLED)) { + $overridden[] = $package->getMachineName(); + } + } + + if (!empty($overridden)) { + $this->import($overridden); + } + else { + $this->logger->info(dt('Current state already matches active config, aborting.')); + } + } + + /** + * Export the configuration on your site into a custom module. + * + * @param array $packages + * A list of features to export. + * + * @command features:export + * + * @option add-profile Package features into an install profile. + * @option bundle Use a specific bundle namespace. + * + * @usage drush features-export + * Export all available packages. + * @usage drush features-export example_article example_page + * Export the example_article and example_page packages. + * @usage drush features-export --add-profile + * Export all available packages and add them to an install profile. + * + * @aliases fex,fu,fua,fu-all,features-export + * + * @throws \Drupal\features\Exception\DomainException + * @throws \Drupal\features\Exception\InvalidArgumentException + * @throws \Drush\Exceptions\UserAbortException + * @throws \Exception + */ + public function export(array $packages, $options = self::OPTIONS_EXPORT) { + $assigner = $this->featuresOptions($options); + $manager = $this->manager; + $generator = $this->generator; + + $current_bundle = $assigner->getBundle(); + + if ($options['add-profile']) { + if ($current_bundle->isDefault) { + throw new InvalidArgumentException(dt("Must specify a profile name with --name")); + } + $current_bundle->setIsProfile(TRUE); + } + + $all_packages = $manager->getPackages(); + foreach ($packages as $name) { + if (!isset($all_packages[$name])) { + throw new DomainException(dt("The package @name does not exist.", [ + '@name' => $name, + ])); + } + } + + if (empty($packages)) { + $packages = $all_packages; + $dt_args = ['@modules' => implode(', ', array_keys($packages))]; + drush_print(dt('The following extensions will be exported: @modules', + $dt_args)); + if (!$this->io()->confirm('Do you really want to continue?')) { + throw new UserAbortException(); + } + } + else { + $packages = array_combine($packages, $packages); + } + + // If any packages exist, confirm before overwriting. + if ($existing_packages = $manager->listPackageDirectories($packages, + $current_bundle)) { + foreach ($existing_packages as $name => $directory) { + drush_print(dt("The extension @name already exists at @directory.", + ['@name' => $name, '@directory' => $directory])); + } + // Apparently, format_plural is not always available. + if (count($existing_packages) == 1) { + $message = dt('Would you like to overwrite it?'); + } + else { + $message = dt('Would you like to overwrite them?'); + } + if (!$this->io()->confirm($message)) { + throw new UserAbortException(); + } + } + + // Use the write generation method. + $method_id = FeaturesGenerationWrite::METHOD_ID; + $result = $generator->generatePackages($method_id, $current_bundle, array_keys($packages)); + + foreach ($result as $message) { + $method = $message['success'] ? 'success' : 'error'; + $this->logger()->$method(dt($message['message'], $message['variables'])); + } + } + + /** + * Add a config item to a feature package. + * + * @param array|null $components + * Patterns of config to add, see features:components for the format to use. + * + * @command features:add + * + * @todo @param $feature Feature package to export and add config to. + * + * @option bundle Use a specific bundle namespace. + * + * @aliases fa,fe,features-add + * + * @throws \Drush\Exceptions\UserAbortException + * @throws \Exception + */ + public function add($components = NULL, $options = self::OPTIONS_ADD) { + if ($components) { + $assigner = $this->featuresOptions($options); + $manager = $this->manager; + $generator = $this->generator; + + $current_bundle = $assigner->getBundle(); + + $module = array_shift($args); + if (empty($args)) { + throw new \Exception('No components supplied.'); + } + $components = $this->componentList(); + $options = [ + 'exported' => FALSE, + ]; + + $filtered_components = $this->componentFilter($components, $args, + $options); + $items = $filtered_components['components']; + + if (empty($items)) { + throw new \Exception('No components to add.'); + } + + $packages = [$module]; + // If any packages exist, confirm before overwriting. + if ($existing_packages = $manager->listPackageDirectories($packages)) { + foreach ($existing_packages as $name => $directory) { + drush_print(dt("The extension @name already exists at @directory.", + ['@name' => $name, '@directory' => $directory])); + } + // Apparently, format_plural is not always available. + if (count($existing_packages) == 1) { + $message = dt('Would you like to overwrite it?'); + } + else { + $message = dt('Would you like to overwrite them?'); + } + if (!$this->io()->confirm($message)) { + throw new UserAbortException(); + } + } + else { + $package = $manager->initPackage($module, NULL, '', 'module', + $current_bundle); + list($full_name, $path) = $manager->getExportInfo($package, + $current_bundle); + drush_print(dt('Will create a new extension @name in @directory', + ['@name' => $full_name, '@directory' => $path])); + if (!$this->io()->confirm(dt('Do you really want to continue?'))) { + throw new UserAbortException(); + } + } + + $config = $this->buildConfig($items); + + $manager->assignConfigPackage($module, $config); + + // Use the write generation method. + $method_id = FeaturesGenerationWrite::METHOD_ID; + $result = $generator->generatePackages($method_id, $current_bundle, + $packages); + + foreach ($result as $message) { + $method = $message['success'] ? 'success' : 'error'; + $this->logger()->$method(dt($message['message'], + $message['variables'])); + } + } + else { + throw new \Exception('No feature name given.'); + } + } + + /** + * List features components. + * + * @param array $patterns + * The components types to list. Omit this argument to list them all. + * + * @command features:components + * + * @option exported Show only components that have been exported. + * @option not-exported Show only components that have not been exported. + * @option bundle Use a specific bundle namespace. + * + * @aliases fc,features-components + * + * @field-labels + * source: Available sources + * + * @return \Consolidation\OutputFormatters\StructuredData\RowsOfFields|null + * The command output. May be empty. + */ + public function components(array $patterns, $options = self::OPTIONS_COMPONENTS) { + $args = $patterns; + $this->featuresOptions($options); + + $components = $this->componentList(); + ksort($components); + // If no args supplied, prompt with a list. + if (empty($args)) { + $types = array_keys($components); + array_unshift($types, 'all'); + $choice = $this->io() + ->choice('Enter a number to choose which component type to list.', $types); + if ($choice === FALSE) { + return NULL; + } + + $args = ($choice == 0) ? ['*'] : [$types[$choice]]; + } + $options = [ + 'provided by' => TRUE, + ]; + if ($options['exported']) { + $options['not exported'] = FALSE; + } + elseif ($options['not-exported']) { + $options['exported'] = FALSE; + } + + $filtered_components = $this->componentFilter($components, $args, $options); + if ($filtered_components) { + return $this->componentPrint($filtered_components); + } + } + + /** + * Show the difference between active|default config from a feature package. + * + * @param string $feature + * The feature in question. + * + * @command features:diff + * + * @option ctypes Comma-separated list of component types to limit the output + * to. Defaults to all types. + * @option lines Generate diffs with lines of context instead of the + * usual two. + * @option bundle Use a specific bundle namespace. + * + * @aliases fd,features-diff + * + * @throws \Exception + */ + public function diff($feature, $options = self::OPTIONS_DIFF) { + $manager = $this->manager; + $assigner = $this->featuresOptions($options); + $assigner->assignConfigPackages(); + + $module = $feature; + + // @FIXME Actually do something with the "ctypes" option. + $filter_ctypes = $options['ctypes']; + if ($filter_ctypes) { + $filter_ctypes = explode(',', $filter_ctypes); + } + + $feature = $manager->loadPackage($module, TRUE); + if (empty($feature)) { + throw new DomainException(dt('No such feature is available: @module', [ + '@module' => $module, + ])); + } + + $lines = $options['lines']; + $lines = isset($lines) ? $lines : 2; + + $formatter = new DiffFormatter(); + $formatter->leading_context_lines = $lines; + $formatter->trailing_context_lines = $lines; + $formatter->show_header = FALSE; + + if (drush_get_context('DRUSH_NOCOLOR')) { + $red = $green = "%s"; + } + else { + $red = "\033[31;40m\033[1m%s\033[0m"; + $green = "\033[0;32;40m\033[1m%s\033[0m"; + } + + $overrides = $manager->detectOverrides($feature); + $missing = $manager->reorderMissing($manager->detectMissing($feature)); + $overrides = array_merge($overrides, $missing); + + $output = $this->output(); + + if (empty($overrides)) { + $output->writeln(dt('Active config matches stored config for @module.', [ + '@module' => $module, + ])); + } + else { + $config_diff = $this->configDiff; + + // Print key for colors. + $output->writeln(dt('Legend: ')); + $output->writeln(sprintf($red, + dt('Code: drush features-import will replace the active config with the displayed code.'))); + $output->writeln(sprintf($green, + dt('Active: drush features-export will update the exported feature with the displayed active config'))); + + foreach ($overrides as $name) { + $message = ''; + if (in_array($name, $missing)) { + $extension = []; + $message = sprintf($red, dt('(missing from active)')); + } + else { + $active = $manager->getActiveStorage()->read($name); + $extension = $manager->getExtensionStorages()->read($name); + if (empty($extension)) { + $extension = []; + $message = sprintf($green, dt('(not exported)')); + } + $diff = $config_diff->diff($extension, $active); + $rows = explode("\n", $formatter->format($diff)); + } + + $output->writeln(''); + $output->writeln(dt("Config @name @message", [ + '@name' => $name, + '@message' => $message, + ])); + + if (!empty($extension)) { + foreach ($rows as $row) { + if (strpos($row, '>') === 0) { + $output->writeln(sprintf($green, $row)); + } + elseif (strpos($row, '<') === 0) { + $output->writeln(sprintf($red, $row)); + } + else { + $output->writeln($row); + } + } + } + } + } + } + + /** + * Import a module config into your site. + * + * @param string $feature + * A comma-delimited list of features or feature:component pairs to import. + * + * @command features:import + * + * @option force Force import even if config is not overridden. + * @option bundle Use a specific bundle namespace. + * + * @usage drush features-import foo:node.type.page + * foo:taxonomy.vocabulary.tags bar Import node and taxonomy config of + * feature "foo". Import all config of feature "bar". + * + * @aliases fim,fr,features-import + * + * @throws \Exception + */ + public function import($feature, $options = self::OPTIONS_IMPORT) { + $this->featuresOptions($options); + + $features = StringUtils::csvToArray($feature); + if (empty($features)) { + drush_invoke_process('@self', 'features:list:packages', [], $options); + return; + } + + // Determine if revert should be forced. + $force = $this->getOption($options, 'force'); + + // Determine if -y was supplied. If so, we can filter out needless output + // from this command. + $skip_confirmation = drush_get_context('DRUSH_AFFIRMATIVE'); + $manager = $this->manager; + + // Parse list of arguments. + $modules = []; + foreach ($features as $featureString) { + list($module, $component) = explode(':', $featureString); + + // We cannot use just a component name without its module. + if (empty($module)) { + continue; + } + + // We received just a feature name, meaning we need all of its components. + if (empty($component)) { + $modules[$module] = TRUE; + continue; + } + + if (empty($modules[$module])) { + $modules[$module] = []; + } + + if ($modules[$module] !== TRUE) { + $modules[$module][] = $component; + } + } + + // Process modules. + foreach ($modules as $module => $componentsNeeded) { + // Reset the arguments on each loop pass. + $dt_args = ['@module' => $module]; + + /** @var \Drupal\features\Package $feature */ + $feature = $manager->loadPackage($module, TRUE); + if (empty($feature)) { + throw new DomainException(dt('No such feature is available: @module', $dt_args)); + } + + if ($feature->getStatus() != FeaturesManagerInterface::STATUS_INSTALLED) { + throw new DomainException(dt('No such feature is installed: @module', $dt_args)); + } + + // Forcefully revert all components of a feature. + if ($force) { + $components = $feature->getConfigOrig(); + } + // Only revert components that are detected to be Overridden. + else { + $overrides = $manager->detectOverrides($feature); + $missing = $manager->reorderMissing($manager->detectMissing($feature)); + + // Be sure to import missing components first. + $components = array_merge($missing, $overrides); + } + + if (!empty($componentsNeeded) && is_array($componentsNeeded)) { + $components = array_intersect($components, $componentsNeeded); + } + + if (empty($components)) { + $this->logger()->info(dt('Current state already matches active config, aborting.')); + continue; + } + + // Determine which config the user wants to import/revert. + $configToCreate = []; + foreach ($components as $component) { + $dt_args['@component'] = $component; + $confirmation_message = 'Do you really want to import @module : @component?'; + if ($skip_confirmation || $this->io()->confirm(dt($confirmation_message, $dt_args))) { + $configToCreate[$component] = ''; + } + } + + // Perform the import/revert. + $importedConfig = $manager->createConfiguration($configToCreate); + + // List the results. + foreach ($components as $component) { + $dt_args['@component'] = $component; + if (isset($importedConfig['new'][$component])) { + $this->logger()->info(dt('Imported @module : @component.', $dt_args)); + } + elseif (isset($importedConfig['updated'][$component])) { + $this->logger()->info(dt('Reverted @module : @component.', $dt_args)); + } + elseif (!isset($configToCreate[$component])) { + $this->logger()->info(dt('Skipping @module : @component.', $dt_args)); + } + else { + $this->logger()->error(dt('Error importing @module : @component.', $dt_args)); + } + } + } + } + + /** + * Returns an array of full config names given a array[$type][$component]. + * + * @param array $items + * The items to return data for. + * + * @return array + * An array of config items. + */ + protected function buildConfig(array $items) { + $result = []; + foreach ($items as $config_type => $item) { + foreach ($item as $item_name => $title) { + $result[] = $this->manager->getFullName($config_type, $item_name); + } + } + return $result; + } + + /** + * Returns a listing of all known components, indexed by source. + */ + protected function componentList() { + $result = []; + $config = $this->manager->getConfigCollection(); + foreach ($config as $item) { + $result[$item->getType()][$item->getShortName()] = $item->getLabel(); + } + return $result; + } + + /** + * Filters components by patterns. + */ + protected function componentFilter($all_components, $patterns = [], $options = []) { + $options += [ + 'exported' => TRUE, + 'not exported' => TRUE, + 'provided by' => FALSE, + ]; + $pool = []; + // Maps exported components to feature modules. + $components_map = $this->componentMap(); + // First filter on exported state. + foreach ($all_components as $source => $components) { + foreach ($components as $name => $title) { + $exported = count($components_map[$source][$name]) > 0; + if ($exported) { + if ($options['exported']) { + $pool[$source][$name] = $title; + } + } + else { + if ($options['not exported']) { + $pool[$source][$name] = $title; + } + } + } + } + + $state_string = ''; + + if (!$options['exported']) { + $state_string = 'unexported'; + } + elseif (!$options['not exported']) { + $state_string = 'exported'; + } + + $selected = []; + foreach ($patterns as $pattern) { + // Rewrite * to %. Let users use both as wildcard. + $pattern = strtr($pattern, ['*' => '%']); + $sources = []; + list($source_pattern, $component_pattern) = explode(':', $pattern, 2); + // If source is empty, use a pattern. + if ($source_pattern == '') { + $source_pattern = '%'; + } + if ($component_pattern == '') { + $component_pattern = '%'; + } + + $preg_source_pattern = strtr(preg_quote($source_pattern, '/'), + ['%' => '.*']); + $preg_component_pattern = strtr(preg_quote($component_pattern, '/'), + ['%' => '.*']); + // If it isn't a pattern, but a simple string, we don't anchor the + // pattern. This allows for abbreviating. Otherwise, we do, as this seems + // more natural for patterns. + if (strpos($source_pattern, '%') !== FALSE) { + $preg_source_pattern = '^' . $preg_source_pattern . '$'; + } + if (strpos($component_pattern, '%') !== FALSE) { + $preg_component_pattern = '^' . $preg_component_pattern . '$'; + } + $matches = []; + + // Find the sources. + $all_sources = array_keys($pool); + $matches = preg_grep('/' . $preg_source_pattern . '/', $all_sources); + if (count($matches) > 0) { + // If we have multiple matches and the source string wasn't a + // pattern, check if one of the matches is equal to the pattern, and + // use that, or error out. + if (count($matches) > 1 and $preg_source_pattern[0] != '^') { + if (in_array($source_pattern, $matches)) { + $matches = [$source_pattern]; + } + else { + throw new \Exception(dt('Ambiguous source "@source", matches @matches', + [ + '@source' => $source_pattern, + '@matches' => implode(', ', $matches), + ])); + } + } + // Loose the indexes preg_grep preserved. + $sources = array_values($matches); + } + else { + throw new \Exception(dt('No @state sources match "@source"', + ['@state' => $state_string, '@source' => $source_pattern])); + } + + // Now find the components. + foreach ($sources as $source) { + // Find the components. + $all_components = array_keys($pool[$source]); + // See if there's any matches. + $matches = preg_grep('/' . $preg_component_pattern . '/', + $all_components); + if (count($matches) > 0) { + // If we have multiple matches and the components string wasn't a + // pattern, check if one of the matches is equal to the pattern, and + // use that, or error out. + if (count($matches) > 1 and $preg_component_pattern[0] != '^') { + if (in_array($component_pattern, $matches)) { + $matches = [$component_pattern]; + } + else { + throw new \Exception(dt('Ambiguous component "@component", matches @matches', + [ + '@component' => $component_pattern, + '@matches' => implode(', ', $matches), + ])); + } + } + if (!is_array($selected[$source])) { + $selected[$source] = []; + } + $selected[$source] += array_intersect_key($pool[$source], + array_flip($matches)); + } + else { + // No matches. If the source was a pattern, just carry on, else + // error out. Allows for patterns like ":*field*". + if ($preg_source_pattern[0] != '^') { + throw new \Exception(dt('No @state @source components match "@component"', + [ + '@state' => $state_string, + '@component' => $component_pattern, + '@source' => $source, + ])); + } + } + } + } + + // Lastly, provide feature module information on the selected components, if + // requested. + $provided_by = []; + if ($options['provided by'] && $options['exported']) { + foreach ($selected as $source => $components) { + foreach ($components as $name => $title) { + $exported = count($components_map[$source][$name]) > 0; + if ($exported) { + $provided_by[$source . ':' . $name] = implode(', ', + $components_map[$source][$name]); + } + } + } + } + + return [ + 'components' => $selected, + 'sources' => $provided_by, + ]; + } + + /** + * Provides a component to feature map (port of features_get_component_map). + */ + protected function componentMap() { + $result = []; + $manager = $this->manager; + // Recalc full config list without running assignments. + $config = $manager->getConfigCollection(); + $packages = $manager->getPackages(); + + foreach ($config as $item) { + $type = $item->getType(); + $short_name = $item->getShortName(); + if (!isset($result[$type][$short_name])) { + $result[$type][$short_name] = []; + } + if (!empty($item->getPackage())) { + $package = $packages[$item->getPackage()]; + $result[$type][$short_name][] = $package->getMachineName(); + } + } + + return $result; + } + + /** + * Prints a list of filtered components. + */ + protected function componentPrint($filtered_components) { + $rows = []; + foreach ($filtered_components['components'] as $source => $components) { + foreach ($components as $name => $value) { + $row = ['source' => $source . ':' . $name]; + if (isset($filtered_components['sources'][$source . ':' . $name])) { + $row['source'] = dt('Provided by') . ': ' . $filtered_components['sources'][$source . ':' . $name]; + } + $rows[] = $row; + } + } + + return new RowsOfFields($rows); + } + +} diff --git a/sites/all/modules/contrib/admin/features/src/Exception/DomainException.php b/sites/all/modules/contrib/admin/features/src/Exception/DomainException.php new file mode 100644 index 000000000..c496d3b0e --- /dev/null +++ b/sites/all/modules/contrib/admin/features/src/Exception/DomainException.php @@ -0,0 +1,7 @@ +createBundleFromDefault($new_bundle['machine_name'], $new_bundle['name'], $new_bundle['description'], $new_bundle['is_profile']); - drupal_set_message($this->t('Features bundle @name automatically created.', ['@name' => $new_bundle->getName()])); + $this->createBundleFromDefault($new_bundle['machine_name'], $new_bundle['name'], $new_bundle['description'], $new_bundle['is_profile']); } } diff --git a/sites/all/modules/contrib/admin/features/src/FeaturesConfigInstaller.php b/sites/all/modules/contrib/admin/features/src/FeaturesConfigInstaller.php index 17fa7c5a4..2d7edd0e6 100644 --- a/sites/all/modules/contrib/admin/features/src/FeaturesConfigInstaller.php +++ b/sites/all/modules/contrib/admin/features/src/FeaturesConfigInstaller.php @@ -57,7 +57,7 @@ class FeaturesConfigInstaller extends ConfigInstaller { list($major, $minor, ) = explode('.', \Drupal::VERSION); if ($major == 8 && $minor > 2) { // D8.3 added the %install_profile% argument. - $install_profile = drupal_get_profile(); + $install_profile = \Drupal::installProfile(); parent::__construct($config_factory, $active_storage, $typed_config, $config_manager, $event_dispatcher, $install_profile); } else { diff --git a/sites/all/modules/contrib/admin/features/src/FeaturesInstallStorage.php b/sites/all/modules/contrib/admin/features/src/FeaturesInstallStorage.php index 55f54bdde..3742ea17b 100644 --- a/sites/all/modules/contrib/admin/features/src/FeaturesInstallStorage.php +++ b/sites/all/modules/contrib/admin/features/src/FeaturesInstallStorage.php @@ -35,7 +35,15 @@ class FeaturesInstallStorage extends ExtensionInstallStorage { * default collection. */ public function __construct(StorageInterface $config_storage, $directory = self::CONFIG_INSTALL_DIRECTORY, $collection = StorageInterface::DEFAULT_COLLECTION) { - parent::__construct($config_storage, $directory, $collection, FALSE); + list($major, $minor, ) = explode('.', \Drupal::VERSION); + if ($major == 8 && $minor > 2) { + // D8.3 added the %profile% argument. + $profile = \Drupal::installProfile(); + parent::__construct($config_storage, $directory, $collection, FALSE, $profile); + } + else { + parent::__construct($config_storage, $directory, $collection, FALSE); + } } /** diff --git a/sites/all/modules/contrib/admin/features/src/FeaturesManager.php b/sites/all/modules/contrib/admin/features/src/FeaturesManager.php index 252ef5856..cf9329707 100644 --- a/sites/all/modules/contrib/admin/features/src/FeaturesManager.php +++ b/sites/all/modules/contrib/admin/features/src/FeaturesManager.php @@ -326,10 +326,13 @@ class FeaturesManager implements FeaturesManagerInterface { // A package matches the namespace if: // - it's prefixed with the namespace, or // - it's assigned to a bundle named for the namespace, or - // - we're looking only for exported packages and it's not exported. - if (empty($namespace) || (strpos($package->getMachineName(), $namespace . '_') === 0) || + // - the namespace is the default bundle and it has an empty bundle, and + // - we're not removing only exported packages, or + // - we are removing only exported packages and it's not exported. + if ((strpos($package->getMachineName(), $namespace . '_') === 0 || ($package->getBundle() && $package->getBundle() === $namespace) || - ($only_exported && $package->getStatus() === FeaturesManagerInterface::STATUS_NO_EXPORT)) { + ($namespace === FeaturesBundleInterface::DEFAULT_BUNDLE && empty($package->getBundle()))) && + (!$only_exported || ($package->getStatus() === FeaturesManagerInterface::STATUS_NO_EXPORT))) { $result[$key] = $package; } } @@ -546,25 +549,30 @@ class FeaturesManager implements FeaturesManagerInterface { protected function getConfigDependency(ConfigurationItem $config, $module_list = array()) { $dependencies = []; $type = $config->getType(); - if ($type != FeaturesManagerInterface::SYSTEM_SIMPLE_CONFIG) { - $provider = $this->entityTypeManager->getDefinition($type)->getProvider(); - // Ensure the provider is an installed module and not, for example, 'core' - if (isset($module_list[$provider])) { - $dependencies[] = $provider; + + // For configuration in the InstallStorage::CONFIG_INSTALL_DIRECTORY + // directory, set any dependencies of the configuration item as package + // dependencies. + // As its name implies, the core-provided + // InstallStorage::CONFIG_OPTIONAL_DIRECTORY should not create + // dependencies. + if ($config->getSubdirectory() === InstallStorage::CONFIG_INSTALL_DIRECTORY) { + if ($type === FeaturesManagerInterface::SYSTEM_SIMPLE_CONFIG) { + $dependencies[] = strtok($config->getName(), '.'); + } + else { + $dependencies[] = $this->entityTypeManager->getDefinition($type)->getProvider(); } - // For configuration in the InstallStorage::CONFIG_INSTALL_DIRECTORY - // directory, set any module dependencies of the configuration item - // as package dependencies. - // As its name implies, the core-provided - // InstallStorage::CONFIG_OPTIONAL_DIRECTORY should not create - // dependencies. - if ($config->getSubdirectory() === InstallStorage::CONFIG_INSTALL_DIRECTORY && - isset($config->getData()['dependencies']['module']) - ) { + if (isset($config->getData()['dependencies']['module'])) { $dependencies = array_merge($dependencies, $config->getData()['dependencies']['module']); } + + // Only return dependencies for installed modules and not, for example, + // 'core'. + $dependencies = array_intersect($dependencies, array_keys($module_list)); } + return $dependencies; } @@ -755,20 +763,28 @@ class FeaturesManager implements FeaturesManagerInterface { } $config_collection = $this->getConfigCollection(); + $module_list = $this->moduleHandler->getModuleList(); /** @var \Drupal\features\Package[] $packages */ foreach ($packages as $package) { foreach ($package->getConfig() as $item_name) { if (!empty($config_collection[$item_name]->getData()['dependencies']['config'])) { foreach ($config_collection[$item_name]->getData()['dependencies']['config'] as $dependency_name) { - if (isset($config_collection[$dependency_name])) { + if (isset($config_collection[$dependency_name]) && + // For configuration in the + // InstallStorage::CONFIG_INSTALL_DIRECTORY directory, set any + // package dependencies of the configuration item. + // As its name implies, the core-provided + // InstallStorage::CONFIG_OPTIONAL_DIRECTORY should not create + // dependencies. + ($config_collection[$dependency_name]->getSubdirectory() === InstallStorage::CONFIG_INSTALL_DIRECTORY)) { // If the required item is assigned to one of the packages, add // a dependency on that package. $dependency_set = FALSE; if ($dependency_package = $config_collection[$dependency_name]->getPackage()) { $package_name = $bundle->getFullName($dependency_package); // Package shouldn't be dependent on itself. - if ($package_name && array_key_exists($package_name, $packages) && $package_name != $package->getMachineName()) { + if ($package_name && array_key_exists($package_name, $packages) && $package_name != $package->getMachineName() && isset($module_list[$package_name])) { $package->setDependencies($this->mergeUniqueItems($package->getDependencies(), [$package_name])); $dependency_set = TRUE; } @@ -778,7 +794,7 @@ class FeaturesManager implements FeaturesManagerInterface { if (!$dependency_set && $extension_name = $config_collection[$dependency_name]->getProvider()) { // No extension should depend on the install profile. $package_name = $bundle->getFullName($package->getMachineName()); - if ($extension_name != $package_name && $extension_name != $this->drupalGetProfile()) { + if ($extension_name != $package_name && $extension_name != $this->drupalGetProfile() && isset($module_list[$extension_name])) { $package->setDependencies($this->mergeUniqueItems($package->getDependencies(), [$extension_name])); } } diff --git a/sites/all/modules/contrib/admin/features/src/Package.php b/sites/all/modules/contrib/admin/features/src/Package.php index 4ceec115e..2fb459a1d 100644 --- a/sites/all/modules/contrib/admin/features/src/Package.php +++ b/sites/all/modules/contrib/admin/features/src/Package.php @@ -235,7 +235,7 @@ class Package { } /** - * @return string[] + * @return string[]|bool */ public function getRequired() { return $this->required; @@ -245,12 +245,20 @@ class Package { * @return bool */ public function getRequiredAll() { + // Mark all as required if the package is not yet exported. + if ($this->getStatus() === FeaturesManagerInterface::STATUS_NO_EXPORT) { + return TRUE; + } + + // Mark all as required if required is TRUE. + if (is_bool($this->required)) { + return $this->required; + } + + // Mark all as required if required contains all the exported config. $config_orig = $this->getConfigOrig(); - $info = is_array($this->required) ? $this->required : array(); - $diff = array_diff($config_orig, $info); - // Mark all as required if required:true, or required is empty, or - // if required contains all the exported config - return empty($diff) || empty($info); + $diff = array_diff($config_orig, $this->required); + return empty($diff); } /** diff --git a/sites/all/modules/contrib/admin/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentPackages.php b/sites/all/modules/contrib/admin/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentPackages.php index f5de0d6f6..759e9efc7 100644 --- a/sites/all/modules/contrib/admin/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentPackages.php +++ b/sites/all/modules/contrib/admin/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentPackages.php @@ -26,7 +26,7 @@ class FeaturesAssignmentPackages extends FeaturesAssignmentMethodBase { $short_name = $package->getMachineName(); // Copy over package excluded settings, if any. - if (!$package->getExcluded()) { + if ($package->getExcluded()) { $config_collection = $this->featuresManager->getConfigCollection(); foreach ($package->getExcluded() as $config_name) { if (isset($config_collection[$config_name])) { diff --git a/sites/all/modules/contrib/admin/features/tests/modules/test_feature/test_feature.info.yml b/sites/all/modules/contrib/admin/features/tests/modules/test_feature/test_feature.info.yml index b6dffcdab..4f9d07045 100644 --- a/sites/all/modules/contrib/admin/features/tests/modules/test_feature/test_feature.info.yml +++ b/sites/all/modules/contrib/admin/features/tests/modules/test_feature/test_feature.info.yml @@ -6,8 +6,8 @@ package: Test dependencies: - features -# Information added by Drupal.org packaging script on 2017-03-07 -version: '8.x-3.5' +# Information added by Drupal.org packaging script on 2018-02-27 +version: '8.x-3.7' core: '8.x' project: 'features' -datestamp: 1488908587 +datestamp: 1519763291 diff --git a/sites/all/modules/contrib/admin/features/tests/modules/test_mybundle_core/test_mybundle_core.features.yml b/sites/all/modules/contrib/admin/features/tests/modules/test_mybundle_core/test_mybundle_core.features.yml index 808e32111..3387e5fee 100644 --- a/sites/all/modules/contrib/admin/features/tests/modules/test_mybundle_core/test_mybundle_core.features.yml +++ b/sites/all/modules/contrib/admin/features/tests/modules/test_mybundle_core/test_mybundle_core.features.yml @@ -1,3 +1,5 @@ bundle: test_mybundle excluded: - system.theme +required: + - core.date_format.long diff --git a/sites/all/modules/contrib/admin/features/tests/modules/test_mybundle_core/test_mybundle_core.info.yml b/sites/all/modules/contrib/admin/features/tests/modules/test_mybundle_core/test_mybundle_core.info.yml index 6478cabdd..f3c033933 100644 --- a/sites/all/modules/contrib/admin/features/tests/modules/test_mybundle_core/test_mybundle_core.info.yml +++ b/sites/all/modules/contrib/admin/features/tests/modules/test_mybundle_core/test_mybundle_core.info.yml @@ -6,8 +6,8 @@ package: Test dependencies: - features -# Information added by Drupal.org packaging script on 2017-03-07 -version: '8.x-3.5' +# Information added by Drupal.org packaging script on 2018-02-27 +version: '8.x-3.7' core: '8.x' project: 'features' -datestamp: 1488908587 +datestamp: 1519763291 diff --git a/sites/all/modules/contrib/admin/features/tests/src/Kernel/FeaturesAssignTest.php b/sites/all/modules/contrib/admin/features/tests/src/Kernel/FeaturesAssignTest.php index a57338dc7..59b4ad961 100644 --- a/sites/all/modules/contrib/admin/features/tests/src/Kernel/FeaturesAssignTest.php +++ b/sites/all/modules/contrib/admin/features/tests/src/Kernel/FeaturesAssignTest.php @@ -700,6 +700,19 @@ class FeaturesAssignTest extends KernelTestBase { public function testAssignPackages() { $method_id = 'packages'; + // A configuration item that will be excluded. + $this->addConfigurationItem('system.theme', [], [ + 'type' => FeaturesManagerInterface::SYSTEM_SIMPLE_CONFIG, + ]); + // A configuration item that will be required. + $this->addConfigurationItem('core.date_format.long', [], [ + 'type' => 'date_format', + ]); + // A configuration item that will be neither excluded nor required. + $this->addConfigurationItem('system.theme', [], [ + 'type' => FeaturesManagerInterface::SYSTEM_SIMPLE_CONFIG, + ]); + // Enable the method. $this->enableAssignmentMethod($method_id); @@ -708,6 +721,14 @@ class FeaturesAssignTest extends KernelTestBase { $packages = $this->featuresManager->getPackages(); $this->assertNotEmpty($packages[self::TEST_INSTALLED_PACKAGE], 'Expected package not created.'); + + $config = $this->featuresManager->getConfigCollection(); + + $this->assertTrue(in_array(self::TEST_INSTALLED_PACKAGE, $config['system.theme']->getPackageExcluded()), 'Configuration item not excluded from package.'); + $this->assertFalse(in_array(self::TEST_INSTALLED_PACKAGE, $config['system.site']->getPackageExcluded()), 'Configuration item excluded from package.'); + + $this->assertEquals(self::TEST_INSTALLED_PACKAGE, $config['core.date_format.long']->getPackage(), 'Required item not assigned to package.'); + $this->assertNotEquals(self::TEST_INSTALLED_PACKAGE, $config['system.site']->getPackage(), 'Unrequired item assigned to package.'); } /** @@ -730,7 +751,7 @@ class FeaturesAssignTest extends KernelTestBase { 'type' => 'image_style', ]); $this->addConfigurationItem('system.cron', [], [ - 'type' => 'simple', + 'type' => FeaturesManagerInterface::SYSTEM_SIMPLE_CONFIG, ]); $this->bundle = $this->assigner->createBundleFromDefault('myprofile'); $this->bundle->setProfileName('myprofile'); diff --git a/sites/all/modules/contrib/admin/features/tests/src/Unit/FeaturesManagerTest.php b/sites/all/modules/contrib/admin/features/tests/src/Unit/FeaturesManagerTest.php index d018b04a7..f53937a7c 100644 --- a/sites/all/modules/contrib/admin/features/tests/src/Unit/FeaturesManagerTest.php +++ b/sites/all/modules/contrib/admin/features/tests/src/Unit/FeaturesManagerTest.php @@ -105,10 +105,23 @@ class FeaturesManagerTest extends UnitTestCase { $this->configManager = $this->getMock(ConfigManagerInterface::class); $this->moduleHandler = $this->getMock(ModuleHandlerInterface::class); // getModuleList should return an array of extension objects. - // but we just need ::getConfigDependency isset($module_list[$provider]). + // but we just need isset($module_list[$provider]) for + // ::getConfigDependency() and ::assignInterPackageDependencies(). $this->moduleHandler->expects($this->any()) ->method('getModuleList') - ->willReturn(['my_module' => true]); + ->willReturn([ + 'my_module' => true, + 'example' => true, + 'example3' => true, + 'my_feature' => true, + 'my_other_feature' => true, + 'package' => true, + 'package2' => true, + 'package3' => true, + 'giraffe_package' => true, + 'giraffe_package2' => true, + 'giraffe_package3' => true, + ]); $this->configReverter = $this->getMock(ConfigRevertInterface::class); $this->configReverter->expects($this->any()) ->method('import') @@ -188,6 +201,55 @@ class FeaturesManagerTest extends UnitTestCase { $this->assertEquals($package, $this->featuresManager->getPackage('foo')); } + /** + * @covers ::filterPackages + */ + public function testGetPackages() { + $packages = [ + 'package' => new Package('package', [ + 'bundle' => '', + 'status' => FeaturesManagerInterface::STATUS_NO_EXPORT, + ]), + 'package2' => new Package('package2', [ + 'bundle' => '', + 'status' => FeaturesManagerInterface::STATUS_UNINSTALLED, + ]), + 'package3' => new Package('package3', [ + 'bundle' => 'my_bundle', + 'status' => FeaturesManagerInterface::STATUS_NO_EXPORT, + ]), + 'package4' => new Package('package4', [ + 'bundle' => 'my_bundle', + 'status' => FeaturesManagerInterface::STATUS_UNINSTALLED, + ]), + ]; + + // Filter for the default bundle. + $filtered_packages = $this->featuresManager->filterPackages($packages, FeaturesBundleInterface::DEFAULT_BUNDLE); + $this->assertEquals(['package', 'package2'], array_keys($filtered_packages)); + + // Filter for a custom bundle. + $filtered_packages = $this->featuresManager->filterPackages($packages, 'my_bundle'); + $this->assertEquals(['package3', 'package4'], array_keys($filtered_packages)); + + // Filter for a non-matching bundle. + $filtered_packages = $this->featuresManager->filterPackages($packages, 'some_bundle'); + $this->assertEquals([], array_keys($filtered_packages)); + + // Filter for the default bundle removing only exported. + $filtered_packages = $this->featuresManager->filterPackages($packages, FeaturesBundleInterface::DEFAULT_BUNDLE, TRUE); + $this->assertEquals(['package'], array_keys($filtered_packages)); + + // Filter for a custom bundle removing only exported. + $filtered_packages = $this->featuresManager->filterPackages($packages, 'my_bundle', TRUE); + $this->assertEquals(['package3'], array_keys($filtered_packages)); + + // Filter for a non-matching bundle removing only exported. + $filtered_packages = $this->featuresManager->filterPackages($packages, 'some_bundle', TRUE); + $this->assertEquals([], array_keys($filtered_packages)); + } + + protected function getAssignInterPackageDependenciesConfigCollection() { $config_collection = []; $config_collection['example.config'] = (new ConfigurationItem('example.config', [ @@ -196,23 +258,46 @@ class FeaturesManagerTest extends UnitTestCase { 'example.config2', 'example.config3', 'example.config4', + 'example.config5', + 'example.config6', + 'example.config7', ], ], - ]))->setPackage('package'); - + ])) + ->setSubdirectory(InstallStorage::CONFIG_INSTALL_DIRECTORY) + ->setPackage('package'); $config_collection['example.config2'] = (new ConfigurationItem('example.config2', [ 'dependencies' => [], ])) + ->setSubdirectory(InstallStorage::CONFIG_INSTALL_DIRECTORY) ->setPackage('package2') ->setProvider('my_feature'); $config_collection['example.config3'] = (new ConfigurationItem('example.config3', [ 'dependencies' => [], ])) + ->setSubdirectory(InstallStorage::CONFIG_INSTALL_DIRECTORY) ->setProvider('my_other_feature'); $config_collection['example.config4'] = (new ConfigurationItem('example.config3', [ 'dependencies' => [], ])) + ->setSubdirectory(InstallStorage::CONFIG_INSTALL_DIRECTORY) ->setProvider(static::PROFILE_NAME); + $config_collection['example.config5'] = (new ConfigurationItem('example.config5', [ + 'dependencies' => [], + ])) + ->setSubdirectory(InstallStorage::CONFIG_OPTIONAL_DIRECTORY) + ->setPackage('package3'); + $config_collection['example.config6'] = (new ConfigurationItem('example.config6', [ + 'dependencies' => [], + ])) + ->setSubdirectory(InstallStorage::CONFIG_INSTALL_DIRECTORY) + ->setProvider('my_uninstalled_feature'); + $config_collection['example.config7'] = (new ConfigurationItem('example.config7', [ + 'dependencies' => [], + ])) + ->setSubdirectory(InstallStorage::CONFIG_INSTALL_DIRECTORY) + ->setProvider('package4'); + return $config_collection; } @@ -225,8 +310,10 @@ class FeaturesManagerTest extends UnitTestCase { // Provide a bundle without any prefix. $bundle->getFullName('package')->willReturn('package'); $bundle->getFullName('package2')->willReturn('package2'); + $bundle->getFullName('package3')->willReturn('package3'); + $bundle->getFullName('package4')->willReturn('package4'); $bundle->isDefault()->willReturn(TRUE); - $assigner->getBundle('')->willReturn($bundle->reveal()); + $assigner->getBundle()->willReturn($bundle->reveal()); // Use the wrapper because we need ::drupalGetProfile(). $features_manager = new TestFeaturesManager($this->root, $this->entityTypeManager, $this->configFactory, $this->configStorage, $this->configManager, $this->moduleHandler, $this->configReverter); $features_manager->setAssigner($assigner->reveal()); @@ -244,6 +331,16 @@ class FeaturesManagerTest extends UnitTestCase { 'dependencies' => [], 'bundle' => '', ]), + 'package3' => new Package('package3', [ + 'config' => ['example.config5'], + 'dependencies' => [], + 'bundle' => '', + ]), + 'package4' => new Package('package4', [ + 'config' => ['example.config7'], + 'dependencies' => [], + 'bundle' => '', + ]), ]; $features_manager->setPackages($packages); @@ -257,6 +354,13 @@ class FeaturesManagerTest extends UnitTestCase { // my_package. // Because package assignments take precedence over providing_feature ones, // package2 should have been assigned rather than my_feature. + // Because it is assigned to the InstallStorage::CONFIG_OPTIONAL_DIRECTORY + // subdirectory, example.config5 does not create a dependency on its + // providing feature, package3. + // Because it's provided by an uninstalled module, example.config6 doesn't + // create a dependency on my_uninstalled_feature. + // Because it's provided by an uninstalled module, example.config7 doesn't + // create a dependency on package4. $this->assertEquals(['my_other_feature', 'package2'], $packages['package']->getDependencies()); $this->assertEquals([], $packages['package2']->getDependencies()); } @@ -270,6 +374,8 @@ class FeaturesManagerTest extends UnitTestCase { // Provide a bundle without any prefix. $bundle->getFullName('package')->willReturn('giraffe_package'); $bundle->getFullName('package2')->willReturn('giraffe_package2'); + $bundle->getFullName('package3')->willReturn('giraffe_package3'); + $bundle->getFullName('package4')->willReturn('giraffe_package4'); $bundle->getFullName('giraffe_package')->willReturn('giraffe_package'); $bundle->getFullName('giraffe_package2')->willReturn('giraffe_package2'); $bundle->isDefault()->willReturn(FALSE); @@ -291,6 +397,16 @@ class FeaturesManagerTest extends UnitTestCase { 'dependencies' => [], 'bundle' => 'giraffe', ]), + 'package3' => new Package('package3', [ + 'config' => ['example.config5'], + 'dependencies' => [], + 'bundle' => 'giraffe', + ]), + 'package4' => new Package('package4', [ + 'config' => ['example.config7'], + 'dependencies' => [], + 'bundle' => 'giraffe', + ]), ]; $features_manager->setPackages($packages); @@ -304,6 +420,13 @@ class FeaturesManagerTest extends UnitTestCase { // my_package. // Because package assignments take precedence over providing_feature ones, // package2 should have been assigned rather than my_feature. + // Because it is assigned to the InstallStorage::CONFIG_OPTIONAL_DIRECTORY + // subdirectory, example.config5 does not create a dependency on its + // providing feature, package3. + // Because it's provided by an uninstalled module, example.config6 doesn't + // create a dependency on my_uninstalled_feature. + // Because it's provided by an uninstalled module, example.config7 doesn't + // create a dependency on giraffe_package4. $expected = ['giraffe_package2', 'my_other_feature']; $this->assertEquals($expected, $packages['giraffe_package']->getDependencies()); } @@ -417,6 +540,7 @@ class FeaturesManagerTest extends UnitTestCase { $assigner = $this->prophesize(FeaturesAssignerInterface::class); $bundle = $this->prophesize(FeaturesBundleInterface::class); $bundle->isProfilePackage('test_package')->willReturn(FALSE); + $bundle->isProfilePackage('test_package2')->willReturn(FALSE); $assigner->getBundle(NULL)->willReturn($bundle->reveal()); $this->featuresManager->setAssigner($assigner->reveal()); @@ -424,21 +548,43 @@ class FeaturesManagerTest extends UnitTestCase { 'test_config' => new ConfigurationItem('test_config', []), 'test_config2' => new ConfigurationItem('test_config2', [ 'dependencies' => [ - 'module' => ['example'], + 'module' => ['example', 'example2'], ] ], [ 'subdirectory' => InstallStorage::CONFIG_INSTALL_DIRECTORY, ]), + 'example3.settings' => new ConfigurationItem('example3.settings', [], [ + 'type' => FeaturesManagerInterface::SYSTEM_SIMPLE_CONFIG, + 'subdirectory' => InstallStorage::CONFIG_INSTALL_DIRECTORY, + ]), + 'test_config3' => new ConfigurationItem('test_config3', [ + 'dependencies' => [ + 'module' => ['example2'], + ] + ], [ + 'subdirectory' => InstallStorage::CONFIG_OPTIONAL_DIRECTORY, + ]), ]; $this->featuresManager->setConfigCollection($config_collection); $package = new Package('test_package'); $this->featuresManager->setPackage($package); - $this->featuresManager->assignConfigPackage('test_package', ['test_config', 'test_config2']); + $this->featuresManager->assignConfigPackage('test_package', ['test_config', 'test_config2', 'example3.settings']); - $this->assertEquals(['test_config', 'test_config2'], $this->featuresManager->getPackage('test_package')->getConfig()); - $this->assertEquals(['example', 'my_module'], $this->featuresManager->getPackage('test_package')->getDependencies()); + $this->assertEquals(['test_config', 'test_config2', 'example3.settings'], $this->featuresManager->getPackage('test_package')->getConfig()); + // 'example2' is not returned by ::getModuleList() and so isn't a + // dependency. + $this->assertEquals(['example', 'example3', 'my_module'], $this->featuresManager->getPackage('test_package')->getDependencies()); + + // Test optional config, which doesn't create module dependencies. + $package = new Package('test_package2'); + $this->featuresManager->setPackage($package); + + $this->featuresManager->assignConfigPackage('test_package2', ['test_config3']); + + $this->assertEquals(['test_config3'], $this->featuresManager->getPackage('test_package2')->getConfig()); + $this->assertEquals([], $this->featuresManager->getPackage('test_package2')->getDependencies()); } /** @@ -451,6 +597,32 @@ class FeaturesManagerTest extends UnitTestCase { ]; $this->featuresManager->setConfigCollection($config_collection); + $feature_assigner = $this->prophesize(FeaturesAssignerInterface::class); + $feature_assigner->getBundle(NULL)->willReturn(new FeaturesBundle(['machine_name' => FeaturesBundleInterface::DEFAULT_BUNDLE], 'features_bundle')); + $this->featuresManager->setAssigner($feature_assigner->reveal()); + + $package = new Package('test_package'); + $original_package = clone $package; + + $this->featuresManager->setPackage($package); + $this->featuresManager->assignConfigPackage('test_package', ['test_config', 'test_config2']); + $this->assertEquals(['test_config'], $this->featuresManager->getPackage('test_package')->getConfig(), 'just assign new packages'); + + $this->featuresManager->setPackage($original_package); + $this->featuresManager->assignConfigPackage('test_package', ['test_config', 'test_config2'], TRUE); + $this->assertEquals(['test_config', 'test_config2'], $this->featuresManager->getPackage('test_package')->getConfig(), 'just assign new packages'); + } + + /** + * @covers ::assignConfigPackage + */ + public function testAssignConfigPackageWithPackageExcludedConfig() { + $config_collection = [ + 'test_config' => new ConfigurationItem('test_config', []), + 'test_config2' => new ConfigurationItem('test_config2', [], ['packageExcluded' => ['test_package']]), + ]; + $this->featuresManager->setConfigCollection($config_collection); + $feature_assigner = $this->prophesize(FeaturesAssignerInterface::class); $feature_assigner->getBundle(NULL)->willReturn(new FeaturesBundle(['machine_name' => 'default'], 'features_bundle')); $this->featuresManager->setAssigner($feature_assigner->reveal()); @@ -687,6 +859,7 @@ EOT /** * @covers ::prepareFiles + * @covers ::addInfoFile */ public function testPrepareFiles() { $packages = []; @@ -695,12 +868,22 @@ EOT 'name' => 'Test feature', ]); + $packages['test_feature2'] = new Package('test_feature2', [ + 'config' => ['test_config2'], + 'name' => 'Test feature 2', + 'type' => 'profile', + 'excluded' => ['my_config'], + 'required' => ['test_config2'], + ]); + $config_collection = []; $config_collection['test_config'] = new ConfigurationItem('test_config', ['foo' => 'bar']); + $config_collection['test_config2'] = new ConfigurationItem('test_config2', ['foo' => 'bar']); $this->featuresManager->setConfigCollection($config_collection); $this->featuresManager->prepareFiles($packages); + // Test test_feature package. $files = $packages['test_feature']->getFiles(); $this->assertCount(3, $files); $this->assertEquals('test_feature.info.yml', $files['info']['filename']); @@ -718,6 +901,14 @@ EOT $this->assertEquals('test_feature.features.yml', $files['features']['filename']); $this->assertEquals(Yaml::encode(TRUE), $files['features']['string']); + + // Test test_feature2 package. + $files = $packages['test_feature2']->getFiles(); + + $this->assertEquals(Yaml::encode([ + 'excluded' => ['my_config'], + 'required' => ['test_config2'], + ]), $files['features']['string']); } /** diff --git a/sites/all/modules/contrib/dev/entity/.travis.yml b/sites/all/modules/contrib/dev/entity/.travis.yml index 8f477f885..e48d5d7d3 100644 --- a/sites/all/modules/contrib/dev/entity/.travis.yml +++ b/sites/all/modules/contrib/dev/entity/.travis.yml @@ -38,7 +38,7 @@ before_script: # Export database variable for kernel tests. - export SIMPLETEST_DB=mysql://root:@127.0.0.1/entity # Download Drupal 8 core. - - travis_retry git clone --branch 8.3.x --depth 1 http://git.drupal.org/project/drupal.git + - travis_retry git clone --branch 8.5.x --depth 1 http://git.drupal.org/project/drupal.git - cd drupal - composer self-update - composer install -n diff --git a/sites/all/modules/contrib/dev/entity/composer.json b/sites/all/modules/contrib/dev/entity/composer.json index 3292711ab..538e0e559 100644 --- a/sites/all/modules/contrib/dev/entity/composer.json +++ b/sites/all/modules/contrib/dev/entity/composer.json @@ -5,6 +5,6 @@ "homepage": "http://drupal.org/project/entity", "license": "GPL-2.0+", "require": { - "drupal/core": "~8.3" + "drupal/core": "~8.5" } } diff --git a/sites/all/modules/contrib/dev/entity/entity.info.yml b/sites/all/modules/contrib/dev/entity/entity.info.yml index 0c2c09e5e..e5aab28c3 100644 --- a/sites/all/modules/contrib/dev/entity/entity.info.yml +++ b/sites/all/modules/contrib/dev/entity/entity.info.yml @@ -3,10 +3,10 @@ description: Provides expanded entity APIs, which will be moved to Drupal core o type: module # core: 8.x dependencies: - - drupal:system (>=8.3.0) + - drupal:system (>=8.5.0) -# Information added by Drupal.org packaging script on 2017-09-20 -version: '8.x-1.0-beta1' +# Information added by Drupal.org packaging script on 2018-03-12 +version: '8.x-1.0-beta2' core: '8.x' project: 'entity' -datestamp: 1505895847 +datestamp: 1520873296 diff --git a/sites/all/modules/contrib/dev/entity/entity.links.action.yml b/sites/all/modules/contrib/dev/entity/entity.links.action.yml new file mode 100644 index 000000000..5e02edcd7 --- /dev/null +++ b/sites/all/modules/contrib/dev/entity/entity.links.action.yml @@ -0,0 +1,2 @@ +entity.entity_actions: + deriver: Drupal\entity\Plugin\Derivative\EntityActionsDeriver diff --git a/sites/all/modules/contrib/dev/entity/entity.services.yml b/sites/all/modules/contrib/dev/entity/entity.services.yml index 3e690d122..c4e5f83f5 100644 --- a/sites/all/modules/contrib/dev/entity/entity.services.yml +++ b/sites/all/modules/contrib/dev/entity/entity.services.yml @@ -1,4 +1,10 @@ services: + access_check.entity_delete_multiple: + class: Drupal\entity\Access\EntityDeleteMultipleAccessCheck + arguments: ['@entity_type.manager', '@tempstore.private', '@request_stack'] + tags: + - { name: access_check, applies_to: _entity_delete_multiple_access } + access_checker.entity_revision: class: \Drupal\entity\Access\EntityRevisionRouteAccessChecker arguments: ['@entity_type.manager', '@current_route_match'] diff --git a/sites/all/modules/contrib/dev/entity/src/Access/EntityDeleteMultipleAccessCheck.php b/sites/all/modules/contrib/dev/entity/src/Access/EntityDeleteMultipleAccessCheck.php new file mode 100644 index 000000000..a04cda68c --- /dev/null +++ b/sites/all/modules/contrib/dev/entity/src/Access/EntityDeleteMultipleAccessCheck.php @@ -0,0 +1,87 @@ +entityTypeManager = $entity_type_manager; + $this->tempStore = $temp_store_factory->get('entity_delete_multiple_confirm'); + $this->requestStack = $request_stack; + } + + /** + * Checks if the user has delete access for at least one item of the store. + * + * @param \Drupal\Core\Session\AccountInterface $account + * Run access checks for this account. + * @param string $entity_type_id + * Entity type ID. + * + * @return \Drupal\Core\Access\AccessResult + * Allowed or forbidden, neutral if tempstore is empty. + */ + public function access(AccountInterface $account, $entity_type_id) { + if (!$this->requestStack->getCurrentRequest()->getSession()) { + return AccessResult::neutral(); + } + $selection = $this->tempStore->get($account->id() . ':' . $entity_type_id); + if (empty($selection) || !is_array($selection)) { + return AccessResult::neutral(); + } + + $entities = $this->entityTypeManager->getStorage($entity_type_id)->loadMultiple(array_keys($selection)); + foreach ($entities as $entity) { + // As long as the user has access to delete one entity allow access to the + // delete form. Access will be checked again in + // Drupal\Core\Entity\Form\DeleteMultipleForm::submit() in case it has + // changed in the meantime. + if ($entity->access('delete', $account)) { + return AccessResult::allowed(); + } + } + return AccessResult::forbidden(); + } + +} diff --git a/sites/all/modules/contrib/dev/entity/src/Controller/RevisionControllerTrait.php b/sites/all/modules/contrib/dev/entity/src/Controller/RevisionControllerTrait.php index 9751b17ae..6be025a6e 100644 --- a/sites/all/modules/contrib/dev/entity/src/Controller/RevisionControllerTrait.php +++ b/sites/all/modules/contrib/dev/entity/src/Controller/RevisionControllerTrait.php @@ -23,7 +23,7 @@ trait RevisionControllerTrait { * * @return \Drupal\Core\Language\LanguageManagerInterface */ - public abstract function languageManager(); + abstract public function languageManager(); /** * Determines if the user has permission to revert revisions. @@ -55,7 +55,6 @@ trait RevisionControllerTrait { * * @return array * A link render array. - * */ abstract protected function buildRevertRevisionLink(EntityInterface $entity_revision); @@ -117,24 +116,17 @@ trait RevisionControllerTrait { $langcode = $this->languageManager() ->getCurrentLanguage(LanguageInterface::TYPE_CONTENT) ->getId(); - $entity_storage = $this->entityTypeManager() - ->getStorage($entity->getEntityTypeId()); + /** @var \Drupal\Core\Entity\ContentEntityStorageInterface $entity_storage */ + $entity_storage = $this->entityTypeManager()->getStorage($entity->getEntityTypeId()); + $revision_ids = $this->revisionIds($entity); + $entity_revisions = $entity_storage->loadMultipleRevisions($revision_ids); $header = [$this->t('Revision'), $this->t('Operations')]; $rows = []; - - $revision_ids = $this->revisionIds($entity); - // @todo Expand the entity storage to load multiple revisions. - $entity_revisions = array_combine($revision_ids, array_map(function($vid) use ($entity_storage) { - return $entity_storage->loadRevision($vid); - }, $revision_ids)); - foreach ($entity_revisions as $revision) { $row = []; /** @var \Drupal\Core\Entity\ContentEntityInterface $revision */ - if ($revision->hasTranslation($langcode) && $revision->getTranslation($langcode) - ->isRevisionTranslationAffected() - ) { + if ($revision->hasTranslation($langcode) && $revision->getTranslation($langcode)->isRevisionTranslationAffected()) { $row[] = $this->getRevisionDescription($revision, $revision->isDefaultRevision()); if ($revision->isDefaultRevision()) { diff --git a/sites/all/modules/contrib/dev/entity/src/Entity/RevisionableEntityBundleInterface.php b/sites/all/modules/contrib/dev/entity/src/Entity/RevisionableEntityBundleInterface.php deleted file mode 100644 index 6e543b17d..000000000 --- a/sites/all/modules/contrib/dev/entity/src/Entity/RevisionableEntityBundleInterface.php +++ /dev/null @@ -1,17 +0,0 @@ -getEntityTypeId(); - if (($entity instanceof ContentEntityInterface && $entity->isDefaultRevision()) || !$entity->getEntityType()->isRevisionable()) { - $build['#contextual_links'][$entity_type_id] = [ - 'route_parameters' => [ - $entity_type_id => $entity->id() - ], - ]; - } - else { - $build['#contextual_links'][$entity_type_id . '_revision'] = [ - 'route_parameters' => [ - $entity_type_id => $entity->id(), - $entity_type_id . '_revision' => $entity->getRevisionId(), - ], - ]; - } - } - -} diff --git a/sites/all/modules/contrib/dev/entity/src/Form/DeleteMultiple.php b/sites/all/modules/contrib/dev/entity/src/Form/DeleteMultiple.php deleted file mode 100644 index 6268a95ac..000000000 --- a/sites/all/modules/contrib/dev/entity/src/Form/DeleteMultiple.php +++ /dev/null @@ -1,226 +0,0 @@ - langcodes format. - * - * @var array - */ - protected $selection = []; - - /** - * Constructs a new DeleteMultiple object. - * - * @param \Drupal\Core\Session\AccountInterface $current_user - * The current user. - * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager - * The entity type manager. - * @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory - * The tempstore factory. - */ - public function __construct(AccountInterface $current_user, EntityTypeManagerInterface $entity_type_manager, PrivateTempStoreFactory $temp_store_factory) { - $this->currentUser = $current_user; - $this->entityTypeManager = $entity_type_manager; - $this->tempStore = $temp_store_factory->get('entity_delete_multiple_confirm'); - } - - /** - * {@inheritdoc} - */ - public static function create(ContainerInterface $container) { - return new static( - $container->get('current_user'), - $container->get('entity_type.manager'), - $container->get('user.private_tempstore') - ); - } - - /** - * {@inheritdoc} - */ - public function getFormId() { - return 'entity_delete_multiple_confirm'; - } - - /** - * {@inheritdoc} - */ - public function getQuestion() { - return $this->formatPlural(count($this->selection), 'Are you sure you want to delete this item?', 'Are you sure you want to delete these items?'); - } - - /** - * {@inheritdoc} - */ - public function getCancelUrl() { - return new Url('entity.' . $this->entityTypeId . '.collection'); - } - - /** - * {@inheritdoc} - */ - public function getConfirmText() { - return $this->t('Delete'); - } - - /** - * {@inheritdoc} - * - * @param string $entity_type_id - * The entity type id. - */ - public function buildForm(array $form, FormStateInterface $form_state, $entity_type_id = NULL) { - $this->entityTypeId = $entity_type_id; - $this->selection = $this->tempStore->get($this->currentUser->id()); - if (empty($this->entityTypeId) || empty($this->selection)) { - return new RedirectResponse($this->getCancelUrl()->setAbsolute()->toString()); - } - - $storage = $this->entityTypeManager->getStorage($this->entityTypeId); - /** @var \Drupal\Core\Entity\ContentEntityInterface[] $entities */ - $entities = $storage->loadMultiple(array_keys($this->selection)); - $items = []; - foreach ($this->selection as $id => $langcodes) { - foreach ($langcodes as $langcode) { - $entity = $entities[$id]->getTranslation($langcode); - $key = $id . ':' . $langcode; - $default_key = $id . ':' . $entity->getUntranslated()->language()->getId(); - - // If we have a translated entity we build a nested list of translations - // that will be deleted. - $languages = $entity->getTranslationLanguages(); - if (count($languages) > 1 && $entity->isDefaultTranslation()) { - $names = []; - foreach ($languages as $translation_langcode => $language) { - $names[] = $language->getName(); - unset($items[$id . ':' . $translation_langcode]); - } - $items[$default_key] = [ - 'label' => [ - '#markup' => $this->t('@label (Original translation) - The following translations will be deleted:', ['@label' => $entity->label()]), - ], - 'deleted_translations' => [ - '#theme' => 'item_list', - '#items' => $names, - ], - ]; - } - elseif (!isset($items[$default_key])) { - $items[$key] = $entity->label(); - } - } - } - - $form['entities'] = [ - '#theme' => 'item_list', - '#items' => $items, - ]; - $form = parent::buildForm($form, $form_state); - - return $form; - } - - /** - * {@inheritdoc} - */ - public function submitForm(array &$form, FormStateInterface $form_state) { - $total_count = 0; - $delete_entities = []; - $delete_translations = []; - $storage = $this->entityTypeManager->getStorage($this->entityTypeId); - /** @var \Drupal\Core\Entity\ContentEntityInterface[] $entities */ - $entities = $storage->loadMultiple(array_keys($this->selection)); - - foreach ($this->selection as $id => $langcodes) { - foreach ($langcodes as $langcode) { - $entity = $entities[$id]->getTranslation($langcode); - if ($entity->isDefaultTranslation()) { - $delete_entities[$id] = $entity; - unset($delete_translations[$id]); - $total_count += count($entity->getTranslationLanguages()); - } - elseif (!isset($delete_entities[$id])) { - $delete_translations[$id][] = $entity; - } - } - } - - if ($delete_entities) { - $storage->delete($delete_entities); - $this->logger('content')->notice('Deleted @count @entity_type items.', [ - '@count' => count($delete_entities), - '@entity_type' => $this->entityTypeId, - ]); - } - - if ($delete_translations) { - $count = 0; - /** @var \Drupal\Core\Entity\ContentEntityInterface[][] $delete_translations */ - foreach ($delete_translations as $id => $translations) { - $entity = $entities[$id]->getUntranslated(); - foreach ($translations as $translation) { - $entity->removeTranslation($translation->language()->getId()); - } - $entity->save(); - $count += count($translations); - } - if ($count) { - $total_count += $count; - $this->logger('content')->notice('Deleted @count @entity_type translations.', [ - '@count' => $count, - '@entity_type' => $this->entityTypeId, - ]); - } - } - - if ($total_count) { - drupal_set_message($this->formatPlural($total_count, 'Deleted 1 item.', 'Deleted @count items.')); - } - $this->tempStore->delete($this->currentUser->id()); - $form_state->setRedirectUrl($this->getCancelUrl()); - } - -} diff --git a/sites/all/modules/contrib/dev/entity/src/Form/DeleteMultipleForm.php b/sites/all/modules/contrib/dev/entity/src/Form/DeleteMultipleForm.php new file mode 100644 index 000000000..aed711dfc --- /dev/null +++ b/sites/all/modules/contrib/dev/entity/src/Form/DeleteMultipleForm.php @@ -0,0 +1,323 @@ + langcodes format. + * + * @var array + */ + protected $selection = []; + + /** + * The entity type definition. + * + * @var \Drupal\Core\Entity\EntityTypeInterface + */ + protected $entityType; + + /** + * Constructs a new DeleteMultiple object. + * + * @param \Drupal\Core\Session\AccountInterface $current_user + * The current user. + * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager + * The entity type manager. + * @param \Drupal\Core\TempStore\PrivateTempStoreFactory $temp_store_factory + * The tempstore factory. + * @param \Drupal\Core\Messenger\MessengerInterface $messenger + * The messenger service. + */ + public function __construct(AccountInterface $current_user, EntityTypeManagerInterface $entity_type_manager, PrivateTempStoreFactory $temp_store_factory, MessengerInterface $messenger) { + $this->currentUser = $current_user; + $this->entityTypeManager = $entity_type_manager; + $this->tempStore = $temp_store_factory->get('entity_delete_multiple_confirm'); + $this->messenger = $messenger; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('current_user'), + $container->get('entity_type.manager'), + $container->get('tempstore.private'), + $container->get('messenger') + ); + } + + /** + * {@inheritdoc} + */ + public function getBaseFormId() { + return 'entity_delete_multiple_confirm_form'; + } + + /** + * {@inheritdoc} + */ + public function getFormId() { + // Get entity type ID from the route because ::buildForm has not yet been + // called. + $entity_type_id = $this->getRouteMatch()->getParameter('entity_type_id'); + return $entity_type_id . '_delete_multiple_confirm_form'; + } + + /** + * {@inheritdoc} + */ + public function getQuestion() { + return $this->formatPlural(count($this->selection), 'Are you sure you want to delete this @item?', 'Are you sure you want to delete these @items?', [ + '@item' => $this->entityType->getSingularLabel(), + '@items' => $this->entityType->getPluralLabel(), + ]); + } + + /** + * {@inheritdoc} + */ + public function getCancelUrl() { + if ($this->entityType->hasLinkTemplate('collection')) { + return new Url('entity.' . $this->entityTypeId . '.collection'); + } + else { + return new Url(''); + } + } + + /** + * {@inheritdoc} + */ + public function getConfirmText() { + return $this->t('Delete'); + } + + /** + * {@inheritdoc} + */ + public function buildForm(array $form, FormStateInterface $form_state, $entity_type_id = NULL) { + $this->entityTypeId = $entity_type_id; + $this->entityType = $this->entityTypeManager->getDefinition($this->entityTypeId); + $this->selection = $this->tempStore->get($this->currentUser->id() . ':' . $entity_type_id); + if (empty($this->entityTypeId) || empty($this->selection)) { + return new RedirectResponse($this->getCancelUrl() + ->setAbsolute() + ->toString()); + } + + $items = []; + $entities = $this->entityTypeManager->getStorage($entity_type_id)->loadMultiple(array_keys($this->selection)); + foreach ($this->selection as $id => $selected_langcodes) { + $entity = $entities[$id]; + foreach ($selected_langcodes as $langcode) { + $key = $id . ':' . $langcode; + if ($entity instanceof TranslatableInterface) { + $entity = $entity->getTranslation($langcode); + $default_key = $id . ':' . $entity->getUntranslated()->language()->getId(); + + // Build a nested list of translations that will be deleted if the + // entity has multiple translations. + $entity_languages = $entity->getTranslationLanguages(); + if (count($entity_languages) > 1 && $entity->isDefaultTranslation()) { + $names = []; + foreach ($entity_languages as $translation_langcode => $language) { + $names[] = $language->getName(); + unset($items[$id . ':' . $translation_langcode]); + } + $items[$default_key] = [ + 'label' => [ + '#markup' => $this->t('@label (Original translation) - The following @entity_type translations will be deleted:', + [ + '@label' => $entity->label(), + '@entity_type' => $this->entityType->getSingularLabel(), + ]), + ], + 'deleted_translations' => [ + '#theme' => 'item_list', + '#items' => $names, + ], + ]; + } + elseif (!isset($items[$default_key])) { + $items[$key] = $entity->label(); + } + } + elseif (!isset($items[$key])) { + $items[$key] = $entity->label(); + } + } + } + + $form['entities'] = [ + '#theme' => 'item_list', + '#items' => $items, + ]; + $form = parent::buildForm($form, $form_state); + + return $form; + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, FormStateInterface $form_state) { + $total_count = 0; + $delete_entities = []; + $delete_translations = []; + $inaccessible_entities = []; + $storage = $this->entityTypeManager->getStorage($this->entityTypeId); + + $entities = $storage->loadMultiple(array_keys($this->selection)); + foreach ($this->selection as $id => $selected_langcodes) { + $entity = $entities[$id]; + if (!$entity->access('delete', $this->currentUser)) { + $inaccessible_entities[] = $entity; + continue; + } + foreach ($selected_langcodes as $langcode) { + if ($entity instanceof TranslatableInterface) { + $entity = $entity->getTranslation($langcode); + // If the entity is the default translation then deleting it will + // delete all the translations. + if ($entity->isDefaultTranslation()) { + $delete_entities[$id] = $entity; + // If there are translations already marked for deletion then remove + // them as they will be deleted anyway. + unset($delete_translations[$id]); + // Update the total count. Since a single delete will delete all + // translations, we need to add the number of translations to the + // count. + $total_count += count($entity->getTranslationLanguages()); + } + // Add the translation to the list of translations to be deleted + // unless the default translation is being deleted. + elseif (!isset($delete_entities[$id])) { + $delete_translations[$id][] = $entity; + } + } + elseif (!isset($delete_entities[$id])) { + $delete_entities[$id] = $entity; + $total_count++; + } + } + } + + if ($delete_entities) { + $storage->delete($delete_entities); + foreach ($delete_entities as $entity) { + $this->logger($entity->getEntityType()->getProvider())->notice('The @entity-type %label has been deleted.', [ + '@entity-type' => $entity->getEntityType()->getLowercaseLabel(), + '%label' => $entity->label(), + ]); + } + } + + if ($delete_translations) { + /** @var \Drupal\Core\Entity\TranslatableInterface[][] $delete_translations */ + foreach ($delete_translations as $id => $translations) { + $entity = $entities[$id]->getUntranslated(); + foreach ($translations as $translation) { + $entity->removeTranslation($translation->language()->getId()); + } + $entity->save(); + foreach ($translations as $translation) { + $this->logger($entity->getEntityType()->getProvider())->notice('The @entity-type %label @language translation has been deleted.', [ + '@entity-type' => $entity->getEntityType()->getLowercaseLabel(), + '%label' => $entity->label(), + '@language' => $translation->language()->getName(), + ]); + } + $total_count += count($translations); + } + } + + if ($total_count) { + $this->messenger->addStatus($this->getDeletedMessage($total_count)); + } + if ($inaccessible_entities) { + $this->messenger->addWarning($this->getInaccessibleMessage(count($inaccessible_entities))); + } + $this->tempStore->delete($this->currentUser->id()); + $form_state->setRedirectUrl($this->getCancelUrl()); + } + + /** + * Returns the message to show the user after an item was deleted. + * + * @param int $count + * Count of deleted translations. + * + * @return \Drupal\Core\StringTranslation\TranslatableMarkup + * The item deleted message. + */ + protected function getDeletedMessage($count) { + return $this->formatPlural($count, 'Deleted @count item.', 'Deleted @count items.'); + } + + /** + * Returns the message to show the user when an item has not been deleted. + * + * @param int $count + * Count of deleted translations. + * + * @return \Drupal\Core\StringTranslation\TranslatableMarkup + * The item inaccessible message. + */ + protected function getInaccessibleMessage($count) { + return $this->formatPlural($count, "@count item has not been deleted because you do not have the necessary permissions.", "@count items have not been deleted because you do not have the necessary permissions."); + } + +} diff --git a/sites/all/modules/contrib/dev/entity/src/Form/RevisionableContentEntityForm.php b/sites/all/modules/contrib/dev/entity/src/Form/RevisionableContentEntityForm.php deleted file mode 100644 index d4a1b35b3..000000000 --- a/sites/all/modules/contrib/dev/entity/src/Form/RevisionableContentEntityForm.php +++ /dev/null @@ -1,159 +0,0 @@ -getBundleEntity(); - - // Set up default values, if required. - if (!$this->entity->isNew()) { - $this->entity->setRevisionLogMessage(NULL); - } - - if ($bundle_entity instanceof RevisionableEntityBundleInterface) { - // Always use the default revision setting. - $this->entity->setNewRevision($bundle_entity && $bundle_entity->shouldCreateNewRevision()); - } - } - - /** - * Returns the bundle entity of the entity, or NULL if there is none. - * - * @return \Drupal\Core\Entity\EntityInterface|null - */ - protected function getBundleEntity() { - if ($bundle_key = $this->entity->getEntityType()->getKey('bundle')) { - return $this->entity->{$bundle_key}->referencedEntities()[0]; - } - return NULL; - } - - /** - * {@inheritdoc} - */ - public function form(array $form, FormStateInterface $form_state) { - $entity_type = $this->entity->getEntityType(); - $bundle_entity = $this->getBundleEntity(); - $account = $this->currentUser(); - - if ($this->operation == 'edit') { - $form['#title'] = $this->t('Edit %bundle_label @label', [ - '%bundle_label' => $bundle_entity ? $bundle_entity->label() : '', - '@label' => $this->entity->label(), - ]); - } - - $form['advanced'] = [ - '#type' => 'vertical_tabs', - '#weight' => 99, - ]; - - // Add a log field if the "Create new revision" option is checked, or if the - // current user has the ability to check that option. - // @todo Could we autogenerate this form by using some widget on the - // revision info field. - $form['revision_information'] = [ - '#type' => 'details', - '#title' => $this->t('Revision information'), - // Open by default when "Create new revision" is checked. - '#open' => $this->entity->isNewRevision(), - '#group' => 'advanced', - '#weight' => 20, - '#access' => $this->entity->isNewRevision() || $account->hasPermission($entity_type->get('admin_permission')), - ]; - - $form['revision_information']['revision'] = [ - '#type' => 'checkbox', - '#title' => $this->t('Create new revision'), - '#default_value' => $this->entity->isNewRevision(), - '#access' => $account->hasPermission($entity_type->get('admin_permission')), - ]; - - // Check the revision log checkbox when the log textarea is filled in. - // This must not happen if "Create new revision" is enabled by default, - // since the state would auto-disable the checkbox otherwise. - if (!$this->entity->isNewRevision()) { - $form['revision_information']['revision']['#states'] = [ - 'checked' => [ - 'textarea[name="revision_log"]' => ['empty' => FALSE], - ], - ]; - } - - $form['revision_information']['revision_log'] = [ - '#type' => 'textarea', - '#title' => $this->t('Revision log message'), - '#rows' => 4, - '#default_value' => $this->entity->getRevisionLogMessage(), - '#description' => $this->t('Briefly describe the changes you have made.'), - ]; - - return parent::form($form, $form_state); - } - - /** - * {@inheritdoc} - */ - public function save(array $form, FormStateInterface $form_state) { - // Save as a new revision if requested to do so. - if (!$form_state->isValueEmpty('revision')) { - $this->entity->setNewRevision(); - } - - $insert = $this->entity->isNew(); - $this->entity->save(); - $context = ['@type' => $this->entity->bundle(), '%info' => $this->entity->label()]; - $logger = $this->logger('content'); - $bundle_entity = $this->getBundleEntity(); - $t_args = ['@type' => $bundle_entity ? $bundle_entity->label() : 'None', '%info' => $this->entity->label()]; - - if ($insert) { - $logger->notice('@type: added %info.', $context); - drupal_set_message($this->t('@type %info has been created.', $t_args)); - } - else { - $logger->notice('@type: updated %info.', $context); - drupal_set_message($this->t('@type %info has been updated.', $t_args)); - } - - if ($this->entity->id()) { - $form_state->setValue('id', $this->entity->id()); - $form_state->set('id', $this->entity->id()); - - if ($this->entity->getEntityType()->hasLinkTemplate('collection')) { - $form_state->setRedirectUrl($this->entity->toUrl('collection')); - } - else { - $form_state->setRedirectUrl($this->entity->toUrl('canonical')); - } - } - else { - // In the unlikely case something went wrong on save, the entity will be - // rebuilt and entity form redisplayed. - drupal_set_message($this->t('The entity could not be saved.'), 'error'); - $form_state->setRebuild(); - } - } - -} diff --git a/sites/all/modules/contrib/dev/entity/src/Menu/EntityAddLocalAction.php b/sites/all/modules/contrib/dev/entity/src/Menu/EntityAddLocalAction.php new file mode 100644 index 000000000..8b7a04e7a --- /dev/null +++ b/sites/all/modules/contrib/dev/entity/src/Menu/EntityAddLocalAction.php @@ -0,0 +1,81 @@ +entityType = $entity_type; + $this->setStringTranslation($string_translation); + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + /* @var \Drupal\Core\Entity\EntityTypeManagerInterface */ + $entity_type_manager = $container->get('entity_type.manager'); + // The plugin ID is of the form + // "entity.entity_actions:entity.$entity_type_id.collection". + // @see entity.links.action.yml + // @see \Drupal\entity\Menu\EntityCollectionLocalActionProvider::buildLocalActions() + list(, $derivate_id) = explode(':', $plugin_id); + list(, $entity_type_id, ) = explode('.', $derivate_id); + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('router.route_provider'), + $entity_type_manager->getDefinition($entity_type_id), + $container->get('string_translation') + ); + } + + /** + * {@inheritdoc} + */ + public function getTitle(Request $request = NULL) { + return (string) $this->t('Add @entity', [ + '@entity' => (string) $this->entityType->getSingularLabel(), + ]); + } + +} diff --git a/sites/all/modules/contrib/dev/entity/src/Menu/EntityCollectionLocalActionProvider.php b/sites/all/modules/contrib/dev/entity/src/Menu/EntityCollectionLocalActionProvider.php new file mode 100644 index 000000000..b0103709d --- /dev/null +++ b/sites/all/modules/contrib/dev/entity/src/Menu/EntityCollectionLocalActionProvider.php @@ -0,0 +1,41 @@ +hasLinkTemplate('collection')) { + $entity_type_id = $entity_type->id(); + + if ($entity_type->hasLinkTemplate('add-page')) { + $route_name = "entity.$entity_type_id.add_page"; + } + elseif ($entity_type->hasLinkTemplate('add-form')) { + $route_name = "entity.$entity_type_id.add_form"; + } + + if (isset($route_name)) { + $actions[$route_name] = [ + // The title is translated at runtime by EntityAddLocalAction. + /* @see \Drupal\entity\Menu\EntityAddLocalAction::getTitle() */ + 'title' => 'Add ' . $entity_type->getSingularLabel(), + 'route_name' => $route_name, + 'appears_on' => ["entity.$entity_type_id.collection"], + 'class' => EntityAddLocalAction::class, + ]; + } + } + return $actions; + } + +} diff --git a/sites/all/modules/contrib/dev/entity/src/Menu/EntityLocalActionProviderInterface.php b/sites/all/modules/contrib/dev/entity/src/Menu/EntityLocalActionProviderInterface.php new file mode 100644 index 000000000..bba16c328 --- /dev/null +++ b/sites/all/modules/contrib/dev/entity/src/Menu/EntityLocalActionProviderInterface.php @@ -0,0 +1,23 @@ +get('user.private_tempstore'), + $container->get('tempstore.private'), $container->get('current_user') ); } @@ -71,13 +71,13 @@ class DeleteAction extends ActionBase implements ContainerFactoryPluginInterface * {@inheritdoc} */ public function executeMultiple(array $entities) { - /** @var \Drupal\Core\Entity\ContentEntityInterface[] $entities */ + /** @var \Drupal\Core\Entity\EntityInterface[] $entities */ $selection = []; foreach ($entities as $entity) { $langcode = $entity->language()->getId(); $selection[$entity->id()][$langcode] = $langcode; } - $this->tempStore->set($this->currentUser->id(), $selection); + $this->tempStore->set($this->currentUser->id() . ':' . $this->getPluginDefinition()['type'], $selection); } /** diff --git a/sites/all/modules/contrib/dev/entity/src/Plugin/Action/Derivative/DeleteActionDeriver.php b/sites/all/modules/contrib/dev/entity/src/Plugin/Action/Derivative/DeleteActionDeriver.php index d4eec7d2f..1f7d76b8d 100644 --- a/sites/all/modules/contrib/dev/entity/src/Plugin/Action/Derivative/DeleteActionDeriver.php +++ b/sites/all/modules/contrib/dev/entity/src/Plugin/Action/Derivative/DeleteActionDeriver.php @@ -46,7 +46,7 @@ class DeleteActionDeriver extends DeriverBase implements ContainerDeriverInterfa $definitions = []; foreach ($this->getParticipatingEntityTypes() as $entity_type_id => $entity_type) { $definition = $base_plugin_definition; - $definition['label'] = t('Delete @entity_type', ['@entity_type' => $entity_type->getLowercaseLabel()]); + $definition['label'] = t('Delete @entity_type', ['@entity_type' => $entity_type->getSingularLabel()]); $definition['type'] = $entity_type_id; $definition['confirm_form_route_name'] = 'entity.' . $entity_type_id . '.delete_multiple_form'; $definitions[$entity_type_id] = $definition; diff --git a/sites/all/modules/contrib/dev/entity/src/Plugin/Derivative/EntityActionsDeriver.php b/sites/all/modules/contrib/dev/entity/src/Plugin/Derivative/EntityActionsDeriver.php new file mode 100644 index 000000000..568ad7e87 --- /dev/null +++ b/sites/all/modules/contrib/dev/entity/src/Plugin/Derivative/EntityActionsDeriver.php @@ -0,0 +1,58 @@ +entityTypeManager = $entity_type_manager; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, $base_plugin_id) { + return new static($container->get('entity_type.manager')); + } + + /** + * {@inheritdoc} + */ + public function getDerivativeDefinitions($base_plugin_definition) { + if (!$this->derivatives) { + foreach ($this->entityTypeManager->getDefinitions() as $entity_type_id => $entity_type) { + $handlers = $entity_type->getHandlerClasses(); + if (isset($handlers['local_action_provider'])) { + foreach ($handlers['local_action_provider'] as $class) { + /** @var \Drupal\entity\Menu\EntityLocalActionProviderInterface $handler */ + $handler = $this->entityTypeManager->createHandlerInstance($class, $entity_type); + $this->derivatives += $handler->buildLocalActions($entity_type); + } + } + } + } + return $this->derivatives; + } + +} diff --git a/sites/all/modules/contrib/dev/entity/src/Revision/RevisionableContentEntityBase.php b/sites/all/modules/contrib/dev/entity/src/Revision/RevisionableContentEntityBase.php index 856c6def2..f6dc11cb3 100644 --- a/sites/all/modules/contrib/dev/entity/src/Revision/RevisionableContentEntityBase.php +++ b/sites/all/modules/contrib/dev/entity/src/Revision/RevisionableContentEntityBase.php @@ -13,12 +13,8 @@ abstract class RevisionableContentEntityBase extends BaseRevisionableContentEnti * {@inheritdoc} */ protected function urlRouteParameters($rel) { - $uri_route_parameters = []; + $uri_route_parameters = parent::urlRouteParameters($rel); - if ($rel != 'collection') { - // The entity ID is needed as a route parameter. - $uri_route_parameters[$this->getEntityTypeId()] = $this->id(); - } if (strpos($this->getEntityType()->getLinkTemplate($rel), $this->getEntityTypeId() . '_revision') !== FALSE) { $uri_route_parameters[$this->getEntityTypeId() . '_revision'] = $this->getRevisionId(); } diff --git a/sites/all/modules/contrib/dev/entity/src/Routing/AdminHtmlRouteProvider.php b/sites/all/modules/contrib/dev/entity/src/Routing/AdminHtmlRouteProvider.php new file mode 100644 index 000000000..7ef2f6e18 --- /dev/null +++ b/sites/all/modules/contrib/dev/entity/src/Routing/AdminHtmlRouteProvider.php @@ -0,0 +1,26 @@ +hasHandlerClass('permission_provider')) { + $admin_permission = $entity_type->getAdminPermission(); + $overview_permission = "access {$entity_type->id()} overview"; + $route->setRequirement('_permission', "$admin_permission+$overview_permission"); + } + return $route; + } + +} diff --git a/sites/all/modules/contrib/dev/entity/src/Routing/DefaultHtmlRouteProvider.php b/sites/all/modules/contrib/dev/entity/src/Routing/DefaultHtmlRouteProvider.php new file mode 100644 index 000000000..06a350400 --- /dev/null +++ b/sites/all/modules/contrib/dev/entity/src/Routing/DefaultHtmlRouteProvider.php @@ -0,0 +1,26 @@ +hasHandlerClass('permission_provider')) { + $admin_permission = $entity_type->getAdminPermission(); + $overview_permission = "access {$entity_type->id()} overview"; + $route->setRequirement('_permission', "$admin_permission+$overview_permission"); + } + return $route; + } + +} diff --git a/sites/all/modules/contrib/dev/entity/src/Routing/DeleteMultipleRouteProvider.php b/sites/all/modules/contrib/dev/entity/src/Routing/DeleteMultipleRouteProvider.php index a9ca06e79..b8dced03f 100644 --- a/sites/all/modules/contrib/dev/entity/src/Routing/DeleteMultipleRouteProvider.php +++ b/sites/all/modules/contrib/dev/entity/src/Routing/DeleteMultipleRouteProvider.php @@ -36,9 +36,9 @@ class DeleteMultipleRouteProvider implements EntityRouteProviderInterface { protected function deleteMultipleFormRoute(EntityTypeInterface $entity_type) { if ($entity_type->hasLinkTemplate('delete-multiple-form')) { $route = new Route($entity_type->getLinkTemplate('delete-multiple-form')); - $route->setDefault('_form', '\Drupal\entity\Form\DeleteMultiple'); + $route->setDefault('_form', '\Drupal\entity\Form\DeleteMultipleForm'); $route->setDefault('entity_type_id', $entity_type->id()); - $route->setRequirement('_permission', $entity_type->getAdminPermission()); + $route->setRequirement('_entity_delete_multiple_access', $entity_type->id()); return $route; } diff --git a/sites/all/modules/contrib/dev/entity/src/UncacheableEntityPermissionProvider.php b/sites/all/modules/contrib/dev/entity/src/UncacheableEntityPermissionProvider.php index 9cac04238..4d105c0ae 100644 --- a/sites/all/modules/contrib/dev/entity/src/UncacheableEntityPermissionProvider.php +++ b/sites/all/modules/contrib/dev/entity/src/UncacheableEntityPermissionProvider.php @@ -2,13 +2,8 @@ namespace Drupal\entity; -use Drupal\Core\Entity\EntityHandlerInterface; -use Drupal\Core\Entity\EntityPublishedInterface; -use Drupal\Core\Entity\EntityTypeBundleInfoInterface; use Drupal\Core\Entity\EntityTypeInterface; -use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\user\EntityOwnerInterface; -use Symfony\Component\DependencyInjection\ContainerInterface; /** * Provides generic entity permissions which are cached per user. @@ -25,7 +20,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface; * - create $bundle $entity_type * * As this class supports "view own ($bundle) $entity_type" it is just cacheable - * per user, which might harm performance of sites. Given that please use + * per user, which might harm performance of sites. Given that please use * \Drupal\entity\EntityPermissionProvider unless you need the feature, or your * entity type is not really user facing (commerce orders for example). * diff --git a/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_bundle_plugin_examples_test/entity_module_bundle_plugin_examples_test.info.yml b/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_bundle_plugin_examples_test/entity_module_bundle_plugin_examples_test.info.yml index 0881d7115..30a86e39b 100644 --- a/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_bundle_plugin_examples_test/entity_module_bundle_plugin_examples_test.info.yml +++ b/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_bundle_plugin_examples_test/entity_module_bundle_plugin_examples_test.info.yml @@ -6,8 +6,8 @@ package: Testing dependencies: - entity -# Information added by Drupal.org packaging script on 2017-09-20 -version: '8.x-1.0-beta1' +# Information added by Drupal.org packaging script on 2018-03-12 +version: '8.x-1.0-beta2' core: '8.x' project: 'entity' -datestamp: 1505895847 +datestamp: 1520873296 diff --git a/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_bundle_plugin_test/entity_module_bundle_plugin_test.info.yml b/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_bundle_plugin_test/entity_module_bundle_plugin_test.info.yml index 3888bb799..5beb85c6a 100644 --- a/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_bundle_plugin_test/entity_module_bundle_plugin_test.info.yml +++ b/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_bundle_plugin_test/entity_module_bundle_plugin_test.info.yml @@ -6,8 +6,8 @@ package: Testing dependencies: - entity -# Information added by Drupal.org packaging script on 2017-09-20 -version: '8.x-1.0-beta1' +# Information added by Drupal.org packaging script on 2018-03-12 +version: '8.x-1.0-beta2' core: '8.x' project: 'entity' -datestamp: 1505895847 +datestamp: 1520873296 diff --git a/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_test/entity_module_test.info.yml b/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_test/entity_module_test.info.yml index c246fa55f..bb830cff3 100644 --- a/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_test/entity_module_test.info.yml +++ b/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_test/entity_module_test.info.yml @@ -3,8 +3,8 @@ type: module package: Testing # core: 8.x -# Information added by Drupal.org packaging script on 2017-09-20 -version: '8.x-1.0-beta1' +# Information added by Drupal.org packaging script on 2018-03-12 +version: '8.x-1.0-beta2' core: '8.x' project: 'entity' -datestamp: 1505895847 +datestamp: 1520873296 diff --git a/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_test/entity_module_test.routing.yml b/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_test/entity_module_test.routing.yml deleted file mode 100644 index 3724a6524..000000000 --- a/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_test/entity_module_test.routing.yml +++ /dev/null @@ -1,7 +0,0 @@ -entity.entity_test_enhanced.collection: - path: '/entity_test_enhanced' - defaults: - _entity_list: 'entity_test_enhanced' - _title: 'Entity test with enhancements' - requirements: - _permission: 'administer entity_test_enhanced' diff --git a/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_test/src/Entity/EnhancedEntity.php b/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_test/src/Entity/EnhancedEntity.php index 51e074b30..c5df7d2d5 100644 --- a/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_test/src/Entity/EnhancedEntity.php +++ b/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_test/src/Entity/EnhancedEntity.php @@ -11,21 +11,31 @@ use Drupal\entity\Revision\RevisionableContentEntityBase; * * @ContentEntityType( * id = "entity_test_enhanced", - * label = @Translation("Entity test with enhancements"), + * label = @Translation("Enhanced entity"), + * label_collection = @Translation("Enhanced entities"), + * label_singular = @Translation("enhanced entity"), + * label_plural = @Translation("enhanced entities"), + * label_count = @PluralTranslation( + * singular = "@count enhanced entity", + * plural = "@count enhanced entities", + * ), * handlers = { * "storage" = "\Drupal\Core\Entity\Sql\SqlContentEntityStorage", * "access" = "\Drupal\Core\Entity\EntityAccessControlHandler", * "permission_provider" = "\Drupal\entity\EntityPermissionProvider", * "form" = { - * "add" = "\Drupal\entity\Form\RevisionableContentEntityForm", - * "edit" = "\Drupal\entity\Form\RevisionableContentEntityForm", + * "add" = "\Drupal\Core\Entity\ContentEntityForm", + * "edit" = "\Drupal\Core\Entity\ContentEntityForm", * "delete" = "\Drupal\Core\Entity\EntityDeleteForm", * }, * "route_provider" = { - * "html" = "\Drupal\Core\Entity\Routing\DefaultHtmlRouteProvider", + * "html" = "\Drupal\entity\Routing\DefaultHtmlRouteProvider", * "revision" = "\Drupal\entity\Routing\RevisionRouteProvider", * "delete-multiple" = "\Drupal\entity\Routing\DeleteMultipleRouteProvider", * }, + * "local_action_provider" = { + * "collection" = "\Drupal\entity\Menu\EntityCollectionLocalActionProvider", + * }, * "list_builder" = "\Drupal\Core\Entity\EntityListBuilder", * }, * base_table = "entity_test_enhanced", diff --git a/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_test/src/Entity/EnhancedEntityBundle.php b/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_test/src/Entity/EnhancedEntityBundle.php index 43780746d..48524a828 100644 --- a/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_test/src/Entity/EnhancedEntityBundle.php +++ b/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_test/src/Entity/EnhancedEntityBundle.php @@ -4,7 +4,7 @@ namespace Drupal\entity_module_test\Entity; use Drupal\Core\Config\Entity\ConfigEntityBundleBase; use Drupal\Core\Entity\EntityDescriptionInterface; -use Drupal\entity\Entity\RevisionableEntityBundleInterface; +use Drupal\Core\Entity\RevisionableEntityBundleInterface; /** * Provides bundles for the test entity. diff --git a/sites/all/modules/contrib/dev/entity/tests/src/Functional/CollectionRouteAccessTest.php b/sites/all/modules/contrib/dev/entity/tests/src/Functional/CollectionRouteAccessTest.php new file mode 100644 index 000000000..5160ed402 --- /dev/null +++ b/sites/all/modules/contrib/dev/entity/tests/src/Functional/CollectionRouteAccessTest.php @@ -0,0 +1,77 @@ + 'default', + 'label' => 'Default', + ])->save(); + + $this->placeBlock('local_tasks_block'); + $this->placeBlock('system_breadcrumb_block'); + } + + /** + * Test the collection route access. + */ + public function testCollectionRouteAccess() { + $entity = EnhancedEntity::create([ + 'name' => 'rev 1', + 'type' => 'default', + ]); + $entity->save(); + + // User without any relevant permissions. + $account = $this->drupalCreateUser(['access administration pages']); + $this->drupalLogin($account); + + $this->drupalGet($entity->toUrl('collection')); + $this->assertSession()->statusCodeEquals(403); + + // User with "access overview" permissions. + $account = $this->drupalCreateUser(['access entity_test_enhanced overview']); + $this->drupalLogin($account); + + $this->drupalGet($entity->toUrl('collection')); + $this->assertSession()->statusCodeEquals(200); + + // User with full administration permissions. + $account = $this->drupalCreateUser(['administer entity_test_enhanced']); + $this->drupalLogin($account); + + $this->drupalGet($entity->toUrl('collection')); + $this->assertSession()->statusCodeEquals(200); + } + +} diff --git a/sites/all/modules/contrib/dev/entity/tests/src/Functional/DeleteMultipleFormTest.php b/sites/all/modules/contrib/dev/entity/tests/src/Functional/DeleteMultipleFormTest.php index 21661a47a..1dc6931c6 100644 --- a/sites/all/modules/contrib/dev/entity/tests/src/Functional/DeleteMultipleFormTest.php +++ b/sites/all/modules/contrib/dev/entity/tests/src/Functional/DeleteMultipleFormTest.php @@ -18,7 +18,7 @@ class DeleteMultipleFormTest extends BrowserTestBase { /** * The current user. * - * @var \Drupal\Core\Session\AccountInterface; + * @var \Drupal\Core\Session\AccountInterface */ protected $account; @@ -60,13 +60,13 @@ class DeleteMultipleFormTest extends BrowserTestBase { $selection[$entity->id()][$langcode] = $langcode; } // Add the selection to the tempstore just like DeleteAction would. - $tempstore = \Drupal::service('user.private_tempstore')->get('entity_delete_multiple_confirm'); - $tempstore->set($this->account->id(), $selection); + $tempstore = \Drupal::service('tempstore.private')->get('entity_delete_multiple_confirm'); + $tempstore->set($this->account->id() . ':entity_test_enhanced', $selection); $this->drupalGet('/entity_test_enhanced/delete'); $assert = $this->assertSession(); $assert->statusCodeEquals(200); - $assert->elementTextContains('css', '.page-title', 'Are you sure you want to delete these items?'); + $assert->elementTextContains('css', '.page-title', 'Are you sure you want to delete these enhanced entities?'); $delete_button = $this->getSession()->getPage()->findButton('Delete'); $delete_button->click(); $assert = $this->assertSession(); diff --git a/sites/all/modules/contrib/dev/entity/tests/src/Functional/Menu/EntityLocalActionTest.php b/sites/all/modules/contrib/dev/entity/tests/src/Functional/Menu/EntityLocalActionTest.php new file mode 100644 index 000000000..4fb4faabe --- /dev/null +++ b/sites/all/modules/contrib/dev/entity/tests/src/Functional/Menu/EntityLocalActionTest.php @@ -0,0 +1,44 @@ +drupalPlaceBlock('local_actions_block'); + + $account = $this->drupalCreateUser(['administer entity_test_enhanced']); + $this->drupalLogin($account); + } + + /** + * Tests the local action on the collection is provided correctly. + */ + public function testCollectionLocalAction() { + $this->drupalGet('/entity_test_enhanced'); + $this->assertSession()->linkByHrefExists('/entity_test_enhanced/add'); + $this->assertSession()->linkExists('Add enhanced entity'); + } + +} diff --git a/sites/all/modules/contrib/dev/entity/tests/src/Functional/RevisionRouteAccessTest.php b/sites/all/modules/contrib/dev/entity/tests/src/Functional/RevisionRouteAccessTest.php index 8eddca491..f3c205a20 100644 --- a/sites/all/modules/contrib/dev/entity/tests/src/Functional/RevisionRouteAccessTest.php +++ b/sites/all/modules/contrib/dev/entity/tests/src/Functional/RevisionRouteAccessTest.php @@ -4,7 +4,7 @@ namespace Drupal\Tests\entity\Functional; use Drupal\entity_module_test\Entity\EnhancedEntity; use Drupal\entity_module_test\Entity\EnhancedEntityBundle; -use Drupal\simpletest\BlockCreationTrait; +use Drupal\Tests\block\Traits\BlockCreationTrait; use Drupal\Tests\BrowserTestBase; /** @@ -75,7 +75,7 @@ class RevisionRouteAccessTest extends BrowserTestBase { $this->drupalGet('/entity_test_enhanced/1/revisions'); $this->assertSession()->statusCodeEquals(200); $this->assertSession()->responseContains('Revisions'); - $collection_link = $this->getSession()->getPage()->findLink('Entity test with enhancements'); + $collection_link = $this->getSession()->getPage()->findLink('Enhanced entities'); $collection_link->click(); $this->assertSession()->addressEquals('/entity_test_enhanced'); $this->assertSession()->responseContains('Edit'); diff --git a/sites/all/modules/contrib/dev/entity/tests/src/Kernel/DeleteActionTest.php b/sites/all/modules/contrib/dev/entity/tests/src/Kernel/DeleteActionTest.php index 140473f91..68680f09d 100644 --- a/sites/all/modules/contrib/dev/entity/tests/src/Kernel/DeleteActionTest.php +++ b/sites/all/modules/contrib/dev/entity/tests/src/Kernel/DeleteActionTest.php @@ -74,8 +74,8 @@ class DeleteActionTest extends KernelTestBase { $action->execute($entities); // Confirm that the entity ids and langcodes are now in the tempstore. - $tempstore = \Drupal::service('user.private_tempstore')->get('entity_delete_multiple_confirm'); - $selection = $tempstore->get($this->user->id()); + $tempstore = \Drupal::service('tempstore.private')->get('entity_delete_multiple_confirm'); + $selection = $tempstore->get($this->user->id() . ':entity_test_enhanced'); $this->assertEquals(array_keys($entities), array_keys($selection)); $this->assertEquals([['en' => 'en'], ['en' => 'en']], array_values($selection)); } diff --git a/sites/all/modules/contrib/migrate/migrate_plus/migrate_example/README.txt b/sites/all/modules/contrib/migrate/migrate_plus/migrate_example/README.txt index 32d77da99..431e22e9b 100644 --- a/sites/all/modules/contrib/migrate/migrate_plus/migrate_example/README.txt +++ b/sites/all/modules/contrib/migrate/migrate_plus/migrate_example/README.txt @@ -65,7 +65,7 @@ read the files in the following order: 5. BeerUser.php 6. migrate_plus.migration.beer_node.yml 7. BeerNode.php -8. migrate_plus.migration.beer_comment.yml +8. beer_comment.yml 9. BeerComment.php RUNNING THE MIGRATIONS diff --git a/sites/all/modules/contrib/migrate/migrate_plus/migrate_example/migrate_example.info.yml b/sites/all/modules/contrib/migrate/migrate_plus/migrate_example/migrate_example.info.yml index 1b0520212..bd446988f 100644 --- a/sites/all/modules/contrib/migrate/migrate_plus/migrate_example/migrate_example.info.yml +++ b/sites/all/modules/contrib/migrate/migrate_plus/migrate_example/migrate_example.info.yml @@ -10,8 +10,8 @@ dependencies: - drupal:menu_ui - drupal:path -# Information added by Drupal.org packaging script on 2017-12-12 -version: '8.x-4.0-beta2' +# Information added by Drupal.org packaging script on 2018-02-23 +version: '8.x-4.0-beta3' core: '8.x' project: 'migrate_plus' -datestamp: 1513088305 +datestamp: 1519400598 diff --git a/sites/all/modules/contrib/migrate/migrate_plus/migrate_example/migrate_example_setup/migrate_example_setup.info.yml b/sites/all/modules/contrib/migrate/migrate_plus/migrate_example/migrate_example_setup/migrate_example_setup.info.yml index 41a2ebf24..ab36c1e3d 100644 --- a/sites/all/modules/contrib/migrate/migrate_plus/migrate_example/migrate_example_setup/migrate_example_setup.info.yml +++ b/sites/all/modules/contrib/migrate/migrate_plus/migrate_example/migrate_example_setup/migrate_example_setup.info.yml @@ -11,8 +11,8 @@ dependencies: - drupal:options - drupal:taxonomy -# Information added by Drupal.org packaging script on 2017-12-12 -version: '8.x-4.0-beta2' +# Information added by Drupal.org packaging script on 2018-02-23 +version: '8.x-4.0-beta3' core: '8.x' project: 'migrate_plus' -datestamp: 1513088305 +datestamp: 1519400598 diff --git a/sites/all/modules/contrib/migrate/migrate_plus/migrate_example/migrate_example_setup/migrate_example_setup.install b/sites/all/modules/contrib/migrate/migrate_plus/migrate_example/migrate_example_setup/migrate_example_setup.install index 0241c1dc0..342bc2dcf 100644 --- a/sites/all/modules/contrib/migrate/migrate_plus/migrate_example/migrate_example_setup/migrate_example_setup.install +++ b/sites/all/modules/contrib/migrate/migrate_plus/migrate_example/migrate_example_setup/migrate_example_setup.install @@ -2,11 +2,16 @@ /** * @file + * Install file for migrate example module. + * * Set up source data and destination configuration for the migration example * module. We do this in a separate module so migrate_example itself is a pure * migration module. */ +/** + * Implements hook_schema(). + */ function migrate_example_setup_schema() { $schema['migrate_example_beer_account'] = migrate_example_beer_schema_account(); $schema['migrate_example_beer_node'] = migrate_example_beer_schema_node(); @@ -17,6 +22,9 @@ function migrate_example_setup_schema() { return $schema; } +/** + * Implements hook_install(). + */ function migrate_example_setup_install() { // Populate our tables. migrate_example_beer_data_account(); @@ -26,6 +34,12 @@ function migrate_example_setup_install() { migrate_example_beer_data_topic_node(); } +/** + * The hook_schema definition for node. + * + * @return array + * The schema definition. + */ function migrate_example_beer_schema_node() { return [ 'description' => 'Beers of the world.', @@ -92,6 +106,12 @@ function migrate_example_beer_schema_node() { ]; } +/** + * The hook_schema definition for topic. + * + * @return array + * The schema definition. + */ function migrate_example_beer_schema_topic() { return [ 'description' => 'Categories', @@ -129,6 +149,12 @@ function migrate_example_beer_schema_topic() { ]; } +/** + * The hook_schema definition for topic node. + * + * @return array + * The schema definition. + */ function migrate_example_beer_schema_topic_node() { return [ 'description' => 'Beers topic pairs.', @@ -149,6 +175,12 @@ function migrate_example_beer_schema_topic_node() { ]; } +/** + * The hook_schema definition for comment. + * + * @return array + * The schema definition. + */ function migrate_example_beer_schema_comment() { return [ 'description' => 'Beers comments.', @@ -202,6 +234,12 @@ function migrate_example_beer_schema_comment() { ]; } +/** + * The hook_schema definition for account. + * + * @return array + * The schema definition. + */ function migrate_example_beer_schema_account() { return [ 'description' => 'Beers accounts.', @@ -262,16 +300,63 @@ function migrate_example_beer_schema_account() { ]; } +/** + * Populate node table. + */ function migrate_example_beer_data_node() { - $fields = ['bid', 'name', 'body', 'excerpt', 'countries', 'aid', 'image', - 'image_alt', 'image_title', 'image_description']; + $fields = [ + 'bid', + 'name', + 'body', + 'excerpt', + 'countries', + 'aid', + 'image', + 'image_alt', + 'image_title', + 'image_description', + ]; $query = db_insert('migrate_example_beer_node') ->fields($fields); // Use high bid numbers to avoid overwriting an existing node id. $data = [ - [99999999, 'Heineken', 'Blab Blah Blah Green', 'Green', 'Netherlands|Belgium', 0, 'heineken.jpg', 'Heinekin alt', 'Heinekin title', 'Heinekin description'], // comes with migrate_example project. - [99999998, 'Miller Lite', 'We love Miller Brewing', 'Tasteless', 'USA|Canada', 1, NULL, NULL, NULL, NULL], - [99999997, 'Boddington', 'English occasionally get something right', 'A treat', 'United Kingdom', 1, NULL, NULL, NULL, NULL], + // Comes with migrate_example project. + [ + 99999999, + 'Heineken', + 'Blab Blah Blah Green', + 'Green', + 'Netherlands|Belgium', + 0, + 'heineken.jpg', + 'Heinekin alt', + 'Heinekin title', + 'Heinekin description', + ], + [ + 99999998, + 'Miller Lite', + 'We love Miller Brewing', + 'Tasteless', + 'USA|Canada', + 1, + NULL, + NULL, + NULL, + NULL, + ], + [ + 99999997, + 'Boddington', + 'English occasionally get something right', + 'A treat', + 'United Kingdom', + 1, + NULL, + NULL, + NULL, + NULL, + ], ]; foreach ($data as $row) { $query->values(array_combine($fields, $row)); @@ -280,18 +365,65 @@ function migrate_example_beer_data_node() { } /** + * Populate account table. + * * Note that alice has duplicate username. Exercises dedupe_entity plugin. - *@TODO duplicate email also. + * TODO duplicate email also. */ function migrate_example_beer_data_account() { - $fields = ['status', 'registered', 'username', 'nickname', 'password', 'email', 'sex', 'beers']; + $fields = [ + 'status', + 'registered', + 'username', + 'nickname', + 'password', + 'email', + 'sex', + 'beers', + ]; $query = db_insert('migrate_example_beer_account') ->fields($fields); $data = [ - [1, '2010-03-30 10:31:05', 'alice', 'alice in beerland', 'alicepass', 'alice@example.com', '1', '99999999|99999998|99999997'], - [1, '2010-04-04 10:31:05', 'alice', 'alice in aleland', 'alicepass', 'alice2@example.com', '1', '99999999|99999998|99999997'], - [0, '2007-03-15 10:31:05', 'bob', 'rebob', 'bobpass', 'bob@example.com', '0', '99999999|99999997'], - [1, '2004-02-29 10:31:05', 'charlie', 'charlie chocolate', 'mykids', 'charlie@example.com', '0', '99999999|99999998'], + [ + 1, + '2010-03-30 10:31:05', + 'alice', + 'alice in beerland', + 'alicepass', + 'alice@example.com', + '1', + '99999999|99999998|99999997', + ], + [ + 1, + '2010-04-04 10:31:05', + 'alice', + 'alice in aleland', + 'alicepass', + 'alice2@example.com', + '1', + '99999999|99999998|99999997', + ], + [ + 0, + '2007-03-15 10:31:05', + 'bob', + 'rebob', + 'bobpass', + 'bob@example.com', + '0', + '99999999|99999997', + ], + [ + 1, + '2004-02-29 10:31:05', + 'charlie', + 'charlie chocolate', + 'mykids', + 'charlie@example.com', + '0', + '99999999|99999998', + ], ]; foreach ($data as $row) { $query->values(array_combine($fields, $row)); @@ -299,6 +431,9 @@ function migrate_example_beer_data_account() { $query->execute(); } +/** + * Populate comment table. + */ function migrate_example_beer_data_comment() { $fields = ['bid', 'cid_parent', 'subject', 'body', 'name', 'mail', 'aid']; $query = db_insert('migrate_example_beer_comment') @@ -308,7 +443,15 @@ function migrate_example_beer_data_comment() { [99999998, NULL, 'im second', 'aromatic', 'alice', 'alice@example.com', 0], [99999999, NULL, 'im parent', 'malty', 'alice', 'alice@example.com', 0], [99999999, 1, 'im child', 'cold body', 'bob', NULL, 1], - [99999999, 4, 'im grandchild', 'bitter body', 'charlie@example.com', NULL, 1], + [ + 99999999, + 4, + 'im grandchild', + 'bitter body', + 'charlie@example.com', + NULL, + 1, + ], ]; foreach ($data as $row) { $query->values(array_combine($fields, $row)); @@ -316,6 +459,9 @@ function migrate_example_beer_data_comment() { $query->execute(); } +/** + * Populate topic table. + */ function migrate_example_beer_data_topic() { $fields = ['style', 'details', 'style_parent', 'region', 'hoppiness']; $query = db_insert('migrate_example_beer_topic') @@ -323,7 +469,13 @@ function migrate_example_beer_data_topic() { $data = [ ['ale', 'traditional', NULL, 'Medieval British Isles', 'Medium'], ['red ale', 'colorful', 'ale', NULL, NULL], - ['pilsner', 'refreshing', NULL, 'Pilsen, Bohemia (now Czech Republic)', 'Low'], + [ + 'pilsner', + 'refreshing', + NULL, + 'Pilsen, Bohemia (now Czech Republic)', + 'Low', + ], ]; foreach ($data as $row) { $query->values(array_combine($fields, $row)); @@ -331,6 +483,9 @@ function migrate_example_beer_data_topic() { $query->execute(); } +/** + * Populate topic node table. + */ function migrate_example_beer_data_topic_node() { $fields = ['bid', 'style']; $query = db_insert('migrate_example_beer_topic_node') diff --git a/sites/all/modules/contrib/migrate/migrate_plus/migrate_example/src/Plugin/migrate/source/BeerComment.php b/sites/all/modules/contrib/migrate/migrate_plus/migrate_example/src/Plugin/migrate/source/BeerComment.php index 361cdd1ac..b5d446a3f 100644 --- a/sites/all/modules/contrib/migrate/migrate_plus/migrate_example/src/Plugin/migrate/source/BeerComment.php +++ b/sites/all/modules/contrib/migrate/migrate_plus/migrate_example/src/Plugin/migrate/source/BeerComment.php @@ -17,9 +17,18 @@ class BeerComment extends SqlBase { * {@inheritdoc} */ public function query() { + $fields = [ + 'cid', + 'cid_parent', + 'name', + 'mail', + 'aid', + 'body', + 'bid', + 'subject', + ]; $query = $this->select('migrate_example_beer_comment', 'mec') - ->fields('mec', ['cid', 'cid_parent', 'name', 'mail', 'aid', - 'body', 'bid', 'subject']) + ->fields('mec', $fields) ->orderBy('cid_parent', 'ASC'); return $query; } diff --git a/sites/all/modules/contrib/migrate/migrate_plus/migrate_example/src/Plugin/migrate/source/BeerNode.php b/sites/all/modules/contrib/migrate/migrate_plus/migrate_example/src/Plugin/migrate/source/BeerNode.php index b3c117e39..40ac4df29 100644 --- a/sites/all/modules/contrib/migrate/migrate_plus/migrate_example/src/Plugin/migrate/source/BeerNode.php +++ b/sites/all/modules/contrib/migrate/migrate_plus/migrate_example/src/Plugin/migrate/source/BeerNode.php @@ -18,21 +18,29 @@ class BeerNode extends SqlBase { * {@inheritdoc} */ public function query() { - /** - * An important point to note is that your query *must* return a single row - * for each item to be imported. Here we might be tempted to add a join to - * migrate_example_beer_topic_node in our query, to pull in the - * relationships to our categories. Doing this would cause the query to - * return multiple rows for a given node, once per related value, thus - * processing the same node multiple times, each time with only one of the - * multiple values that should be imported. To avoid that, we simply query - * the base node data here, and pull in the relationships in prepareRow() - * below. - */ + // An important point to note is that your query *must* return a single row + // for each item to be imported. Here we might be tempted to add a join to + // migrate_example_beer_topic_node in our query, to pull in the + // relationships to our categories. Doing this would cause the query to + // return multiple rows for a given node, once per related value, thus + // processing the same node multiple times, each time with only one of the + // multiple values that should be imported. To avoid that, we simply query + // the base node data here, and pull in the relationships in prepareRow() + // below. + $fields = [ + 'bid', + 'name', + 'body', + 'excerpt', + 'aid', + 'countries', + 'image', + 'image_alt', + 'image_title', + 'image_description', + ]; $query = $this->select('migrate_example_beer_node', 'b') - ->fields('b', ['bid', 'name', 'body', 'excerpt', 'aid', - 'countries', 'image', 'image_alt', 'image_title', - 'image_description']); + ->fields('b', $fields); return $query; } @@ -76,11 +84,9 @@ class BeerNode extends SqlBase { * {@inheritdoc} */ public function prepareRow(Row $row) { - /** - * As explained above, we need to pull the style relationships into our - * source row here, as an array of 'style' values (the unique ID for - * the beer_term migration). - */ + // As explained above, we need to pull the style relationships into our + // source row here, as an array of 'style' values (the unique ID for + // the beer_term migration). $terms = $this->select('migrate_example_beer_topic_node', 'bt') ->fields('bt', ['style']) ->condition('bid', $row->getSourceProperty('bid')) diff --git a/sites/all/modules/contrib/migrate/migrate_plus/migrate_example/src/Plugin/migrate/source/BeerTerm.php b/sites/all/modules/contrib/migrate/migrate_plus/migrate_example/src/Plugin/migrate/source/BeerTerm.php index c03fa1521..5eb3e70f3 100644 --- a/sites/all/modules/contrib/migrate/migrate_plus/migrate_example/src/Plugin/migrate/source/BeerTerm.php +++ b/sites/all/modules/contrib/migrate/migrate_plus/migrate_example/src/Plugin/migrate/source/BeerTerm.php @@ -5,11 +5,12 @@ namespace Drupal\migrate_example\Plugin\migrate\source; use Drupal\migrate\Plugin\migrate\source\SqlBase; /** - * This is an example of a simple SQL-based source plugin. Source plugins are - * classes which deliver source data to the processing pipeline. For SQL - * sources, the SqlBase class provides most of the functionality needed - for - * a specific migration, you are required to implement the three simple public - * methods you see below. + * This is an example of a simple SQL-based source plugin. + * + * Source plugins are classes which deliver source data to the processing + * pipeline. For SQL sources, the SqlBase class provides most of the + * functionality needed - for a specific migration, you are required to + * implement the three simple public methods you see below. * * This annotation tells Drupal that the name of the MigrateSource plugin * implemented by this class is "beer_term". This is the name that the migration @@ -25,16 +26,15 @@ class BeerTerm extends SqlBase { * {@inheritdoc} */ public function query() { - /** - * The most important part of a SQL source plugin is the SQL query to - * retrieve the data to be imported. Note that the query is not executed - * here - the migration process will control execution of the query. Also - * note that it is constructed from a $this->select() call - this ensures - * that the query is executed against the database configured for this - * source plugin. - */ + // The most important part of a SQL source plugin is the SQL query to + // retrieve the data to be imported. Note that the query is not executed + // here - the migration process will control execution of the query. Also + // note that it is constructed from a $this->select() call - this ensures + // that the query is executed against the database configured for this + // source plugin. + $fields = ['style', 'details', 'style_parent', 'region', 'hoppiness']; return $this->select('migrate_example_beer_topic', 'met') - ->fields('met', ['style', 'details', 'style_parent', 'region', 'hoppiness']) + ->fields('met', $fields) // We sort this way to ensure parent terms are imported first. ->orderBy('style_parent', 'ASC'); } @@ -43,12 +43,10 @@ class BeerTerm extends SqlBase { * {@inheritdoc} */ public function fields() { - /** - * This method simply documents the available source fields provided by - * the source plugin, for use by front-end tools. It returns an array keyed - * by field/column name, with the value being a translated string explaining - * to humans what the field represents. You should always - */ + // This method simply documents the available source fields provided by the + // source plugin, for use by front-end tools. It returns an array keyed by + // field/column name, with the value being a translated string explaining + // to humans what the field represents. $fields = [ 'style' => $this->t('Beer style'), 'details' => $this->t('Style details'), @@ -66,14 +64,12 @@ class BeerTerm extends SqlBase { * {@inheritdoc} */ public function getIds() { - /** - * This method indicates what field(s) from the source row uniquely identify - * that source row, and what their types are. This is critical information - * for managing the migration. The keys of the returned array are the field - * names from the query which comprise the unique identifier. The values are - * arrays indicating the type of the field, used for creating compatible - * columns in the map tables that track processed items. - */ + // This method indicates what field(s) from the source row uniquely identify + // that source row, and what their types are. This is critical information + // for managing the migration. The keys of the returned array are the field + // names from the query which comprise the unique identifier. The values are + // arrays indicating the type of the field, used for creating compatible + // columns in the map tables that track processed items. return [ 'style' => [ 'type' => 'string', diff --git a/sites/all/modules/contrib/migrate/migrate_plus/migrate_example/src/Plugin/migrate/source/BeerUser.php b/sites/all/modules/contrib/migrate/migrate_plus/migrate_example/src/Plugin/migrate/source/BeerUser.php index b0d963d3f..398f87c69 100644 --- a/sites/all/modules/contrib/migrate/migrate_plus/migrate_example/src/Plugin/migrate/source/BeerUser.php +++ b/sites/all/modules/contrib/migrate/migrate_plus/migrate_example/src/Plugin/migrate/source/BeerUser.php @@ -18,9 +18,19 @@ class BeerUser extends SqlBase { * {@inheritdoc} */ public function query() { + $fields = [ + 'aid', + 'status', + 'registered', + 'username', + 'nickname', + 'password', + 'email', + 'sex', + 'beers', + ]; return $this->select('migrate_example_beer_account', 'mea') - ->fields('mea', ['aid', 'status', 'registered', 'username', 'nickname', - 'password', 'email', 'sex', 'beers']); + ->fields('mea', $fields); } /** @@ -58,27 +68,22 @@ class BeerUser extends SqlBase { * {@inheritdoc} */ public function prepareRow(Row $row) { - /** - * prepareRow() is the most common place to perform custom run-time - * processing that isn't handled by an existing process plugin. It is called - * when the raw data has been pulled from the source, and provides the - * opportunity to modify or add to that data, creating the canonical set of - * source data that will be fed into the processing pipeline. - * - * In our particular case, the list of a user's favorite beers is a pipe- - * separated list of beer IDs. The processing pipeline deals with arrays - * representing multi-value fields naturally, so we want to explode that - * string to an array of individual beer IDs. - */ + // A prepareRow() is the most common place to perform custom run-time + // processing that isn't handled by an existing process plugin. It is called + // when the raw data has been pulled from the source, and provides the + // opportunity to modify or add to that data, creating the canonical set of + // source data that will be fed into the processing pipeline. + // In our particular case, the list of a user's favorite beers is a pipe- + // separated list of beer IDs. The processing pipeline deals with arrays + // representing multi-value fields naturally, so we want to explode that + // string to an array of individual beer IDs. if ($value = $row->getSourceProperty('beers')) { $row->setSourceProperty('beers', explode('|', $value)); } - /** - * Always call your parent! Essential processing is performed in the base - * class. Be mindful that prepareRow() returns a boolean status - if FALSE - * that indicates that the item being processed should be skipped. Unless - * we're deciding to skip an item ourselves, let the parent class decide. - */ + // Always call your parent! Essential processing is performed in the base + // class. Be mindful that prepareRow() returns a boolean status - if FALSE + // that indicates that the item being processed should be skipped. Unless + // we're deciding to skip an item ourselves, let the parent class decide. return parent::prepareRow($row); } diff --git a/sites/all/modules/contrib/migrate/migrate_plus/migrate_example_advanced/migrate_example_advanced.info.yml b/sites/all/modules/contrib/migrate/migrate_plus/migrate_example_advanced/migrate_example_advanced.info.yml index f2ecc93f4..b0226fb3e 100644 --- a/sites/all/modules/contrib/migrate/migrate_plus/migrate_example_advanced/migrate_example_advanced.info.yml +++ b/sites/all/modules/contrib/migrate/migrate_plus/migrate_example_advanced/migrate_example_advanced.info.yml @@ -8,8 +8,8 @@ dependencies: - migrate_plus:migrate_example_advanced_setup - migrate_plus:migrate_plus -# Information added by Drupal.org packaging script on 2017-12-12 -version: '8.x-4.0-beta2' +# Information added by Drupal.org packaging script on 2018-02-23 +version: '8.x-4.0-beta3' core: '8.x' project: 'migrate_plus' -datestamp: 1513088305 +datestamp: 1519400598 diff --git a/sites/all/modules/contrib/migrate/migrate_plus/migrate_example_advanced/migrate_example_advanced.install b/sites/all/modules/contrib/migrate/migrate_plus/migrate_example_advanced/migrate_example_advanced.install index b2506e4a9..fa931770c 100644 --- a/sites/all/modules/contrib/migrate/migrate_plus/migrate_example_advanced/migrate_example_advanced.install +++ b/sites/all/modules/contrib/migrate/migrate_plus/migrate_example_advanced/migrate_example_advanced.install @@ -2,20 +2,20 @@ /** * @file - * Install, update and uninstall functions for the migrate_example_advanced module. + * Install, update and uninstall functions for migrate_example_advanced module. */ use Drupal\migrate_plus\Entity\Migration; /** * Implements hook_install(). + * + * We need the urls to be absolute for the XML source plugin to read them, but + * the static configuration files on disk can't know the server and port to + * use. So, in the .yml files we provide the REST resources relative to the + * site root and here rewrite them to fully-qualified paths. */ function migrate_example_advanced_install() { - // We need the urls to be absolute for the XML source plugin to read them, but - // the static configuration files on disk can't know the server and port to - // use. So, in the .yml files we provide the REST resources relative to the - // site root and here rewrite them to fully-qualified paths. - /** @var \Drupal\migrate_plus\Entity\MigrationInterface $wine_role_xml_migration */ $wine_role_xml_migration = Migration::load('wine_role_xml'); if ($wine_role_xml_migration) { diff --git a/sites/all/modules/contrib/migrate/migrate_plus/migrate_example_advanced/migrate_example_advanced_setup/migrate_example_advanced_setup.info.yml b/sites/all/modules/contrib/migrate/migrate_plus/migrate_example_advanced/migrate_example_advanced_setup/migrate_example_advanced_setup.info.yml index 7a4d6692d..8913482e0 100644 --- a/sites/all/modules/contrib/migrate/migrate_plus/migrate_example_advanced/migrate_example_advanced_setup/migrate_example_advanced_setup.info.yml +++ b/sites/all/modules/contrib/migrate/migrate_plus/migrate_example_advanced/migrate_example_advanced_setup/migrate_example_advanced_setup.info.yml @@ -11,8 +11,8 @@ dependencies: - drupal:taxonomy - drupal:rest -# Information added by Drupal.org packaging script on 2017-12-12 -version: '8.x-4.0-beta2' +# Information added by Drupal.org packaging script on 2018-02-23 +version: '8.x-4.0-beta3' core: '8.x' project: 'migrate_plus' -datestamp: 1513088305 +datestamp: 1519400598 diff --git a/sites/all/modules/contrib/migrate/migrate_plus/migrate_example_advanced/migrate_example_advanced_setup/migrate_example_advanced_setup.install b/sites/all/modules/contrib/migrate/migrate_plus/migrate_example_advanced/migrate_example_advanced_setup/migrate_example_advanced_setup.install index 98f77d872..be9031a6b 100644 --- a/sites/all/modules/contrib/migrate/migrate_plus/migrate_example_advanced/migrate_example_advanced_setup/migrate_example_advanced_setup.install +++ b/sites/all/modules/contrib/migrate/migrate_plus/migrate_example_advanced/migrate_example_advanced_setup/migrate_example_advanced_setup.install @@ -55,6 +55,12 @@ function migrate_example_advanced_setup_install() { migrate_example_advanced_data_table_source(); } +/** + * The hook_schema definition for wine. + * + * @return array + * The schema definition. + */ function migrate_example_advanced_schema_wine() { return [ 'description' => 'Wines of the world', @@ -123,6 +129,12 @@ function migrate_example_advanced_schema_wine() { ]; } +/** + * The hook_schema definition for updates. + * + * @return array + * The schema definition. + */ function migrate_example_advanced_schema_updates() { return [ 'description' => 'Updated wine ratings', @@ -144,6 +156,12 @@ function migrate_example_advanced_schema_updates() { ]; } +/** + * The hook_schema definition for producer. + * + * @return array + * The schema definition. + */ function migrate_example_advanced_schema_producer() { return [ 'description' => 'Wine producers of the world', @@ -182,6 +200,12 @@ function migrate_example_advanced_schema_producer() { ]; } +/** + * The hook_schema definition for categories. + * + * @return array + * The schema definition. + */ function migrate_example_advanced_schema_categories() { return [ 'description' => 'Categories', @@ -225,6 +249,12 @@ function migrate_example_advanced_schema_categories() { ]; } +/** + * The hook_schema definition for vintages. + * + * @return array + * The schema definition. + */ function migrate_example_advanced_schema_vintages() { return [ 'description' => 'Wine vintages', @@ -245,6 +275,12 @@ function migrate_example_advanced_schema_vintages() { ]; } +/** + * The hook_schema definition for variety updates. + * + * @return array + * The schema definition. + */ function migrate_example_advanced_schema_variety_updates() { return [ 'description' => 'Variety updates', @@ -265,6 +301,12 @@ function migrate_example_advanced_schema_variety_updates() { ]; } +/** + * The hook_schema definition for category wine. + * + * @return array + * The schema definition. + */ function migrate_example_advanced_schema_category_wine() { return [ 'description' => 'Wine category assignments', @@ -285,6 +327,12 @@ function migrate_example_advanced_schema_category_wine() { ]; } +/** + * The hook_schema definition for category producer. + * + * @return array + * The schema definition. + */ function migrate_example_advanced_schema_category_producer() { return [ 'description' => 'Producer category assignments', @@ -305,6 +353,12 @@ function migrate_example_advanced_schema_category_producer() { ]; } +/** + * The hook_schema definition for comment. + * + * @return array + * The schema definition. + */ function migrate_example_advanced_schema_comment() { return [ 'description' => 'Wine comments', @@ -386,6 +440,12 @@ function migrate_example_advanced_schema_comment() { ]; } +/** + * The hook_schema definition for comment updates. + * + * @return array + * The schema definition. + */ function migrate_example_advanced_schema_comment_updates() { return [ 'description' => 'Wine comment updates', @@ -407,6 +467,12 @@ function migrate_example_advanced_schema_comment_updates() { ]; } +/** + * The hook_schema definition for account. + * + * @return array + * The schema definition. + */ function migrate_example_advanced_schema_account() { return [ 'description' => 'Wine accounts.', @@ -492,6 +558,12 @@ function migrate_example_advanced_schema_account() { ]; } +/** + * The hook_schema definition for account updates. + * + * @return array + * The schema definition. + */ function migrate_example_advanced_schema_account_updates() { return [ 'description' => 'Wine account updates', @@ -512,6 +584,12 @@ function migrate_example_advanced_schema_account_updates() { ]; } +/** + * The hook_schema definition for blobs. + * + * @return array + * The schema definition. + */ function migrate_example_advanced_schema_blobs() { return [ 'description' => 'Wine blobs to be migrated to file entities', @@ -532,6 +610,12 @@ function migrate_example_advanced_schema_blobs() { ]; } +/** + * The hook_schema definition for files. + * + * @return array + * The schema definition. + */ function migrate_example_advanced_schema_files() { return [ 'description' => 'Wine and account files', @@ -571,6 +655,12 @@ function migrate_example_advanced_schema_files() { ]; } +/** + * The hook_schema definition for table source. + * + * @return array + * The schema definition. + */ function migrate_example_advanced_schema_table_source() { return [ 'description' => 'Source data to go into a custom Drupal table', @@ -598,6 +688,12 @@ function migrate_example_advanced_schema_table_source() { ]; } +/** + * The hook_schema definition for table destination. + * + * @return array + * The schema definition. + */ function migrate_example_advanced_schema_table_dest() { return [ 'description' => 'Custom Drupal table to receive source data directly', @@ -625,16 +721,49 @@ function migrate_example_advanced_schema_table_dest() { ]; } +/** + * Populate wine table. + */ function migrate_example_advanced_data_wine() { - $fields = ['wineid', 'name', 'body', 'excerpt', 'accountid', - 'posted', 'last_changed', 'variety', 'region', 'rating']; + $fields = [ + 'wineid', + 'name', + 'body', + 'excerpt', + 'accountid', + 'posted', + 'last_changed', + 'variety', + 'region', + 'rating', + ]; $query = db_insert('migrate_example_wine') ->fields($fields); $data = [ - [1, 'Montes Classic Cabernet Sauvignon', 'Intense ruby-red color', 'Great!', 9, - strtotime('2010-01-02 03:04:05'), strtotime('2010-03-04 05:06:07'), 25, 17, 95], - [2, 'Archeo Ruggero di Tasso Nero d\'Avola', 'Lots of berry character', 'Pair with red sauced dishes', 3, - strtotime('2010-09-03 18:23:58'), strtotime('2010-09-03 18:23:58'), 26, 2, 85], + [ + 1, + 'Montes Classic Cabernet Sauvignon', + 'Intense ruby-red color', + 'Great!', + 9, + strtotime('2010-01-02 03:04:05'), + strtotime('2010-03-04 05:06:07'), + 25, + 17, + 95, + ], + [ + 2, + 'Archeo Ruggero di Tasso Nero d\'Avola', + 'Lots of berry character', + 'Pair with red sauced dishes', + 3, + strtotime('2010-09-03 18:23:58'), + strtotime('2010-09-03 18:23:58'), + 26, + 2, + 85, + ], ]; foreach ($data as $row) { $query->values(array_combine($fields, $row)); @@ -642,6 +771,9 @@ function migrate_example_advanced_data_wine() { $query->execute(); } +/** + * Populate updates table. + */ function migrate_example_advanced_data_updates() { $fields = ['wineid', 'rating']; $query = db_insert('migrate_example_advanced_updates') @@ -656,6 +788,9 @@ function migrate_example_advanced_data_updates() { $query->execute(); } +/** + * Populate producer table. + */ function migrate_example_advanced_data_producer() { $fields = ['producerid', 'name', 'body', 'excerpt', 'accountid']; $query = db_insert('migrate_example_advanced_producer') @@ -670,21 +805,73 @@ function migrate_example_advanced_data_producer() { $query->execute(); } +/** + * Populate account table. + */ function migrate_example_advanced_data_account() { - $fields = ['accountid', 'status', 'posted', 'last_access', 'last_login', - 'name', 'sex', 'password', 'mail', 'original_mail', 'sig', 'imageid', 'positions']; + $fields = [ + 'accountid', + 'status', + 'posted', + 'last_access', + 'last_login', + 'name', + 'sex', + 'password', + 'mail', + 'original_mail', + 'sig', + 'imageid', + 'positions', + ]; $query = db_insert('migrate_example_advanced_account') ->fields($fields); $data = [ - [1, 1, '2010-03-30 10:31:05', '2010-04-30 18:25:24', '2010-04-30 14:01:02', - 'darren', 'M', 'dpass', 'ddarren@example.com', 'darren@example.com', - 'All about the Australians', NULL, '5'], - [3, 0, '2007-03-15 10:31:05', '2007-06-10 04:11:38', '2007-06-10 04:11:38', - 'emily', 'F', 'insecure', 'emily@example.com', 'emily@example.com', - 'Sommelier to the stars', NULL, '18'], - [9, 1, '2004-02-29 10:31:05', '2004-02-29 10:31:05', '2004-02-29 10:31:05', - 'fonzie', NULL, 'bike', 'thefonz@example.com', 'arthur@example.com', - 'Aaay!', 1, '5,18'], + [ + 1, + 1, + '2010-03-30 10:31:05', + '2010-04-30 18:25:24', + '2010-04-30 14:01:02', + 'darren', + 'M', + 'dpass', + 'ddarren@example.com', + 'darren@example.com', + 'All about the Australians', + NULL, + '5', + ], + [ + 3, + 0, + '2007-03-15 10:31:05', + '2007-06-10 04:11:38', + '2007-06-10 04:11:38', + 'emily', + 'F', + 'insecure', + 'emily@example.com', + 'emily@example.com', + 'Sommelier to the stars', + NULL, + '18', + ], + [ + 9, + 1, + '2004-02-29 10:31:05', + '2004-02-29 10:31:05', + '2004-02-29 10:31:05', + 'fonzie', + NULL, + 'bike', + 'thefonz@example.com', + 'arthur@example.com', + 'Aaay!', + 1, + '5,18', + ], ]; foreach ($data as $row) { $query->values(array_combine($fields, $row)); @@ -692,6 +879,9 @@ function migrate_example_advanced_data_account() { $query->execute(); } +/** + * Populate account updates table. + */ function migrate_example_advanced_data_account_updates() { $fields = ['accountid', 'sex']; $query = db_insert('migrate_example_advanced_account_updates') @@ -707,27 +897,97 @@ function migrate_example_advanced_data_account_updates() { $query->execute(); } +/** + * Populate comment table. + */ function migrate_example_advanced_data_comment() { - $fields = ['commentid', 'wineid', 'comment_parent', 'subject', 'body', - 'name', 'mail', 'accountid', 'commenthost', 'userpage', 'posted', 'lastchanged']; + $fields = [ + 'commentid', + 'wineid', + 'comment_parent', + 'subject', + 'body', + 'name', + 'mail', + 'accountid', + 'commenthost', + 'userpage', + 'posted', + 'lastchanged', + ]; $query = db_insert('migrate_example_advanced_comment') ->fields($fields); $data = [ - [1, 1, NULL, 'im first', 'Tasty', 'grace', 'grace@example.com', 0, - '123.456.78.9', 'http:://grace.example.com/', - strtotime('2010-01-02 03:04:05'), strtotime('2010-04-05 06:07:08')], - [2, 1, NULL, 'im second', 'Delicious', 'horace', 'horace@example.com', 0, - 'example.com', NULL, - strtotime('2010-02-02 03:04:05'), strtotime('2010-05-05 06:07:08')], - [3, 1, NULL, 'im parent', 'Don\'t care for it', 'irene', 'irene@example.com', 0, - '254.0.2.5', 'http:://www.example.com/irene', - strtotime('2010-03-02 03:04:05'), strtotime('2010-03-02 03:04:05')], - [4, 1, 3, 'im child', 'But it\'s so good!', 'emily', NULL, 3, - '58.29.126.1', 'http:://www.wine.com/', - strtotime('2010-01-02 03:04:05'), strtotime('2010-01-02 03:04:05')], - [5, 1, 4, 'im grandchild', 'Right on, Emily!', 'thefonz@example.com', NULL, 9, - '123.456.78.9', NULL, - strtotime('2010-06-02 03:04:05'), strtotime('2010-06-02 03:04:05')], + [ + 1, + 1, + NULL, + 'im first', + 'Tasty', + 'grace', + 'grace@example.com', + 0, + '123.456.78.9', + 'http:://grace.example.com/', + strtotime('2010-01-02 03:04:05'), + strtotime('2010-04-05 06:07:08'), + ], + [ + 2, + 1, + NULL, + 'im second', + 'Delicious', + 'horace', + 'horace@example.com', + 0, + 'example.com', + NULL, + strtotime('2010-02-02 03:04:05'), + strtotime('2010-05-05 06:07:08'), + ], + [ + 3, + 1, + NULL, + 'im parent', + 'Don\'t care for it', + 'irene', + 'irene@example.com', + 0, + '254.0.2.5', + 'http:://www.example.com/irene', + strtotime('2010-03-02 03:04:05'), + strtotime('2010-03-02 03:04:05'), + ], + [ + 4, + 1, + 3, + 'im child', + 'But it\'s so good!', + 'emily', + NULL, + 3, + '58.29.126.1', + 'http:://www.wine.com/', + strtotime('2010-01-02 03:04:05'), + strtotime('2010-01-02 03:04:05'), + ], + [ + 5, + 1, + 4, + 'im grandchild', + 'Right on, Emily!', + 'thefonz@example.com', + NULL, + 9, + '123.456.78.9', + NULL, + strtotime('2010-06-02 03:04:05'), + strtotime('2010-06-02 03:04:05'), + ], ]; foreach ($data as $row) { $query->values(array_combine($fields, $row)); @@ -735,6 +995,9 @@ function migrate_example_advanced_data_comment() { $query->execute(); } +/** + * Populate comment updates table. + */ function migrate_example_advanced_data_comment_updates() { $fields = ['commentid', 'subject']; $query = db_insert('migrate_example_advanced_comment_updates') @@ -752,13 +1015,37 @@ function migrate_example_advanced_data_comment_updates() { $query->execute(); } +/** + * Populate categories table. + */ function migrate_example_advanced_data_categories() { - $fields = ['categoryid', 'type', 'name', 'category_parent', 'details', 'ordering']; + $fields = [ + 'categoryid', + 'type', + 'name', + 'category_parent', + 'details', + 'ordering', + ]; $query = db_insert('migrate_example_advanced_categories') ->fields($fields); $data = [ - [1, 'variety', 'White wine', NULL, 'White wines are generally simpler and sweeter than red', 3], - [3, 'variety', 'Red wine', NULL, 'Red wines are generally more complex and "dry" than white', 1], + [ + 1, + 'variety', + 'White wine', + NULL, + 'White wines are generally simpler and sweeter than red', + 3, + ], + [ + 3, + 'variety', + 'Red wine', + NULL, + 'Red wines are generally more complex and "dry" than white', + 1, + ], [8, 'variety', 'Riesling', 1, 'Associated with Germany', 2], [9, 'variety', 'Chardonnay', 1, 'One of the most popular whites', 1], [13, 'variety', 'Merlot', 3, 'Very drinkable', 4], @@ -787,6 +1074,9 @@ function migrate_example_advanced_data_categories() { $query->execute(); } +/** + * Populate vintages table. + */ function migrate_example_advanced_data_vintages() { $fields = ['wineid', 'vintage']; $query = db_insert('migrate_example_advanced_vintages') @@ -802,6 +1092,9 @@ function migrate_example_advanced_data_vintages() { $query->execute(); } +/** + * Populate variety updates table. + */ function migrate_example_advanced_data_variety_updates() { $fields = ['categoryid', 'details']; $query = db_insert('migrate_example_advanced_variety_updates') @@ -822,6 +1115,9 @@ function migrate_example_advanced_data_variety_updates() { $query->execute(); } +/** + * Populate category wine table. + */ function migrate_example_advanced_data_category_wine() { $fields = ['wineid', 'categoryid']; $query = db_insert('migrate_example_advanced_category_wine') @@ -837,6 +1133,9 @@ function migrate_example_advanced_data_category_wine() { $query->execute(); } +/** + * Populate category producer table. + */ function migrate_example_advanced_data_category_producer() { $fields = ['producerid', 'categoryid']; $query = db_insert('migrate_example_advanced_category_producer') @@ -850,15 +1149,36 @@ function migrate_example_advanced_data_category_producer() { $query->execute(); } +/** + * Populate files table. + */ function migrate_example_advanced_data_files() { $fields = ['imageid', 'url', 'image_alt', 'image_title', 'wineid']; $query = db_insert('migrate_example_advanced_files') ->fields($fields); $data = [ - [1, 'http://placekitten.com/200/200', NULL, NULL, NULL], - [2, 'http://cyrve.com/files/penguin.jpeg', 'Penguin alt', 'Penguin title', 1], + [ + 1, + 'http://placekitten.com/200/200', + NULL, + NULL, + NULL, + ], + [ + 2, + 'http://cyrve.com/files/penguin.jpeg', + 'Penguin alt', + 'Penguin title', + 1, + ], [3, 'http://cyrve.com/files/rioja.jpeg', 'Rioja alt', 'Rioja title', 2], - [4, 'http://cyrve.com/files/boutisse_0.jpeg', 'Boutisse alt', 'Boutisse title', 2], + [ + 4, + 'http://cyrve.com/files/boutisse_0.jpeg', + 'Boutisse alt', + 'Boutisse title', + 2, + ], ]; foreach ($data as $row) { $query->values(array_combine($fields, $row)); @@ -866,6 +1186,9 @@ function migrate_example_advanced_data_files() { $query->execute(); } +/** + * Populate blobs table. + */ function migrate_example_advanced_data_blobs() { $blob = file_get_contents('core/misc/druplicon.png'); $fields = ['imageid', 'imageblob']; @@ -880,6 +1203,9 @@ function migrate_example_advanced_data_blobs() { $query->execute(); } +/** + * Populate table source table. + */ function migrate_example_advanced_data_table_source() { $fields = ['fooid', 'field1', 'field2']; $query = db_insert('migrate_example_advanced_table_source') diff --git a/sites/all/modules/contrib/migrate/migrate_plus/migrate_example_advanced/migrate_example_advanced_setup/src/Plugin/rest/resource/VarietyItems.php b/sites/all/modules/contrib/migrate/migrate_plus/migrate_example_advanced/migrate_example_advanced_setup/src/Plugin/rest/resource/VarietyItems.php index b3fafabaf..670134c34 100644 --- a/sites/all/modules/contrib/migrate/migrate_plus/migrate_example_advanced/migrate_example_advanced_setup/src/Plugin/rest/resource/VarietyItems.php +++ b/sites/all/modules/contrib/migrate/migrate_plus/migrate_example_advanced/migrate_example_advanced_setup/src/Plugin/rest/resource/VarietyItems.php @@ -31,22 +31,26 @@ class VarietyItems extends ResourceBase { $varieties = [ 'retsina' => [ 'name' => 'Retsina', - 'parent' => 1, // categoryid for 'white'. + // The categoryid for 'white'. + 'parent' => 1, 'details' => 'Greek', ], 'trebbiano' => [ 'name' => 'Trebbiano', - 'parent' => 1, // categoryid for 'white'. + // The categoryid for 'white'. + 'parent' => 1, 'details' => 'Italian', ], 'valpolicella' => [ 'name' => 'Valpolicella', - 'parent' => 3, // categoryid for 'red'. + // The categoryid for 'red'. + 'parent' => 3, 'details' => 'Italian Venoto region', ], 'bardolino' => [ 'name' => 'Bardolino', - 'parent' => 3, // categoryid for 'red'. + // The categoryid for 'red'. + 'parent' => 3, 'details' => 'Italian Venoto region', ], ]; diff --git a/sites/all/modules/contrib/migrate/migrate_plus/migrate_example_advanced/migrate_example_advanced_setup/src/Plugin/rest/resource/VarietyMultiFiles.php b/sites/all/modules/contrib/migrate/migrate_plus/migrate_example_advanced/migrate_example_advanced_setup/src/Plugin/rest/resource/VarietyMultiFiles.php index 6a44b923e..5db35b5ce 100644 --- a/sites/all/modules/contrib/migrate/migrate_plus/migrate_example_advanced/migrate_example_advanced_setup/src/Plugin/rest/resource/VarietyMultiFiles.php +++ b/sites/all/modules/contrib/migrate/migrate_plus/migrate_example_advanced/migrate_example_advanced_setup/src/Plugin/rest/resource/VarietyMultiFiles.php @@ -32,7 +32,8 @@ class VarietyMultiFiles extends ResourceBase { if (strtolower($type) != 'white') { $data['variety'][] = [ 'name' => 'Amarone', - 'parent' => 3, // categoryid for 'red'. + // The categoryid for 'red'. + 'parent' => 3, 'details' => 'Italian Venoto region', 'attributes' => [ 'rich', @@ -41,7 +42,8 @@ class VarietyMultiFiles extends ResourceBase { ]; $data['variety'][] = [ 'name' => 'Barbaresco', - 'parent' => 3, // categoryid for 'red'. + // The categoryid for 'red'. + 'parent' => 3, 'details' => 'Italian Piedmont region', 'attributes' => [ 'smoky', @@ -52,13 +54,15 @@ class VarietyMultiFiles extends ResourceBase { if (strtolower($type) != 'red') { $data['variety'][] = [ 'name' => 'Kir', - 'parent' => 1, // categoryid for 'white'. + // The categoryid for 'white'. + 'parent' => 1, 'details' => 'French Burgundy region', 'attributes' => [], ]; $data['variety'][] = [ 'name' => 'Pinot Grigio', - 'parent' => 1, // categoryid for 'white'. + // The categoryid for 'white'. + 'parent' => 1, 'details' => 'From the northeast of Italy', 'attributes' => [ 'fruity', diff --git a/sites/all/modules/contrib/migrate/migrate_plus/migrate_example_advanced/src/Plugin/migrate/source/WineTerm.php b/sites/all/modules/contrib/migrate/migrate_plus/migrate_example_advanced/src/Plugin/migrate/source/WineTerm.php index 4bc143fcd..3d3d235dd 100644 --- a/sites/all/modules/contrib/migrate/migrate_plus/migrate_example_advanced/src/Plugin/migrate/source/WineTerm.php +++ b/sites/all/modules/contrib/migrate/migrate_plus/migrate_example_advanced/src/Plugin/migrate/source/WineTerm.php @@ -5,8 +5,7 @@ namespace Drupal\migrate_example_advanced\Plugin\migrate\source; use Drupal\migrate\Plugin\migrate\source\SqlBase; /** - * A straight-forward SQL-based source plugin, to retrieve category data from - * the source database. + * A SQL-based source plugin, to retrieve category data from a source database. * * @MigrateSource( * id = "wine_term" @@ -18,8 +17,16 @@ class WineTerm extends SqlBase { * {@inheritdoc} */ public function query() { + $fields = [ + 'categoryid', + 'type', + 'name', + 'details', + 'category_parent', + 'ordering', + ]; return $this->select('migrate_example_advanced_categories', 'wc') - ->fields('wc', ['categoryid', 'type', 'name', 'details', 'category_parent', 'ordering']) + ->fields('wc', $fields) // This sort assures that parents are saved before children. ->orderBy('category_parent', 'ASC'); } diff --git a/sites/all/modules/contrib/migrate/migrate_plus/migrate_plus.info.yml b/sites/all/modules/contrib/migrate/migrate_plus/migrate_plus.info.yml index eb6c1e3b5..e63da44a9 100644 --- a/sites/all/modules/contrib/migrate/migrate_plus/migrate_plus.info.yml +++ b/sites/all/modules/contrib/migrate/migrate_plus/migrate_plus.info.yml @@ -6,8 +6,8 @@ package: Migration dependencies: - drupal:migrate (>=8.3) -# Information added by Drupal.org packaging script on 2017-12-12 -version: '8.x-4.0-beta2' +# Information added by Drupal.org packaging script on 2018-02-23 +version: '8.x-4.0-beta3' core: '8.x' project: 'migrate_plus' -datestamp: 1513088305 +datestamp: 1519400598 diff --git a/sites/all/modules/contrib/migrate/migrate_plus/phpcs.xml b/sites/all/modules/contrib/migrate/migrate_plus/phpcs.xml index 1ccfe7eb4..a18054efb 100644 --- a/sites/all/modules/contrib/migrate/migrate_plus/phpcs.xml +++ b/sites/all/modules/contrib/migrate/migrate_plus/phpcs.xml @@ -1,126 +1,207 @@ - - - PHP CodeSniffer configuration + + + Drupal 8 coding standards + . - + ./vendor/* - - - - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + - + + + + - + + + + + + + - + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + 0 + + + 0 + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + 0 + + + 0 + + + + + 0 + + + 0 + + + + 0 + + + 0 + + + + 0 + + + 0 + + + 0 + + + + + + + + 0 + + - + + + + + + + diff --git a/sites/all/modules/contrib/migrate/migrate_plus/src/Annotation/Authentication.php b/sites/all/modules/contrib/migrate/migrate_plus/src/Annotation/Authentication.php index 910adb04c..5b63e1af8 100644 --- a/sites/all/modules/contrib/migrate/migrate_plus/src/Annotation/Authentication.php +++ b/sites/all/modules/contrib/migrate/migrate_plus/src/Annotation/Authentication.php @@ -7,7 +7,7 @@ use Drupal\Component\Annotation\Plugin; /** * Defines an authentication annotation object. * - * Plugin Namespace: Plugin\migrate_plus\authentication + * Plugin namespace: Plugin\migrate_plus\authentication. * * @see \Drupal\migrate_plus\AuthenticationPluginBase * @see \Drupal\migrate_plus\AuthenticationPluginInterface diff --git a/sites/all/modules/contrib/migrate/migrate_plus/src/Annotation/DataFetcher.php b/sites/all/modules/contrib/migrate/migrate_plus/src/Annotation/DataFetcher.php index 5dba1df8b..5c6e24ccb 100644 --- a/sites/all/modules/contrib/migrate/migrate_plus/src/Annotation/DataFetcher.php +++ b/sites/all/modules/contrib/migrate/migrate_plus/src/Annotation/DataFetcher.php @@ -7,7 +7,7 @@ use Drupal\Component\Annotation\Plugin; /** * Defines a data fetcher annotation object. * - * Plugin Namespace: Plugin\migrate_plus\data_fetcher + * Plugin namespace: Plugin\migrate_plus\data_fetcher. * * @see \Drupal\migrate_plus\DataFetcherPluginBase * @see \Drupal\migrate_plus\DataFetcherPluginInterface diff --git a/sites/all/modules/contrib/migrate/migrate_plus/src/Annotation/DataParser.php b/sites/all/modules/contrib/migrate/migrate_plus/src/Annotation/DataParser.php index 6f9de0aec..6bc01e24a 100644 --- a/sites/all/modules/contrib/migrate/migrate_plus/src/Annotation/DataParser.php +++ b/sites/all/modules/contrib/migrate/migrate_plus/src/Annotation/DataParser.php @@ -7,7 +7,7 @@ use Drupal\Component\Annotation\Plugin; /** * Defines a data parser annotation object. * - * Plugin Namespace: Plugin\migrate_plus\data_parser + * Plugin namespace: Plugin\migrate_plus\data_parser. * * @see \Drupal\migrate_plus\DataParserPluginBase * @see \Drupal\migrate_plus\DataParserPluginInterface diff --git a/sites/all/modules/contrib/migrate/migrate_plus/src/AuthenticationPluginManager.php b/sites/all/modules/contrib/migrate/migrate_plus/src/AuthenticationPluginManager.php index 8907b9ebd..041094e4d 100644 --- a/sites/all/modules/contrib/migrate/migrate_plus/src/AuthenticationPluginManager.php +++ b/sites/all/modules/contrib/migrate/migrate_plus/src/AuthenticationPluginManager.php @@ -21,7 +21,7 @@ class AuthenticationPluginManager extends DefaultPluginManager { * * @param \Traversable $namespaces * An object that implements \Traversable which contains the root paths - * keyed by the corresponding namespace to look for plugin implementations, + * keyed by the corresponding namespace to look for plugin implementations. * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend * Cache backend instance to use. * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler diff --git a/sites/all/modules/contrib/migrate/migrate_plus/src/DataFetcherPluginInterface.php b/sites/all/modules/contrib/migrate/migrate_plus/src/DataFetcherPluginInterface.php index a64b47923..f35042fcf 100644 --- a/sites/all/modules/contrib/migrate/migrate_plus/src/DataFetcherPluginInterface.php +++ b/sites/all/modules/contrib/migrate/migrate_plus/src/DataFetcherPluginInterface.php @@ -15,7 +15,7 @@ interface DataFetcherPluginInterface { /** * Set the client headers. * - * @param $headers + * @param array $headers * An array of the headers to set on the HTTP request. */ public function setRequestHeaders(array $headers); @@ -28,7 +28,7 @@ interface DataFetcherPluginInterface { /** * Return content. * - * @param $url + * @param string $url * URL to retrieve from. * * @return string @@ -39,10 +39,11 @@ interface DataFetcherPluginInterface { /** * Return Http Response object for a given url. * - * @param $url + * @param string $url * URL to retrieve from. * * @return \Psr\Http\Message\ResponseInterface + * The HTTP response message. */ public function getResponse($url); diff --git a/sites/all/modules/contrib/migrate/migrate_plus/src/DataFetcherPluginManager.php b/sites/all/modules/contrib/migrate/migrate_plus/src/DataFetcherPluginManager.php index 9e9e238e7..941252ed7 100644 --- a/sites/all/modules/contrib/migrate/migrate_plus/src/DataFetcherPluginManager.php +++ b/sites/all/modules/contrib/migrate/migrate_plus/src/DataFetcherPluginManager.php @@ -21,7 +21,7 @@ class DataFetcherPluginManager extends DefaultPluginManager { * * @param \Traversable $namespaces * An object that implements \Traversable which contains the root paths - * keyed by the corresponding namespace to look for plugin implementations, + * keyed by the corresponding namespace to look for plugin implementations. * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend * Cache backend instance to use. * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler diff --git a/sites/all/modules/contrib/migrate/migrate_plus/src/DataParserPluginBase.php b/sites/all/modules/contrib/migrate/migrate_plus/src/DataParserPluginBase.php index a1e4c2dd3..c74c6c53a 100644 --- a/sites/all/modules/contrib/migrate/migrate_plus/src/DataParserPluginBase.php +++ b/sites/all/modules/contrib/migrate/migrate_plus/src/DataParserPluginBase.php @@ -127,7 +127,7 @@ abstract class DataParserPluginBase extends PluginBase implements DataParserPlug /** * Opens the specified URL. * - * @param $url + * @param string $url * URL to open. * * @return bool @@ -136,8 +136,9 @@ abstract class DataParserPluginBase extends PluginBase implements DataParserPlug abstract protected function openSourceUrl($url); /** - * Retrieves the next row of data from the open source URL, populating - * currentItem. + * Retrieves the next row of data. populating currentItem. + * + * Retrieves from the open source URL. */ abstract protected function fetchNextRow(); diff --git a/sites/all/modules/contrib/migrate/migrate_plus/src/DataParserPluginManager.php b/sites/all/modules/contrib/migrate/migrate_plus/src/DataParserPluginManager.php index b69cc148d..65d92b1b7 100644 --- a/sites/all/modules/contrib/migrate/migrate_plus/src/DataParserPluginManager.php +++ b/sites/all/modules/contrib/migrate/migrate_plus/src/DataParserPluginManager.php @@ -21,7 +21,7 @@ class DataParserPluginManager extends DefaultPluginManager { * * @param \Traversable $namespaces * An object that implements \Traversable which contains the root paths - * keyed by the corresponding namespace to look for plugin implementations, + * keyed by the corresponding namespace to look for plugin implementations. * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend * Cache backend instance to use. * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler diff --git a/sites/all/modules/contrib/migrate/migrate_plus/src/Event/MigrateEvents.php b/sites/all/modules/contrib/migrate/migrate_plus/src/Event/MigrateEvents.php index 90a2155b8..6ce44ee62 100644 --- a/sites/all/modules/contrib/migrate/migrate_plus/src/Event/MigrateEvents.php +++ b/sites/all/modules/contrib/migrate/migrate_plus/src/Event/MigrateEvents.php @@ -16,7 +16,8 @@ final class MigrateEvents { * has read the inital source data into a Row object. Typically, this would be * used to add data to the row, manipulate the data into a canonical form, or * signal by exception that the row should be skipped. The event listener - * method receives a \Drupal\migrate_plus\Event\MigratePrepareRowEvent instance. + * method receives a \Drupal\migrate_plus\Event\MigratePrepareRowEvent + * instance. * * @Event * diff --git a/sites/all/modules/contrib/migrate/migrate_plus/src/Plugin/migrate/destination/Table.php b/sites/all/modules/contrib/migrate/migrate_plus/src/Plugin/migrate/destination/Table.php index 4c6ee57c1..f04d9f66d 100755 --- a/sites/all/modules/contrib/migrate/migrate_plus/src/Plugin/migrate/destination/Table.php +++ b/sites/all/modules/contrib/migrate/migrate_plus/src/Plugin/migrate/destination/Table.php @@ -51,6 +51,20 @@ class Table extends DestinationBase implements ContainerFactoryPluginInterface { */ protected $dbConnection; + /** + * Constructs a new Table. + * + * @param array $configuration + * A configuration array containing information about the plugin instance. + * @param string $plugin_id + * The plugin_id for the plugin instance. + * @param mixed $plugin_definition + * The plugin implementation definition. + * @param \Drupal\migrate\Plugin\MigrationInterface $migration + * The migration. + * @param \Drupal\Core\Database\Connection $connection + * The database connection. + */ public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, Connection $connection) { parent::__construct($configuration, $plugin_id, $plugin_definition, $migration); $this->dbConnection = $connection; diff --git a/sites/all/modules/contrib/migrate/migrate_plus/src/Plugin/migrate/process/ArrayPop.php b/sites/all/modules/contrib/migrate/migrate_plus/src/Plugin/migrate/process/ArrayPop.php new file mode 100644 index 000000000..d4749caff --- /dev/null +++ b/sites/all/modules/contrib/migrate/migrate_plus/src/Plugin/migrate/process/ArrayPop.php @@ -0,0 +1,44 @@ +lookupValueKey) || empty($this->lookupBundleKey) || empty($this->lookupBundle) || empty($this->lookupEntityType)) { - // See if we can introspect the lookup properties from the destination field. + // See if we can introspect the lookup properties from destination field. if (!empty($this->migration->getProcess()[$this->destinationBundleKey][0]['default_value'])) { $destinationEntityBundle = $this->migration->getProcess()[$this->destinationBundleKey][0]['default_value']; $fieldConfig = $this->entityManager->getFieldDefinitions($this->destinationEntityType, $destinationEntityBundle)[$destinationProperty]->getConfig($destinationEntityBundle); @@ -203,8 +203,8 @@ class EntityLookup extends ProcessPluginBase implements ContainerFactoryPluginIn } } - // Make an assumption that if the selection handler can target more than - // one type of entity that we will use the first entity type. + // Make an assumption that if the selection handler can target more + // than one type of entity that we will use the first entity type. $this->lookupEntityType = $this->lookupEntityType ?: reset($this->selectionPluginManager->createInstance($fieldConfig->getSetting('handler'))->getPluginDefinition()['entity_types']); $this->lookupValueKey = $this->lookupValueKey ?: $this->entityManager->getDefinition($this->lookupEntityType)->getKey('label'); $this->lookupBundleKey = $this->lookupBundleKey ?: $this->entityManager->getDefinition($this->lookupEntityType)->getKey('bundle'); @@ -238,8 +238,8 @@ class EntityLookup extends ProcessPluginBase implements ContainerFactoryPluginIn /** * Checks for the existence of some value. * - * @param $value - * The value to query. + * @param mixed $value + * The value to query. * * @return mixed|null * Entity id if the queried entity exists. Otherwise NULL. diff --git a/sites/all/modules/contrib/migrate/migrate_plus/src/Plugin/migrate/process/FileBlob.php b/sites/all/modules/contrib/migrate/migrate_plus/src/Plugin/migrate/process/FileBlob.php index 94c7ae8f1..22341b6bc 100644 --- a/sites/all/modules/contrib/migrate/migrate_plus/src/Plugin/migrate/process/FileBlob.php +++ b/sites/all/modules/contrib/migrate/migrate_plus/src/Plugin/migrate/process/FileBlob.php @@ -38,7 +38,7 @@ class FileBlob extends ProcessPluginBase implements ContainerFactoryPluginInterf * @param \Drupal\Core\File\FileSystemInterface $file_system * The file system service. */ - public function __construct(array $configuration, $plugin_id, array $plugin_definition, FileSystemInterface $file_system) { + public function __construct(array $configuration, $plugin_id, $plugin_definition, FileSystemInterface $file_system) { $configuration += [ 'reuse' => FALSE, ]; diff --git a/sites/all/modules/contrib/migrate/migrate_plus/src/Plugin/migrate/process/SkipOnValue.php b/sites/all/modules/contrib/migrate/migrate_plus/src/Plugin/migrate/process/SkipOnValue.php index 90dc33dc7..f25b1a47f 100644 --- a/sites/all/modules/contrib/migrate/migrate_plus/src/Plugin/migrate/process/SkipOnValue.php +++ b/sites/all/modules/contrib/migrate/migrate_plus/src/Plugin/migrate/process/SkipOnValue.php @@ -65,11 +65,11 @@ class SkipOnValue extends ProcessPluginBase { /** * Compare values to see if they are equal. * - * @param $value - * Actual value - * @param $skipValue + * @param mixed $value + * Actual value. + * @param mixed $skipValue * Value to compare against. - * @param $equal + * @param bool $equal * Compare as equal or not equal. * * @return bool diff --git a/sites/all/modules/contrib/migrate/migrate_plus/src/Plugin/migrate/process/StrReplace.php b/sites/all/modules/contrib/migrate/migrate_plus/src/Plugin/migrate/process/StrReplace.php index 43d772c90..2b033bebc 100644 --- a/sites/all/modules/contrib/migrate/migrate_plus/src/Plugin/migrate/process/StrReplace.php +++ b/sites/all/modules/contrib/migrate/migrate_plus/src/Plugin/migrate/process/StrReplace.php @@ -17,44 +17,44 @@ use Drupal\migrate\Row; * To do a simple hardcoded string replace use the following: * * @code - * field_text: - * plugin: str_replace - * source: text - * search: foo - * replace: bar + * field_text: + * plugin: str_replace + * source: text + * search: foo + * replace: bar * @endcode * - * If the value of text is "vero eos et accusam et justo vero" - * in source, foo is "et" in search and bar is "that" in replace, - * field_text will be "vero eos that accusam that justo vero". + * If the value of text is "vero eos et accusam et justo vero" in source, foo is + * "et" in search and bar is "that" in replace, field_text will be "vero eos + * that accusam that justo vero". * * Case insensitive searches can be achieved using the following: * @code - * field_text: - * plugin: str_replace - * case_insensitive: true - * source: text - * search: foo - * replace: bar + * field_text: + * plugin: str_replace + * case_insensitive: true + * source: text + * search: foo + * replace: bar * @endcode * - * If the value of text is "VERO eos et accusam et justo vero" - * in source, foo is "vero" in search and bar is "that" in replace, - * field_text will be "that eos et accusam et justo that". + * If the value of text is "VERO eos et accusam et justo vero" in source, foo is + * "vero" in search and bar is "that" in replace, field_text will be "that eos + * et accusam et justo that". * * Also regular expressions can be matched using: * @code - * field_text: - * plugin: str_replace - * regex: true - * source: text - * search: foo - * replace: bar + * field_text: + * plugin: str_replace + * regex: true + * source: text + * search: foo + * replace: bar * @endcode * - * If the value of text is "vero eos et 123 accusam et justo 123 duo" - * in source, foo is "/[0-9]{3}/" in search and bar is "the" in replace, - * field_text will be "vero eos et the accusam et justo the duo". + * If the value of text is "vero eos et 123 accusam et justo 123 duo" in source, + * foo is "/[0-9]{3}/" in search and bar is "the" in replace, field_text will be + * "vero eos et the accusam et justo the duo". * * All the rules for * @link http://php.net/manual/function.str-replace.php str_replace @endlink diff --git a/sites/all/modules/contrib/migrate/migrate_plus/src/Plugin/migrate/process/Transliteration.php b/sites/all/modules/contrib/migrate/migrate_plus/src/Plugin/migrate/process/Transliteration.php index 0ce2f6e65..217869e20 100644 --- a/sites/all/modules/contrib/migrate/migrate_plus/src/Plugin/migrate/process/Transliteration.php +++ b/sites/all/modules/contrib/migrate/migrate_plus/src/Plugin/migrate/process/Transliteration.php @@ -11,7 +11,7 @@ use Drupal\migrate\Row; use Symfony\Component\DependencyInjection\ContainerInterface; /** - * Transliterates text from Unicode to US-ASCII + * Transliterates text from Unicode to US-ASCII. * * The transliteration process plugin takes the source value and runs it through * the transliteration service. Letters will have language decorations and @@ -26,8 +26,8 @@ use Symfony\Component\DependencyInjection\ContainerInterface; * source: foo * @endcode * - * If the value of foo in the source is 'áéí!' then the destination value of bar - * will be 'aei!'. + * If the value of foo in the source is 'áéí!' then the destination value of + * bar will be 'aei!'. * * @see \Drupal\migrate\Plugin\MigrateProcessInterface * @@ -81,4 +81,3 @@ class Transliteration extends ProcessPluginBase implements ContainerFactoryPlugi } } - diff --git a/sites/all/modules/contrib/migrate/migrate_plus/src/Plugin/migrate_plus/authentication/OAuth2.php b/sites/all/modules/contrib/migrate/migrate_plus/src/Plugin/migrate_plus/authentication/OAuth2.php index 65cd0e553..116314d6b 100755 --- a/sites/all/modules/contrib/migrate/migrate_plus/src/Plugin/migrate_plus/authentication/OAuth2.php +++ b/sites/all/modules/contrib/migrate/migrate_plus/src/Plugin/migrate_plus/authentication/OAuth2.php @@ -16,7 +16,7 @@ use Sainsburys\Guzzle\Oauth2\Middleware\OAuthMiddleware; /** * Provides OAuth2 authentication for the HTTP resource. - * + * * @link https://packagist.org/packages/sainsburys/guzzle-oauth2-plugin * * @Authentication( diff --git a/sites/all/modules/contrib/migrate/migrate_plus/src/Plugin/migrate_plus/data_fetcher/Http.php b/sites/all/modules/contrib/migrate/migrate_plus/src/Plugin/migrate_plus/data_fetcher/Http.php index 7f39246d6..db4c423a6 100755 --- a/sites/all/modules/contrib/migrate/migrate_plus/src/Plugin/migrate_plus/data_fetcher/Http.php +++ b/sites/all/modules/contrib/migrate/migrate_plus/src/Plugin/migrate_plus/data_fetcher/Http.php @@ -10,7 +10,7 @@ use GuzzleHttp\Exception\RequestException; /** * Retrieve data over an HTTP connection for migration. * - * * Example: + * Example: * * @code * source: @@ -31,7 +31,7 @@ use GuzzleHttp\Exception\RequestException; class Http extends DataFetcherPluginBase implements ContainerFactoryPluginInterface { /** - * The HTTP Client + * The HTTP client. * * @var \GuzzleHttp\Client */ @@ -58,6 +58,8 @@ class Http extends DataFetcherPluginBase implements ContainerFactoryPluginInterf parent::__construct($configuration, $plugin_id, $plugin_definition); $this->httpClient = \Drupal::httpClient(); + // Ensure there is a 'headers' key in the configuration. + $configuration += ['headers' => []]; $this->setRequestHeaders($configuration['headers']); } diff --git a/sites/all/modules/contrib/migrate/migrate_plus/tests/src/Kernel/MigrateTableTest.php b/sites/all/modules/contrib/migrate/migrate_plus/tests/src/Kernel/MigrateTableTest.php index b91f8c4eb..dc471770d 100755 --- a/sites/all/modules/contrib/migrate/migrate_plus/tests/src/Kernel/MigrateTableTest.php +++ b/sites/all/modules/contrib/migrate/migrate_plus/tests/src/Kernel/MigrateTableTest.php @@ -16,12 +16,17 @@ class MigrateTableTest extends MigrateTestBase { const TABLE_NAME = 'migrate_test_destination_table'; /** + * The database connection. + * * @var \Drupal\Core\Database\Connection */ protected $connection; public static $modules = ['migrate_plus']; + /** + * {@inheritdoc} + */ protected function setUp() { parent::setUp(); @@ -50,22 +55,42 @@ class MigrateTableTest extends MigrateTestBase { ]); } + /** + * {@inheritdoc} + */ protected function tearDown() { $this->connection->schema()->dropTable(static::TABLE_NAME); parent::tearDown(); } + /** + * Create a minimally valid migration with some source data. + * + * @return array + * The migration definition. + */ protected function getTableDestinationMigration() { - // Create a minimally valid migration with some source data. $definition = [ 'id' => 'migration_table_test', 'migration_tags' => ['Testing'], 'source' => [ 'plugin' => 'embedded_data', 'data_rows' => [ - ['data' => 'dummy value', 'data2' => 'dummy2 value', 'data3' => 'dummy3 value'], - ['data' => 'dummy value2', 'data2' => 'dummy2 value2', 'data3' => 'dummy3 value2'], - ['data' => 'dummy value3', 'data2' => 'dummy2 value3', 'data3' => 'dummy3 value3'], + [ + 'data' => 'dummy value', + 'data2' => 'dummy2 value', + 'data3' => 'dummy3 value', + ], + [ + 'data' => 'dummy value2', + 'data2' => 'dummy2 value2', + 'data3' => 'dummy3 value2', + ], + [ + 'data' => 'dummy value3', + 'data2' => 'dummy2 value3', + 'data3' => 'dummy3 value3', + ], ], 'ids' => [ 'data' => ['type' => 'string'], @@ -106,6 +131,9 @@ class MigrateTableTest extends MigrateTestBase { $this->assertEquals(3, count($values)); } + /** + * Tests table rollback. + */ public function testTableRollback() { $this->testTableDestination(); diff --git a/sites/all/modules/contrib/migrate/migrate_plus/tests/src/Kernel/MigrationConfigEntityTest.php b/sites/all/modules/contrib/migrate/migrate_plus/tests/src/Kernel/MigrationConfigEntityTest.php index 386363a36..354da7628 100644 --- a/sites/all/modules/contrib/migrate/migrate_plus/tests/src/Kernel/MigrationConfigEntityTest.php +++ b/sites/all/modules/contrib/migrate/migrate_plus/tests/src/Kernel/MigrationConfigEntityTest.php @@ -15,15 +15,23 @@ class MigrationConfigEntityTest extends KernelTestBase { public static $modules = ['migrate', 'migrate_plus']; /** + * The plugin manager. + * * @var \Drupal\migrate\Plugin\MigrationPluginManager */ protected $pluginManager; + /** + * {@inheritdoc} + */ protected function setUp() { parent::setUp(); $this->pluginManager = \Drupal::service('plugin.manager.migration'); } + /** + * Tests cache invalidation. + */ public function testCacheInvalidation() { $config = Migration::create([ 'id' => 'test', diff --git a/sites/all/modules/contrib/migrate/migrate_plus/tests/src/Kernel/MigrationGroupTest.php b/sites/all/modules/contrib/migrate/migrate_plus/tests/src/Kernel/MigrationGroupTest.php index 71d3452d3..53d3ad467 100644 --- a/sites/all/modules/contrib/migrate/migrate_plus/tests/src/Kernel/MigrationGroupTest.php +++ b/sites/all/modules/contrib/migrate/migrate_plus/tests/src/Kernel/MigrationGroupTest.php @@ -25,14 +25,18 @@ class MigrationGroupTest extends KernelTestBase { $group_configuration = [ 'id' => $group_id, 'shared_configuration' => [ - 'migration_tags' => ['Drupal 6'], // In migration, so will be overridden. + // In migration, so will be overridden. + 'migration_tags' => ['Drupal 6'], 'source' => [ 'constants' => [ - 'type' => 'image', // Not in migration, so will be added. - 'cardinality' => '1', // In migration, so will be overridden. + // Not in migration, so will be added. + 'type' => 'image', + // In migration, so will be overridden. + 'cardinality' => '1', ], ], - 'destination' => ['plugin' => 'field_storage_config'], // Not in migration, so will be added. + // Not in migration, so will be added. + 'destination' => ['plugin' => 'field_storage_config'], ], ]; $this->container->get('entity_type.manager')->getStorage('migration_group') @@ -41,21 +45,25 @@ class MigrationGroupTest extends KernelTestBase { /** @var \Drupal\migrate_plus\Entity\MigrationInterface $migration */ $migration = $this->container->get('entity_type.manager') ->getStorage('migration')->create([ - 'id' => 'specific_migration', - 'load' => [], - 'migration_group' => $group_id, - 'label' => 'Unaffected by the group', - 'migration_tags' => ['Drupal 7'], // Overrides group. - 'destination' => [], - 'source' => [], - 'process' => [], - 'migration_dependencies' => [], - ]); + 'id' => 'specific_migration', + 'load' => [], + 'migration_group' => $group_id, + 'label' => 'Unaffected by the group', + // Overrides group. + 'migration_tags' => ['Drupal 7'], + 'destination' => [], + 'source' => [], + 'process' => [], + 'migration_dependencies' => [], + ]); $migration->set('source', [ - 'plugin' => 'empty', // Not in group, persists. + // Not in group, persists. + 'plugin' => 'empty', 'constants' => [ - 'entity_type' => 'user', // Not in group, persists. - 'cardinality' => '3', // Overrides group. + // Not in group, persists. + 'entity_type' => 'user', + // Overrides group. + 'cardinality' => '3', ], ]); $migration->save(); @@ -98,14 +106,14 @@ class MigrationGroupTest extends KernelTestBase { /** @var \Drupal\migrate_plus\Entity\MigrationInterface $migration */ $migration = $this->container->get('entity_type.manager') ->getStorage('migration')->create([ - 'id' => 'specific_migration', - 'migration_group' => 'test_group', - 'migration_tags' => [], - 'load' => [], - 'destination' => [], - 'source' => [], - 'migration_dependencies' => [], - ]); + 'id' => 'specific_migration', + 'migration_group' => 'test_group', + 'migration_tags' => [], + 'load' => [], + 'destination' => [], + 'source' => [], + 'migration_dependencies' => [], + ]); $migration->save(); /** @var \Drupal\migrate_plus\Entity\MigrationGroupInterface $loaded_migration_group */ diff --git a/sites/all/modules/contrib/migrate/migrate_plus/tests/src/Kernel/Plugin/migrate/process/EntityGenerateTest.php b/sites/all/modules/contrib/migrate/migrate_plus/tests/src/Kernel/Plugin/migrate/process/EntityGenerateTest.php index 558b222c7..a4c0f27f6 100644 --- a/sites/all/modules/contrib/migrate/migrate_plus/tests/src/Kernel/Plugin/migrate/process/EntityGenerateTest.php +++ b/sites/all/modules/contrib/migrate/migrate_plus/tests/src/Kernel/Plugin/migrate/process/EntityGenerateTest.php @@ -58,9 +58,9 @@ class EntityGenerateTest extends KernelTestBase implements MigrateMessageInterfa protected $vocabulary = 'fruit'; /** - * @var \Drupal\migrate\Plugin\MigrationPluginManager $migrationManager - * * The migration plugin manager. + * + * @var \Drupal\migrate\Plugin\MigrationPluginManager */ protected $migrationPluginManager; diff --git a/sites/all/modules/contrib/migrate/migrate_plus/tests/src/Kernel/Plugin/migrate_plus/data_fetcher/HttpTest.php b/sites/all/modules/contrib/migrate/migrate_plus/tests/src/Kernel/Plugin/migrate_plus/data_fetcher/HttpTest.php index 09aef97b3..76a5c1847 100644 --- a/sites/all/modules/contrib/migrate/migrate_plus/tests/src/Kernel/Plugin/migrate_plus/data_fetcher/HttpTest.php +++ b/sites/all/modules/contrib/migrate/migrate_plus/tests/src/Kernel/Plugin/migrate_plus/data_fetcher/HttpTest.php @@ -2,14 +2,11 @@ namespace Drupal\Tests\migrate_plus\Kernel\Plugin\migrate_plus\data_fetcher; -use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\KernelTests\KernelTestBase; use Drupal\migrate_plus\Plugin\migrate_plus\data_fetcher\Http; -use Drupal\Tests\Core\Test\KernelTestBaseTest; -use Drupal\Tests\UnitTestCase; /** - * Class HttpTest + * Class HttpTest. * * @group migrate_plus * @package Drupal\Tests\migrate_plus\Unit\migrate_plus\data_fetcher @@ -18,26 +15,45 @@ class HttpTest extends KernelTestBase { /** * Test http headers option. + * + * @dataProvider headerDataProvider */ - function testHttpHeaders() { - $expected = [ - 'Accept' => 'application/json', - 'User-Agent' => 'Internet Explorer 6', - 'Authorization-Key' => 'secret', - 'Arbitrary-Header' => 'foobarbaz' - ]; - - $configuration = [ - 'headers' => [ - 'Accept' => 'application/json', - 'User-Agent' => 'Internet Explorer 6', - 'Authorization-Key' => 'secret', - 'Arbitrary-Header' => 'foobarbaz' - ] - ]; - - $http = new Http($configuration, 'http', []); - + public function testHttpHeaders(array $definition, array $expected, array $preSeed = []) { + $http = new Http($definition, 'http', []); $this->assertEquals($expected, $http->getRequestHeaders()); } + + /** + * Provides multiple test cases for the testHttpHeaders method. + * + * @return array + * The test cases + */ + public function headerDataProvider() { + return [ + 'dummy headers specified' => [ + 'definition' => [ + 'headers' => [ + 'Accept' => 'application/json', + 'User-Agent' => 'Internet Explorer 6', + 'Authorization-Key' => 'secret', + 'Arbitrary-Header' => 'foobarbaz', + ], + ], + 'expected' => [ + 'Accept' => 'application/json', + 'User-Agent' => 'Internet Explorer 6', + 'Authorization-Key' => 'secret', + 'Arbitrary-Header' => 'foobarbaz', + ], + ], + 'no headers specified' => [ + 'definition' => [ + 'no_headers_here' => 'foo', + ], + 'expected' => [], + ], + ]; + } + } diff --git a/sites/all/modules/contrib/migrate/migrate_plus/tests/src/Unit/process/ArrayPopTest.php b/sites/all/modules/contrib/migrate/migrate_plus/tests/src/Unit/process/ArrayPopTest.php new file mode 100644 index 000000000..84316d799 --- /dev/null +++ b/sites/all/modules/contrib/migrate/migrate_plus/tests/src/Unit/process/ArrayPopTest.php @@ -0,0 +1,71 @@ +plugin = new ArrayPop([], 'array_pop', []); + parent::setUp(); + } + + /** + * Data provider for testArrayPop(). + * + * @return array + * An array containing input values and expected output values. + */ + public function arrayPopDataProvider() { + return [ + 'indexed array' => [ + 'input' => ['v1', 'v2', 'v3'], + 'expected_output' => 'v3', + ], + 'associative array' => [ + 'input' => ['i1' => 'v1', 'i2' => 'v2', 'i3' => 'v3'], + 'expected_output' => 'v3', + ], + 'empty array' => [ + 'input' => [], + 'expected_output' => NULL, + ], + ]; + } + + /** + * Test array pop plugin. + * + * @param array $input + * The input values. + * @param mixed $expected_output + * The expected output. + * + * @dataProvider arrayPopDataProvider + */ + public function testArrayPop(array $input, $expected_output) { + $output = $this->plugin->transform($input, $this->migrateExecutable, $this->row, 'destinationproperty'); + $this->assertSame($output, $expected_output); + } + + /** + * Test invalid input. + */ + public function testArrayPopFromString() { + $this->setExpectedException(MigrateException::class, 'Input should be an array.'); + $this->plugin->transform('foo', $this->migrateExecutable, $this->row, 'destinationproperty'); + } + +} diff --git a/sites/all/modules/contrib/migrate/migrate_plus/tests/src/Unit/process/ArrayShiftTest.php b/sites/all/modules/contrib/migrate/migrate_plus/tests/src/Unit/process/ArrayShiftTest.php new file mode 100644 index 000000000..6c6950fee --- /dev/null +++ b/sites/all/modules/contrib/migrate/migrate_plus/tests/src/Unit/process/ArrayShiftTest.php @@ -0,0 +1,71 @@ +plugin = new ArrayShift([], 'array_shift', []); + parent::setUp(); + } + + /** + * Data provider for testArrayShift(). + * + * @return array + * An array containing input values and expected output values. + */ + public function arrayShiftDataProvider() { + return [ + 'indexed array' => [ + 'input' => ['v1', 'v2', 'v3'], + 'expected_output' => 'v1', + ], + 'associative array' => [ + 'input' => ['i1' => 'v1', 'i2' => 'v2', 'i3' => 'v3'], + 'expected_output' => 'v1', + ], + 'empty array' => [ + 'input' => [], + 'expected_output' => NULL, + ], + ]; + } + + /** + * Test array shift plugin. + * + * @param array $input + * The input values. + * @param mixed $expected_output + * The expected output. + * + * @dataProvider arrayShiftDataProvider + */ + public function testArrayShift(array $input, $expected_output) { + $output = $this->plugin->transform($input, $this->migrateExecutable, $this->row, 'destinationproperty'); + $this->assertSame($output, $expected_output); + } + + /** + * Test invalid input. + */ + public function testArrayShiftFromString() { + $this->setExpectedException(MigrateException::class, 'Input should be an array.'); + $this->plugin->transform('foo', $this->migrateExecutable, $this->row, 'destinationproperty'); + } + +} diff --git a/sites/all/modules/contrib/migrate/migrate_plus/tests/src/Unit/process/StrReplaceTest.php b/sites/all/modules/contrib/migrate/migrate_plus/tests/src/Unit/process/StrReplaceTest.php index f1e0120b3..7194c711b 100644 --- a/sites/all/modules/contrib/migrate/migrate_plus/tests/src/Unit/process/StrReplaceTest.php +++ b/sites/all/modules/contrib/migrate/migrate_plus/tests/src/Unit/process/StrReplaceTest.php @@ -5,7 +5,6 @@ namespace Drupal\Tests\migrate_plus\Unit\process; use Drupal\migrate_plus\Plugin\migrate\process\StrReplace; use Drupal\Tests\migrate\Unit\process\MigrateProcessTestCase; - /** * Tests the str replace process plugin. * @@ -56,7 +55,6 @@ class StrReplaceTest extends MigrateProcessTestCase { /** * Test for MigrateException for "search" configuration. - * */ public function testSearchMigrateException() { $value = 'vero eos et accusam et justo vero'; @@ -80,11 +78,11 @@ class StrReplaceTest extends MigrateProcessTestCase { /** * Test for multiple. */ - public function testIsMultiple() { + public function testIsMultiple() { $value = [ 'vero eos et accusam et justo vero', 'et eos vero accusam vero justo et', - ]; + ]; $expected = [ 'vero eos that accusam that justo vero', diff --git a/sites/all/modules/contrib/migrate/migrate_tools/composer.json b/sites/all/modules/contrib/migrate/migrate_tools/composer.json index 227a90349..562c6a254 100644 --- a/sites/all/modules/contrib/migrate/migrate_tools/composer.json +++ b/sites/all/modules/contrib/migrate/migrate_tools/composer.json @@ -2,10 +2,22 @@ "name": "drupal/migrate_tools", "description": "Tools to assist in developing and running migrations.", "type": "drupal-module", - "require-dev": { - "drupal/coder": "^8" + "homepage": "http://drupal.org/project/migrate_tools", + "support": { + "issues": "http://drupal.org/project/migrate_tools", + "irc": "irc://irc.freenode.org/drupal-migrate", + "source": "http://cgit.drupalcode.org/migrate_tools" }, "license": "GPL-2.0+", - "require": {}, - "minimum-stability": "dev" + "require-dev": { + "drupal/coder": "^8" + }, + "minimum-stability": "dev", + "extra": { + "drush": { + "services": { + "drush.services.yml": "^9" + } + } + } } diff --git a/sites/all/modules/contrib/migrate/migrate_tools/migrate_tools.drush.inc b/sites/all/modules/contrib/migrate/migrate_tools/migrate_tools.drush.inc index 4612874b6..73ddec530 100644 --- a/sites/all/modules/contrib/migrate/migrate_tools/migrate_tools.drush.inc +++ b/sites/all/modules/contrib/migrate/migrate_tools/migrate_tools.drush.inc @@ -9,10 +9,9 @@ use Drupal\Component\Utility\Unicode; use Drupal\migrate\Exception\RequirementsException; use Drupal\migrate\Plugin\MigrationInterface; use Drupal\migrate\Plugin\RequirementsInterface; -use Drupal\migrate_tools\MigrateExecutable; -use Drupal\migrate_tools\DrushLogMigrateMessage; -use Drupal\Core\Datetime\DateFormatter; use Drupal\migrate_plus\Entity\MigrationGroup; +use Drupal\migrate_tools\DrushLogMigrateMessage; +use Drupal\migrate_tools\MigrateExecutable; /** * Implements hook_drush_command(). @@ -68,27 +67,27 @@ function migrate_tools_drush_command() { 'aliases' => ['mi', 'mim'], ]; - $items['migrate-rollback'] = array( + $items['migrate-rollback'] = [ 'description' => 'Rollback one or more migrations.', - 'options' => array( + 'options' => [ 'all' => 'Process all migrations.', 'group' => 'A comma-separated list of migration groups to rollback', 'tag' => 'ID of the migration tag to rollback', 'feedback' => 'Frequency of progress messages, in items processed', - ), - 'arguments' => array( + ], + 'arguments' => [ 'migration' => 'Name of migration(s) to rollback. Delimit multiple using commas.', - ), - 'examples' => array( + ], + 'examples' => [ 'migrate-rollback --all' => 'Perform all migrations', 'migrate-rollback --group=beer' => 'Rollback all migrations in the beer group', 'migrate-rollback --tag=user' => 'Rollback all migrations with the user tag', 'migrate-rollback --group=beer --tag=user' => 'Rollback all migrations in the beer group and with the user tag', 'migrate-rollback beer_term,beer_node' => 'Rollback imported terms and nodes', - ), - 'drupal dependencies' => array('migrate_tools'), - 'aliases' => array('mr'), - ); + ], + 'drupal dependencies' => ['migrate_tools'], + 'aliases' => ['mr'], + ]; $items['migrate-stop'] = [ 'description' => 'Stop an active migration operation.', @@ -114,7 +113,7 @@ function migrate_tools_drush_command() { 'migration' => 'ID of the migration', ], 'options' => [ - 'csv' => 'Export messages as a CSV' + 'csv' => 'Export messages as a CSV', ], 'examples' => [ 'migrate-messages MyNode' => 'Show all messages for the MyNode migration', @@ -139,7 +138,10 @@ function migrate_tools_drush_command() { } /** + * Display migration status. + * * @param string $migration_names + * The migration names. */ function drush_migrate_tools_migrate_status($migration_names = '') { $names_only = drush_get_option('names-only'); @@ -153,12 +155,12 @@ function drush_migrate_tools_migrate_status($migration_names = '') { $group_name = !empty($group) ? "{$group->label()} ({$group->id()})" : $group_id; if ($names_only) { $table[] = [ - dt('Group: @name', array('@name' => $group_name)) + dt('Group: @name', ['@name' => $group_name]), ]; } else { $table[] = [ - dt('Group: @name', array('@name' => $group_name)), + dt('Group: @name', ['@name' => $group_name]), dt('Status'), dt('Total'), dt('Imported'), @@ -204,7 +206,7 @@ function drush_migrate_tools_migrate_status($migration_names = '') { $migrate_last_imported_store = \Drupal::keyValue('migrate_last_imported'); $last_imported = $migrate_last_imported_store->get($migration->id(), FALSE); if ($last_imported) { - /** @var DateFormatter $date_formatter */ + /** @var \Drupal\Core\Datetime\DateFormatter $date_formatter */ $date_formatter = \Drupal::service('date.formatter'); $last_imported = $date_formatter->format($last_imported / 1000, 'custom', 'Y-m-d H:i:s'); @@ -212,7 +214,14 @@ function drush_migrate_tools_migrate_status($migration_names = '') { else { $last_imported = ''; } - $table[] = [$migration_id, $status, $source_rows, $imported, $unprocessed, $last_imported]; + $table[] = [ + $migration_id, + $status, + $source_rows, + $imported, + $unprocessed, + $last_imported, + ]; } } } @@ -220,7 +229,10 @@ function drush_migrate_tools_migrate_status($migration_names = '') { } /** + * Import a migration. + * * @param string $migration_names + * The migration names. */ function drush_migrate_tools_migrate_import($migration_names = '') { $group_names = drush_get_option('group'); @@ -257,17 +269,19 @@ function drush_migrate_tools_migrate_import($migration_names = '') { } /** - * Executes a single migration. If the --execute-dependencies option was given, - * the migration's dependencies will also be executed first. + * Executes a single migration. + * + * If the --execute-dependencies option was given, the migration's dependencies + * will also be executed first. * * @param \Drupal\migrate\Plugin\MigrationInterface $migration - * The migration to execute. + * The migration to execute. * @param string $migration_id - * The migration ID (not used, just an artifact of array_walk()). + * The migration ID (not used, just an artifact of array_walk()). * @param array $options - * Additional options for the migration. + * Additional options for the migration. */ -function _drush_migrate_tools_execute_migration(MigrationInterface $migration, $migration_id, array $options = []) { +function _drush_migrate_tools_execute_migration(MigrationInterface $migration, $migration_id, array $options = []) { $log = new DrushLogMigrateMessage(); if (drush_get_option('execute-dependencies')) { @@ -285,16 +299,22 @@ function _drush_migrate_tools_execute_migration(MigrationInterface $migration, $ $migration->getIdMap()->prepareUpdate(); } $executable = new MigrateExecutable($migration, $log, $options); - // drush_op() provides --simulate support - drush_op(array($executable, 'import')); + // Function drush_op() provides --simulate support. + drush_op([$executable, 'import']); if ($count = $executable->getFailedCount()) { // Nudge Drush to use a non-zero exit code. - drush_set_error('MIGRATE_ERROR', dt('!name Migration - !count failed.', array('!name' => $migration_id, '!count' => $count))); + drush_set_error('MIGRATE_ERROR', dt('!name Migration - !count failed.', [ + '!name' => $migration_id, + '!count' => $count, + ])); } } /** + * Rollback migrations. + * * @param string $migration_names + * The migration names. */ function drush_migrate_tools_migrate_rollback($migration_names = '') { $group_names = drush_get_option('group'); @@ -324,17 +344,21 @@ function drush_migrate_tools_migrate_rollback($migration_names = '') { foreach ($migration_list as $migration_id => $migration) { $executable = new MigrateExecutable($migration, $log, $options); // drush_op() provides --simulate support. - drush_op(array($executable, 'rollback')); + drush_op([$executable, 'rollback']); } } } /** + * Stop a migration. + * * @param string $migration_id + * The migration id. */ function drush_migrate_tools_migrate_stop($migration_id = '') { - /** @var MigrationInterface $migration */ - $migration = \Drupal::service('plugin.manager.migration')->createInstance($migration_id); + /** @var \Drupal\migrate\Plugin\MigrationInterface $migration */ + $migration = \Drupal::service('plugin.manager.migration') + ->createInstance($migration_id); if ($migration) { $status = $migration->getStatus(); switch ($status) { @@ -359,11 +383,15 @@ function drush_migrate_tools_migrate_stop($migration_id = '') { } /** + * Reset status. + * * @param string $migration_id + * The migration id. */ function drush_migrate_tools_migrate_reset_status($migration_id = '') { - /** @var MigrationInterface $migration */ - $migration = \Drupal::service('plugin.manager.migration')->createInstance($migration_id); + /** @var \Drupal\migrate\Plugin\MigrationInterface $migration */ + $migration = \Drupal::service('plugin.manager.migration') + ->createInstance($migration_id); if ($migration) { $status = $migration->getStatus(); if ($status == MigrationInterface::STATUS_IDLE) { @@ -380,11 +408,15 @@ function drush_migrate_tools_migrate_reset_status($migration_id = '') { } /** + * Print messages. + * * @param string $migration_id + * The migration id. */ function drush_migrate_tools_migrate_messages($migration_id) { - /** @var MigrationInterface $migration */ - $migration = \Drupal::service('plugin.manager.migration')->createInstance($migration_id); + /** @var \Drupal\migrate\Plugin\MigrationInterface $migration */ + $migration = \Drupal::service('plugin.manager.migration') + ->createInstance($migration_id); if ($migration) { $map = $migration->getIdMap(); $first = TRUE; @@ -399,7 +431,7 @@ function drush_migrate_tools_migrate_messages($migration_id) { } $first = FALSE; } - $table[] = (array)$row; + $table[] = (array) $row; } if (empty($table)) { drush_log(dt('No messages for this migration'), 'status'); @@ -425,11 +457,15 @@ function drush_migrate_tools_migrate_messages($migration_id) { } /** + * Print source fields. + * * @param string $migration_id + * The migration id. */ function drush_migrate_tools_migrate_fields_source($migration_id) { - /** @var MigrationInterface $migration */ - $migration = \Drupal::service('plugin.manager.migration')->createInstance($migration_id); + /** @var \Drupal\migrate\Plugin\MigrationInterface $migration */ + $migration = \Drupal::service('plugin.manager.migration') + ->createInstance($migration_id); if ($migration) { $source = $migration->getSourcePlugin(); $table = []; @@ -447,9 +483,10 @@ function drush_migrate_tools_migrate_fields_source($migration_id) { * Retrieve a list of active migrations. * * @param string $migration_ids - * Comma-separated list of migrations - if present, return only these migrations. + * Comma-separated list of migrations - if present, return only these + * migrations. * - * @return MigrationInterface[][] + * @return \Drupal\migrate\Plugin\MigrationInterface[][] * An array keyed by migration group, each value containing an array of * migrations or an empty array if no migrations match the input criteria. */ diff --git a/sites/all/modules/contrib/migrate/migrate_tools/migrate_tools.info.yml b/sites/all/modules/contrib/migrate/migrate_tools/migrate_tools.info.yml index 7743ae941..30ccca99f 100644 --- a/sites/all/modules/contrib/migrate/migrate_tools/migrate_tools.info.yml +++ b/sites/all/modules/contrib/migrate/migrate_tools/migrate_tools.info.yml @@ -7,8 +7,8 @@ dependencies: - drupal:migrate (>=8.3) - migrate_plus:migrate_plus -# Information added by Drupal.org packaging script on 2017-11-27 -version: '8.x-4.0-beta2' +# Information added by Drupal.org packaging script on 2018-02-23 +version: '8.x-4.0-beta3' core: '8.x' project: 'migrate_tools' -datestamp: 1511790488 +datestamp: 1519400307 diff --git a/sites/all/modules/contrib/migrate/migrate_tools/migrate_tools.module b/sites/all/modules/contrib/migrate/migrate_tools/migrate_tools.module index bf1c8065c..6e4dde593 100644 --- a/sites/all/modules/contrib/migrate/migrate_tools/migrate_tools.module +++ b/sites/all/modules/contrib/migrate/migrate_tools/migrate_tools.module @@ -9,7 +9,8 @@ * Implements hook_entity_type_build(). */ function migrate_tools_entity_type_build(array &$entity_types) { - // Inject our UI into the general migration and migration group config entities. + // Inject our UI into the general migration and migration group config + // entities. /** @var \Drupal\Core\Config\Entity\ConfigEntityType[] $entity_types */ $entity_types['migration'] ->set('admin_permission', 'administer migrations') diff --git a/sites/all/modules/contrib/migrate/migrate_tools/migrate_tools.services.yml b/sites/all/modules/contrib/migrate/migrate_tools/migrate_tools.services.yml new file mode 100644 index 000000000..98aebdf28 --- /dev/null +++ b/sites/all/modules/contrib/migrate/migrate_tools/migrate_tools.services.yml @@ -0,0 +1,5 @@ +services: + logger.channel.migrate_tools: + class: Drupal\Core\Logger\LoggerChannel + factory: logger.factory:get + arguments: ['migrate_tools'] diff --git a/sites/all/modules/contrib/migrate/migrate_tools/phpcs.xml b/sites/all/modules/contrib/migrate/migrate_tools/phpcs.xml index 1ccfe7eb4..a18054efb 100644 --- a/sites/all/modules/contrib/migrate/migrate_tools/phpcs.xml +++ b/sites/all/modules/contrib/migrate/migrate_tools/phpcs.xml @@ -1,126 +1,207 @@ - - - PHP CodeSniffer configuration + + + Drupal 8 coding standards + . - + ./vendor/* - - - - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + - + + + + - + + + + + + + - + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + 0 + + + 0 + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + 0 + + + 0 + + + + + 0 + + + 0 + + + + 0 + + + 0 + + + + 0 + + + 0 + + + 0 + + + + + + + + 0 + + - + + + + + + + diff --git a/sites/all/modules/contrib/migrate/migrate_tools/src/Commands/MigrateToolsCommands.php b/sites/all/modules/contrib/migrate/migrate_tools/src/Commands/MigrateToolsCommands.php index 501c6ac3b..5d3402244 100644 --- a/sites/all/modules/contrib/migrate/migrate_tools/src/Commands/MigrateToolsCommands.php +++ b/sites/all/modules/contrib/migrate/migrate_tools/src/Commands/MigrateToolsCommands.php @@ -12,10 +12,8 @@ use Drupal\migrate\Plugin\MigrationInterface; use Drupal\migrate\Plugin\MigrationPluginManager; use Drupal\migrate\Plugin\RequirementsInterface; use Drupal\migrate_tools\Drush9LogMigrateMessage; -use Drupal\migrate_tools\DrushLogMigrateMessage; use Drupal\migrate_tools\MigrateExecutable; use Drush\Commands\DrushCommands; -use Drush\Drush; /** * Migrate Tools drush commands. diff --git a/sites/all/modules/contrib/migrate/migrate_tools/src/Controller/MessageController.php b/sites/all/modules/contrib/migrate/migrate_tools/src/Controller/MessageController.php index abf921b19..068f9e148 100644 --- a/sites/all/modules/contrib/migrate/migrate_tools/src/Controller/MessageController.php +++ b/sites/all/modules/contrib/migrate/migrate_tools/src/Controller/MessageController.php @@ -83,7 +83,7 @@ class MessageController extends ControllerBase { public function overview($migration_group, $migration) { $rows = []; $classes = static::getLogLevelClassMap(); - /** @var MigrationInterface $migration */ + /** @var \Drupal\migrate\Plugin\MigrationInterface $migration */ $migration = $this->migrationPluginManager->createInstance($migration); $source_id_field_names = array_keys($migration->getSourcePlugin()->getIds()); $column_number = 1; diff --git a/sites/all/modules/contrib/migrate/migrate_tools/src/Controller/MigrationGroupListBuilder.php b/sites/all/modules/contrib/migrate/migrate_tools/src/Controller/MigrationGroupListBuilder.php index 6757c22b1..8ab2b87fb 100644 --- a/sites/all/modules/contrib/migrate/migrate_tools/src/Controller/MigrationGroupListBuilder.php +++ b/sites/all/modules/contrib/migrate/migrate_tools/src/Controller/MigrationGroupListBuilder.php @@ -34,13 +34,13 @@ class MigrationGroupListBuilder extends ConfigEntityListBuilder { /** * Builds a row for an entity in the entity listing. * - * @param EntityInterface $entity + * @param \Drupal\Core\Entity\EntityInterface $entity * The entity for which to build the row. * * @return array * A render array of the table row for displaying the entity. * - * @see Drupal\Core\Entity\EntityListController::render() + * @see \Drupal\Core\Entity\EntityListController::render() */ public function buildRow(EntityInterface $entity) { $row['label'] = $entity->label(); diff --git a/sites/all/modules/contrib/migrate/migrate_tools/src/Controller/MigrationListBuilder.php b/sites/all/modules/contrib/migrate/migrate_tools/src/Controller/MigrationListBuilder.php index b14fc45f0..14c3e550b 100644 --- a/sites/all/modules/contrib/migrate/migrate_tools/src/Controller/MigrationListBuilder.php +++ b/sites/all/modules/contrib/migrate/migrate_tools/src/Controller/MigrationListBuilder.php @@ -8,6 +8,7 @@ use Drupal\Core\Entity\EntityHandlerInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Entity\EntityTypeInterface; +use Drupal\Core\Logger\LoggerChannelInterface; use Drupal\Core\Routing\CurrentRouteMatch; use Drupal\migrate\Plugin\MigrationPluginManagerInterface; use Drupal\migrate_plus\Entity\MigrationGroup; @@ -37,6 +38,13 @@ class MigrationListBuilder extends ConfigEntityListBuilder implements EntityHand */ protected $migrationPluginManager; + /** + * The logger service. + * + * @var \Drupal\Core\Logger\LoggerChannelInterface + */ + protected $logger; + /** * Constructs a new EntityListBuilder object. * @@ -48,11 +56,14 @@ class MigrationListBuilder extends ConfigEntityListBuilder implements EntityHand * The current route match service. * @param \Drupal\migrate\Plugin\MigrationPluginManagerInterface $migration_plugin_manager * The plugin manager for config entity-based migrations. + * @param \Drupal\Core\Logger\LoggerChannelInterface $logger + * The logger service. */ - public function __construct(EntityTypeInterface $entity_type, EntityStorageInterface $storage, CurrentRouteMatch $current_route_match, MigrationPluginManagerInterface $migration_plugin_manager) { + public function __construct(EntityTypeInterface $entity_type, EntityStorageInterface $storage, CurrentRouteMatch $current_route_match, MigrationPluginManagerInterface $migration_plugin_manager, LoggerChannelInterface $logger) { parent::__construct($entity_type, $storage); $this->currentRouteMatch = $current_route_match; $this->migrationPluginManager = $migration_plugin_manager; + $this->logger = $logger; } /** @@ -63,7 +74,8 @@ class MigrationListBuilder extends ConfigEntityListBuilder implements EntityHand $entity_type, $container->get('entity.manager')->getStorage($entity_type->id()), $container->get('current_route_match'), - $container->get('plugin.manager.migration') + $container->get('plugin.manager.migration'), + $container->get('logger.channel.migrate_tools') ); } @@ -121,7 +133,7 @@ class MigrationListBuilder extends ConfigEntityListBuilder implements EntityHand * @param \Drupal\Core\Entity\EntityInterface $migration_entity * The migration plugin for which to build the row. * - * @return array + * @return array|null * A render array of the table row for displaying the plugin information. * * @see \Drupal\Core\Entity\EntityListController::render() @@ -147,7 +159,9 @@ class MigrationListBuilder extends ConfigEntityListBuilder implements EntityHand ]; $row['machine_name'] = $migration->id(); $row['status'] = $migration->getStatusLabel(); - } catch (PluginException $e) { + } + catch (PluginException $e) { + $this->logger->warning('Migration entity id %id is malformed', ['%id' => $migration_entity->id()]); return NULL; } @@ -196,7 +210,8 @@ class MigrationListBuilder extends ConfigEntityListBuilder implements EntityHand ], ], ]; - } catch (PluginException $e) { + } + catch (PluginException $e) { // Derive the stats. $row['status'] = $this->t('No data found'); $row['total'] = $this->t('N/A'); @@ -211,10 +226,11 @@ class MigrationListBuilder extends ConfigEntityListBuilder implements EntityHand } /** + * Add group route parameter. + * * @param \Drupal\Core\Url $url * The URL associated with an operation. - * - * @param $migration_group + * @param string $migration_group * The migration's parent group. */ protected function addGroupParameter(Url $url, $migration_group) { diff --git a/sites/all/modules/contrib/migrate/migrate_tools/src/DrushLogMigrateMessage.php b/sites/all/modules/contrib/migrate/migrate_tools/src/DrushLogMigrateMessage.php index 9ed1d9fb0..4f7e92494 100644 --- a/sites/all/modules/contrib/migrate/migrate_tools/src/DrushLogMigrateMessage.php +++ b/sites/all/modules/contrib/migrate/migrate_tools/src/DrushLogMigrateMessage.php @@ -4,6 +4,11 @@ namespace Drupal\migrate_tools; use Drupal\migrate\MigrateMessageInterface; +/** + * Class DrushLogMigrateMessage. + * + * @package Drupal\migrate_tools + */ class DrushLogMigrateMessage implements MigrateMessageInterface { /** diff --git a/sites/all/modules/contrib/migrate/migrate_tools/src/Form/MigrationDeleteForm.php b/sites/all/modules/contrib/migrate/migrate_tools/src/Form/MigrationDeleteForm.php index 2c29991ff..593046dba 100644 --- a/sites/all/modules/contrib/migrate/migrate_tools/src/Form/MigrationDeleteForm.php +++ b/sites/all/modules/contrib/migrate/migrate_tools/src/Form/MigrationDeleteForm.php @@ -7,7 +7,7 @@ use Drupal\Core\Url; use Drupal\Core\Form\FormStateInterface; /** - * Class MigrationDeleteForm. + * Provides the delete form for our Migration entity. * * @package Drupal\migrate_tools\Form * @@ -23,7 +23,7 @@ class MigrationDeleteForm extends EntityConfirmFormBase { */ public function getQuestion() { return $this->t('Are you sure you want to delete migration %label?', [ - '%label' => $this->entity->label(), + '%label' => $this->entity->label(), ]); } diff --git a/sites/all/modules/contrib/migrate/migrate_tools/src/Form/MigrationEditForm.php b/sites/all/modules/contrib/migrate/migrate_tools/src/Form/MigrationEditForm.php index ad9ba8c7a..214d0ae35 100644 --- a/sites/all/modules/contrib/migrate/migrate_tools/src/Form/MigrationEditForm.php +++ b/sites/all/modules/contrib/migrate/migrate_tools/src/Form/MigrationEditForm.php @@ -6,8 +6,6 @@ use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Url; /** - * Class MigrationEditForm - * * Provides the edit form for our Migration entity. * * @package Drupal\migrate_tools\Form @@ -37,10 +35,11 @@ class MigrationEditForm extends MigrationFormBase { } /** + * Add group route parameter. + * * @param \Drupal\Core\Url $url * The URL associated with an operation. - * - * @param $migration_group + * @param string $migration_group * The migration's parent group. */ protected function addGroupParameter(Url $url, $migration_group) { diff --git a/sites/all/modules/contrib/migrate/migrate_tools/src/Form/MigrationExecuteForm.php b/sites/all/modules/contrib/migrate/migrate_tools/src/Form/MigrationExecuteForm.php index 9bfd8fbdc..bf81215aa 100644 --- a/sites/all/modules/contrib/migrate/migrate_tools/src/Form/MigrationExecuteForm.php +++ b/sites/all/modules/contrib/migrate/migrate_tools/src/Form/MigrationExecuteForm.php @@ -1,22 +1,13 @@ 'textfield', -// '#title' => t('Limit to:'), -// '#size' => 10, -// '#description' => t('Set a limit of how many items to process for each migration task.'), -// ]; + // https://www.drupal.org/project/migrate_tools/issues/2924298. return $form; } @@ -181,7 +166,7 @@ class MigrationExecuteForm extends FormBase { if ($migration_name) { - /** @var MigrationInterface $migration */ + /** @var \Drupal\migrate\Plugin\MigrationInterface $migration */ $migration = $this->migrationPluginManager->createInstance($migration_name); $migrateMessage = new MigrateMessage(); @@ -204,7 +189,7 @@ class MigrationExecuteForm extends FormBase { $options = [ 'limit' => $limit, 'update' => $update, - 'force' => $force + 'force' => $force, ]; $executable = new MigrateBatchExecutable($migration, $migrateMessage, $options); diff --git a/sites/all/modules/contrib/migrate/migrate_tools/src/Form/MigrationFormBase.php b/sites/all/modules/contrib/migrate/migrate_tools/src/Form/MigrationFormBase.php index cf2c8cee7..3ba6a0f55 100644 --- a/sites/all/modules/contrib/migrate/migrate_tools/src/Form/MigrationFormBase.php +++ b/sites/all/modules/contrib/migrate/migrate_tools/src/Form/MigrationFormBase.php @@ -18,6 +18,8 @@ use Symfony\Component\DependencyInjection\ContainerInterface; class MigrationFormBase extends EntityForm { /** + * The entity query factory. + * * @var \Drupal\Core\Entity\Query\QueryFactory */ protected $entityQueryFactory; @@ -25,8 +27,8 @@ class MigrationFormBase extends EntityForm { /** * Construct the MigrationGroupFormBase. * - * For simple entity forms, there's no need for a constructor. Our migration form - * base, however, requires an entity query factory to be injected into it + * For simple entity forms, there's no need for a constructor. Our migration + * form base, however, requires an entity query factory to be injected into it * from the container. We later use this query factory to build an entity * query for the exists() method. * @@ -38,12 +40,7 @@ class MigrationFormBase extends EntityForm { } /** - * Factory method for MigrationFormBase. - * - * @param \Symfony\Component\DependencyInjection\ContainerInterface $container - * A container interface service. - * - * @return \Drupal\migrate_tools\Form\MigrationGroupFormBase + * {@inheritdoc} */ public static function create(ContainerInterface $container) { return new static($container->get('entity.query')); @@ -72,7 +69,7 @@ class MigrationFormBase extends EntityForm { $form['warning'] = [ '#markup' => $this->t('Creating migrations is not yet supported. See :url', [ ':url' => 'https://www.drupal.org/node/2573241', - ]) + ]), ]; // Build the form. @@ -123,7 +120,7 @@ class MigrationFormBase extends EntityForm { * The entity ID. * @param array $element * The form element. - * @param FormStateInterface $form_state + * @param \Drupal\Core\Form\FormStateInterface $form_state * The form state. * * @return bool @@ -164,14 +161,7 @@ class MigrationFormBase extends EntityForm { } /** - * Overrides Drupal\Core\Entity\EntityFormController::save(). - * - * @param array $form - * An associative array containing the structure of the form. - * @param \Drupal\Core\Form\FormStateInterface $form_state - * An associative array containing the current state of the form. - * - * @return $this + * {@inheritdoc} */ public function save(array $form, FormStateInterface $form_state) { $migration = $this->getEntity(); diff --git a/sites/all/modules/contrib/migrate/migrate_tools/src/Form/MigrationGroupDeleteForm.php b/sites/all/modules/contrib/migrate/migrate_tools/src/Form/MigrationGroupDeleteForm.php index a126856bf..98d1baf70 100644 --- a/sites/all/modules/contrib/migrate/migrate_tools/src/Form/MigrationGroupDeleteForm.php +++ b/sites/all/modules/contrib/migrate/migrate_tools/src/Form/MigrationGroupDeleteForm.php @@ -7,7 +7,7 @@ use Drupal\Core\Url; use Drupal\Core\Form\FormStateInterface; /** - * Class MigrationGroupDeleteForm. + * Provides the delete form for our Migration Group entity. * * @package Drupal\migrate_tools\Form * @@ -23,7 +23,7 @@ class MigrationGroupDeleteForm extends EntityConfirmFormBase { */ public function getQuestion() { return $this->t('Are you sure you want to delete migration group %label?', [ - '%label' => $this->entity->label(), + '%label' => $this->entity->label(), ]); } diff --git a/sites/all/modules/contrib/migrate/migrate_tools/src/Form/MigrationGroupEditForm.php b/sites/all/modules/contrib/migrate/migrate_tools/src/Form/MigrationGroupEditForm.php index ee52359cd..1eedc2d26 100644 --- a/sites/all/modules/contrib/migrate/migrate_tools/src/Form/MigrationGroupEditForm.php +++ b/sites/all/modules/contrib/migrate/migrate_tools/src/Form/MigrationGroupEditForm.php @@ -5,8 +5,6 @@ namespace Drupal\migrate_tools\Form; use Drupal\Core\Form\FormStateInterface; /** - * Class MigrationGroupEditForm - * * Provides the edit form for our Migration Group entity. * * @package Drupal\migrate_tools\Form diff --git a/sites/all/modules/contrib/migrate/migrate_tools/src/Form/MigrationGroupFormBase.php b/sites/all/modules/contrib/migrate/migrate_tools/src/Form/MigrationGroupFormBase.php index 8d31ab4c3..d60944a75 100644 --- a/sites/all/modules/contrib/migrate/migrate_tools/src/Form/MigrationGroupFormBase.php +++ b/sites/all/modules/contrib/migrate/migrate_tools/src/Form/MigrationGroupFormBase.php @@ -17,6 +17,8 @@ use Symfony\Component\DependencyInjection\ContainerInterface; class MigrationGroupFormBase extends EntityForm { /** + * The query factory service. + * * @var \Drupal\Core\Entity\Query\QueryFactory */ protected $entityQueryFactory; @@ -24,10 +26,10 @@ class MigrationGroupFormBase extends EntityForm { /** * Construct the MigrationGroupFormBase. * - * For simple entity forms, there's no need for a constructor. Our migration group form - * base, however, requires an entity query factory to be injected into it - * from the container. We later use this query factory to build an entity - * query for the exists() method. + * For simple entity forms, there's no need for a constructor. Our migration + * group form base, however, requires an entity query factory to be injected + * into it from the container. We later use this query factory to build an + * entity query for the exists() method. * * @param \Drupal\Core\Entity\Query\QueryFactory $query_factory * An entity query factory for the migration group entity type. @@ -37,12 +39,7 @@ class MigrationGroupFormBase extends EntityForm { } /** - * Factory method for MigrationGroupFormBase. - * - * @param \Symfony\Component\DependencyInjection\ContainerInterface $container - * A container interface service. - * - * @return \Drupal\migrate_tools\Form\MigrationFormBase + * {@inheritdoc} */ public static function create(ContainerInterface $container) { return new static($container->get('entity.query')); @@ -112,7 +109,7 @@ class MigrationGroupFormBase extends EntityForm { * The entity ID. * @param array $element * The form element. - * @param FormStateInterface $form_state + * @param \Drupal\Core\Form\FormStateInterface $form_state * The form state. * * @return bool @@ -153,14 +150,7 @@ class MigrationGroupFormBase extends EntityForm { } /** - * Overrides Drupal\Core\Entity\EntityFormController::save(). - * - * @param array $form - * An associative array containing the structure of the form. - * @param \Drupal\Core\Form\FormStateInterface $form_state - * An associative array containing the current state of the form. - * - * @return $this + * {@inheritdoc} */ public function save(array $form, FormStateInterface $form_state) { $migration_group = $this->getEntity(); diff --git a/sites/all/modules/contrib/migrate/migrate_tools/src/MigrateBatchExecutable.php b/sites/all/modules/contrib/migrate/migrate_tools/src/MigrateBatchExecutable.php index d1aa35e1a..ee24f64d7 100644 --- a/sites/all/modules/contrib/migrate/migrate_tools/src/MigrateBatchExecutable.php +++ b/sites/all/modules/contrib/migrate/migrate_tools/src/MigrateBatchExecutable.php @@ -66,8 +66,9 @@ class MigrateBatchExecutable extends MigrateExecutable { * Sets the current batch content so listeners can update the messages. * * @param array $context + * The batch context. */ - public function setBatchContext(&$context) { + public function setBatchContext(array &$context) { $this->batchContext = &$context; } @@ -75,6 +76,7 @@ class MigrateBatchExecutable extends MigrateExecutable { * Gets a reference to the current batch context. * * @return array + * The batch context. */ public function &getBatchContext() { return $this->batchContext; @@ -90,7 +92,7 @@ class MigrateBatchExecutable extends MigrateExecutable { $operations = $this->batchOperations([$this->migration], 'import', [ 'limit' => $this->itemLimit, 'update' => $this->updateExistingRows, - 'force' => $this->checkDependencies + 'force' => $this->checkDependencies, ]); if (count($operations) > 0) { @@ -110,20 +112,18 @@ class MigrateBatchExecutable extends MigrateExecutable { /** * Helper to generate the batch operations for importing migrations. * - * @param array $migrations - * @param array $operation + * @param \Drupal\migrate\Plugin\MigrationInterface[] $migrations + * The migrations. + * @param string $operation + * The batch operation to perform. * @param array $options + * The migration options. * * @return array + * The batch operations to perform. */ - protected function batchOperations($migrations, $operation, $options = []) { - + protected function batchOperations(array $migrations, $operation, array $options = []) { $operations = []; - - /** - * @var string $id - * @var Migration $migration - */ foreach ($migrations as $id => $migration) { if (!empty($options['update'])) { @@ -143,14 +143,14 @@ class MigrateBatchExecutable extends MigrateExecutable { $operations += $this->batchOperations($required_migrations, $operation, [ 'limit' => 0, 'update' => $options['update'], - 'force' => $options['force'] + 'force' => $options['force'], ]); } } $operations[] = [ '\Drupal\migrate_tools\MigrateBatchExecutable::batchProcessImport', - [$migration->id(), $options] + [$migration->id(), $options], ]; } @@ -158,15 +158,16 @@ class MigrateBatchExecutable extends MigrateExecutable { } /** - * Batch 'operation' callback + * Batch 'operation' callback. * * @param string $migration_id + * The migration id. * @param array $options + * The batch executable options. * @param array $context - * + * The sandbox context. */ - static public function batchProcessImport($migration_id, $options, &$context) { - + public static function batchProcessImport($migration_id, array $options, array &$context) { if (empty($context['sandbox'])) { $context['finished'] = 0; $context['sandbox'] = []; @@ -178,7 +179,7 @@ class MigrateBatchExecutable extends MigrateExecutable { // Prepare the migration executable. $message = new MigrateMessage(); - /** @var MigrationInterface $migration */ + /** @var \Drupal\migrate\Plugin\MigrationInterface $migration */ $migration = \Drupal::getContainer()->get('plugin.manager.migration')->createInstance($migration_id); $executable = new MigrateBatchExecutable($migration, $message, $options); @@ -191,7 +192,7 @@ class MigrateBatchExecutable extends MigrateExecutable { '@updated' => 0, '@failures' => 0, '@ignored' => 0, - '@name' => $migration->id() + '@name' => $migration->id(), ]; } @@ -204,14 +205,14 @@ class MigrateBatchExecutable extends MigrateExecutable { // Do the import. $result = $executable->import(); - // Store the result, we will need to combine the results of all our iterations. + // Store the result; will need to combine the results of all our iterations. $context['results'][$migration->id()] = [ '@numitems' => $context['results'][$migration->id()]['@numitems'] + $executable->getProcessedCount(), '@created' => $context['results'][$migration->id()]['@created'] + $executable->getCreatedCount(), '@updated' => $context['results'][$migration->id()]['@updated'] + $executable->getUpdatedCount(), '@failures' => $context['results'][$migration->id()]['@failures'] + $executable->getFailedCount(), '@ignored' => $context['results'][$migration->id()]['@ignored'] + $executable->getIgnoredCount(), - '@name' => $migration->id() + '@name' => $migration->id(), ]; // Do some housekeeping. @@ -226,7 +227,7 @@ class MigrateBatchExecutable extends MigrateExecutable { $context['finished'] = ((float) $context['sandbox']['counter'] / (float) $context['sandbox']['total']); $context['message'] = t('Importing %migration (@percent%).', [ '%migration' => $migration->label(), - '@percent' => (int) ($context['finished'] * 100) + '@percent' => (int) ($context['finished'] * 100), ]); } } @@ -236,12 +237,14 @@ class MigrateBatchExecutable extends MigrateExecutable { /** * Finished callback for import batches. * - * @param $success - * @param $results - * @param $operations - * @param $elapsed + * @param bool $success + * A boolean indicating whether the batch has completed successfully. + * @param array $results + * The value set in $context['results'] by callback_batch_operation(). + * @param array $operations + * If $success is FALSE, contains the operations that remained unprocessed. */ - static public function batchFinishedImport($success, $results, $operations, $elapsed) { + public static function batchFinishedImport($success, array $results, array $operations) { if ($success) { foreach ($results as $migration_id => $result) { $singular_message = "Processed 1 item (@created created, @updated updated, @failures failed, @ignored ignored) - done with '@name'"; @@ -255,7 +258,7 @@ class MigrateBatchExecutable extends MigrateExecutable { } /** - * @inheritdoc + * {@inheritdoc} */ public function checkStatus() { $status = parent::checkStatus(); @@ -278,11 +281,13 @@ class MigrateBatchExecutable extends MigrateExecutable { /** * Calculates how much a single batch iteration will handle. * - * @param $context + * @param array $context + * The sandbox context. * * @return float + * The batch limit. */ - public function calculateBatchLimit($context) { + public function calculateBatchLimit(array $context) { // TODO Maybe we need some other more sophisticated logic here? return ceil($context['sandbox']['total'] / 100); } diff --git a/sites/all/modules/contrib/migrate/migrate_tools/src/MigrateExecutable.php b/sites/all/modules/contrib/migrate/migrate_tools/src/MigrateExecutable.php index 01dba4234..9d7f15069 100644 --- a/sites/all/modules/contrib/migrate/migrate_tools/src/MigrateExecutable.php +++ b/sites/all/modules/contrib/migrate/migrate_tools/src/MigrateExecutable.php @@ -17,6 +17,9 @@ use Drupal\migrate\Event\MigrateMapDeleteEvent; use Drupal\migrate\Event\MigrateImportEvent; use Drupal\migrate_plus\Event\MigratePrepareRowEvent; +/** + * Defines a migrate executable class for drush. + */ class MigrateExecutable extends MigrateExecutableBase { /** @@ -40,8 +43,9 @@ class MigrateExecutable extends MigrateExecutableBase { protected $deleteCounter = 0; /** - * Maximum number of items to process in this migration. 0 indicates no limit - * is to be applied. + * Maximum number of items to process in this migration. + * + * 0 indicates no limit is to be applied. * * @var int */ @@ -63,6 +67,7 @@ class MigrateExecutable extends MigrateExecutableBase { /** * Count of number of items processed so far in this migration. + * * @var int */ protected $counter = 0; @@ -149,6 +154,7 @@ class MigrateExecutable extends MigrateExecutableBase { * Return the number of items created. * * @return int + * The number of items created. */ public function getCreatedCount() { return $this->saveCounters[MigrateIdMapInterface::STATUS_IMPORTED]; @@ -158,6 +164,7 @@ class MigrateExecutable extends MigrateExecutableBase { * Return the number of items updated. * * @return int + * The updated count. */ public function getUpdatedCount() { return $this->saveCounters[MigrateIdMapInterface::STATUS_NEEDS_UPDATE]; @@ -167,6 +174,7 @@ class MigrateExecutable extends MigrateExecutableBase { * Return the number of items ignored. * * @return int + * The ignored count. */ public function getIgnoredCount() { return $this->saveCounters[MigrateIdMapInterface::STATUS_IGNORED]; @@ -176,17 +184,20 @@ class MigrateExecutable extends MigrateExecutableBase { * Return the number of items that failed. * * @return int + * The failed count. */ public function getFailedCount() { return $this->saveCounters[MigrateIdMapInterface::STATUS_FAILED]; } /** - * Return the total number of items processed. Note that STATUS_NEEDS_UPDATE - * is not counted, since this is typically set on stubs created as side - * effects, not on the primary item being imported. + * Return the total number of items processed. + * + * Note that STATUS_NEEDS_UPDATE is not counted, since this is typically set + * on stubs created as side effects, not on the primary item being imported. * * @return int + * The processed count. */ public function getProcessedCount() { return $this->saveCounters[MigrateIdMapInterface::STATUS_IMPORTED] + @@ -199,6 +210,7 @@ class MigrateExecutable extends MigrateExecutableBase { * Return the number of items rolled back. * * @return int + * The rollback count. */ public function getRollbackCount() { return $this->deleteCounter; @@ -237,10 +249,12 @@ class MigrateExecutable extends MigrateExecutableBase { } /** - * Emit information on what we've done since the last feedback (or the - * beginning of this migration). + * Emit information on what we've done. + * + * Either since the last feedback or the beginning of this migration. * * @param bool $done + * TRUE if this is the last items to process. Otherwise FALSE. */ protected function progressMessage($done = TRUE) { $processed = $this->getProcessedCount(); @@ -254,12 +268,15 @@ class MigrateExecutable extends MigrateExecutableBase { } $this->message->display(\Drupal::translation()->formatPlural($processed, $singular_message, $plural_message, - ['@numitems' => $processed, - '@created' => $this->getCreatedCount(), - '@updated' => $this->getUpdatedCount(), - '@failures' => $this->getFailedCount(), - '@ignored' => $this->getIgnoredCount(), - '@name' => $this->migration->id()])); + [ + '@numitems' => $processed, + '@created' => $this->getCreatedCount(), + '@updated' => $this->getUpdatedCount(), + '@failures' => $this->getFailedCount(), + '@ignored' => $this->getIgnoredCount(), + '@name' => $this->migration->id(), + ] + )); } /** @@ -274,10 +291,12 @@ class MigrateExecutable extends MigrateExecutableBase { } /** - * Emit information on what we've done since the last feedback (or the - * beginning of this migration). + * Emit information on what we've done. + * + * Either since the last feedback or the beginning of this migration. * * @param bool $done + * TRUE if this is the last items to rollback. Otherwise FALSE. */ protected function rollbackMessage($done = TRUE) { $rolled_back = $this->getRollbackCount(); @@ -290,9 +309,12 @@ class MigrateExecutable extends MigrateExecutableBase { $plural_message = "Rolled back @numitems items - continuing with '@name'"; } $this->message->display(\Drupal::translation()->formatPlural($rolled_back, - $singular_message, $plural_message, - ['@numitems' => $rolled_back, - '@name' => $this->migration->id()])); + $singular_message, $plural_message, + [ + '@numitems' => $rolled_back, + '@name' => $this->migration->id(), + ] + )); } /** @@ -335,9 +357,8 @@ class MigrateExecutable extends MigrateExecutableBase { public function onPrepareRow(MigratePrepareRowEvent $event) { if (!empty($this->idlist)) { $row = $event->getRow(); - /** - * @TODO replace for $source_id = $row->getSourceIdValues(); when https://www.drupal.org/node/2698023 is fixed - */ + // TODO: replace for $source_id = $row->getSourceIdValues(); + // when https://www.drupal.org/node/2698023 is fixed. $migration = $event->getMigration(); $source_id = array_merge(array_flip(array_keys($migration->getSourcePlugin() ->getIds())), $row->getSourceIdValues()); diff --git a/sites/all/modules/contrib/migrate/migrate_tools/tests/modules/migrate_tools_test/migrate_tools_test.info.yml b/sites/all/modules/contrib/migrate/migrate_tools/tests/modules/migrate_tools_test/migrate_tools_test.info.yml index a3688e8a5..ca10d0196 100644 --- a/sites/all/modules/contrib/migrate/migrate_tools/tests/modules/migrate_tools_test/migrate_tools_test.info.yml +++ b/sites/all/modules/contrib/migrate/migrate_tools/tests/modules/migrate_tools_test/migrate_tools_test.info.yml @@ -7,8 +7,8 @@ dependencies: - drupal:migrate (>=8.3) - migrate_plus:migrate_plus -# Information added by Drupal.org packaging script on 2017-11-27 -version: '8.x-4.0-beta2' +# Information added by Drupal.org packaging script on 2018-02-23 +version: '8.x-4.0-beta3' core: '8.x' project: 'migrate_tools' -datestamp: 1511790488 +datestamp: 1519400307 diff --git a/sites/all/modules/contrib/migrate/migrate_tools/tests/src/Functional/MigrateExecutionFormTest.php b/sites/all/modules/contrib/migrate/migrate_tools/tests/src/Functional/MigrateExecutionFormTest.php index 76bb7caca..2f29bf5ba 100644 --- a/sites/all/modules/contrib/migrate/migrate_tools/tests/src/Functional/MigrateExecutionFormTest.php +++ b/sites/all/modules/contrib/migrate/migrate_tools/tests/src/Functional/MigrateExecutionFormTest.php @@ -6,7 +6,7 @@ use Drupal\taxonomy\Entity\Vocabulary; use Drupal\Tests\BrowserTestBase; /** - * Execution form test + * Execution form test. * * @group migrate_tools */ diff --git a/sites/all/modules/contrib/views/views_bulk_edit/README.txt b/sites/all/modules/contrib/views/views_bulk_edit/README.txt new file mode 100644 index 000000000..c8cabd78e --- /dev/null +++ b/sites/all/modules/contrib/views/views_bulk_edit/README.txt @@ -0,0 +1,29 @@ +Introduction +------------ + +Views Bulk Edit allows modifying field values of a selected list of entities +of any type. It works with Views Bulk Operations (VBO) module, offering all of its +benefits like batching, ability to select all view results or persistent +selection across pages. + + +Requirements +------------ + +Views Bulk Edit requires Views Bulk operations module to be installed. + + +Installation +------------ + +Install as any other Drupal 8 module. + + +Configuration +------------- + +1. Create or edit any view, the most convenient display type for end + user in case of VBO views is Table. +2. Add a "Views bulk operations" field (global), available on + all entity types, if not already added. +3. Check the "Modify field values" action. diff --git a/sites/all/modules/contrib/views/views_bulk_edit/composer.json b/sites/all/modules/contrib/views/views_bulk_edit/composer.json index 149365759..d46feae44 100644 --- a/sites/all/modules/contrib/views/views_bulk_edit/composer.json +++ b/sites/all/modules/contrib/views/views_bulk_edit/composer.json @@ -2,7 +2,16 @@ "name": "drupal/views_bulk_edit", "type": "drupal-module", "description": "Allows bulk edition of entity field values.", - "homepage": "http://drupal.org/project/views_bulk_edit", + "homepage": "https://www.drupal.org/project/views_bulk_edit", + "authors": [ + { + "name": "Marcin Grabias", + "homepage": "https://www.drupal.org/u/graber" + } + ], + "support": { + "issues": "https://www.drupal.org/project/issues/views_bulk_edit?version=8.x" + }, "license": "GPL-2.0+", "require": { "drupal/views_bulk_operations": "~1.0 | ~2.0" diff --git a/sites/all/modules/contrib/views/views_bulk_edit/src/Plugin/Action/ModifyEntityValues.php b/sites/all/modules/contrib/views/views_bulk_edit/src/Plugin/Action/ModifyEntityValues.php index 16d1cf214..a1a6df0dc 100644 --- a/sites/all/modules/contrib/views/views_bulk_edit/src/Plugin/Action/ModifyEntityValues.php +++ b/sites/all/modules/contrib/views/views_bulk_edit/src/Plugin/Action/ModifyEntityValues.php @@ -52,6 +52,8 @@ class ModifyEntityValues extends ViewsBulkOperationsActionBase implements Contai * Entity type manager. * @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $bundleInfo * Bundle info object. + * @param \Drupal\Core\Database\Connection $database + * Database conection. */ public function __construct(array $configuration, $plugin_id, $plugin_definition, ViewsbulkOperationsViewData $viewDataService, ViewsBulkOperationsActionProcessor $actionProcessor, EntityTypeManagerInterface $entityTypeManager, EntityTypeBundleInfoInterface $bundleInfo, Connection $database) { parent::__construct($configuration, $plugin_id, $plugin_definition); @@ -290,6 +292,8 @@ class ModifyEntityValues extends ViewsBulkOperationsActionBase implements Contai * Given an entity form, create a selector form to provide options to update * values. * + * @param string $entity_type_id + * Entity type ID. * @param string $bundle * The bundle machine name. * @param array $form diff --git a/sites/all/modules/contrib/views/views_bulk_edit/tests/src/Functional/ViewsBulkEditModifyEntityValuesTest.php b/sites/all/modules/contrib/views/views_bulk_edit/tests/src/Functional/ViewsBulkEditModifyEntityValuesTest.php new file mode 100644 index 000000000..1d8de05eb --- /dev/null +++ b/sites/all/modules/contrib/views/views_bulk_edit/tests/src/Functional/ViewsBulkEditModifyEntityValuesTest.php @@ -0,0 +1,158 @@ +createContentType(['type' => 'article', 'name' => 'Article']); + $this->createContentType(['type' => 'page', 'name' => 'Page']); + + // Create a text field on the page content type. + $entityTypeManager = $this->container->get('entity_type.manager'); + $entityTypeManager->getStorage('field_storage_config')->create([ + 'field_name' => 'text', + 'entity_type' => 'node', + 'type' => 'text', + 'module' => 'text', + 'cardinality' => 1, + ])->save(); + $entityTypeManager->getStorage('field_config')->create([ + 'field_name' => 'text', + 'entity_type' => 'node', + 'bundle' => 'page', + 'label' => 'Field text', + ])->save(); + $entityTypeManager->getStorage('entity_form_display')->load('node.page.default')->setComponent('text', [ + 'type' => 'text_textfield', + 'region' => 'content', + 'settings' => [ + 'size' => 10, + ], + ])->save(); + + $this->testNodes = []; + $time = REQUEST_TIME; + for ($i = 0; $i < 4; $i++) { + // Ensure nodes are sorted in the same order they are inserted in the + // array. + $time -= $i; + $type = ($i % 2 == 0) ? 'article' : 'page'; + $this->testNodes[] = $this->drupalCreateNode([ + // Bundles will be: page, article, page, article. + 'type' => $type, + 'title' => 'Title ' . $i . ' (' . $type . ')', + 'sticky' => FALSE, + 'created' => $time, + 'changed' => $time, + ]); + } + + } + + /** + * Test the bulk edit operation. + */ + public function testViewsBulkEdit() { + + // Log in as a user with 'edit any page content' permission + // to have access to perform the test operation. + $admin_user = $this->drupalCreateUser([ + 'administer nodes', + 'bypass node access', + 'execute advanced test action', + ]); + $this->drupalLogin($admin_user); + + // Modify config of the test view: add the views_bulk_edit operation, + // set items per page to 10 and offset to 0. + $testViewConfig = $this->container->get('config.factory')->getEditable('views.view.views_bulk_operations_test_advanced'); + $configData = $testViewConfig->getRawData(); + $configData['display']['default']['display_options']['fields']['views_bulk_operations_bulk_form']['selected_actions']['views_bulk_edit'] = 'views_bulk_edit'; + $configData['display']['default']['display_options']['fields']['views_bulk_operations_bulk_form']['preconfiguration']['views_bulk_edit'] = ['label_override' => '']; + $configData['display']['default']['display_options']['pager']['options']['items_per_page'] = 10; + $configData['display']['default']['display_options']['pager']['options']['offset'] = 0; + $testViewConfig->setData($configData); + $testViewConfig->save(); + + // Post the VBO form with one page and one article selected. + $edit = [ + 'action' => 'views_bulk_edit', + 'views_bulk_operations_bulk_form[1]' => TRUE, + 'views_bulk_operations_bulk_form[2]' => TRUE, + ]; + $this->drupalPostForm('views-bulk-operations-test-advanced', $edit, t('Apply to selected items')); + + // Post the configuration form: modify status and text value field on the + // article content type. + $expected_text_value = 'some text'; + $this->drupalPostForm(NULL, [ + 'node[article][_field_selector][status]' => TRUE, + 'node[article][status][value]' => FALSE, + 'node[page][_field_selector][status]' => TRUE, + 'node[page][status][value]' => FALSE, + 'node[page][_field_selector][text]' => TRUE, + 'node[page][text][0][value]' => $expected_text_value, + ], t('Apply')); + + // Assert if field values have been changed on the selected entities + // and unchanged otherwise. + $nodeStorage = $this->container->get('entity_type.manager')->getStorage('node'); + + foreach ($this->testNodes as $index => $node) { + // Reload the node. + $node = $nodeStorage->load($node->id()); + $status = intval($node->status->value); + $text = isset($node->text) ? $node->text->value : FALSE; + + switch ($index) { + case 0: + $this->assertEquals(NodeInterface::PUBLISHED, $status); + $this->assertEquals(FALSE, $text); + break; + + case 1: + $this->assertEquals(NodeInterface::NOT_PUBLISHED, $status); + $this->assertEquals($expected_text_value, $text); + break; + + case 2: + $this->assertEquals(NodeInterface::NOT_PUBLISHED, $status); + $this->assertEquals(FALSE, $text); + break; + + case 3: + $this->assertEquals(NodeInterface::PUBLISHED, $status); + $this->assertEquals('', $text); + break; + } + } + } + +} diff --git a/sites/all/modules/contrib/views/views_bulk_edit/tests/src/Kernel/ViewsBulkEditActionTest.php b/sites/all/modules/contrib/views/views_bulk_edit/tests/src/Kernel/ViewsBulkEditActionTest.php new file mode 100644 index 000000000..b55592a29 --- /dev/null +++ b/sites/all/modules/contrib/views/views_bulk_edit/tests/src/Kernel/ViewsBulkEditActionTest.php @@ -0,0 +1,79 @@ +createTestNodes([ + 'page' => [ + 'count' => 10, + ], + ]); + } + + /** + * Tests the bulk edit action. + * + * @covers ::getViewBundles + * @covers ::execute + */ + public function testModifyEntityValues() { + $vbo_data = [ + 'view_id' => 'views_bulk_operations_test', + 'action_id' => 'views_bulk_edit', + 'configuration' => [ + 'node' => [ + 'page' => [ + 'status' => [ + ['value' => 0], + ], + ], + ], + ], + ]; + + // Get list of rows to process from different view pages. + $selection = [0, 3, 6, 8]; + $vbo_data['list'] = $this->getResultsList($vbo_data, $selection); + + // Execute the action. + $results = $this->executeAction($vbo_data); + + $nodeStorage = $this->container->get('entity_type.manager')->getStorage('node'); + + $statuses = []; + + foreach ($this->testNodesData as $id => $lang_data) { + $node = $nodeStorage->load($id); + $status = intval($node->status->value); + foreach ($vbo_data['list'] as $item) { + if ($item[3] == $id) { + $this->assertEquals(NodeInterface::NOT_PUBLISHED, $status); + break 2; + } + } + $this->assertEquals(NodeInterface::PUBLISHED, $status); + } + } + +} diff --git a/sites/all/modules/contrib/views/views_bulk_edit/views_bulk_edit.info.yml b/sites/all/modules/contrib/views/views_bulk_edit/views_bulk_edit.info.yml index dbea0751e..dd58266e6 100644 --- a/sites/all/modules/contrib/views/views_bulk_edit/views_bulk_edit.info.yml +++ b/sites/all/modules/contrib/views/views_bulk_edit/views_bulk_edit.info.yml @@ -6,8 +6,8 @@ package: 'Views Bulk Operations' dependencies: - drupal:views_bulk_operations -# Information added by Drupal.org packaging script on 2018-02-06 -version: '8.x-2.0-beta4' +# Information added by Drupal.org packaging script on 2018-03-12 +version: '8.x-2.0-rc1' core: '8.x' project: 'views_bulk_edit' -datestamp: 1517947086 +datestamp: 1520840585 diff --git a/sites/all/modules/contrib/views/views_bulk_edit/views_bulk_edit.module b/sites/all/modules/contrib/views/views_bulk_edit/views_bulk_edit.module new file mode 100644 index 000000000..56bca3c4f --- /dev/null +++ b/sites/all/modules/contrib/views/views_bulk_edit/views_bulk_edit.module @@ -0,0 +1,24 @@ +' . $readme . ''; + + return $output; + } + } +} diff --git a/sites/all/modules/contrib/views/views_bulk_operations/modules/actions_permissions/actions_permissions.info.yml b/sites/all/modules/contrib/views/views_bulk_operations/modules/actions_permissions/actions_permissions.info.yml index 4f0bb4f4c..144d7f91b 100644 --- a/sites/all/modules/contrib/views/views_bulk_operations/modules/actions_permissions/actions_permissions.info.yml +++ b/sites/all/modules/contrib/views/views_bulk_operations/modules/actions_permissions/actions_permissions.info.yml @@ -6,8 +6,8 @@ package: 'Views Bulk Operations' dependencies: - drupal:views_bulk_operations -# Information added by Drupal.org packaging script on 2018-02-08 -version: '8.x-2.0-rc4+1-dev' +# Information added by Drupal.org packaging script on 2018-03-10 +version: '8.x-2.1' core: '8.x' project: 'views_bulk_operations' -datestamp: 1518076986 +datestamp: 1520668088 diff --git a/sites/all/modules/contrib/views/views_bulk_operations/modules/views_bulk_operations_example/views_bulk_operations_example.info.yml b/sites/all/modules/contrib/views/views_bulk_operations/modules/views_bulk_operations_example/views_bulk_operations_example.info.yml index f6dac3b4a..1752d29fd 100644 --- a/sites/all/modules/contrib/views/views_bulk_operations/modules/views_bulk_operations_example/views_bulk_operations_example.info.yml +++ b/sites/all/modules/contrib/views/views_bulk_operations/modules/views_bulk_operations_example/views_bulk_operations_example.info.yml @@ -6,8 +6,8 @@ package: 'Examples' dependencies: - drupal:views_bulk_operations -# Information added by Drupal.org packaging script on 2018-02-08 -version: '8.x-2.0-rc4+1-dev' +# Information added by Drupal.org packaging script on 2018-03-10 +version: '8.x-2.1' core: '8.x' project: 'views_bulk_operations' -datestamp: 1518076986 +datestamp: 1520668088 diff --git a/sites/all/modules/contrib/views/views_bulk_operations/tests/src/Kernel/ViewsBulkOperationsActionProcessorTest.php b/sites/all/modules/contrib/views/views_bulk_operations/tests/src/Kernel/ViewsBulkOperationsActionProcessorTest.php new file mode 100644 index 000000000..a62a06233 --- /dev/null +++ b/sites/all/modules/contrib/views/views_bulk_operations/tests/src/Kernel/ViewsBulkOperationsActionProcessorTest.php @@ -0,0 +1,89 @@ +createTestNodes([ + 'page' => [ + 'count' => 20, + ], + ]); + } + + /** + * Tests general functionality of ViewsBulkOperationsActionProcessor. + * + * @covers ::getPageList + * @covers ::populateQueue + * @covers ::process + */ + public function testViewsbulkOperationsActionProcessor() { + $vbo_data = [ + 'view_id' => 'views_bulk_operations_test', + 'action_id' => 'views_bulk_operations_simple_test_action', + 'configuration' => [ + 'preconfig' => 'test', + ], + ]; + + // Test executing all view results first. + $results = $this->executeAction($vbo_data); + + // The default batch size is 10 and there are 20 result rows total + // (10 nodes, each having a translation), check messages: + $this->assertEquals('Processed 10 of 20 entities.', $results['messages'][0]); + $this->assertEquals('Processed 20 of 20 entities.', $results['messages'][1]); + $this->assertEquals(20, $results['operations']['Test']); + + // For a more advanced test, check if randomly selected entities + // have been unpublished. + $vbo_data = [ + 'view_id' => 'views_bulk_operations_test', + 'action_id' => 'views_bulk_operations_advanced_test_action', + 'preconfiguration' => [ + 'test_preconfig' => 'test', + 'test_config' => 'unpublish', + ], + ]; + + // Get list of rows to process from different view pages. + $selection = [0, 3, 6, 8, 15, 16, 18]; + $vbo_data['list'] = $this->getResultsList($vbo_data, $selection); + + // Execute the action. + $results = $this->executeAction($vbo_data); + + $nodeStorage = $this->container->get('entity_type.manager')->getStorage('node'); + + $statuses = []; + + foreach ($this->testNodesData as $id => $lang_data) { + $node = $nodeStorage->load($id); + $statuses[$id] = intval($node->status->value); + } + + foreach ($statuses as $id => $status) { + foreach ($vbo_data['list'] as $item) { + if ($item[3] == $id) { + $this->assertEquals(NodeInterface::NOT_PUBLISHED, $status); + break 2; + } + } + $this->assertEquals(NodeInterface::PUBLISHED, $status); + } + } + +} diff --git a/sites/all/modules/contrib/views/views_bulk_operations/tests/src/Kernel/ViewsBulkOperationsDataServiceTest.php b/sites/all/modules/contrib/views/views_bulk_operations/tests/src/Kernel/ViewsBulkOperationsDataServiceTest.php index e640a1082..1a004a32b 100644 --- a/sites/all/modules/contrib/views/views_bulk_operations/tests/src/Kernel/ViewsBulkOperationsDataServiceTest.php +++ b/sites/all/modules/contrib/views/views_bulk_operations/tests/src/Kernel/ViewsBulkOperationsDataServiceTest.php @@ -2,62 +2,13 @@ namespace Drupal\Tests\views_bulk_operations\Kernel; -use Drupal\KernelTests\KernelTestBase; -use Drupal\simpletest\NodeCreationTrait; -use Drupal\node\Entity\NodeType; -use Drupal\user\Entity\User; use Drupal\views\Views; -use Drupal\language\Entity\ConfigurableLanguage; /** * @coversDefaultClass \Drupal\views_bulk_operations\Service\ViewsBulkOperationsViewData * @group views_bulk_operations */ -class ViewsBulkOperationsDataServiceTest extends KernelTestBase { - - use NodeCreationTrait { - getNodeByTitle as drupalGetNodeByTitle; - createNode as drupalCreateNode; - } - - /** - * Test nodes data. - * - * @var array - */ - protected $testNodesData; - - /** - * The expected total number of view results. - * - * @var int - */ - protected $resultsCount = 0; - - /** - * The tested service. - * - * @var \Drupal\views_bulk_operations\Service\ViewsbulkOperationsViewData - */ - protected $vboDataService; - - /** - * {@inheritdoc} - */ - public static $modules = [ - 'user', - 'node', - 'field', - 'content_translation', - 'views_bulk_operations', - 'views_bulk_operations_test', - 'views', - 'filter', - 'language', - 'text', - 'action', - 'system', - ]; +class ViewsBulkOperationsDataServiceTest extends ViewsBulkOperationsKernelTestBase { /** * {@inheritdoc} @@ -65,71 +16,12 @@ class ViewsBulkOperationsDataServiceTest extends KernelTestBase { public function setUp() { parent::setUp(); - $this->installEntitySchema('user'); - $this->installEntitySchema('node'); - $this->installSchema('node', 'node_access'); - $this->installSchema('system', 'sequences'); - $this->installSchema('system', 'key_value_expire'); - - $user = User::create(); - $user->setPassword('password'); - $user->enforceIsNew(); - $user->setEmail('email'); - $user->setUsername('user_name'); - $user->save(); - user_login_finalize($user); - - $this->installConfig([ - 'system', - 'filter', - 'views_bulk_operations_test', - 'language', + $this->createTestNodes([ + 'page' => [ + 'languages' => ['pl', 'es', 'it', 'fr', 'de'], + 'count' => 20, + ], ]); - - $languages = ['pl', 'es', 'it', 'fr', 'de']; - $count_languages = count($languages); - for ($i = 0; $i < $count_languages; $i++) { - $language = ConfigurableLanguage::createFromLangcode($languages[$i]); - $language->save(); - } - - $type = NodeType::create([ - 'type' => 'page', - 'name' => 'page', - ]); - $type->save(); - - \Drupal::service('content_translation.manager')->setEnabled('node', 'page', TRUE); - \Drupal::entityManager()->clearCachedDefinitions(); - - // Create some test nodes with translations. - $this->testNodesData = []; - $time = REQUEST_TIME; - for ($i = 0; $i < 10; $i++) { - $time -= $i; - $title = 'Title ' . $i; - $node = $this->drupalCreateNode([ - 'type' => 'page', - 'title' => $title, - 'sticky' => FALSE, - 'created' => $time, - 'changed' => $time, - ]); - $this->testNodesData[$node->id()]['en'] = $title; - $this->resultsCount++; - - $langcode = $languages[rand(0, $count_languages - 1)]; - $title = 'Translated title ' . $langcode . ' ' . $i; - $translation = $node->addTranslation($langcode, [ - 'title' => $title, - ]); - $translation->save(); - $this->testNodesData[$node->id()][$langcode] = $title; - $this->resultsCount++; - } - - // Initialize the tested service. - $this->vboDataService = $this->container->get('views_bulk_operations.data'); } /** @@ -138,7 +30,6 @@ class ViewsBulkOperationsDataServiceTest extends KernelTestBase { * @covers ::getEntityDefault */ public function testViewsbulkOperationsViewDataEntityGetter() { - $this->assertTrue(TRUE); // Initialize and execute the test view with all items displayed. $view = Views::getView('views_bulk_operations_test'); $view->setDisplay('page_1'); diff --git a/sites/all/modules/contrib/views/views_bulk_operations/tests/src/Kernel/ViewsBulkOperationsKernelTestBase.php b/sites/all/modules/contrib/views/views_bulk_operations/tests/src/Kernel/ViewsBulkOperationsKernelTestBase.php new file mode 100644 index 000000000..00264d00a --- /dev/null +++ b/sites/all/modules/contrib/views/views_bulk_operations/tests/src/Kernel/ViewsBulkOperationsKernelTestBase.php @@ -0,0 +1,296 @@ + [], + 'display_id' => 'default', + 'preconfiguration' => [], + 'batch' => TRUE, + 'arguments' => [], + 'exposed_input' => [], + 'batch_size' => 10, + 'relationship_id' => 'none', + ]; + + /** + * Test node types already created. + * + * @var array + */ + protected $testNodesTypes; + + + /** + * Test nodes data including titles and languages. + * + * @var array + */ + protected $testNodesData; + + /** + * VBO views data service. + * + * @var \Drupal\views_bulk_operations\Service\ViewsBulkOperationsViewDataInterface + */ + protected $vboDataService; + + /** + * {@inheritdoc} + */ + public static $modules = [ + 'user', + 'node', + 'field', + 'content_translation', + 'views_bulk_operations', + 'views_bulk_operations_test', + 'views', + 'filter', + 'language', + 'text', + 'action', + 'system', + ]; + + /** + * {@inheritdoc} + */ + public function setUp() { + parent::setUp(); + + $this->installEntitySchema('user'); + $this->installEntitySchema('node'); + $this->installSchema('node', 'node_access'); + $this->installSchema('system', 'sequences'); + $this->installSchema('system', 'key_value_expire'); + + $user = User::create(); + $user->setPassword('password'); + $user->enforceIsNew(); + $user->setEmail('email'); + $user->setUsername('user_name'); + $user->save(); + user_login_finalize($user); + + $this->installConfig([ + 'system', + 'filter', + 'views_bulk_operations_test', + 'language', + ]); + + // Get VBO view data service. + $this->vboDataService = $this->container->get('views_bulk_operations.data'); + } + + /** + * Create some test nodes. + * + * @param array $test_node_data + * Describes test node bundles and properties. + * + * @see Drupal\Tests\views_bulk_operations\Kernel\ViewsBulkOperationsDataServiceTest::setUp() + */ + protected function createTestNodes(array $test_node_data) { + $this->testNodesData = []; + foreach ($test_node_data as $type_name => $type_data) { + $type = NodeType::create([ + 'type' => $type_name, + 'name' => $type_name, + ]); + $type->save(); + + $count_languages = isset($type_data['languages']) ? count($type_data['languages']) : 0; + if ($count_languages) { + for ($i = 0; $i < $count_languages; $i++) { + $language = ConfigurableLanguage::createFromLangcode($type_data['languages'][$i]); + $language->save(); + } + $this->container->get('content_translation.manager')->setEnabled('node', $type_name, TRUE); + // $this->container->get('entity_type.manager')->clearCachedDefinitions(); + } + + // Create some test nodes. + $time = REQUEST_TIME; + if (!isset($type_data['count'])) { + $type_data['count'] = 10; + } + for ($i = 0; $i < $type_data['count']; $i++) { + $time -= $i; + $title = 'Title ' . $i; + $node = $this->drupalCreateNode([ + 'type' => $type_name, + 'title' => $title, + 'sticky' => FALSE, + 'created' => $time, + 'changed' => $time, + ]); + $this->testNodesData[$node->id()]['en'] = $title; + + if ($count_languages) { + // It doesn't really matter to which languages we translate + // from the API point of view so some randomness should be fine. + $langcode = $type_data['languages'][rand(0, $count_languages - 1)]; + $title = 'Translated title ' . $langcode . ' ' . $i; + $translation = $node->addTranslation($langcode, [ + 'title' => $title, + ]); + $translation->save(); + $this->testNodesData[$node->id()][$langcode] = $title; + } + } + } + } + + /** + * Initialize and return the view described by $vbo_data. + * + * @param array $vbo_data + * An array of data passed to VBO Processor service. + * + * @return \Drupal\views\ViewExecutable + * The view object. + */ + protected function initializeView(array $vbo_data) { + if (!$view = Views::getView($vbo_data['view_id'])) { + throw new \Exception('Incorrect view ID provided.'); + } + if (!$view->setDisplay($vbo_data['display_id'])) { + throw new \Exception('Incorrect view display ID provided.'); + } + $view->built = FALSE; + $view->executed = FALSE; + + return $view; + } + + /** + * Get a random list of results bulk keys. + * + * @param array $vbo_data + * An array of data passed to VBO Processor service. + * @param array $deltas + * Array of result rows deltas. + * + * @return array + * List of results to process. + */ + protected function getResultsList(array $vbo_data, array $deltas) { + // Merge in defaults. + $vbo_data += static::VBO_DEFAULTS; + + $view = $this->initializeView($vbo_data); + if (!empty($vbo_data['arguments'])) { + $view->setArguments($vbo_data['arguments']); + } + if (!empty($vbo_data['exposed_input'])) { + $view->setExposedInput($vbo_data['exposed_input']); + } + + $view->setItemsPerPage(0); + $view->setCurrentPage(0); + $view->execute(); + + $this->vboDataService->init($view, $view->getDisplay(), $vbo_data['relationship_id']); + + $list = []; + $base_field = $view->storage->get('base_field'); + foreach ($deltas as $delta) { + $entity = $this->vboDataService->getEntity($view->result[$delta]); + + $list[] = [ + $view->result[$delta]->{$base_field}, + $entity->language()->getId(), + $entity->getEntityTypeId(), + $entity->id(), + ]; + } + + $view->destroy(); + + return $list; + } + + /** + * Execute an action on a specific view results. + * + * @param array $vbo_data + * An array of data passed to VBO Processor service. + */ + protected function executeAction(array $vbo_data) { + + // Merge in defaults. + $vbo_data += static::VBO_DEFAULTS; + + $view = $this->initializeView($vbo_data); + $view->get_total_rows = TRUE; + + $view->execute(); + + // Get total rows count. + $this->vboDataService->init($view, $view->getDisplay(), $vbo_data['relationship_id']); + $vbo_data['total_results'] = $this->vboDataService->getTotalResults(); + + // Get action definition and check if action ID is correct. + $action_definition = $this->container->get('plugin.manager.views_bulk_operations_action')->getDefinition($vbo_data['action_id']); + if (!isset($vbo_data['action_label'])) { + $vbo_data['action_label'] = (string) $action_definition['label']; + } + + // Populate entity list if empty. + if (empty($vbo_data['list'])) { + $context = []; + do { + $context['finished'] = 1; + $context['message'] = ''; + ViewsBulkOperationsBatch::getList($vbo_data, $context); + } while ($context['finished'] < 1); + $vbo_data = $context['results']; + } + + $summary = [ + 'messages' => [], + ]; + + // Execute the selected action. + $context = []; + do { + $context['finished'] = 1; + $context['message'] = ''; + ViewsBulkOperationsBatch::operation($vbo_data, $context); + if (!empty($context['message'])) { + $summary['messages'][] = (string) $context['message']; + } + } while ($context['finished'] < 1); + + // Add information to the summary array. + $summary += [ + 'operations' => array_count_values($context['results']['operations']), + ]; + + return $summary; + } + +} diff --git a/sites/all/modules/contrib/views/views_bulk_operations/tests/views_bulk_operations_test/config/install/views.view.views_bulk_operations_test.yml b/sites/all/modules/contrib/views/views_bulk_operations/tests/views_bulk_operations_test/config/install/views.view.views_bulk_operations_test.yml index 6c8d17336..9a2d0057f 100644 --- a/sites/all/modules/contrib/views/views_bulk_operations/tests/views_bulk_operations_test/config/install/views.view.views_bulk_operations_test.yml +++ b/sites/all/modules/contrib/views/views_bulk_operations/tests/views_bulk_operations_test/config/install/views.view.views_bulk_operations_test.yml @@ -181,7 +181,22 @@ display: preconfig: 'Test setting' plugin_id: views_bulk_operations_bulk_form filters: { } - sorts: { } + sorts: + created: + id: created + table: node_field_data + field: created + relationship: none + group_type: group + admin_label: '' + order: DESC + exposed: false + expose: + label: '' + granularity: second + entity_type: node + entity_field: created + plugin_id: date title: 'Views Bulk Operations Test' header: { } footer: { } diff --git a/sites/all/modules/contrib/views/views_bulk_operations/tests/views_bulk_operations_test/config/install/views.view.views_bulk_operations_test_advanced.yml b/sites/all/modules/contrib/views/views_bulk_operations/tests/views_bulk_operations_test/config/install/views.view.views_bulk_operations_test_advanced.yml index 9fa3c93af..67805a381 100644 --- a/sites/all/modules/contrib/views/views_bulk_operations/tests/views_bulk_operations_test/config/install/views.view.views_bulk_operations_test_advanced.yml +++ b/sites/all/modules/contrib/views/views_bulk_operations/tests/views_bulk_operations_test/config/install/views.view.views_bulk_operations_test_advanced.yml @@ -219,7 +219,22 @@ display: entity_type: node entity_field: status plugin_id: boolean - sorts: { } + sorts: + created: + id: created + table: node_field_data + field: created + relationship: none + group_type: group + admin_label: '' + order: DESC + exposed: false + expose: + label: '' + granularity: second + entity_type: node + entity_field: created + plugin_id: date title: 'Views Bulk Operations Test' header: { } footer: { } diff --git a/sites/all/modules/contrib/views/views_bulk_operations/tests/views_bulk_operations_test/src/Plugin/Action/ViewsBulkOperationsAdvancedTestAction.php b/sites/all/modules/contrib/views/views_bulk_operations/tests/views_bulk_operations_test/src/Plugin/Action/ViewsBulkOperationsAdvancedTestAction.php index 90029f724..b56702688 100644 --- a/sites/all/modules/contrib/views/views_bulk_operations/tests/views_bulk_operations_test/src/Plugin/Action/ViewsBulkOperationsAdvancedTestAction.php +++ b/sites/all/modules/contrib/views/views_bulk_operations/tests/views_bulk_operations_test/src/Plugin/Action/ViewsBulkOperationsAdvancedTestAction.php @@ -46,7 +46,10 @@ class ViewsBulkOperationsAdvancedTestAction extends ViewsBulkOperationsActionBas // Unpublish entity. if ($this->configuration['test_config'] === 'unpublish') { - $entity->status = NODE_NOT_PUBLISHED; + if (!$entity->isDefaultTranslation()) { + $entity = \Drupal::service('entity_type.manager')->getStorage('node')->load($entity->id()); + } + $entity->setPublished(FALSE); $entity->save(); } diff --git a/sites/all/modules/contrib/views/views_bulk_operations/tests/views_bulk_operations_test/views_bulk_operations_test.info.yml b/sites/all/modules/contrib/views/views_bulk_operations/tests/views_bulk_operations_test/views_bulk_operations_test.info.yml index 51886a831..f49899bcb 100644 --- a/sites/all/modules/contrib/views/views_bulk_operations/tests/views_bulk_operations_test/views_bulk_operations_test.info.yml +++ b/sites/all/modules/contrib/views/views_bulk_operations/tests/views_bulk_operations_test/views_bulk_operations_test.info.yml @@ -7,8 +7,8 @@ dependencies: - drupal:views_bulk_operations - drupal:node -# Information added by Drupal.org packaging script on 2018-02-08 -version: '8.x-2.0-rc4+1-dev' +# Information added by Drupal.org packaging script on 2018-03-10 +version: '8.x-2.1' core: '8.x' project: 'views_bulk_operations' -datestamp: 1518076986 +datestamp: 1520668088 diff --git a/sites/all/modules/contrib/views/views_bulk_operations/views_bulk_operations.info.yml b/sites/all/modules/contrib/views/views_bulk_operations/views_bulk_operations.info.yml index 236e4822b..c4a22d2fa 100644 --- a/sites/all/modules/contrib/views/views_bulk_operations/views_bulk_operations.info.yml +++ b/sites/all/modules/contrib/views/views_bulk_operations/views_bulk_operations.info.yml @@ -6,8 +6,8 @@ package: 'Views' dependencies: - drupal:views (>=8.4) -# Information added by Drupal.org packaging script on 2018-02-08 -version: '8.x-2.0-rc4+1-dev' +# Information added by Drupal.org packaging script on 2018-03-10 +version: '8.x-2.1' core: '8.x' project: 'views_bulk_operations' -datestamp: 1518076986 +datestamp: 1520668088 diff --git a/sites/default/config/sync/core.extension.yml b/sites/default/config/sync/core.extension.yml index ca0798108..3a72c938a 100644 --- a/sites/default/config/sync/core.extension.yml +++ b/sites/default/config/sync/core.extension.yml @@ -52,7 +52,6 @@ module: link: 0 linkit: 0 locale: 0 - login_destination: 0 maillog: 0 menu_ui: 0 migrate: 0 diff --git a/sites/default/config/sync/locale.settings.yml b/sites/default/config/sync/locale.settings.yml index 1a4c03b8a..cf5066ba4 100644 --- a/sites/default/config/sync/locale.settings.yml +++ b/sites/default/config/sync/locale.settings.yml @@ -5,7 +5,7 @@ javascript: translation: use_source: remote_and_local default_filename: '%project-%version.%language.po' - default_server_pattern: 'http://ftp.drupal.org/files/translations/%core/%project/%project-%version.%language.po' + default_server_pattern: 'https://ftp.drupal.org/files/translations/%core/%project/%project-%version.%language.po' overwrite_customized: false overwrite_not_customized: true update_interval_days: 0 diff --git a/sites/default/config/sync/login_destination.destination.admin.yml b/sites/default/config/sync/login_destination.destination.admin.yml deleted file mode 100644 index d2883ea5e..000000000 --- a/sites/default/config/sync/login_destination.destination.admin.yml +++ /dev/null @@ -1,15 +0,0 @@ -uuid: 8bf9796d-9629-497d-b98e-23b913147c98 -langcode: fr -status: true -dependencies: { } -name: admin -label: Admin -triggers: - login: login -destination_path: 'internal:/admin/content/collection' -pages_type: 0 -pages: '' -roles: - admin: admin -weight: 0 -enabled: true diff --git a/sites/default/config/sync/login_destination.destination.collectionneur.yml b/sites/default/config/sync/login_destination.destination.collectionneur.yml deleted file mode 100644 index 1ca40f4ce..000000000 --- a/sites/default/config/sync/login_destination.destination.collectionneur.yml +++ /dev/null @@ -1,15 +0,0 @@ -uuid: b51bd11c-541e-410c-8c71-ec03ca936dff -langcode: fr -status: true -dependencies: { } -name: collectionneur -label: Collectionneur -triggers: - login: login -destination_path: 'internal:/admin/content/collection' -pages_type: 0 -pages: '' -roles: - collectionneur: collectionneur -weight: 0 -enabled: true diff --git a/sites/default/config/sync/login_destination.destination.root.yml b/sites/default/config/sync/login_destination.destination.root.yml deleted file mode 100644 index e5b30d319..000000000 --- a/sites/default/config/sync/login_destination.destination.root.yml +++ /dev/null @@ -1,15 +0,0 @@ -uuid: f82c8723-f591-40ab-8ca3-9e3c5d1bdb81 -langcode: fr -status: true -dependencies: { } -name: root -label: Root -triggers: - login: login -destination_path: 'internal:/admin/content/collection' -pages_type: 0 -pages: '' -roles: - root: root -weight: 0 -enabled: true diff --git a/sites/default/config/sync/login_destination.settings.yml b/sites/default/config/sync/login_destination.settings.yml deleted file mode 100644 index ab3a23498..000000000 --- a/sites/default/config/sync/login_destination.settings.yml +++ /dev/null @@ -1,5 +0,0 @@ -preserve_destination: false -immediate_redirect: false -_core: - default_config_hash: SWXPN5YCm4J7782lXTPqDAneUijUwni85dQTQVjHYtw -langcode: fr diff --git a/sites/default/config/sync/migrate_drupal.settings.yml b/sites/default/config/sync/migrate_drupal.settings.yml new file mode 100644 index 000000000..55482b4d9 --- /dev/null +++ b/sites/default/config/sync/migrate_drupal.settings.yml @@ -0,0 +1,3 @@ +enforce_source_module_tags: + - 'Drupal 6' + - 'Drupal 7' diff --git a/sites/default/config/sync/system.action.node_publish_action.yml b/sites/default/config/sync/system.action.node_publish_action.yml index 1067c73b0..78921cb89 100644 --- a/sites/default/config/sync/system.action.node_publish_action.yml +++ b/sites/default/config/sync/system.action.node_publish_action.yml @@ -9,5 +9,5 @@ _core: id: node_publish_action label: 'Publier un contenu' type: node -plugin: node_publish_action +plugin: 'entity:publish_action:node' configuration: { } diff --git a/sites/default/config/sync/system.action.node_save_action.yml b/sites/default/config/sync/system.action.node_save_action.yml index ebc0e7399..23f84d4d1 100644 --- a/sites/default/config/sync/system.action.node_save_action.yml +++ b/sites/default/config/sync/system.action.node_save_action.yml @@ -9,5 +9,5 @@ _core: id: node_save_action label: 'Enregistrer un contenu' type: node -plugin: node_save_action +plugin: 'entity:save_action:node' configuration: { } diff --git a/sites/default/config/sync/system.action.node_unpublish_action.yml b/sites/default/config/sync/system.action.node_unpublish_action.yml index 509b0d38b..47a3d626b 100644 --- a/sites/default/config/sync/system.action.node_unpublish_action.yml +++ b/sites/default/config/sync/system.action.node_unpublish_action.yml @@ -9,5 +9,5 @@ _core: id: node_unpublish_action label: 'Dépublier un contenu' type: node -plugin: node_unpublish_action +plugin: 'entity:unpublish_action:node' configuration: { } diff --git a/sites/default/config/sync/views.view.content.yml b/sites/default/config/sync/views.view.content.yml index 8810959f9..b1ac046e5 100644 --- a/sites/default/config/sync/views.view.content.yml +++ b/sites/default/config/sync/views.view.content.yml @@ -785,6 +785,7 @@ display: authenticated: authenticated anonymous: '0' administrator: '0' + placeholder: '' is_grouped: false group_info: label: '' @@ -1144,6 +1145,7 @@ display: authenticated: authenticated anonymous: '0' administrator: '0' + placeholder: '' is_grouped: false group_info: label: '' @@ -1739,7 +1741,7 @@ display: - user - 'user.node_grants:view' - user.roles - max-age: 0 + max-age: -1 tags: - 'config:field.storage.node.field_page_type' - 'config:field.storage.node.field_son' @@ -1876,6 +1878,7 @@ display: authenticated: authenticated anonymous: '0' administrator: '0' + placeholder: '' is_grouped: false group_info: label: '' @@ -1919,6 +1922,7 @@ display: admin: '0' root: '0' invite: '0' + placeholder: '' is_grouped: true group_info: label: Article @@ -2763,7 +2767,7 @@ display: - user - 'user.node_grants:view' - user.roles - max-age: 0 + max-age: -1 tags: - 'config:field.storage.node.body' - 'config:field.storage.node.field_collectionneurs' @@ -2928,6 +2932,7 @@ display: authenticated: authenticated anonymous: '0' administrator: '0' + placeholder: '' is_grouped: false group_info: label: '' @@ -3390,7 +3395,7 @@ display: - user - 'user.node_grants:view' - user.roles - max-age: 0 + max-age: -1 tags: - 'config:field.storage.node.field_date' - 'config:field.storage.node.field_page_liee' @@ -3552,6 +3557,7 @@ display: authenticated: authenticated anonymous: '0' administrator: '0' + placeholder: '' is_grouped: false group_info: label: '' @@ -3825,6 +3831,6 @@ display: - user - 'user.node_grants:view' - user.roles - max-age: 0 + max-age: -1 tags: - 'config:field.storage.node.field_enregistrement' diff --git a/sites/default/config/sync/views.view.entree_s_.yml b/sites/default/config/sync/views.view.entree_s_.yml index 0e9699eba..afc6b3a28 100644 --- a/sites/default/config/sync/views.view.entree_s_.yml +++ b/sites/default/config/sync/views.view.entree_s_.yml @@ -502,6 +502,7 @@ display: admin: '0' root: '0' invite: '0' + placeholder: '' is_grouped: false group_info: label: '' @@ -540,7 +541,7 @@ display: groups: 1: AND cache_metadata: - max-age: 0 + max-age: -1 contexts: - 'languages:language_content' - 'languages:language_interface' @@ -568,7 +569,7 @@ display: context: '0' menu_name: admin cache_metadata: - max-age: 0 + max-age: -1 contexts: - 'languages:language_content' - 'languages:language_interface' diff --git a/sites/default/config/sync/views.view.files.yml b/sites/default/config/sync/views.view.files.yml index 9d5a6bedf..b31fac927 100644 --- a/sites/default/config/sync/views.view.files.yml +++ b/sites/default/config/sync/views.view.files.yml @@ -688,6 +688,7 @@ display: authenticated: authenticated anonymous: '0' administrator: '0' + placeholder: '' is_grouped: false group_info: label: '' @@ -728,6 +729,7 @@ display: authenticated: authenticated anonymous: '0' administrator: '0' + placeholder: '' is_grouped: false group_info: label: '' @@ -816,7 +818,7 @@ display: - url - url.query_args - user.permissions - max-age: 0 + max-age: -1 tags: { } page_1: display_plugin: page @@ -855,7 +857,7 @@ display: - url - url.query_args - user.permissions - max-age: 0 + max-age: -1 tags: { } page_2: display_plugin: page @@ -1212,5 +1214,5 @@ display: - url - url.query_args - user.permissions - max-age: 0 + max-age: -1 tags: { } diff --git a/sites/default/config/sync/views.view.glossary.yml b/sites/default/config/sync/views.view.glossary.yml index 0c9ad1a84..356bc44fa 100644 --- a/sites/default/config/sync/views.view.glossary.yml +++ b/sites/default/config/sync/views.view.glossary.yml @@ -360,7 +360,7 @@ display: - url.query_args - 'user.node_grants:view' - user.permissions - max-age: 0 + max-age: -1 tags: { } attachment_1: id: attachment_1 @@ -428,7 +428,7 @@ display: - url.query_args - 'user.node_grants:view' - user.permissions - max-age: 0 + max-age: -1 tags: { } page_1: id: page_1 @@ -455,5 +455,5 @@ display: - url.query_args - 'user.node_grants:view' - user.permissions - max-age: 0 + max-age: -1 tags: { } diff --git a/sites/default/config/sync/views.view.maillog_overview.yml b/sites/default/config/sync/views.view.maillog_overview.yml index 2e713cfdd..ab1391a72 100644 --- a/sites/default/config/sync/views.view.maillog_overview.yml +++ b/sites/default/config/sync/views.view.maillog_overview.yml @@ -8,6 +8,7 @@ dependencies: module: - maillog module: + - maillog - user _core: default_config_hash: SentX2vMVdSwdCGG33n1_hb9MfAEjswvc8Oyob3KQSA @@ -416,7 +417,7 @@ display: - url.query_args - user.permissions cacheable: false - max-age: 0 + max-age: -1 tags: { } page_1: display_plugin: page @@ -440,5 +441,5 @@ display: - url.query_args - user.permissions cacheable: false - max-age: 0 + max-age: -1 tags: { } diff --git a/sites/default/config/sync/views.view.user_admin_people.yml b/sites/default/config/sync/views.view.user_admin_people.yml index 8ee393049..6005c6eb9 100644 --- a/sites/default/config/sync/views.view.user_admin_people.yml +++ b/sites/default/config/sync/views.view.user_admin_people.yml @@ -604,6 +604,7 @@ display: authenticated: authenticated anonymous: '0' administrator: '0' + placeholder: '' is_grouped: false group_info: label: '' @@ -812,6 +813,9 @@ display: multiple: false remember_roles: authenticated: authenticated + placeholder: '' + min_placeholder: '' + max_placeholder: '' is_grouped: false group_info: label: '' diff --git a/sites/default/config/sync/views.view.who_s_new.yml b/sites/default/config/sync/views.view.who_s_new.yml index 2b8d077c3..8857867a3 100644 --- a/sites/default/config/sync/views.view.who_s_new.yml +++ b/sites/default/config/sync/views.view.who_s_new.yml @@ -129,6 +129,9 @@ display: multiple: false remember_roles: authenticated: authenticated + placeholder: '' + min_placeholder: '' + max_placeholder: '' is_grouped: false group_info: label: '' diff --git a/sites/default/config/sync/views.view.who_s_online.yml b/sites/default/config/sync/views.view.who_s_online.yml index e4bbbcdab..d9ad53ce1 100644 --- a/sites/default/config/sync/views.view.who_s_online.yml +++ b/sites/default/config/sync/views.view.who_s_online.yml @@ -138,6 +138,9 @@ display: authenticated: authenticated anonymous: '0' administrator: '0' + placeholder: '' + min_placeholder: '' + max_placeholder: '' is_grouped: false group_info: label: ''