diff --git a/README.txt b/README.txt new file mode 100644 index 000000000..0bafcc1b8 --- /dev/null +++ b/README.txt @@ -0,0 +1,139 @@ + +CONTENTS OF THIS FILE +--------------------- + + * About Drupal + * Configuration and features + * Installation profiles + * Appearance + * Developing for Drupal + * More information + +ABOUT DRUPAL +------------ + +Drupal is an open source content management platform supporting a variety of +websites ranging from personal weblogs to large community-driven websites. For +more information, see the Drupal website at https://www.drupal.org, and join +the Drupal community at https://www.drupal.org/community. + +Legal information about Drupal: + * Know your rights when using Drupal: + See LICENSE.txt in the "core" directory. + * Learn about the Drupal trademark and logo policy: + https://www.drupal.com/trademark + +CONFIGURATION AND FEATURES +-------------------------- + +Drupal core (what you get when you download and extract a drupal-x.y.tar.gz or +drupal-x.y.zip file from https://www.drupal.org/project/drupal) has what you +need to get started with your website. It includes several modules (extensions +that add functionality) for common website features, such as managing content, +user accounts, image uploading, and search. Core comes with many options that +allow site-specific configuration. In addition to the core modules, there are +thousands of contributed modules (for functionality not included with Drupal +core) available for download. + +More about configuration: + * Install, update, and maintain Drupal: + See INSTALL.txt and UPDATE.txt in the "core" directory. + * Learn about how to use Drupal to create your site: + https://www.drupal.org/documentation + * Follow best practices: + https://www.drupal.org/best-practices + * Download contributed modules to /modules to extend Drupal's functionality: + https://www.drupal.org/project/modules + * See also: "Developing for Drupal" for writing your own modules, below. + + +INSTALLATION PROFILES +--------------------- + +Installation profiles define additional steps (such as enabling modules, +defining content types, etc.) that run after the base installation provided +by core when Drupal is first installed. There are two basic installation +profiles provided with Drupal core. + +Installation profiles from the Drupal community modify the installation process +to provide a website for a specific use case, such as a CMS for media +publishers, a web-based project tracking tool, or a full-fledged CRM for +non-profit organizations raising money and accepting donations. They can be +distributed as bare installation profiles or as "distributions". Distributions +include Drupal core, the installation profile, and all other required +extensions, such as contributed and custom modules, themes, and third-party +libraries. Bare installation profiles require you to download Drupal Core and +the required extensions separately; place the downloaded profile in the +/profiles directory before you start the installation process. + +More about installation profiles and distributions: + * Read about the difference between installation profiles and distributions: + https://www.drupal.org/node/1089736 + * Download contributed installation profiles and distributions: + https://www.drupal.org/project/distributions + * Develop your own installation profile or distribution: + https://www.drupal.org/developing/distributions + + +APPEARANCE +---------- + +In Drupal, the appearance of your site is set by the theme (themes are +extensions that set fonts, colors, and layout). Drupal core comes with several +themes. More themes are available for download, and you can also create your own +custom theme. + +More about themes: + * Download contributed themes to /themes to modify Drupal's appearance: + https://www.drupal.org/project/themes + * Develop your own theme: + https://www.drupal.org/documentation/theme + +DEVELOPING FOR DRUPAL +--------------------- + +Drupal contains an extensive API that allows you to add to and modify the +functionality of your site. The API consists of "hooks", which allow modules to +react to system events and customize Drupal's behavior, and functions that +standardize common operations such as database queries and form generation. The +flexible hook architecture means that you should never need to directly modify +the files that come with Drupal core to achieve the functionality you want; +instead, functionality modifications take the form of modules. + +When you need new functionality for your Drupal site, search for existing +contributed modules. If you find a module that matches except for a bug or an +additional needed feature, change the module and contribute your improvements +back to the project in the form of a "patch". Create new custom modules only +when nothing existing comes close to what you need. + +More about developing: + * Search for existing contributed modules: + https://www.drupal.org/project/modules + * Contribute a patch: + https://www.drupal.org/patch/submit + * Develop your own module: + https://www.drupal.org/developing/modules + * Follow programming best practices: + https://www.drupal.org/developing/best-practices + * Refer to the API documentation: + https://api.drupal.org/api/drupal/8 + * Learn from documented Drupal API examples: + https://www.drupal.org/project/examples + +MORE INFORMATION +---------------- + + * See the Drupal.org online documentation: + https://www.drupal.org/documentation + + * For a list of security announcements, see the "Security advisories" page at + https://www.drupal.org/security (available as an RSS feed). This page also + describes how to subscribe to these announcements via email. + + * For information about the Drupal security process, or to find out how to + report a potential security issue to the Drupal security team, see the + "Security team" page at https://www.drupal.org/security-team + + * For information about the wide range of available support options, visit + https://www.drupal.org and click on Community and Support in the top or + bottom navigation. diff --git a/sites/all/modules/contrib/admin/admin_toolbar/CHANGELOG.txt b/sites/all/modules/contrib/admin/admin_toolbar/CHANGELOG.txt index e4a5c8163..3078d5f3b 100644 --- a/sites/all/modules/contrib/admin/admin_toolbar/CHANGELOG.txt +++ b/sites/all/modules/contrib/admin/admin_toolbar/CHANGELOG.txt @@ -1,3 +1,24 @@ +Admin Toolbar 8.1.22, 2017-XX-XX +-------------------------------- +Changes since 8.1.21: + +- #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. +- #2925501 by eme, adriancid, RumyanaRuseva: Menu does not take changes into + account (caching issue). +- #2927914 by adriancid: Parameter comment indentation must be 3 spaces. +- #2927911 by adriancid: Remove unused variables. +- #2927905 by adriancid: All dependencies must be prefixed with the project + name. +- #2925327 by Berdir, adriancid: Better check for is-link-in-admin-menu for + local task links. +- #2922046 by mikejw, adriancid, Berdir, BrianLewisDesign: Notice: Undefined + index: entity.eform_type.collection in + admin_toolbar_tools_menu_links_discovered_alter. +- #2925128 by adriancid: Create the module help page for the Admin Toolbar Links + Access Filter submodule. + Admin Toolbar 8.1.21, 2017-11-20 -------------------------------- Changes since 8.1.20: 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 c8369b523..6f8a5e9ed 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 @@ -6,10 +6,10 @@ type: module # core: 8.x dependencies: - - toolbar + - drupal:toolbar -# Information added by Drupal.org packaging script on 2017-11-20 -version: '8.x-1.21' +# Information added by Drupal.org packaging script on 2018-01-02 +version: '8.x-1.22' core: '8.x' project: 'admin_toolbar' -datestamp: 1511190792 +datestamp: 1514888588 diff --git a/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar_links_access_filter/README.txt b/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar_links_access_filter/README.txt index ecd1e4e4b..60598b871 100644 --- a/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar_links_access_filter/README.txt +++ b/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar_links_access_filter/README.txt @@ -27,7 +27,9 @@ https://www.drupal.org/node/296693 be solved, this module will be deprecated. REQUIREMENTS ------------ -No special requirements. +This module requires the following modules: + + * Admin Toolbar (https://www.drupal.org/project/admin_toolbar) RECOMMENDED MODULES 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 d5744d559..771c011e2 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,12 +1,13 @@ 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 2017-11-20 -version: '8.x-1.21' +# Information added by Drupal.org packaging script on 2018-01-02 +version: '8.x-1.22' core: '8.x' project: 'admin_toolbar' -datestamp: 1511190792 +datestamp: 1514888588 diff --git a/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar_links_access_filter/admin_toolbar_links_access_filter.module b/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar_links_access_filter/admin_toolbar_links_access_filter.module index 66d5c0d8b..7b4476897 100644 --- a/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar_links_access_filter/admin_toolbar_links_access_filter.module +++ b/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar_links_access_filter/admin_toolbar_links_access_filter.module @@ -9,6 +9,22 @@ use Drupal\Core\Session\AccountInterface; use Drupal\Core\Url; use Drupal\user\Entity\Role; use Symfony\Component\Routing\Exception\RouteNotFoundException; +use Drupal\Core\Routing\RouteMatchInterface; + +/** + * Implements hook_help(). + */ +function admin_toolbar_links_access_filter_help($route_name, RouteMatchInterface $route_match) { + switch ($route_name) { + // Main module help. + case 'help.page.admin_toolbar_links_access_filter': + $output = ''; + $output .= '
' . t("The Admin Toolbar Links Access Filter module 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 Hide empty admin categories be solved, this module will be deprecated.", ['@url' => Url::fromUri('https://www.drupal.org/node/296693')->toString()]) . '
'; + + return $output; + } +} /** * Implements hook_preprocess_menu(). @@ -152,6 +168,7 @@ function admin_toolbar_links_access_filter_is_overview_page($route_name) { return !empty($controller) && in_array($controller, $overview_page_controllers); } catch (RouteNotFoundException $ex) { + } return FALSE; } 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 c1e2bb892..82051f62c 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 @@ -6,10 +6,10 @@ type: module # core: 8.x dependencies: - - admin_toolbar + - admin_toolbar:admin_toolbar -# Information added by Drupal.org packaging script on 2017-11-20 -version: '8.x-1.21' +# Information added by Drupal.org packaging script on 2018-01-02 +version: '8.x-1.22' core: '8.x' project: 'admin_toolbar' -datestamp: 1511190792 +datestamp: 1514888588 diff --git a/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar_tools/admin_toolbar_tools.links.menu.yml b/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar_tools/admin_toolbar_tools.links.menu.yml index 69df35f58..cb8cc2587 100644 --- a/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar_tools/admin_toolbar_tools.links.menu.yml +++ b/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar_tools/admin_toolbar_tools.links.menu.yml @@ -12,6 +12,13 @@ system.admin_index: parent: admin_toolbar_tools.help weight: -100 +system.run_cron: + title: 'Run cron' + route_name: admin_toolbar.run.cron + menu_name: admin + parent: admin_toolbar_tools.help + weight: -8 + system.db_update: title: 'Run updates' route_name: system.db_update @@ -25,6 +32,43 @@ system.modules_uninstall: menu_name: admin parent: system.modules_list +admin_toolbar_tools.flush: + title: 'Flush all caches' + route_name: admin_toolbar_tools.flush + weight: -9 + parent: admin_toolbar_tools.help + menu_name: admin + +admin_toolbar_tools.cssjs: + title: 'Flush CSS and Javascript' + route_name: admin_toolbar_tools.cssjs + parent: admin_toolbar_tools.flush + menu_name: admin + +admin_toolbar_tools.plugin: + title: 'Flush plugins cache' + route_name: admin_toolbar_tools.plugin + parent: admin_toolbar_tools.flush + menu_name: admin + +admin_toolbar_tools.flush_static: + title: 'Flush static cache' + route_name: admin_toolbar_tools.flush_static + parent: admin_toolbar_tools.flush + menu_name: admin + +admin_toolbar_tools.flush_menu: + title: 'Flush routing and links cache' + route_name: admin_toolbar_tools.flush_menu + parent: admin_toolbar_tools.flush + menu_name: admin + +admin_toolbar_tools.flush_rendercache: + title: 'Flush render cache' + route_name: admin_toolbar_tools.flush_rendercache + parent: admin_toolbar_tools.flush + menu_name: admin + admin_toolbar_tools.drupalorg: title: 'Drupal.org' weight: -5 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 40c839ab5..f67573933 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 @@ -28,17 +28,6 @@ function admin_toolbar_tools_toolbar() { return $items; } -/** - * Implements hook_toolbar_alter(). - */ -function admin_toolbar_tools_toolbar_alter(&$items) { - // Use lazybuilder for links so the page is cacheable. - $items['administration']['tray']['toolbar_administration'] = [ - '#lazy_builder' => ['admin_toolbar_tools.toolbar_handler:lazyBuilder', []], - '#create_placeholder' => TRUE, - ]; -} - /** * Implements hook_help(). */ @@ -88,8 +77,18 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) { } } + // Adding a menu link to clean the Views cache. + if ($moduleHandler->moduleExists('views')) { + $links['admin_toolbar_tools.flush_views'] = [ + 'title' => t('Flush views cache'), + 'route_name' => 'admin_toolbar_tools.flush_views', + 'menu_name' => 'admin', + 'parent' => 'admin_toolbar_tools.flush', + ]; + } + // Adds common links to entities. - foreach ($content_entities as $module_name => $entities) { + foreach ($content_entities as $entities) { $content_entity_bundle = $entities['content_entity_bundle']; $content_entity = $entities['content_entity']; foreach ($entityTypeManager->getStorage($content_entity_bundle)->loadMultiple() as $machine_name => $bundle) { @@ -539,19 +538,45 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) { $manager = \Drupal::service('plugin.manager.menu.local_task'); foreach ($links as $key => $link) { - // Ignore menu links that have no route name or are not in the admin menu. - // @todo Use configuration for admin menu name once added in - // https://www.drupal.org/node/1869638. - if (empty($link['route_name']) || !isset($link['menu_name']) || $link['menu_name'] !== 'admin') { + // 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 $plugin_id => $task_plugin) { + foreach ($route_local_tasks[0] as $task_plugin) { $definition = $task_plugin->getPluginDefinition(); $local_route = $definition['route_name']; if (empty($local_route)) { @@ -596,7 +621,7 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) { // "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'])) { + if (!empty($link['parent']) && isset($links[$link['parent']])) { $parentlink = $links[$link['parent']]; $parentlink_route = $parentlink['route_name']; $parent_primary = $manager->getLocalTasks($parentlink_route, 0); diff --git a/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar_tools/admin_toolbar_tools.services.yml b/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar_tools/admin_toolbar_tools.services.yml deleted file mode 100644 index 1343ef7d2..000000000 --- a/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar_tools/admin_toolbar_tools.services.yml +++ /dev/null @@ -1,4 +0,0 @@ -services: - admin_toolbar_tools.toolbar_handler: - class: Drupal\admin_toolbar_tools\ToolbarHandler - arguments: ['@module_handler'] diff --git a/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar_tools/src/Tests/AdminToolbarToolsAlterTest.php b/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar_tools/src/Tests/AdminToolbarToolsAlterTest.php index 6c464916e..73035efb1 100644 --- a/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar_tools/src/Tests/AdminToolbarToolsAlterTest.php +++ b/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar_tools/src/Tests/AdminToolbarToolsAlterTest.php @@ -44,7 +44,7 @@ class AdminToolbarToolsAlterTest extends WebTestBase { */ public function testAdminToolbarTools() { // Assert that special menu items are present in the HTML. - $this->assertRaw('class="toolbar-icon toolbar-icon-admin-toolbar-tools-help"'); + $this->assertRaw('class="toolbar-icon toolbar-icon-admin-toolbar-tools-flush"'); } } diff --git a/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar_tools/src/ToolbarHandler.php b/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar_tools/src/ToolbarHandler.php deleted file mode 100644 index 58a548b24..000000000 --- a/sites/all/modules/contrib/admin/admin_toolbar/admin_toolbar_tools/src/ToolbarHandler.php +++ /dev/null @@ -1,135 +0,0 @@ -moduleHandler = $module_handler; - } - - /** - * {@inheritdoc} - */ - public static function create(ContainerInterface $container) { - return new static( - $container->get('module_handler') - ); - } - - /** - * Lazy builder callback for the admin_toolbar_tool items. - * - * @return array - * A renderable array as expected by the renderer service. - */ - public function lazyBuilder() { - // Render the pre_render callback we disabled earlier. - $build = admin_toolbar_prerender_toolbar_administration_tray([]); - - // Add links that are uncacheable. - // Core toolbar module calculates cachability in advance so we have to build - // a fake menu tree here, including access checks. - $tools_menu = &$build['administration_menu']['#items']['admin_toolbar_tools.help']['below']; - - // Adding the 'Flush all caches' menu in the correct place. - $menu_render_array = $this->createMenuRenderArray('admin_toolbar_tools.flush', $this->t('Flush all caches'), TRUE); - $this->arrayInsert($tools_menu, 1, $menu_render_array); - - // Adding the submenus to 'Flush all caches' menu. - if (!empty($tools_menu['admin_toolbar_tools.flush'])) { - $tools_sub_menu = &$tools_menu['admin_toolbar_tools.flush']['below']; - $tools_sub_menu += $this->createMenuRenderArray('admin_toolbar_tools.cssjs', $this->t('Flush CSS and Javascript')); - $tools_sub_menu += $this->createMenuRenderArray('admin_toolbar_tools.plugin', $this->t('Flush plugins cache')); - $tools_sub_menu += $this->createMenuRenderArray('admin_toolbar_tools.flush_static', $this->t('Flush static cache')); - $tools_sub_menu += $this->createMenuRenderArray('admin_toolbar_tools.flush_menu', $this->t('Flush routing and links cache')); - $tools_sub_menu += $this->createMenuRenderArray('admin_toolbar_tools.flush_rendercache', $this->t('Flush render cache')); - - // Adding a menu link to clean the Views cache. - if ($this->moduleHandler->moduleExists('views')) { - $tools_sub_menu += $this->createMenuRenderArray('admin_toolbar_tools.flush_views', $this->t('Flush views cache')); - } - } - - // Adding the 'Run Cron' menu in the correct place. - $menu_render_array = $this->createMenuRenderArray('system.run_cron', $this->t('Run cron')); - $this->arrayInsert($tools_menu, 3, $menu_render_array); - - return $build; - } - - /** - * Create the menu render array. - * - * @param string $route - * The route. - * @param string $title - * The menu title. - * @param bool $submenu - * Specify if the current menu element have a submenu. - * - * @return array - * A renderable array as expected by the renderer service. - */ - private function createMenuRenderArray($route, $title, $submenu = FALSE) { - $data = []; - $url = Url::fromRoute($route); - if ($url->access()) { - $data[$route] = [ - 'title' => $title, - 'url' => $url, - 'attributes' => new Attribute(['class' => ['menu-item'] + ($submenu ? ['menu-item--expanded'] : [])]), - ]; - if ($submenu) { - $data[$route]['below'] = []; - $data[$route]['is_expanded'] = TRUE; - } - } - return $data; - } - - /** - * Insert an array in a given position of another array. - * - * @param array $array - * The array where we need to insert new elements. - * @param int $position - * The position where we will add the new array. - * @param array $insert_array - * The array that will be inserted. - * - * @see http://php.net/manual/en/function.array-splice.php#56794 - */ - private function arrayInsert(array &$array, $position, array $insert_array) { - // Getting the first part of the array. - $first_array = array_splice($array, 0, $position); - // Inserting the new part in the desired position. - $array = array_merge($first_array, $insert_array, $array); - } - -} 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 ecac624cb..44d97919d 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 @@ -23,7 +23,7 @@ background-color: #f5f5f2; } -.toolbar-tray-horizontal ul li.menu-item { +.toolbar-tray-horizontal ul li li.menu-item { border-top: none transparent; border-right: 1px solid #dddddd; border-bottom: 1px solid #dddddd; 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 588eb812b..ec322f200 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,50 +1,53 @@ (function ($) { - $(document).ready(function () { - $('a.toolbar-icon').removeAttr('title'); + Drupal.behaviors.adminToolbar = { + attach: function (context, settings) { - $('.toolbar-tray-horizontal li.menu-item--expanded, .toolbar-tray-horizontal ul li.menu-item--expanded .menu-item').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. - $(this).parent().find('li').removeClass('hover-intent'); - $(this).addClass('hover-intent'); - }, - out: function () { - $(this).removeClass('hover-intent'); - }, - timeout: 250 - }); - - // Make the toolbar menu navigable with keyboard. - $('ul.toolbar-menu li.menu-item--expanded a').on('focusin', function () { - $('li.menu-item--expanded').removeClass('hover-intent'); - $(this).parents('li.menu-item--expanded').addClass('hover-intent'); - }); - - $('ul.toolbar-menu li.menu-item a').keydown(function (e) { - if ((e.shiftKey && (e.keyCode || e.which) == 9)) { - if ($(this).parent('.menu-item').prev().hasClass('menu-item--expanded')) { - $(this).parent('.menu-item').prev().addClass('hover-intent'); + $('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({ + 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. + $(this).parent().find('li').removeClass('hover-intent'); + $(this).addClass('hover-intent'); + }, + out: function () { + $(this).removeClass('hover-intent'); + }, + 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')) { + $(this).parent('.menu-item').prev().addClass('hover-intent'); + } } - } - }); + }); + + $('.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;"); + }); + + $('ul:not(.toolbar-menu)', context).on({ + mousemove: function () { + $('li.menu-item--expanded').removeClass('hover-intent'); + }, + hover: function () { + $('li.menu-item--expanded').removeClass('hover-intent'); + } + }); - $('.toolbar-menu:first-child > .menu-item:not(.menu-item--expanded) a, .toolbar-tab > a').on('focusin', function () { - $('.menu-item--expanded').removeClass('hover-intent'); - }); - - $('.toolbar-menu:first-child > .menu-item').on('hover', function () { - $(this,'a').css("background: #fff;"); - }); - - $('ul:not(.toolbar-menu)').on({ - mousemove: function () { - $('li.menu-item--expanded').removeClass('hover-intent'); - }, - hover: function () { - $('li.menu-item--expanded').removeClass('hover-intent'); - } - }); - - }); + } + }; })(jQuery); diff --git a/sites/all/modules/contrib/admin/config_update/config_update.info.yml b/sites/all/modules/contrib/admin/config_update/config_update.info.yml index 8164552d6..a26c33f74 100644 --- a/sites/all/modules/contrib/admin/config_update/config_update.info.yml +++ b/sites/all/modules/contrib/admin/config_update/config_update.info.yml @@ -5,8 +5,8 @@ description: 'Provides basic revert and update functionality for other modules' dependencies: - drupal:config -# Information added by Drupal.org packaging script on 2017-09-18 -version: '8.x-1.4' +# Information added by Drupal.org packaging script on 2017-12-05 +version: '8.x-1.5' core: '8.x' project: 'config_update' -datestamp: 1505755746 +datestamp: 1512514387 diff --git a/sites/all/modules/contrib/admin/config_update/config_update_ui/config_update_ui.info.yml b/sites/all/modules/contrib/admin/config_update/config_update_ui/config_update_ui.info.yml index 85a5eec58..a65420a2f 100644 --- a/sites/all/modules/contrib/admin/config_update/config_update_ui/config_update_ui.info.yml +++ b/sites/all/modules/contrib/admin/config_update/config_update_ui/config_update_ui.info.yml @@ -7,8 +7,8 @@ dependencies: - config_update:config_update - drupal:config -# Information added by Drupal.org packaging script on 2017-09-18 -version: '8.x-1.4' +# Information added by Drupal.org packaging script on 2017-12-05 +version: '8.x-1.5' core: '8.x' project: 'config_update' -datestamp: 1505755746 +datestamp: 1512514387 diff --git a/sites/all/modules/contrib/admin/config_update/config_update_ui/config_update_ui.routing.yml b/sites/all/modules/contrib/admin/config_update/config_update_ui/config_update_ui.routing.yml index 15ce16bb8..9f2f35585 100644 --- a/sites/all/modules/contrib/admin/config_update/config_update_ui/config_update_ui.routing.yml +++ b/sites/all/modules/contrib/admin/config_update/config_update_ui/config_update_ui.routing.yml @@ -12,9 +12,7 @@ config_update_ui.import: path: '/admin/config/development/configuration/report/import/{config_type}/{config_name}' defaults: _title: 'Import' - _controller: '\Drupal\config_update_ui\Controller\ConfigUpdateController::import' - config_type: NULL - config_name: NULL + _form: '\Drupal\config_update_ui\Form\ConfigImportConfirmForm' requirements: _permission: 'import configuration' diff --git a/sites/all/modules/contrib/admin/config_update/config_update_ui/src/Controller/ConfigUpdateController.php b/sites/all/modules/contrib/admin/config_update/config_update_ui/src/Controller/ConfigUpdateController.php index 36cf6f2cd..31ed06d7a 100644 --- a/sites/all/modules/contrib/admin/config_update/config_update_ui/src/Controller/ConfigUpdateController.php +++ b/sites/all/modules/contrib/admin/config_update/config_update_ui/src/Controller/ConfigUpdateController.php @@ -112,26 +112,6 @@ class ConfigUpdateController extends ControllerBase { ); } - /** - * Imports configuration from a module, theme, or profile. - * - * Configuration is assumed not to currently exist. - * - * @param string $config_type - * The type of configuration. - * @param string $config_name - * The name of the config item, without the prefix. - * - * @return \Symfony\Component\HttpFoundation\RedirectResponse - * Redirects to the updates report. - */ - public function import($config_type, $config_name) { - $this->configRevert->import($config_type, $config_name); - - drupal_set_message($this->t('The configuration was imported.')); - return $this->redirect('config_update_ui.report'); - } - /** * Shows the diff between active and provided configuration. * diff --git a/sites/all/modules/contrib/admin/config_update/config_update_ui/src/Form/ConfigDeleteConfirmForm.php b/sites/all/modules/contrib/admin/config_update/config_update_ui/src/Form/ConfigDeleteConfirmForm.php index 0c272388f..e8206b581 100644 --- a/sites/all/modules/contrib/admin/config_update/config_update_ui/src/Form/ConfigDeleteConfirmForm.php +++ b/sites/all/modules/contrib/admin/config_update/config_update_ui/src/Form/ConfigDeleteConfirmForm.php @@ -8,6 +8,7 @@ use Drupal\Core\Url; use Drupal\config_update\ConfigListInterface; use Drupal\config_update\ConfigRevertInterface; use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * Defines a confirmation form for deleting configuration. @@ -81,9 +82,20 @@ class ConfigDeleteConfirmForm extends ConfirmFormBase { } else { $definition = $this->configList->getType($this->type); + if (!$definition) { + // Make a 404 error if the type doesn't exist. + throw new NotFoundHttpException(); + } $type_label = $definition->get('label'); } + // To delete, the configuration item must exist in active storage. Check + // that and make a 404 error if not. + $active = $this->configRevert->getFromActive($this->type, $this->name); + if (!$active) { + throw new NotFoundHttpException(); + } + return $this->t('Are you sure you want to delete the %type config %item?', ['%type' => $type_label, '%item' => $this->name]); } @@ -119,17 +131,6 @@ class ConfigDeleteConfirmForm extends ConfirmFormBase { return $form; } - /** - * {@inheritdoc} - */ - public function validateForm(array &$form, FormStateInterface $form_state) { - $value = $this->configRevert->getFromActive($this->type, $this->name); - if (!$value) { - $form_state->setErrorByName('', $this->t('There is no configuration @type named @name to delete', ['@type' => $this->type, '@name' => $this->name])); - return; - } - } - /** * {@inheritdoc} */ diff --git a/sites/all/modules/contrib/admin/config_update/config_update_ui/src/Form/ConfigImportConfirmForm.php b/sites/all/modules/contrib/admin/config_update/config_update_ui/src/Form/ConfigImportConfirmForm.php new file mode 100644 index 000000000..20790ed73 --- /dev/null +++ b/sites/all/modules/contrib/admin/config_update/config_update_ui/src/Form/ConfigImportConfirmForm.php @@ -0,0 +1,146 @@ +configList = $config_list; + $this->configRevert = $config_update; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('config_update.config_list'), + $container->get('config_update.config_update') + ); + } + + /** + * {@inheritdoc} + */ + public function getFormId() { + return 'config_import_confirm'; + } + + /** + * {@inheritdoc} + */ + public function getQuestion() { + if ($this->type == 'system.simple') { + $type_label = $this->t('Simple configuration'); + } + else { + $definition = $this->configList->getType($this->type); + if (!$definition) { + // Make a 404 error if the type doesn't exist. + throw new NotFoundHttpException(); + } + $type_label = $definition->get('label'); + } + + // To import (as opposed to revert), the configuration item must exist in + // extension storage but not active storage, so check that, and make a 404 + // error if not. + $extension = $this->configRevert->getFromExtension($this->type, $this->name); + $active = $this->configRevert->getFromActive($this->type, $this->name); + if (!$extension || $active) { + throw new NotFoundHttpException(); + } + + return $this->t('Are you sure you want to import the %type config %item from its source configuration?', ['%type' => $type_label, '%item' => $this->name]); + } + + /** + * {@inheritdoc} + */ + public function getCancelUrl() { + return new Url('config_update_ui.report'); + } + + /** + * {@inheritdoc} + */ + public function getDescription() { + return $this->t('Configuration will be added to your site. This action cannot be undone.'); + } + + /** + * {@inheritdoc} + */ + public function getConfirmText() { + return $this->t('Import'); + } + + /** + * {@inheritdoc} + */ + public function buildForm(array $form, FormStateInterface $form_state, $config_type = NULL, $config_name = NULL) { + $this->type = $config_type; + $this->name = $config_name; + + $form = parent::buildForm($form, $form_state); + return $form; + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, FormStateInterface $form_state) { + $this->configRevert->import($this->type, $this->name); + + drupal_set_message($this->t('The configuration was imported from its source.')); + $form_state->setRedirectUrl($this->getCancelUrl()); + } + +} diff --git a/sites/all/modules/contrib/admin/config_update/config_update_ui/src/Form/ConfigRevertConfirmForm.php b/sites/all/modules/contrib/admin/config_update/config_update_ui/src/Form/ConfigRevertConfirmForm.php index efb6b3a9a..9699ba3a0 100644 --- a/sites/all/modules/contrib/admin/config_update/config_update_ui/src/Form/ConfigRevertConfirmForm.php +++ b/sites/all/modules/contrib/admin/config_update/config_update_ui/src/Form/ConfigRevertConfirmForm.php @@ -8,6 +8,7 @@ use Drupal\Core\Url; use Drupal\config_update\ConfigListInterface; use Drupal\config_update\ConfigRevertInterface; use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * Defines a confirmation form for reverting configuration. @@ -81,9 +82,22 @@ class ConfigRevertConfirmForm extends ConfirmFormBase { } else { $definition = $this->configList->getType($this->type); + if (!$definition) { + // Make a 404 error if the type doesn't exist. + throw new NotFoundHttpException(); + } $type_label = $definition->get('label'); } + // To revert (as opposed to import), the configuration item must exist in + // both active storage and extension storage, so check that and make a 404 + // error if not. + $extension = $this->configRevert->getFromExtension($this->type, $this->name); + $active = $this->configRevert->getFromActive($this->type, $this->name); + if (!$extension || !$active) { + throw new NotFoundHttpException(); + } + return $this->t('Are you sure you want to revert the %type config %item to its source configuration?', ['%type' => $type_label, '%item' => $this->name]); } @@ -119,17 +133,6 @@ class ConfigRevertConfirmForm extends ConfirmFormBase { return $form; } - /** - * {@inheritdoc} - */ - public function validateForm(array &$form, FormStateInterface $form_state) { - $value = $this->configRevert->getFromExtension($this->type, $this->name); - if (!$value) { - $form_state->setErrorByName('', $this->t('There is no configuration @type named @name to import', ['@type' => $this->type, '@name' => $this->name])); - return; - } - } - /** * {@inheritdoc} */ diff --git a/sites/all/modules/contrib/admin/config_update/config_update_ui/src/Tests/ConfigUpdateTest.php b/sites/all/modules/contrib/admin/config_update/config_update_ui/src/Tests/ConfigUpdateTest.php index 2df324f4e..1ac7aefba 100644 --- a/sites/all/modules/contrib/admin/config_update/config_update_ui/src/Tests/ConfigUpdateTest.php +++ b/sites/all/modules/contrib/admin/config_update/config_update_ui/src/Tests/ConfigUpdateTest.php @@ -106,6 +106,11 @@ class ConfigUpdateTest extends WebTestBase { $this->assertText('Testing profile'); $this->assertDrushReports('profile', '', [], [], [], array_keys($inactive)); + // Verify that the user search page cannot be imported (because it already + // exists). + $this->drupalGet('admin/config/development/configuration/report/import/search_page/user_search'); + $this->assertResponse(404); + // Delete the user search page from the search UI and verify report for // both the search page config type and user module. $this->drupalGet('admin/config/search/pages'); @@ -130,10 +135,19 @@ class ConfigUpdateTest extends WebTestBase { 'views.view.who_s_online', ], ['changed']); + // Verify that the user search page cannot be reverted (because it does + // not already exist). + $this->drupalGet('admin/config/development/configuration/report/revert/search_page/user_search'); + $this->assertResponse(404); + // Verify that the delete URL doesn't work either. + $this->drupalGet('admin/config/development/configuration/report/delete/search_page/user_search'); + $this->assertResponse(404); + // Use the import link to get it back. Do this from the search page // report to make sure we are importing the right config. $this->drupalGet('admin/config/development/configuration/report/type/search_page'); $this->clickLink('Import from source'); + $this->drupalPostForm(NULL, [], 'Import'); $this->assertText('The configuration was imported'); $this->assertNoReport(); $this->drupalGet('admin/config/development/configuration/report/type/search_page'); @@ -277,6 +291,7 @@ class ConfigUpdateTest extends WebTestBase { $this->assertText('cannot be undone'); $this->drupalPostForm(NULL, [], 'Delete'); $this->assertText('The configuration was deleted'); + // And verify the report again. $this->drupalGet('admin/config/development/configuration/report/type/search_page'); $this->assertReport('Search page', [], [], [], []); diff --git a/sites/all/modules/contrib/admin/config_update/src/ConfigLister.php b/sites/all/modules/contrib/admin/config_update/src/ConfigLister.php index a86e9d297..4c0bf9a14 100644 --- a/sites/all/modules/contrib/admin/config_update/src/ConfigLister.php +++ b/sites/all/modules/contrib/admin/config_update/src/ConfigLister.php @@ -123,7 +123,7 @@ class ConfigLister implements ConfigListInterface { public function getTypeNameByConfigName($name) { $definitions = $this->listTypes(); foreach ($this->typesByPrefix as $prefix => $entity_type) { - if (strpos($name, $prefix) === 0) { + if (strpos($name, $prefix . '.') === 0) { return $entity_type; } } @@ -174,6 +174,12 @@ class ConfigLister implements ConfigListInterface { break; } + // This only seems to be a problem in unit tests, where a mock object + // is returning NULL instead of an empy array for some reason. + if (!is_array($optional_list)) { + $optional_list = []; + } + return [$active_list, $install_list, $optional_list]; } @@ -211,7 +217,7 @@ class ConfigLister implements ConfigListInterface { $list = array_combine($list, $list); foreach ($list as $name) { foreach ($prefixes as $prefix) { - if (strpos($name, $prefix) === 0) { + if (strpos($name, $prefix . '.') === 0) { unset($list[$name]); } } diff --git a/sites/all/modules/contrib/admin/config_update/tests/src/Unit/ConfigListerTest.php b/sites/all/modules/contrib/admin/config_update/tests/src/Unit/ConfigListerTest.php new file mode 100644 index 000000000..b2a749335 --- /dev/null +++ b/sites/all/modules/contrib/admin/config_update/tests/src/Unit/ConfigListerTest.php @@ -0,0 +1,265 @@ +configLister = new ConfigLister($this->getEntityManagerMock(), $this->getConfigStorageMock('active'), $this->getConfigStorageMock('extension'), $this->getConfigStorageMock('optional')); + } + + /** + * Creates a mock entity manager for the test. + */ + protected function getEntityManagerMock() { + // Make a list of fake entity definitions. Make sure they are not sorted, + // to test that the methods sort them. Also make sure there are a couple + // with prefixes that are subsets of each other. + $this->entityDefinitionInformation = [ + ['prefix' => 'foo.bar', 'type' => 'foo'], + ['prefix' => 'foo.barbaz', 'type' => 'bar'], + ['prefix' => 'baz.foo', 'type' => 'baz'], + ]; + + $definitions = []; + foreach ($this->entityDefinitionInformation as $info) { + $def = $this->getMockBuilder('Drupal\Core\Config\Entity\ConfigEntityTypeInterface')->getMock(); + $def + ->expects($this->any()) + ->method('getConfigPrefix') + ->willReturn($info['prefix']); + $def + ->expects($this->any()) + ->method('isSubclassOf') + ->willReturn(TRUE); + + $def->getConfigPrefix(); + + $definitions[$info['type']] = $def; + } + + $manager = $this->getMockBuilder('Drupal\Core\Entity\EntityTypeManagerInterface')->getMock(); + $manager + ->method('getDefinitions') + ->willReturn($definitions); + + return($manager); + } + + /** + * Creates a mock config storage object for the test. + * + * @param string $type + * Type of storage object to return: 'active', 'extension', or 'optional'. + */ + protected function getConfigStorageMock($type) { + if ($type == 'active') { + $storage = $this->getMockBuilder('Drupal\Core\Config\StorageInterface')->getMock(); + + // The only use of the read() method on active storage is + // with the core.extension config, to get the profile name. + $storage + ->method('read') + ->willReturn(['profile' => 'standard']); + + $map = [ + ['foo.bar', ['foo.bar.one', 'foo.bar.two', 'foo.bar.three']], + ['foo.barbaz', ['foo.barbaz.four', 'foo.barbaz.five', 'foo.barbaz.six']], + ['baz.foo'], [], + ['', + [ + 'foo.bar.one', + 'foo.bar.two', + 'foo.bar.three', + 'foo.barbaz.four', + 'foo.barbaz.five', + 'foo.barbaz.six', + 'something.else', + 'another.one', + ], + ], + ]; + + $storage + ->method('listAll') + ->will($this->returnValueMap($map)); + } + elseif ($type == 'extension') { + $storage = $this->getMockBuilder('Drupal\Core\Config\ExtensionInstallStorage')->disableOriginalConstructor()->getMock(); + $storage + ->method('getComponentNames') + ->willReturn([ + 'foo.bar.one' => 'ignored', + 'foo.bar.two' => 'ignored', + 'foo.bar.seven' => 'ignored', + 'foo.barnot.three' => 'ignored', + 'something.else' => 'ignored', + ]); + + $map = [ + ['foo.bar', ['foo.bar.one', 'foo.bar.two', 'foo.bar.seven']], + ['baz.foo'], [], + ['', + [ + 'foo.bar.one', + 'foo.bar.two', + 'foo.bar.seven', + 'foo.barbaz.four', + 'foo.barnot.three', + 'something.else', + ], + ], + ]; + + $storage + ->method('listAll') + ->will($this->returnValueMap($map)); + } + else { + $storage = $this->getMockBuilder('Drupal\Core\Config\ExtensionInstallStorage')->disableOriginalConstructor()->getMock(); + $storage + ->method('getComponentNames') + ->willReturn([ + 'foo.barbaz.four' => 'ignored', + ]); + + $map = [ + ['foo.bar'], [], + ['foo.barbaz', ['foo.barbaz.four']], + ['', ['foo.barbaz.four']], + ]; + $storage + ->method('listAll') + ->will($this->returnValueMap($map)); + } + return $storage; + + } + + /** + * @covers \Drupal\config_update\ConfigLister::listConfig + * @dataProvider listConfigProvider + */ + public function testListConfig($a, $b, $expected) { + $this->assertEquals($expected, $this->configLister->listConfig($a, $b)); + } + + /** + * Data provider for self:testListConfig(). + */ + public function listConfigProvider() { + return [ + // Arguments are $list_type, $name. + // We cannot really test the extension types here, because they rely + // on the going out to the file system to find out what config objects + // are there. This is too complex to mock. It is tested in the tests for + // the report output in the config_update_ui module tests. Anyway, we + // can test the other types. + ['type', 'system.all', + [ + [ + 'foo.bar.one', + 'foo.bar.two', + 'foo.bar.three', + 'foo.barbaz.four', + 'foo.barbaz.five', + 'foo.barbaz.six', + 'something.else', + 'another.one', + ], + [ + 'foo.bar.one', + 'foo.bar.two', + 'foo.bar.seven', + 'foo.barbaz.four', + 'foo.barnot.three', + 'something.else', + ], + ['foo.barbaz.four'], + ], + ], + ['type', 'system.simple', + [ + ['something.else', 'another.one'], + ['foo.barnot.three', 'something.else'], + [], + ], + ], + ['type', 'foo', + [ + ['foo.bar.one', 'foo.bar.two', 'foo.bar.three'], + ['foo.bar.one', 'foo.bar.two', 'foo.bar.seven'], + [], + ], + ], + ['type', 'unknown.type', [[], [], []]], + ]; + } + + /** + * @covers \Drupal\config_update\ConfigLister::getType + */ + public function testGetType() { + $return = $this->configLister->getType('not_in_list'); + $this->assertNull($return); + + foreach ($this->entityDefinitionInformation as $info) { + $return = $this->configLister->getType($info['type']); + $this->assertEquals($return->getConfigPrefix(), $info['prefix']); + } + } + + /** + * @covers \Drupal\config_update\ConfigLister::getTypeByPrefix + */ + public function testGetTypeByPrefix() { + $return = $this->configLister->getTypeByPrefix('not_in_list'); + $this->assertNull($return); + + foreach ($this->entityDefinitionInformation as $info) { + $return = $this->configLister->getTypeByPrefix($info['prefix']); + $this->assertEquals($return->getConfigPrefix(), $info['prefix']); + } + } + + /** + * @covers \Drupal\config_update\ConfigLister::getTypeNameByConfigName + */ + public function testGetTypeNameByConfigName() { + $return = $this->configLister->getTypeNameByConfigName('not_in_list'); + $this->assertNull($return); + + foreach ($this->entityDefinitionInformation as $info) { + $return = $this->configLister->getTypeNameByConfigName($info['prefix'] . '.something'); + $this->assertEquals($return, $info['type']); + } + } + +} diff --git a/sites/all/modules/contrib/fields/audiofield/audiofield.info.yml b/sites/all/modules/contrib/fields/audiofield/audiofield.info.yml index ebb4cf80e..ce0527c39 100644 --- a/sites/all/modules/contrib/fields/audiofield/audiofield.info.yml +++ b/sites/all/modules/contrib/fields/audiofield/audiofield.info.yml @@ -5,8 +5,8 @@ type: module package: Field types # core: '8.x' -# Information added by Drupal.org packaging script on 2017-10-23 -version: '8.x-1.5' +# Information added by Drupal.org packaging script on 2017-12-27 +version: '8.x-1.6' core: '8.x' project: 'audiofield' -datestamp: 1508783950 +datestamp: 1514414887 diff --git a/sites/all/modules/contrib/fields/audiofield/audiofield.module b/sites/all/modules/contrib/fields/audiofield/audiofield.module index 813327196..2777d79a4 100644 --- a/sites/all/modules/contrib/fields/audiofield/audiofield.module +++ b/sites/all/modules/contrib/fields/audiofield/audiofield.module @@ -78,7 +78,7 @@ function audiofield_theme($existing, $type, $theme, $path) { } /** - * Implements hook_theme_suggestions_HOOK(). + * Implements hook_theme_suggestions_HOOK_alter(). */ function audiofield_theme_suggestions_audioplayer_alter(array &$suggestions, array $variables) { // Suggest a template using the plugin name. diff --git a/sites/all/modules/contrib/fields/audiofield/composer.json b/sites/all/modules/contrib/fields/audiofield/composer.json new file mode 100644 index 000000000..240f5dbed --- /dev/null +++ b/sites/all/modules/contrib/fields/audiofield/composer.json @@ -0,0 +1,18 @@ +{ + "name": "drupal/audiofield", + "description": "AudioField Module", + "type": "drupal-module", + "license": "GPL-2.0+", + "homepage": "https://www.drupal.org/project/audiofield", + "minimum-stability": "dev", + "authors": [ + { + "name": "Daniel Moberly", + "homepage": "https://www.drupal.org/u/danielmoberly", + "role": "Maintainer" + } + ], + "support": { + "issues": "https://www.drupal.org/project/issues/audiofield" + } +} diff --git a/sites/all/modules/contrib/fields/audiofield/js/jplayer.builder.es6.js b/sites/all/modules/contrib/fields/audiofield/js/jplayer.builder.es6.js index 9dee43113..533f759cd 100644 --- a/sites/all/modules/contrib/fields/audiofield/js/jplayer.builder.es6.js +++ b/sites/all/modules/contrib/fields/audiofield/js/jplayer.builder.es6.js @@ -41,6 +41,7 @@ wmode: 'window', useStateClassSkin: true, autoBlur: false, + preload: settings.lazyload, smoothPlayBar: true, keyEnabled: true, remainingDuration: false, @@ -78,6 +79,7 @@ wmode: 'window', useStateClassSkin: true, autoBlur: false, + preload: settings.lazyload, smoothPlayBar: true, keyEnabled: true, volume: settings.volume, @@ -125,6 +127,7 @@ }, swfPath: '/libraries/jplayer/dist/jplayer', wmode: 'window', + preload: settings.lazyload, keyEnabled: true, supplied: file.filetype, }, diff --git a/sites/all/modules/contrib/fields/audiofield/js/jplayer.builder.js b/sites/all/modules/contrib/fields/audiofield/js/jplayer.builder.js index 4b8549f68..bb75be6c5 100644 --- a/sites/all/modules/contrib/fields/audiofield/js/jplayer.builder.js +++ b/sites/all/modules/contrib/fields/audiofield/js/jplayer.builder.js @@ -31,6 +31,7 @@ wmode: 'window', useStateClassSkin: true, autoBlur: false, + preload: settings.lazyload, smoothPlayBar: true, keyEnabled: true, remainingDuration: false, @@ -57,6 +58,7 @@ wmode: 'window', useStateClassSkin: true, autoBlur: false, + preload: settings.lazyload, smoothPlayBar: true, keyEnabled: true, volume: settings.volume @@ -88,6 +90,7 @@ swfPath: '/libraries/jplayer/dist/jplayer', wmode: 'window', keyEnabled: true, + preload: settings.lazyload, supplied: file.filetype }); }); @@ -108,4 +111,4 @@ }); } }; -})(jQuery, Drupal); \ No newline at end of file +})(jQuery, Drupal); diff --git a/sites/all/modules/contrib/fields/audiofield/src/Plugin/AudioPlayer/JPlayerAudioPlayer.php b/sites/all/modules/contrib/fields/audiofield/src/Plugin/AudioPlayer/JPlayerAudioPlayer.php index c5820a3fb..d43ef1f5b 100644 --- a/sites/all/modules/contrib/fields/audiofield/src/Plugin/AudioPlayer/JPlayerAudioPlayer.php +++ b/sites/all/modules/contrib/fields/audiofield/src/Plugin/AudioPlayer/JPlayerAudioPlayer.php @@ -64,6 +64,7 @@ class JPlayerAudioPlayer extends AudioFieldPluginBase { 'filetype' => $renderInfo->filetype, 'fid' => $renderInfo->id, 'autoplay' => $settings['audio_player_autoplay'], + 'lazyload' => $settings['audio_player_lazyload'], ]; } } @@ -98,6 +99,7 @@ class JPlayerAudioPlayer extends AudioFieldPluginBase { // JPlayer expects this as a 0 - 1 value. 'volume' => ($settings['audio_player_initial_volume'] / 10), 'autoplay' => $settings['audio_player_autoplay'], + 'lazyload' => $settings['audio_player_lazyload'], ]; // Store the unique id for the template. @@ -120,6 +122,7 @@ class JPlayerAudioPlayer extends AudioFieldPluginBase { 'files' => [], 'filetypes' => [], 'autoplay' => $settings['audio_player_autoplay'], + 'lazyload' => $settings['audio_player_lazyload'], ]; // Format files for output. diff --git a/sites/all/modules/contrib/fields/audiofield/src/Plugin/Field/FieldFormatter/AudioFieldFieldFormatter.php b/sites/all/modules/contrib/fields/audiofield/src/Plugin/Field/FieldFormatter/AudioFieldFieldFormatter.php index 62d80bf4a..408505378 100644 --- a/sites/all/modules/contrib/fields/audiofield/src/Plugin/Field/FieldFormatter/AudioFieldFieldFormatter.php +++ b/sites/all/modules/contrib/fields/audiofield/src/Plugin/Field/FieldFormatter/AudioFieldFieldFormatter.php @@ -7,7 +7,6 @@ use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Field\FieldItemListInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Field\FormatterBase; -use Drupal\Core\Render\Markup; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -216,6 +215,33 @@ class AudioFieldFieldFormatter extends FormatterBase implements ContainerFactory ], ], ]; + // Settings for autoplay. + $elements['audio_player_lazyload'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Lazy Load audio'), + '#description' => $this->t("This setting causes audio not to be loaded until it is played."), + '#default_value' => $this->getSetting('audio_player_lazyload'), + '#states' => [ + 'visible' => [ + [':input[name="fields[' . $fieldname . '][settings_edit_form][settings][audio_player]"]' => ['value' => 'audiojs_audio_player']], + [':input[name="fields[' . $fieldname . '][settings_edit_form][settings][audio_player]"]' => ['value' => 'default_mp3_player']], + [':input[name="fields[' . $fieldname . '][settings_edit_form][settings][audio_player]"]' => ['value' => 'jplayer_audio_player']], + [':input[name="fields[' . $fieldname . '][settings_edit_form][settings][audio_player]"]' => ['value' => 'mediaelement_audio_player']], + [':input[name="fields[' . $fieldname . '][settings_edit_form][settings][audio_player]"]' => ['value' => 'projekktor_audio_player']], + ], + ], + ]; + // Settings for download button. + $elements['download_button'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Display download button on player'), + '#default_value' => $this->getSetting('download_button'), + '#states' => [ + 'visible' => [ + [':input[name="fields[' . $fieldname . '][settings_edit_form][settings][audio_player]"]' => ['value' => 'default_mp3_player']], + ], + ], + ]; // Setting for optional download link. $elements['download_link'] = [ '#type' => 'checkbox', @@ -236,7 +262,9 @@ class AudioFieldFieldFormatter extends FormatterBase implements ContainerFactory // Show which player we are currently using for the field. $summary = [ - Markup::create('Selected player: ' . $plugin_definitions[$settings['audio_player']]['title'] . ''), + $this->t('Selected player: @player', [ + '@player' => $plugin_definitions[$settings['audio_player']]['title'], + ]), ]; // If this is jPlayer, add those settings. if ($settings['audio_player'] == 'jplayer_audio_player') { @@ -254,16 +282,24 @@ class AudioFieldFieldFormatter extends FormatterBase implements ContainerFactory } } } - $summary[] = Markup::create('Skin: ' . $theme . ''); + $summary[] = $this->t('Skin: @theme', [ + '@theme' => $theme, + ]); } // If this is wavesurfer, add those settings. elseif ($settings['audio_player'] == 'wavesurfer_audio_player') { - $summary[] = Markup::create('Combine files into single player? ' . ($settings['audio_player_wavesurfer_combine_files'] ? 'Yes' : 'No') . ''); + $summary[] = $this->t('Combine files into single player? @combine', [ + '@combine' => ($settings['audio_player_wavesurfer_combine_files'] ? 'Yes' : 'No'), + ]); } // If this is wordpress, add those settings. elseif ($settings['audio_player'] == 'wordpress_audio_player') { - $summary[] = Markup::create('Combine files into single player? ' . ($settings['audio_player_wordpress_combine_files'] ? 'Yes' : 'No') . ''); - $summary[] = Markup::create('Animate player? ' . ($settings['audio_player_wordpress_animation'] ? 'Yes' : 'No') . ''); + $summary[] = $this->t('Combine files into single player? @combine', [ + '@combine' => ($settings['audio_player_wordpress_combine_files'] ? 'Yes' : 'No'), + ]); + $summary[] = $this->t('Animate player? @animate', [ + '@animate' => ($settings['audio_player_wordpress_animation'] ? 'Yes' : 'No'), + ]); } // If this is soundmanager, add those settings. elseif ($settings['audio_player'] == 'soundmanager_audio_player') { @@ -273,7 +309,9 @@ class AudioFieldFieldFormatter extends FormatterBase implements ContainerFactory 'barui' => 'Bar UI', 'inlineplayer' => 'Inline Player', ]; - $summary[] = Markup::create('Skin: ' . $skins[$settings['audio_player_soundmanager_theme']] . ''); + $summary[] = $this->t('Skin: @skin', [ + '@skin' => $skins[$settings['audio_player_soundmanager_theme']], + ]); } // Show combined settings for multiple players. @@ -286,7 +324,9 @@ class AudioFieldFieldFormatter extends FormatterBase implements ContainerFactory 'wordpress_audio_player', ])) { // Display volume. - $summary[] = Markup::create('Initial volume: ' . $settings['audio_player_initial_volume'] . ' out of 10'); + $summary[] = $this->t('Initial volume: @volume out of 10', [ + '@volume' => $settings['audio_player_initial_volume'], + ]); } // Display autoplay. @@ -299,17 +339,39 @@ class AudioFieldFieldFormatter extends FormatterBase implements ContainerFactory 'wavesurfer_audio_player', 'wordpress_audio_player', ])) { - $summary[] = Markup::create('Autoplay: ' . ($settings['audio_player_autoplay'] ? 'Yes' : 'No') . ''); + $summary[] = $this->t('Autoplay: @autoplay', [ + '@autoplay' => ($settings['audio_player_autoplay'] ? 'Yes' : 'No'), + ]); + } + + // Display lazy load. + if (in_array($settings['audio_player'], [ + 'audiojs_audio_player', + 'default_mp3_player', + 'jplayer_audio_player', + 'mediaelement_audio_player', + 'projekktor_audio_player', + ])) { + $summary[] = $this->t('Lazy Load: @lazyload', [ + '@lazyload' => ($settings['audio_player_lazyload'] ? 'Yes' : 'No'), + ]); } // Check to make sure the library is installed. $player = $this->audioPlayerManager->createInstance($settings['audio_player']); if (!$player->checkInstalled()) { - $summary[] = Markup::create('' . t('Error: this player library is currently not installed. Please select another player or reinstall the library.') . ''); + $summary[] = $this->t('Error: this player library is currently not installed. Please select another player or reinstall the library.'); } + // Show whether or not we are displaying download buttons. + $summary[] = $this->t('Display download button: @display_link', [ + '@display_link' => ($settings['download_button'] ? 'Yes' : 'No'), + ]); + // Show whether or not we are displaying direct downloads. - $summary[] = Markup::create('Display download link: ' . ($settings['download_link'] ? 'Yes' : 'No') . ''); + $summary[] = $this->t('Display download link: @display_link', [ + '@display_link' => ($settings['download_link'] ? 'Yes' : 'No'), + ]); return $summary; } @@ -327,6 +389,8 @@ class AudioFieldFieldFormatter extends FormatterBase implements ContainerFactory 'audio_player_soundmanager_theme' => 'default', 'audio_player_initial_volume' => 8, 'audio_player_autoplay' => FALSE, + 'audio_player_lazyload' => FALSE, + 'download_button' => FALSE, 'download_link' => FALSE, ] + parent::defaultSettings(); } diff --git a/sites/all/modules/contrib/fields/audiofield/templates/audioplayer--audiojs.html.twig b/sites/all/modules/contrib/fields/audiofield/templates/audioplayer--audiojs.html.twig index 276961b18..d03f0e1a9 100644 --- a/sites/all/modules/contrib/fields/audiofield/templates/audioplayer--audiojs.html.twig +++ b/sites/all/modules/contrib/fields/audiofield/templates/audioplayer--audiojs.html.twig @@ -15,7 +15,7 @@