' . t('The Admin Toolbar module enhances the Toolbar module by providing fast access to all the administrative links at the top of your site. Admin Toolbar remains a very "lightweight" module by closely integrating with all Toolbar functionality. It can be used in conjunction with all the sub or complimentary modules, listed on Admin Toolbar, for quick access to system commands such as Flush all caches, Run cron, Run Updates, etc... For more information, see the online documentation for the Admin Toolbar module.', $variables) . '
';
+ $output .= '
' . t('The Admin Toolbar module enhances the Toolbar module by providing fast access to all the administrative links at the top of your site. Admin Toolbar remains a very "lightweight" module by closely integrating with all Toolbar functionality. It can be used in conjunction with all the sub modules included on Admin Toolbar, for quick access to system commands such as Flush all caches, Run cron, Run Updates, etc.', $variables) . '
';
$output .= '
' . t('Uses') . '
';
- $output .= '
' . t('The Admin Toolbar greatly improves the user experience for those who regularly interact with the Drupal Toolbar by providing fast, full access to all links in the Drupal Toolbar without having to click to get there.') . '
';
+ $output .= '
' . t('The Admin Toolbar greatly improves the user experience for those who regularly interact with the site Toolbar by providing fast, full access to all links in the site Toolbar without having to click to get there.') . '
';
return $output;
}
diff --git a/web/modules/contrib/admin_toolbar/admin_toolbar_links_access_filter/README.txt b/web/modules/contrib/admin_toolbar/admin_toolbar_links_access_filter/README.txt
index 60598b871..37670cf49 100644
--- a/web/modules/contrib/admin_toolbar/admin_toolbar_links_access_filter/README.txt
+++ b/web/modules/contrib/admin_toolbar/admin_toolbar_links_access_filter/README.txt
@@ -3,7 +3,6 @@ CONTENTS OF THIS FILE
* Introduction
* Requirements
- * Recommended modules
* Installation
* Configuration
* Maintainers
@@ -32,15 +31,6 @@ This module requires the following modules:
* Admin Toolbar (https://www.drupal.org/project/admin_toolbar)
-RECOMMENDED MODULES
--------------------
-
- * Admin Toolbar (https://www.drupal.org/project/admin_toolbar):
- Improve the default Drupal Toolbar (the administration menu at the top of
- your site) to transform it into a drop-down menu, providing a fast access to
- all administration pages.
-
-
INSTALLATION
------------
diff --git a/web/modules/contrib/admin_toolbar/admin_toolbar_links_access_filter/admin_toolbar_links_access_filter.info.yml b/web/modules/contrib/admin_toolbar/admin_toolbar_links_access_filter/admin_toolbar_links_access_filter.info.yml
index 355a40cac..46edfd8a4 100644
--- a/web/modules/contrib/admin_toolbar/admin_toolbar_links_access_filter/admin_toolbar_links_access_filter.info.yml
+++ b/web/modules/contrib/admin_toolbar/admin_toolbar_links_access_filter/admin_toolbar_links_access_filter.info.yml
@@ -8,8 +8,8 @@ type: module
dependencies:
- admin_toolbar:admin_toolbar
-# Information added by Drupal.org packaging script on 2018-02-06
-version: '8.x-1.23'
+# Information added by Drupal.org packaging script on 2018-05-28
+version: '8.x-1.24'
core: '8.x'
project: 'admin_toolbar'
-datestamp: 1517936588
+datestamp: 1527522484
diff --git a/web/modules/contrib/admin_toolbar/admin_toolbar_links_access_filter/admin_toolbar_links_access_filter.module b/web/modules/contrib/admin_toolbar/admin_toolbar_links_access_filter/admin_toolbar_links_access_filter.module
index 7b4476897..d9930e07b 100644
--- a/web/modules/contrib/admin_toolbar/admin_toolbar_links_access_filter/admin_toolbar_links_access_filter.module
+++ b/web/modules/contrib/admin_toolbar/admin_toolbar_links_access_filter/admin_toolbar_links_access_filter.module
@@ -20,7 +20,7 @@ function admin_toolbar_links_access_filter_help($route_name, RouteMatchInterface
case 'help.page.admin_toolbar_links_access_filter':
$output = '';
$output .= '
' . t('About') . '
';
- $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()]) . '
';
+ $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 done not have access permission for.') . '
';
return $output;
}
@@ -184,10 +184,17 @@ function admin_toolbar_links_access_filter_is_overview_page($route_name) {
* assigned, FALSE otherwise.
*/
function admin_toolbar_links_access_filter_user_has_admin_role(AccountInterface $account) {
- foreach ($account->getRoles() as $role_id) {
- if (Role::load($role_id)->isAdmin()) {
- return TRUE;
+ static $user_has_admin_role = [];
+ $uid = $account->id();
+ if (!isset($user_has_admin_role[$uid])) {
+ $roles = Role::loadMultiple($account->getRoles());
+ foreach ($roles as $role) {
+ if ($role->isAdmin()) {
+ $user_has_admin_role[$uid] = TRUE;
+ break;
+ }
+ $user_has_admin_role[$uid] = FALSE;
}
}
- return FALSE;
+ return $user_has_admin_role[$uid];
}
diff --git a/web/modules/contrib/admin_toolbar/admin_toolbar_links_access_filter/composer.json b/web/modules/contrib/admin_toolbar/admin_toolbar_links_access_filter/composer.json
new file mode 100644
index 000000000..d75f3b0c6
--- /dev/null
+++ b/web/modules/contrib/admin_toolbar/admin_toolbar_links_access_filter/composer.json
@@ -0,0 +1,38 @@
+{
+ "name": "drupal/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.",
+ "type": "drupal-module",
+ "keywords": ["Drupal", "Toolbar"],
+ "homepage": "http://drupal.org/project/admin_toolbar",
+ "license": "GPL-2.0+",
+ "authors": [
+ {
+ "name": "Wilfrid Roze (eme)",
+ "homepage": "https://www.drupal.org/u/eme",
+ "role": "Maintainer"
+ },
+ {
+ "name": "Romain Jarraud (romainj)",
+ "homepage": "https://www.drupal.org/u/romainj",
+ "role": "Maintainer"
+ },
+ {
+ "name": "Adrian Cid Almaguer (adriancid)",
+ "email": "adriancid@gmail.com",
+ "homepage": "https://www.drupal.org/u/adriancid",
+ "role": "Maintainer"
+ },
+ {
+ "name": "Mohamed Anis Taktak (matio89)",
+ "homepage": "https://www.drupal.org/u/matio89",
+ "role": "Maintainer"
+ }
+ ],
+ "support": {
+ "issues": "https://www.drupal.org/project/issues/admin_toolbar",
+ "source": "http://cgit.drupalcode.org/admin_toolbar"
+ },
+ "require": {
+ "drupal/admin_toolbar": "^1"
+ }
+}
diff --git a/web/modules/contrib/admin_toolbar/admin_toolbar_tools/README.txt b/web/modules/contrib/admin_toolbar/admin_toolbar_tools/README.txt
index 4e40e8730..263cde93c 100644
--- a/web/modules/contrib/admin_toolbar/admin_toolbar_tools/README.txt
+++ b/web/modules/contrib/admin_toolbar/admin_toolbar_tools/README.txt
@@ -33,15 +33,6 @@ This module requires the following modules:
* Admin Toolbar (https://www.drupal.org/project/admin_toolbar)
-RECOMMENDED MODULES
--------------------
-
- * Admin Toolbar (https://www.drupal.org/project/admin_toolbar):
- Improve the default Drupal Toolbar (the administration menu at the top of
- your site) to transform it into a drop-down menu, providing a fast access to
- all administration pages.
-
-
INSTALLATION
------------
diff --git a/web/modules/contrib/admin_toolbar/admin_toolbar_tools/admin_toolbar_tools.info.yml b/web/modules/contrib/admin_toolbar/admin_toolbar_tools/admin_toolbar_tools.info.yml
index 8166fe66e..a42c0ccbe 100644
--- a/web/modules/contrib/admin_toolbar/admin_toolbar_tools/admin_toolbar_tools.info.yml
+++ b/web/modules/contrib/admin_toolbar/admin_toolbar_tools/admin_toolbar_tools.info.yml
@@ -7,9 +7,10 @@ type: module
dependencies:
- admin_toolbar:admin_toolbar
+ - drupal:system (>=8.3)
-# Information added by Drupal.org packaging script on 2018-02-06
-version: '8.x-1.23'
+# Information added by Drupal.org packaging script on 2018-05-28
+version: '8.x-1.24'
core: '8.x'
project: 'admin_toolbar'
-datestamp: 1517936588
+datestamp: 1527522484
diff --git a/web/modules/contrib/admin_toolbar/admin_toolbar_tools/admin_toolbar_tools.links.menu.yml b/web/modules/contrib/admin_toolbar/admin_toolbar_tools/admin_toolbar_tools.links.menu.yml
index cb8cc2587..fc7df7f1c 100644
--- a/web/modules/contrib/admin_toolbar/admin_toolbar_tools/admin_toolbar_tools.links.menu.yml
+++ b/web/modules/contrib/admin_toolbar/admin_toolbar_tools/admin_toolbar_tools.links.menu.yml
@@ -63,6 +63,12 @@ admin_toolbar_tools.flush_menu:
parent: admin_toolbar_tools.flush
menu_name: admin
+admin_toolbar_tools.flush_twig:
+ title: 'Flush twig cache'
+ route_name: admin_toolbar_tools.flush_twig
+ parent: admin_toolbar_tools.flush
+ menu_name: admin
+
admin_toolbar_tools.flush_rendercache:
title: 'Flush render cache'
route_name: admin_toolbar_tools.flush_rendercache
diff --git a/web/modules/contrib/admin_toolbar/admin_toolbar_tools/admin_toolbar_tools.module b/web/modules/contrib/admin_toolbar/admin_toolbar_tools/admin_toolbar_tools.module
index d08141db4..1db436a1d 100644
--- a/web/modules/contrib/admin_toolbar/admin_toolbar_tools/admin_toolbar_tools.module
+++ b/web/modules/contrib/admin_toolbar/admin_toolbar_tools/admin_toolbar_tools.module
@@ -5,7 +5,6 @@
* Provides extra menu links for the core drupal toolbar.
*/
-use Drupal\Core\Link;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Url;
@@ -34,21 +33,12 @@ function admin_toolbar_tools_toolbar() {
function admin_toolbar_tools_help($route_name, RouteMatchInterface $route_match) {
switch ($route_name) {
case 'help.page.admin_toolbar_tools':
- $url = Url::fromUri('https://www.drupal.org/project/admin_toolbar');
- $external_link = Link::fromTextAndUrl(t('Admin Toolbar'), $url);
- $external_link2 = Link::fromTextAndUrl(t('Toolbar'), $url);
- $url = Url::fromUri('https://www.drupal.org/node/2713693');
- $external_link3 = Link::fromTextAndUrl(t('online documentation for Admin Toolbar'), $url);
$output = '';
$output .= '
';
- $output .= t('The Admin Toolbar Extra Tools module comes packaged with the :link module and adds functionality to it. The additional functionality is accessed thru extra links on the main administration :link2. Some links to Admin Toolbar Extra Tools administration pages are located at the bottom of this page. For more information, see the :link3', [
- ':link' => $external_link,
- ':link2' => $external_link2,
- ':link3' => $external_link3,
- ]);
+ $output .= t('The Admin Toolbar Extra Tools module comes packaged with the Admin Toolbar module and adds functionality to it. The additional functionality is accessed thru extra links on the main administration Toolbar. Some links to Admin Toolbar Extra Tools administration pages are located at the bottom of this page.', [':admin-toolbar' => Url::fromRoute('help.page', ['name' => 'admin_toolbar'])->toString()]);
$output .= '
';
$output .= '
' . t('Uses') . '
';
- $output .= '
' . t('To use Admin Toolbar Extra Tools just install it like any other module. There is no other configuration required. The Admin Toolbar functionality can be further extended by installing complimentary modules. See :link for a complete listing of these complimentary modules.', [':link' => $external_link]) . '
';
+ $output .= '
' . t('To use Admin Toolbar Extra Tools just install it like any other module. There is no other configuration required.') . '
';
return $output;
}
@@ -85,6 +75,15 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
'menu_name' => 'admin',
'parent' => 'admin_toolbar_tools.flush',
];
+ // Adding a menu link to Files.
+ if ($moduleHandler->moduleExists('file') && in_array('view.files.page_1', $routes)) {
+ $links['admin_toolbar_tools.view.files'] = [
+ 'title' => t('Files'),
+ 'route_name' => 'view.files.page_1',
+ 'menu_name' => 'admin',
+ 'parent' => 'system.admin_content',
+ ];
+ }
}
// Adds common links to entities.
@@ -568,7 +567,7 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
];
// Add node links for each media type.
foreach (\Drupal::entityTypeManager()->getStorage('media_type')->loadMultiple() as $type) {
- $links['node.add.' . $type->id()] = [
+ $links['media.add.' . $type->id()] = [
'title' => t($type->label()),
'route_name' => 'entity.media.add_form',
'parent' => 'admin_toolbar_tools.add_media',
diff --git a/web/modules/contrib/admin_toolbar/admin_toolbar_tools/admin_toolbar_tools.routing.yml b/web/modules/contrib/admin_toolbar/admin_toolbar_tools/admin_toolbar_tools.routing.yml
index 277808c8e..dc081c860 100644
--- a/web/modules/contrib/admin_toolbar/admin_toolbar_tools/admin_toolbar_tools.routing.yml
+++ b/web/modules/contrib/admin_toolbar/admin_toolbar_tools/admin_toolbar_tools.routing.yml
@@ -61,6 +61,15 @@ admin_toolbar_tools.flush_views:
_permission: 'administer site configuration'
_csrf_token: 'TRUE'
+admin_toolbar_tools.flush_twig:
+ path: '/admin/flush/twig'
+ defaults:
+ _controller: '\Drupal\admin_toolbar_tools\Controller\ToolbarController::flushTwig'
+ _title: 'Twig'
+ requirements:
+ _permission: 'administer site configuration'
+ _csrf_token: 'TRUE'
+
admin_toolbar.run.cron:
path: '/run-cron'
defaults:
diff --git a/web/modules/contrib/admin_toolbar/admin_toolbar_tools/composer.json b/web/modules/contrib/admin_toolbar/admin_toolbar_tools/composer.json
new file mode 100644
index 000000000..49414fc2b
--- /dev/null
+++ b/web/modules/contrib/admin_toolbar/admin_toolbar_tools/composer.json
@@ -0,0 +1,39 @@
+{
+ "name": "drupal/admin_toolbar_tools",
+ "description": "Adds menu links to the Admin Toolbar.",
+ "type": "drupal-module",
+ "keywords": ["Drupal", "Toolbar"],
+ "homepage": "http://drupal.org/project/admin_toolbar",
+ "license": "GPL-2.0+",
+ "authors": [
+ {
+ "name": "Wilfrid Roze (eme)",
+ "homepage": "https://www.drupal.org/u/eme",
+ "role": "Maintainer"
+ },
+ {
+ "name": "Romain Jarraud (romainj)",
+ "homepage": "https://www.drupal.org/u/romainj",
+ "role": "Maintainer"
+ },
+ {
+ "name": "Adrian Cid Almaguer (adriancid)",
+ "email": "adriancid@gmail.com",
+ "homepage": "https://www.drupal.org/u/adriancid",
+ "role": "Maintainer"
+ },
+ {
+ "name": "Mohamed Anis Taktak (matio89)",
+ "homepage": "https://www.drupal.org/u/matio89",
+ "role": "Maintainer"
+ }
+ ],
+ "support": {
+ "issues": "https://www.drupal.org/project/issues/admin_toolbar",
+ "source": "http://cgit.drupalcode.org/admin_toolbar"
+ },
+ "require": {
+ "drupal/admin_toolbar": "^1",
+ "drupal/core": "~8.3"
+ }
+}
diff --git a/web/modules/contrib/admin_toolbar/admin_toolbar_tools/src/Controller/ToolbarController.php b/web/modules/contrib/admin_toolbar/admin_toolbar_tools/src/Controller/ToolbarController.php
index b1f275a79..8b74436c8 100644
--- a/web/modules/contrib/admin_toolbar/admin_toolbar_tools/src/Controller/ToolbarController.php
+++ b/web/modules/contrib/admin_toolbar/admin_toolbar_tools/src/Controller/ToolbarController.php
@@ -2,18 +2,19 @@
namespace Drupal\admin_toolbar_tools\Controller;
-use Drupal\Component\Datetime\Time;
+use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\CronInterface;
-use Drupal\Core\Menu\ContextualLinkManager;
-use Drupal\Core\Menu\LocalActionManager;
-use Drupal\Core\Menu\LocalTaskManager;
-use Drupal\Core\Menu\MenuLinkManager;
+use Drupal\Core\Menu\ContextualLinkManagerInterface;
+use Drupal\Core\Menu\LocalActionManagerInterface;
+use Drupal\Core\Menu\LocalTaskManagerInterface;
+use Drupal\Core\Menu\MenuLinkManagerInterface;
use Drupal\Core\Plugin\CachedDiscoveryClearerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\RequestStack;
+use Drupal\Core\PhpStorage\PhpStorageFactory;
/**
* Class ToolbarController.
@@ -32,28 +33,28 @@ class ToolbarController extends ControllerBase {
/**
* A menu link manager instance.
*
- * @var \Drupal\Core\Menu\MenuLinkManager
+ * @var \Drupal\Core\Menu\MenuLinkManagerInterface
*/
protected $menuLinkManager;
/**
* A context link manager instance.
*
- * @var \Drupal\Core\Menu\ContextualLinkManager
+ * @var \Drupal\Core\Menu\ContextualLinkManagerInterface
*/
protected $contextualLinkManager;
/**
* A local task manager instance.
*
- * @var \Drupal\Core\Menu\LocalTaskManager
+ * @var \Drupal\Core\Menu\LocalTaskManagerInterface
*/
protected $localTaskLinkManager;
/**
* A local action manager instance.
*
- * @var \Drupal\Core\Menu\LocalActionManager
+ * @var \Drupal\Core\Menu\LocalActionManagerInterface
*/
protected $localActionLinkManager;
@@ -67,7 +68,7 @@ class ToolbarController extends ControllerBase {
/**
* A date time instance.
*
- * @var \Drupal\Component\Datetime\Time
+ * @var \Drupal\Component\Datetime\TimeInterface
*/
protected $time;
@@ -86,15 +87,34 @@ class ToolbarController extends ControllerBase {
protected $pluginCacheClearer;
/**
- * {@inheritdoc}
+ * Constructs a ToolbarController object.
+ *
+ * @param \Drupal\Core\CronInterface $cron
+ * A cron instance.
+ * @param \Drupal\Core\Menu\MenuLinkManagerInterface $menuLinkManager
+ * A menu link manager instance.
+ * @param \Drupal\Core\Menu\ContextualLinkManagerInterface $contextualLinkManager
+ * A context link manager instance.
+ * @param \Drupal\Core\Menu\LocalTaskManagerInterface $localTaskLinkManager
+ * A local task manager instance.
+ * @param \Drupal\Core\Menu\LocalActionManagerInterface $localActionLinkManager
+ * A local action manager instance.
+ * @param \Drupal\Core\Cache\CacheBackendInterface $cacheRender
+ * A cache backend interface instance.
+ * @param \Drupal\Component\Datetime\TimeInterface $time
+ * A date time instance.
+ * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
+ * A request stack symfony instance.
+ * @param \Drupal\Core\Plugin\CachedDiscoveryClearerInterface $plugin_cache_clearer
+ * A plugin cache clear instance.
*/
public function __construct(CronInterface $cron,
- MenuLinkManager $menuLinkManager,
- ContextualLinkManager $contextualLinkManager,
- LocalTaskManager $localTaskLinkManager,
- LocalActionManager $localActionLinkManager,
+ MenuLinkManagerInterface $menuLinkManager,
+ ContextualLinkManagerInterface $contextualLinkManager,
+ LocalTaskManagerInterface $localTaskLinkManager,
+ LocalActionManagerInterface $localActionLinkManager,
CacheBackendInterface $cacheRender,
- Time $time,
+ TimeInterface $time,
RequestStack $request_stack,
CachedDiscoveryClearerInterface $plugin_cache_clearer) {
$this->cron = $cron;
@@ -197,6 +217,17 @@ class ToolbarController extends ControllerBase {
return new RedirectResponse($this->reloadPage());
}
+ /**
+ * Clears the twig cache.
+ */
+ public function flushTwig() {
+ // @todo Update once Drupal 8.6 will be released.
+ // @see https://www.drupal.org/node/2908461
+ PhpStorageFactory::get('twig')->deleteAll();
+ drupal_set_message($this->t('Twig cache cleared.'));
+ return new RedirectResponse($this->reloadPage());
+ }
+
/**
* Run the cron.
*/
diff --git a/web/modules/contrib/admin_toolbar/admin_toolbar_tools/src/Tests/AdminToolbarToolsAlterTest.php b/web/modules/contrib/admin_toolbar/admin_toolbar_tools/tests/src/Functional/AdminToolbarToolsAlterTest.php
similarity index 78%
rename from web/modules/contrib/admin_toolbar/admin_toolbar_tools/src/Tests/AdminToolbarToolsAlterTest.php
rename to web/modules/contrib/admin_toolbar/admin_toolbar_tools/tests/src/Functional/AdminToolbarToolsAlterTest.php
index 73035efb1..f61329c63 100644
--- a/web/modules/contrib/admin_toolbar/admin_toolbar_tools/src/Tests/AdminToolbarToolsAlterTest.php
+++ b/web/modules/contrib/admin_toolbar/admin_toolbar_tools/tests/src/Functional/AdminToolbarToolsAlterTest.php
@@ -1,22 +1,26 @@
theme_handler->listInfo();
$result = [];
- foreach ($modules + $themes as $name => $data) {
+ foreach ($modules as $name => $data) {
$result[$name] = $this->module_handler->getName($name);
}
+
+ foreach ($themes as $name => $data) {
+ $result[$name] = $this->theme_handler->getName($name);
+ }
+
return $result;
}
diff --git a/web/modules/contrib/blazy/blazy.info.yml b/web/modules/contrib/blazy/blazy.info.yml
index c123745f3..20b936d10 100644
--- a/web/modules/contrib/blazy/blazy.info.yml
+++ b/web/modules/contrib/blazy/blazy.info.yml
@@ -7,8 +7,8 @@ package: Blazy
dependencies:
- drupal:image
-# Information added by Drupal.org packaging script on 2017-05-25
-version: '8.x-1.0-rc2'
+# Information added by Drupal.org packaging script on 2018-09-27
+version: '8.x-1.0-rc3'
core: '8.x'
project: 'blazy'
-datestamp: 1495745286
+datestamp: 1538045584
diff --git a/web/modules/contrib/blazy/blazy.module b/web/modules/contrib/blazy/blazy.module
index 252c38945..59b1ff753 100644
--- a/web/modules/contrib/blazy/blazy.module
+++ b/web/modules/contrib/blazy/blazy.module
@@ -80,8 +80,7 @@ function blazy_field_formatter_info_alter(array &$info) {
'quickedit' => ['editor' => 'disabled'],
'provider' => 'blazy',
];
-
- if (function_exists('video_embed_media_media_bundle_insert')) {
+ if (\Drupal::moduleHandler()->moduleExists('video_embed_media')) {
$info['blazy_file'] = $common + [
'id' => 'blazy_file',
'label' => t('Blazy Image with Media'),
diff --git a/web/modules/contrib/blazy/blazy.views.inc b/web/modules/contrib/blazy/blazy.views.inc
index c1fbec3c8..8d1246a42 100644
--- a/web/modules/contrib/blazy/blazy.views.inc
+++ b/web/modules/contrib/blazy/blazy.views.inc
@@ -17,8 +17,7 @@ function blazy_views_data_alter(&$data) {
'click sortable' => FALSE,
],
];
-
- if (function_exists('video_embed_media_media_bundle_insert')) {
+ if (\Drupal::moduleHandler()->moduleExists('video_embed_media')) {
$data['media_field_data']['blazy_media'] = [
'title' => 'Blazy',
'help' => t('Displays a preview of a Media using Blazy, if applicable.'),
diff --git a/web/modules/contrib/blazy/blazy_ui/blazy_ui.info.yml b/web/modules/contrib/blazy/blazy_ui/blazy_ui.info.yml
index b5a4dde54..63575981e 100644
--- a/web/modules/contrib/blazy/blazy_ui/blazy_ui.info.yml
+++ b/web/modules/contrib/blazy/blazy_ui/blazy_ui.info.yml
@@ -8,8 +8,8 @@ configure: blazy.settings
dependencies:
- blazy:blazy
-# Information added by Drupal.org packaging script on 2017-05-25
-version: '8.x-1.0-rc2'
+# Information added by Drupal.org packaging script on 2018-09-27
+version: '8.x-1.0-rc3'
core: '8.x'
project: 'blazy'
-datestamp: 1495745286
+datestamp: 1538045584
diff --git a/web/modules/contrib/blazy/src/BlazyLightbox.php b/web/modules/contrib/blazy/src/BlazyLightbox.php
index bd943996c..6d6470d33 100644
--- a/web/modules/contrib/blazy/src/BlazyLightbox.php
+++ b/web/modules/contrib/blazy/src/BlazyLightbox.php
@@ -36,6 +36,9 @@ class BlazyLightbox {
$settings['box_width'] = isset($item->width) ? $item->width : NULL;
$settings['box_height'] = isset($item->height) ? $item->height : NULL;
+ $settings['box_width'] = isset($settings['box_width']) ? $settings['box_width'] : $settings['width'];
+ $settings['box_height'] = isset($settings['box_height']) ? $settings['box_height'] : $settings['height'];
+
$dimensions = ['width' => $settings['box_width'], 'height' => $settings['box_height']];
if (!empty($settings['box_style'])) {
$box_style = ImageStyle::load($settings['box_style']);
@@ -77,7 +80,7 @@ class BlazyLightbox {
$settings['box_url'] = $box_media_style->buildUrl($uri);
// Allows custom work to override this without image style.
- if (empty($settings['_box_width'])) {
+ if (empty($settings['box_width'])) {
$settings['box_width'] = $dimensions['width'];
$settings['box_height'] = $dimensions['height'];
}
diff --git a/web/modules/contrib/blazy/src/Dejavu/BlazyVideoTrait.php b/web/modules/contrib/blazy/src/Dejavu/BlazyVideoTrait.php
index 1a0268131..443e64678 100644
--- a/web/modules/contrib/blazy/src/Dejavu/BlazyVideoTrait.php
+++ b/web/modules/contrib/blazy/src/Dejavu/BlazyVideoTrait.php
@@ -171,7 +171,7 @@ trait BlazyVideoTrait {
$bundle = $media->bundle();
$fields = $media->getFields();
- $config = $media->getType()->getConfiguration();
+ $config = method_exists($media, 'getSource') ? $media->getSource()->getConfiguration() : $media->getType()->getConfiguration();
$source = isset($config['source_url_field']) ? $config['source_url_field'] : '';
$source_field[$bundle] = isset($config['source_field']) ? $config['source_field'] : $source;
diff --git a/web/modules/contrib/blazy/tests/modules/blazy_test/blazy_test.info.yml b/web/modules/contrib/blazy/tests/modules/blazy_test/blazy_test.info.yml
index 5a4639157..ffd481b37 100644
--- a/web/modules/contrib/blazy/tests/modules/blazy_test/blazy_test.info.yml
+++ b/web/modules/contrib/blazy/tests/modules/blazy_test/blazy_test.info.yml
@@ -9,8 +9,8 @@ dependencies:
- drupal:responsive_image
- drupal:views
-# Information added by Drupal.org packaging script on 2017-05-25
-version: '8.x-1.0-rc2'
+# Information added by Drupal.org packaging script on 2018-09-27
+version: '8.x-1.0-rc3'
core: '8.x'
project: 'blazy'
-datestamp: 1495745286
+datestamp: 1538045584
diff --git a/web/modules/contrib/block_class/README.txt b/web/modules/contrib/block_class/README.txt
index 8bf7508af..5fe887806 100644
--- a/web/modules/contrib/block_class/README.txt
+++ b/web/modules/contrib/block_class/README.txt
@@ -1,12 +1,57 @@
-BLOCK CLASS
------------
-Project URL: http://drupal.org/project/block_class
+CONTENTS OF THIS FILE
+---------------------
+
+ * Introduction
+ * Requirements
+ * Installation
+ * Configuration
+ * Maintainers
+
+
+INTRODUCTION
+------------
+
+Block Class allows users to add classes to any block through the block's
+configuration interface.
+
+
+REQUIREMENTS
+------------
+
+The Menu Block just requires the Block project:
+
+ * Block (https://drupal.org/project/block)
-=====
-Installation
------
-1. Enable the module
-2. Visit the block configuration page at Administration -> Structure -> Block Layout
-and click on the Configure link for a block.
-3. Enter the classes in the field provided and save the block.
\ No newline at end of file
+INSTALLATION
+------------
+
+Install as you would normally install a contributed Drupal module. See:
+https://drupal.org/documentation/install/modules-themes/modules-8 for further
+information.
+
+
+CONFIGURATION
+-------------
+
+ * Visit the block configuration page at Administration » Structure » Block
+ Layout and click on the Configure link for a block.
+
+ * Enter the classes in the field provided and save the block.
+
+
+MAINTAINERS
+-----------
+
+Current maintainers:
+ * Todd Nienkerk - https://www.drupal.org/user/92096
+ * Renato Gonçalves (RenatoG) - https://www.drupal.org/user/3326031
+ * Aaron Stanush - https://www.drupal.org/user/89718
+ * David Suissa (DYdave) - https://www.drupal.org/user/467284
+ * Four Kitchens - https://www.drupal.org/user/358502
+ * berenddeboer - https://www.drupal.org/user/143552
+ * elliotttf - https://www.drupal.org/user/61601
+ * Michal Minecki (mirzu) - https://www.drupal.org/user/7710
+ * Patrick Coffey (patrickcoffeyo) - https://www.drupal.org/user/2837945
+ * Patrick Coffey (pcoffey) - https://www.drupal.org/user/1595818
+ * Taylor Smith (tsmith512) - https://www.drupal.org/user/2031446
diff --git a/web/modules/contrib/block_class/block_class.info.yml b/web/modules/contrib/block_class/block_class.info.yml
index 6a831f84f..75701e41a 100644
--- a/web/modules/contrib/block_class/block_class.info.yml
+++ b/web/modules/contrib/block_class/block_class.info.yml
@@ -4,10 +4,10 @@ description: 'Allows assigning classes to Blocks'
package: Other
# core: 8.x
dependencies:
- - block
+ - drupal:block
-# Information added by Drupal.org packaging script on 2016-10-04
-version: '8.x-1.0-alpha1'
+# Information added by Drupal.org packaging script on 2018-07-13
+version: '8.x-1.0'
core: '8.x'
project: 'block_class'
-datestamp: 1475623440
+datestamp: 1531440825
diff --git a/web/modules/contrib/block_class/block_class.module b/web/modules/contrib/block_class/block_class.module
index c43fde2fb..b3afb939f 100644
--- a/web/modules/contrib/block_class/block_class.module
+++ b/web/modules/contrib/block_class/block_class.module
@@ -2,15 +2,28 @@
/**
* @file
- * Module for adding classes to blocks.
+ * Adding classes to blocks.
*/
+use Drupal\Core\Form\FormStateInterface;
use Drupal\block\Entity\Block;
+use Drupal\Component\Utility\Html;
+use Drupal\Core\Routing\RouteMatchInterface;
+use Drupal\block\BlockInterface;
+
+/**
+ * Implements hook_ENTITY_TYPE_presave().
+ */
+function block_class_block_presave(BlockInterface $entity) {
+ if (empty($entity->getThirdPartySetting('block_class', 'classes'))) {
+ $entity->unsetThirdPartySetting('block_class', 'classes');
+ }
+}
/**
* Implements hook_form_FORM_ID_alter().
*/
-function block_class_form_block_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
+function block_class_form_block_form_alter(&$form, FormStateInterface $form_state, $form_id) {
if (\Drupal::currentUser()->hasPermission('administer block classes')) {
/** @var \Drupal\block\BlockInterface $block */
@@ -18,12 +31,12 @@ function block_class_form_block_form_alter(&$form, \Drupal\Core\Form\FormStateIn
// This will automatically be saved in the third party settings.
$form['third_party_settings']['#tree'] = TRUE;
- $form['third_party_settings']['block_class']['classes'] = array(
+ $form['third_party_settings']['block_class']['classes'] = [
'#type' => 'textfield',
'#title' => t('CSS class(es)'),
'#description' => t('Customize the styling of this block by adding CSS classes. Separate multiple classes by spaces.'),
'#default_value' => $block->getThirdPartySetting('block_class', 'classes'),
- );
+ ];
}
}
@@ -35,8 +48,36 @@ function block_class_preprocess_block(&$variables) {
// Blocks coming from page manager widget does not have id.
if (!empty($variables['elements']['#id'])) {
$block = Block::load($variables['elements']['#id']);
- if ($classes = $block->getThirdPartySetting('block_class', 'classes')) {
- $variables['attributes']['class'][] = $classes;
+ if ($block && $classes = $block->getThirdPartySetting('block_class', 'classes')) {
+ $classes_array = explode(' ', $classes);
+ foreach ($classes_array as $class) {
+ $variables['attributes']['class'][] = Html::cleanCssIdentifier($class, []);
+ }
}
}
}
+
+/**
+ * Implements hook_help().
+ */
+function block_class_help($route_name, RouteMatchInterface $route_match) {
+ switch ($route_name) {
+ // Main module help for the forms_to_email module.
+ case 'help.page.block_class':
+ $output = '';
+ $output .= '
' . t('About') . '
';
+ $output .= '
' . t("Block Class allows users to add classes to any block through the block's configuration interface. Hooray for more powerful block theming!") . '
';
+
+ $output .= '
' . t('Installation note') . '
';
+ $output .= '
';
+ $output .= '
' . t('Enable the module on extend menu.', [':extend_link' => \Drupal::url('system.modules_list')]) . '
';
+ $output .= '
';
+
+ $output .= '
' . t('Usage') . '
';
+ $output .= '
';
+ $output .= '
' . t("To add a class to a block, simply visit that block's configuration page at Administration > Structure > Block Layout and click on Configure of the desired block.") . '
',
];
- $this->drupalPostForm('node/add/article', $edit, t('Save and publish'));
+ if (\Drupal::moduleHandler()->moduleExists('content_moderation')) {
+ $edit['moderation_state[0][state]'] = 'published';
+ }
+ $this->drupalPostNodeForm('node/add/article', $edit, t('Save and publish'));
$node_one = $this->drupalGetNodeByTitle($title);
// Create second article.
@@ -429,7 +466,10 @@ class DiffRevisionTest extends DiffTestBase {
'title[0][value]' => $title,
'body[0][value]' => '
Second article
',
];
- $this->drupalPostForm('node/add/article', $edit, t('Save and publish'));
+ if (\Drupal::moduleHandler()->moduleExists('content_moderation')) {
+ $edit['moderation_state[0][state]'] = 'published';
+ }
+ $this->drupalPostNodeForm('node/add/article', $edit, t('Save and publish'));
$node_two = $this->drupalGetNodeByTitle($title);
// Create revision and add entity reference from second node to first.
@@ -438,7 +478,10 @@ class DiffRevisionTest extends DiffTestBase {
'field_content[0][target_id]' => $node_two->getTitle(),
'revision' => TRUE,
];
- $this->drupalPostForm('node/' . $node_one->id() . '/edit', $edit, t('Save and keep published'));
+ if (\Drupal::moduleHandler()->moduleExists('content_moderation')) {
+ $edit['moderation_state[0][state]'] = 'published';
+ }
+ $this->drupalPostNodeForm('node/' . $node_one->id() . '/edit', $edit, t('Save and keep published'));
// Delete referenced node.
$node_two->delete();
diff --git a/web/modules/contrib/diff/src/Tests/DiffViewModeTest.php b/web/modules/contrib/diff/src/Tests/DiffViewModeTest.php
index e07555a4a..352f8b73c 100644
--- a/web/modules/contrib/diff/src/Tests/DiffViewModeTest.php
+++ b/web/modules/contrib/diff/src/Tests/DiffViewModeTest.php
@@ -1,6 +1,7 @@
'Fighters',
'revision' => TRUE,
);
- $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save and keep published'));
+ $this->drupalPostNodeForm('node/' . $node->id() . '/edit', $edit, t('Save and keep published'));
// Set the Body field to hidden in the diff view mode.
$edit = [
diff --git a/web/modules/contrib/diff/tests/modules/diff_test/diff_test.info.yml b/web/modules/contrib/diff/tests/modules/diff_test/diff_test.info.yml
index dc7b7be86..e02bf20d8 100644
--- a/web/modules/contrib/diff/tests/modules/diff_test/diff_test.info.yml
+++ b/web/modules/contrib/diff/tests/modules/diff_test/diff_test.info.yml
@@ -11,8 +11,8 @@ name: Diff tests
package: diff
type: module
-# Information added by Drupal.org packaging script on 2017-01-16
-version: '8.x-1.0-rc1'
+# Information added by Drupal.org packaging script on 2018-06-28
+version: '8.x-1.0-rc2'
core: '8.x'
project: 'diff'
-datestamp: 1484566687
+datestamp: 1530178427
diff --git a/web/modules/contrib/diff/tests/src/Functional/CoreVersionUiTestTrait.php b/web/modules/contrib/diff/tests/src/Functional/CoreVersionUiTestTrait.php
new file mode 100644
index 000000000..07e0ab18c
--- /dev/null
+++ b/web/modules/contrib/diff/tests/src/Functional/CoreVersionUiTestTrait.php
@@ -0,0 +1,39 @@
+drupalPostForm($path, $edit, $submit);
+ }
+
+}
\ No newline at end of file
diff --git a/web/modules/contrib/diff/tests/src/Functional/NodeAccessTest.php b/web/modules/contrib/diff/tests/src/Functional/NodeAccessTest.php
new file mode 100644
index 000000000..046d96470
--- /dev/null
+++ b/web/modules/contrib/diff/tests/src/Functional/NodeAccessTest.php
@@ -0,0 +1,71 @@
+createContentType(['type' => 'article']);
+
+ // Dummy user 1.
+ $this->createUser();
+
+ // Rebuild access.
+ node_access_rebuild();
+ }
+
+ /**
+ * Tests that the revision overview form still works with node access.
+ */
+ public function testOverview() {
+ // Create an unpublished node with 3 revisions.
+ $node = $this->createNode([
+ 'type' => 'article',
+ 'status' => FALSE,
+ ]);
+ $node->setTitle($this->randomString());
+ $node->setNewRevision();
+ $node->save();
+ $node->setTitle($this->randomString());
+ $node->setNewRevision();
+ $node->save();
+ $user = $this->createUser(['access content', 'view all revisions']);
+ $this->drupalLogin($user);
+
+ // Grant access via node_access_test.
+ // @see node_access_test_node_access
+ \Drupal::state()->set('node_access_test.allow_uid', $user->id());
+
+ $this->drupalGet($node->toUrl());
+ $this->assertSession()->statusCodeEquals(200);
+ $this->drupalGet($node->toUrl('version-history'));
+ $this->assertSession()->statusCodeEquals(200);
+
+ // There should be 3 diff rows.
+ $rows = $this->xpath('//tbody/tr');
+ $this->assertCount(3, $rows, 'Did not find 3 diff rows.');
+
+ // Compare selected revisions should not time out.
+ $this->drupalGet('/node/' . $node->id(). '/revisions');
+ $this->drupalPostForm(NULL, NULL, t('Compare selected revisions'));
+ $this->assertSession()->statusCodeEquals(200);
+ }
+
+}
diff --git a/web/modules/contrib/draggableviews/README.md b/web/modules/contrib/draggableviews/README.md
new file mode 100755
index 000000000..d83bdb98f
--- /dev/null
+++ b/web/modules/contrib/draggableviews/README.md
@@ -0,0 +1,59 @@
+INTRODUCTION
+------------
+
+This module provides dragging entities and saving their order.
+
+
+REQUIREMENTS
+-------------
+
+Views, Views UI, Filter, User, System module enabled.
+
+
+INSTALLATION
+------------
+
+Enable this module from extend list page /admin/modules.
+
+
+CONFIGURATION
+-------------
+
+1) Activate Draggableviews module at /admin/modules.
+2) Create a new view
+ - Goto '/admin/structure/views/add' on your site.
+ - Check off 'Create a page'.
+ - Check off 'Create a block'.
+ - Set the 'Display format' for the page to what you desire.
+ - Set the "'Display format' of" to fields.
+ - Set the 'Display format' for the block to table.
+ - Fill in the rest of the views information.
+ - Click Save & edit button.
+3) Under the "FIELDS" section, do you see "Content: Title"? If you do not:
+ - Click 'add' button at the "Fields" section and choose field
+ "Content:title", add and apply.
+4) Add the Draggableviews Field:
+ - Click Add button at the "FIELDS" section.
+ - At the top of the overlay, Change "For: 'All displays'" to 'This block
+ (override)'.
+ - If you do not do this then the field will be add to all displays and
+ will prevent your page display from using the block display to sort the
+ order.
+5) Click Add button at the "SORT CRITERIA" section choose field
+"Draggableviews: Weight", add and choose sort asc, then apply.
+6) Under the "SORT CRITERIA" section, do you see "Content: Post date (asc)"?
+ If you do:
+ - Click on it. At the bottom, click the 'Remove' button.
+ - An alternative is to rearrange the "SORT CRITERIA" order, making sure
+ 'Draggableviews: Weight (asc) appears first (or on top).
+7) Save the view and you're done.
+*Things to confirm after you saved your new view.
+- In the Administrative Views UI, Go back to your View's 'page' display.
+ -> Click 'Draggableviews: Weight (asc)' under 'SORT CRITERIA'
+ -> You should see:
+ Display sort as:
+ ()
+
+ This should the view and block display you just create.
+
+ FYI - This is also where you can change it to another view.
diff --git a/web/modules/contrib/draggableviews/composer.json b/web/modules/contrib/draggableviews/composer.json
new file mode 100644
index 000000000..c1fed0d98
--- /dev/null
+++ b/web/modules/contrib/draggableviews/composer.json
@@ -0,0 +1,39 @@
+{
+ "name": "drupal/draggableviews",
+ "description": "DraggableViews module makes views draggable.",
+ "type": "drupal-module",
+ "homepage": "https://www.drupal.org/project/draggableviews",
+ "authors": [
+ {
+ "name": "Tyler Struyk (iStryker)",
+ "email": "tyler.struyk@gmail.com",
+ "homepage": "https://www.drupal.org/u/istryker",
+ "role": "Maintainer"
+ },
+ {
+ "name": "Andrii Podanenko (podarok)",
+ "email": "podarokua@gmail.com",
+ "homepage": "https://www.drupal.org/u/podarok",
+ "role": "Drupal 7 to 8 Porter"
+ },
+ {
+ "name": "Yuriy Gerasimov (ygerasimov)",
+ "email": "yuriy.gerasimov@gmail.com",
+ "homepage": "https://www.drupal.org/u/ygerasimov",
+ "role": "Ex Maintainer (D7)"
+ },
+ {
+ "name": "Severin Unger (sevi)",
+ "homepage": "https://www.drupal.org/u/sevi",
+ "role": "Ex Maintainer (D6)"
+ }
+ ],
+ "support": {
+ "issues": "https://www.drupal.org/project/issues/draggableviews",
+ "source": "https://cgit.drupalcode.org/draggableviews"
+ },
+ "license": "GPL-2.0+",
+ "minimum-stability": "dev",
+ "require": {
+ }
+}
diff --git a/web/modules/contrib/draggableviews/draggableviews.info.yml b/web/modules/contrib/draggableviews/draggableviews.info.yml
index 1acec7669..803dec3ca 100644
--- a/web/modules/contrib/draggableviews/draggableviews.info.yml
+++ b/web/modules/contrib/draggableviews/draggableviews.info.yml
@@ -1,12 +1,15 @@
name: DraggableViews
type: module
-description: Complete rewrite of D7 draggableviews
+description: 'Allows your views to be draggable and gives you the ability to set the order of how they appear.'
# core: 8.x
dependencies:
- - views
+ - drupal:views
+test_dependencies:
+ - draggableviews:draggableviews_demo
+package: Views
-# Information added by Drupal.org packaging script on 2016-10-21
-version: '8.x-1.0'
+# Information added by Drupal.org packaging script on 2018-11-06
+version: '8.x-1.2'
core: '8.x'
project: 'draggableviews'
-datestamp: 1477076053
+datestamp: 1541518687
diff --git a/web/modules/contrib/draggableviews/draggableviews.install b/web/modules/contrib/draggableviews/draggableviews.install
index 364c65a6d..f05c12a16 100644
--- a/web/modules/contrib/draggableviews/draggableviews.install
+++ b/web/modules/contrib/draggableviews/draggableviews.install
@@ -5,68 +5,78 @@
* Install, update and uninstall functions for the draggableviews module.
*/
+use Drupal\views\Views;
+
/**
* Implements hook_schema().
*/
function draggableviews_schema() {
- $schema['draggableviews_structure'] = array(
- 'description' => 'Table that contains logs of all system events.',
- 'fields' => array(
- 'dvid' => array(
+ $schema['draggableviews_structure'] = [
+ 'description' => 'Saves the order settings of a draggableview view.',
+ 'fields' => [
+ 'dvid' => [
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
'description' => 'The primary identifier.',
- ),
- 'view_name' => array(
+ ],
+ 'view_name' => [
'type' => 'varchar',
'length' => 128,
'not null' => TRUE,
'default' => '',
'description' => 'Makes the order unique for each view.',
- ),
- 'view_display' => array(
+ ],
+ 'view_display' => [
'type' => 'varchar',
'length' => 64,
'not null' => TRUE,
'default' => '',
'description' => 'Makes the order unique for each view display.',
- ),
- 'args' => array(
+ ],
+ 'args' => [
'type' => 'varchar',
'length' => 255,
'not null' => FALSE,
'default' => '',
'description' => 'Makes the order unique for a given set of arguments',
- ),
- 'entity_id' => array(
+ ],
+ 'entity_id' => [
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'description' => 'Id of the entity that we are sorting (node, user, etc.).',
- ),
- 'weight' => array(
+ ],
+ 'weight' => [
'type' => 'int',
'unsigned' => FALSE,
'not null' => TRUE,
'default' => 0,
'description' => 'The order weight.',
- ),
- 'parent' => array(
+ ],
+ 'parent' => [
'type' => 'int',
'unsigned' => FALSE,
'not null' => TRUE,
'default' => 0,
'description' => 'The id of the parent.',
- ),
- ),
- 'indexes' => array(
- 'view' => array('view_name', 'view_display', 'args', 'entity_id'),
- 'weight' => array('weight'),
- 'entity_id' => array('entity_id'),
- ),
- 'primary key' => array('dvid'),
- );
+ ],
+ ],
+ 'indexes' => [
+ 'view' => ['view_name', 'view_display', 'args', 'entity_id'],
+ 'weight' => ['weight'],
+ 'entity_id' => ['entity_id'],
+ ],
+ 'primary key' => ['dvid'],
+ ];
return $schema;
}
+
+/**
+ * Implements hook_update().
+ */
+function draggableviews_update_8104(&$sandbox) {
+ // the update hook here accidentally cropped in into 1.1 but it shouldn't be
+ // there, I belivee that removing it should be harmless.
+}
diff --git a/web/modules/contrib/draggableviews/draggableviews.module b/web/modules/contrib/draggableviews/draggableviews.module
index d5d22eeaa..0950a5a87 100644
--- a/web/modules/contrib/draggableviews/draggableviews.module
+++ b/web/modules/contrib/draggableviews/draggableviews.module
@@ -5,96 +5,109 @@
* Contains draggableviews.module.
*/
+use Drupal\draggableviews\DraggableViews;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Database\Database;
+use Drupal\Core\Cache\Cache;
+
/**
* Implements hook_views_data_alter().
*/
function draggableviews_views_data_alter(&$data) {
- $data['draggableviews_structure']['weight'] = array(
+ $data['draggableviews_structure']['weight'] = [
'title' => t('DraggableViews Weight'),
- 'group' => t('Global'),
+ 'group' => t('Draggableviews'),
'help' => t('Display the weight value.'),
- 'field' => array(
+ 'field' => [
'id' => 'numeric',
- ),
- 'sort' => array(
+ ],
+ 'sort' => [
'id' => 'standard',
- ),
- 'filter' => array(
+ ],
+ 'filter' => [
'help' => t('Filter by the draggableviews weight value (Native handler only).'),
'id' => 'numeric',
- ),
- );
- $data['draggableviews_structure']['parent'] = array(
+ ],
+ 'argument' => [
+ 'id' => 'numeric',
+ ],
+ ];
+ $data['draggableviews_structure']['parent'] = [
'title' => t('Parent'),
'help' => t('The parent entity id.'),
'group' => t('Draggableviews'),
- 'field' => array(
+ 'field' => [
+ 'id' => 'numeric',
+ ],
+ 'filter' => [
+ 'help' => t("Filter by the draggableviews parent's entity id (Native handler only)."),
'id' => 'numeric',
- ),
- 'filter' => array(
- 'help' => t('Filter by the draggableviews parent\'s entity id (Native handler only).'),
+ ],
+ 'argument' => [
'id' => 'numeric',
- ),
- );
+ ],
+ ];
- foreach (\Drupal::entityManager()->getDefinitions() as $entity_type_id => $entity_type) {
+ foreach (\Drupal::entityTypeManager()->getDefinitions() as $entity_type) {
$base_table = $entity_type->getDataTable() ?: $entity_type->getBaseTable();
$entity_keys = $entity_type->getKeys();
if ($base_table && isset($data[$base_table]['table'])) {
- $data[$base_table]['draggableviews'] = array(
+ $data[$base_table]['draggableviews'] = [
'title' => $data[$base_table]['table']['group'],
'group' => t('Draggableviews'),
'help' => t('Provide a draggable functionality.'),
'entity field' => $entity_keys['id'],
- 'field' => array(
+ 'field' => [
'id' => 'draggable_views_field',
'click sortable' => FALSE,
- ),
- );
- // Explain to every entity how to join with draggableviews structure table.
- $data['draggableviews_structure']['table']['join'][$base_table] = array(
+ ],
+ ];
+ // Explain to every entity how to join with draggableviews_structure
+ // table.
+ $data['draggableviews_structure']['table']['join'][$base_table] = [
'handler' => 'draggableviews_join_handler',
// Because this is a direct link it could be left out.
'left_table' => $base_table,
'left_field' => $entity_keys['id'],
'field' => 'entity_id',
- 'extra' => array(
- array('field' => 'view_name', 'value' => '***VIEW_ID***'),
- array('field' => 'view_display', 'value' => '***VIEW_DISPLAY***'),
- ),
- );
+ ];
}
}
}
-/**
- * Implements hook_views_query_substitutions().
- *
- * Allow replacement of current userid so we can cache these queries.
- */
-function draggableviews_views_query_substitutions(\Drupal\views\ViewExecutable $view) {
- return array('***VIEW_ID***' => $view->id(), '***VIEW_DISPLAY***' => $view->current_display);
-}
-
/**
* Implements hook_preprocess_views_view_table().
*/
function draggableviews_preprocess_views_view_table(&$variables) {
$view = $variables['view'];
+
+ // If this view is not the sort view, then stop here.
if (!isset($view->field['draggableviews'])) {
return;
}
- $draggableviews = new \Drupal\draggableviews\DraggableViews($variables['view']);
+ $draggableviews = new DraggableViews($variables['view']);
// Add hierarchy.
foreach ($variables['rows'] as $key => $row) {
- $title = $row['columns']['title']['content'][0]['field_output']['#markup'];
+ $columns = array_keys($row['columns']);
+ // Find the first column that is not the draggableviews field.
+ do {
+ $first_column = current($columns);
+ if ($first_column !== 'draggableviews') {
+ break;
+ }
+ // Set the first column.
+ $first_column = each($columns);
+ } while ($first_column);
+
+ // Indent the first column that is not the draggableviews field.
+ $columns_title = $row['columns'][$first_column]['content'][0]['field_output']['#markup'];
$indent = [
'#theme' => 'indentation',
'#size' => $draggableviews->getDepth($key),
];
- $variables['rows'][$key]['columns']['title']['content'][0]['field_output']['#markup'] = render($indent) . $title;
+ $variables['rows'][$key]['columns'][$first_column]['content'][0]['field_output']['#markup'] = (string) (render($indent) . $columns_title);
}
// Add table attributes.
@@ -110,7 +123,7 @@ function draggableviews_preprocess_views_view_table(&$variables) {
/**
* Implements hook_form_alter().
*/
-function draggableviews_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
+function draggableviews_form_alter(&$form, FormStateInterface $form_state, $form_id) {
// Filter the right form.
if (strpos($form_id, 'views_form_') === FALSE) {
return;
@@ -127,10 +140,10 @@ function draggableviews_form_alter(&$form, \Drupal\Core\Form\FormStateInterface
if (\Drupal::currentUser()->hasPermission('access draggableviews')) {
// Create draggableviews save order button.
- $form['actions']['save_order'] = array(
+ $form['actions']['save_order'] = [
'#value' => t('Save order'),
'#type' => 'submit',
- );
+ ];
}
// If there is no results remove the save-order button.
@@ -145,7 +158,7 @@ function draggableviews_form_alter(&$form, \Drupal\Core\Form\FormStateInterface
/**
* Submit handler.
*/
-function draggableviews_views_submit(&$form, \Drupal\Core\Form\FormStateInterface $form_state) {
+function draggableviews_views_submit(&$form, FormStateInterface $form_state) {
$input = $form_state->getUserInput();
/** @var \Drupal\views\ViewExecutable $view */
@@ -155,7 +168,7 @@ function draggableviews_views_submit(&$form, \Drupal\Core\Form\FormStateInterfac
$weight = 0;
- $connection = \Drupal\Core\Database\Database::getConnection();
+ $connection = Database::getConnection();
$transaction = $connection->startTransaction();
try {
foreach ($input['draggableviews'] as $item) {
@@ -185,12 +198,12 @@ function draggableviews_views_submit(&$form, \Drupal\Core\Form\FormStateInterfac
// cache.
$views_entity_table_info = $view->query->getEntityTableInfo();
// Find the entity type used by the view.
- $result = array_keys(array_filter($views_entity_table_info, function($info) {
+ $result = array_keys(array_filter($views_entity_table_info, function ($info) {
return $info['relationship_id'] == 'none';
}));
$entity_type_id = reset($result);
$list_cache_tags = \Drupal::entityTypeManager()->getDefinition($entity_type_id)->getListCacheTags();
- \Drupal\Core\Cache\Cache::invalidateTags($list_cache_tags);
+ Cache::invalidateTags($list_cache_tags);
}
catch (\Exception $e) {
$transaction->rollback();
diff --git a/web/modules/contrib/draggableviews/draggableviews.module.rej b/web/modules/contrib/draggableviews/draggableviews.module.rej
new file mode 100644
index 000000000..1c1c2f443
--- /dev/null
+++ b/web/modules/contrib/draggableviews/draggableviews.module.rej
@@ -0,0 +1,26 @@
+--- draggableviews.module (revision 76d7ca84425218e1e9f60633767bcbb5024a3d8c)
++++ draggableviews.module (revision )
+@@ -58,10 +58,23 @@
+ 'left_table' => $base_table,
+ 'left_field' => $entity_keys['id'],
+ 'field' => 'entity_id',
++ 'extra' => array(
++ array('field' => 'view_name', 'value' => '***VIEW_ID***'),
++ array('field' => 'view_display', 'value' => '***VIEW_DISPLAY***'),
++ ),
+ );
+ }
+ }
+ }
++
++/**
++ * Implements hook_views_query_substitutions().
++ *
++ * Allow replacement of current userid so we can cache these queries.
++ */
++function draggableviews_views_query_substitutions(\Drupal\views\ViewExecutable $view) {
++ return array('***VIEW_ID***' => $view->id(), '***VIEW_DISPLAY***' => $view->current_display);
++}
+
+ /**
+ * Implements hook_preprocess_views_view_table().
diff --git a/web/modules/contrib/draggableviews/draggableviews.permissions.yml b/web/modules/contrib/draggableviews/draggableviews.permissions.yml
index 7a1a06f09..43e7afbb9 100644
--- a/web/modules/contrib/draggableviews/draggableviews.permissions.yml
+++ b/web/modules/contrib/draggableviews/draggableviews.permissions.yml
@@ -1,4 +1,3 @@
access draggableviews:
title: 'Access Draggableviews'
description: 'Give users a permission to sort draggableviews.'
- restrict access: true
diff --git a/web/modules/contrib/draggableviews/modules/draggableviews_demo/config/install/node.type.draggableviews_demo.yml b/web/modules/contrib/draggableviews/modules/draggableviews_demo/config/install/node.type.draggableviews_demo.yml
new file mode 100644
index 000000000..0fa539c83
--- /dev/null
+++ b/web/modules/contrib/draggableviews/modules/draggableviews_demo/config/install/node.type.draggableviews_demo.yml
@@ -0,0 +1,18 @@
+langcode: en
+status: true
+dependencies:
+ enforced:
+ module:
+ - draggableviews_demo
+third_party_settings:
+ menu_ui:
+ available_menus:
+ - main
+ parent: 'main:'
+name: 'Draggableviews Demo'
+type: draggableviews_demo
+description: ''
+help: ''
+new_revision: true
+preview_mode: 1
+display_submitted: true
diff --git a/web/modules/contrib/draggableviews/modules/draggableviews_demo/config/install/views.view.draggableviews_demo.yml b/web/modules/contrib/draggableviews/modules/draggableviews_demo/config/install/views.view.draggableviews_demo.yml
new file mode 100644
index 000000000..4bb7c4d0a
--- /dev/null
+++ b/web/modules/contrib/draggableviews/modules/draggableviews_demo/config/install/views.view.draggableviews_demo.yml
@@ -0,0 +1,519 @@
+langcode: en
+status: true
+dependencies:
+ config:
+ - core.entity_view_mode.node.teaser
+ - node.type.draggableviews_demo
+ module:
+ - draggableviews
+ - node
+ - user
+_core:
+ default_config_hash: jNovwA94yRL5frztAOmdSCWDJHEa4UJhryQKRWYwJ98
+id: draggableviews_demo
+label: 'Draggableviews Demo'
+module: views
+description: ''
+tag: ''
+base_table: node_field_data
+base_field: nid
+core: 8.x
+display:
+ default:
+ display_plugin: default
+ id: default
+ display_title: Master
+ position: 0
+ display_options:
+ access:
+ type: perm
+ options:
+ perm: 'access content'
+ cache:
+ type: tag
+ options: { }
+ query:
+ type: views_query
+ options:
+ disable_sql_rewrite: false
+ distinct: false
+ replica: false
+ query_comment: ''
+ query_tags: { }
+ exposed_form:
+ type: basic
+ options:
+ submit_button: Apply
+ reset_button: false
+ reset_button_label: Reset
+ exposed_sorts_label: 'Sort by'
+ expose_sort_order: true
+ sort_asc_label: Asc
+ sort_desc_label: Desc
+ pager:
+ type: mini
+ options:
+ items_per_page: 10
+ offset: 0
+ id: 0
+ total_pages: null
+ expose:
+ items_per_page: false
+ items_per_page_label: 'Items per page'
+ items_per_page_options: '5, 10, 25, 50'
+ items_per_page_options_all: false
+ items_per_page_options_all_label: '- All -'
+ offset: false
+ offset_label: Offset
+ tags:
+ previous: â¹â¹
+ next: âºâº
+ style:
+ type: default
+ row:
+ type: fields
+ options:
+ default_field_elements: true
+ inline: { }
+ separator: ''
+ hide_empty: false
+ fields:
+ title:
+ id: title
+ table: node_field_data
+ field: title
+ entity_type: node
+ entity_field: title
+ label: ''
+ alter:
+ alter_text: false
+ make_link: false
+ absolute: false
+ trim: false
+ word_boundary: false
+ ellipsis: false
+ strip_tags: false
+ html: false
+ hide_empty: false
+ empty_zero: false
+ settings:
+ link_to_entity: true
+ plugin_id: field
+ relationship: none
+ group_type: group
+ admin_label: ''
+ exclude: false
+ element_type: ''
+ element_class: ''
+ element_label_type: ''
+ element_label_class: ''
+ element_label_colon: true
+ element_wrapper_type: ''
+ element_wrapper_class: ''
+ element_default_classes: true
+ empty: ''
+ hide_alter_empty: true
+ click_sort_column: value
+ type: string
+ group_column: value
+ group_columns: { }
+ group_rows: true
+ delta_limit: 0
+ delta_offset: 0
+ delta_reversed: false
+ delta_first_last: false
+ multi_type: separator
+ separator: ', '
+ field_api_classes: false
+ draggableviews:
+ id: draggableviews
+ table: node_field_data
+ field: draggableviews
+ relationship: none
+ group_type: group
+ admin_label: ''
+ label: Content
+ exclude: false
+ alter:
+ alter_text: false
+ text: ''
+ make_link: false
+ path: ''
+ absolute: false
+ external: false
+ replace_spaces: false
+ path_case: none
+ trim_whitespace: false
+ alt: ''
+ rel: ''
+ link_class: ''
+ prefix: ''
+ suffix: ''
+ target: ''
+ nl2br: false
+ max_length: 0
+ word_boundary: true
+ ellipsis: true
+ more_link: false
+ more_link_text: ''
+ more_link_path: ''
+ strip_tags: false
+ trim: false
+ preserve_tags: ''
+ html: false
+ element_type: ''
+ element_class: ''
+ element_label_type: ''
+ element_label_class: ''
+ element_label_colon: true
+ element_wrapper_type: ''
+ element_wrapper_class: ''
+ element_default_classes: true
+ empty: ''
+ hide_empty: false
+ empty_zero: false
+ hide_alter_empty: true
+ entity_type: node
+ entity_field: nid
+ plugin_id: draggable_views_field
+ weight:
+ id: weight
+ table: draggableviews_structure
+ field: weight
+ relationship: none
+ group_type: group
+ admin_label: ''
+ label: 'DraggableViews Weight'
+ exclude: false
+ alter:
+ alter_text: false
+ text: ''
+ make_link: false
+ path: ''
+ absolute: false
+ external: false
+ replace_spaces: false
+ path_case: none
+ trim_whitespace: false
+ alt: ''
+ rel: ''
+ link_class: ''
+ prefix: ''
+ suffix: ''
+ target: ''
+ nl2br: false
+ max_length: 0
+ word_boundary: true
+ ellipsis: true
+ more_link: false
+ more_link_text: ''
+ more_link_path: ''
+ strip_tags: false
+ trim: false
+ preserve_tags: ''
+ html: false
+ element_type: ''
+ element_class: ''
+ element_label_type: ''
+ element_label_class: ''
+ element_label_colon: true
+ element_wrapper_type: ''
+ element_wrapper_class: ''
+ element_default_classes: true
+ empty: ''
+ hide_empty: false
+ empty_zero: false
+ hide_alter_empty: true
+ set_precision: false
+ precision: 0
+ decimal: .
+ separator: ','
+ format_plural: false
+ format_plural_string: "1\x03@count"
+ prefix: ''
+ suffix: ''
+ plugin_id: numeric
+ filters:
+ status:
+ value: '1'
+ table: node_field_data
+ field: status
+ plugin_id: boolean
+ entity_type: node
+ entity_field: status
+ id: status
+ expose:
+ operator: ''
+ group: 1
+ type:
+ id: type
+ table: node_field_data
+ field: type
+ relationship: none
+ group_type: group
+ admin_label: ''
+ operator: in
+ value:
+ draggableviews_demo: draggableviews_demo
+ group: 1
+ exposed: false
+ expose:
+ operator_id: ''
+ label: ''
+ description: ''
+ use_operator: false
+ operator: ''
+ identifier: ''
+ required: false
+ remember: false
+ multiple: false
+ remember_roles:
+ authenticated: authenticated
+ reduce: false
+ is_grouped: false
+ group_info:
+ label: ''
+ description: ''
+ identifier: ''
+ optional: true
+ widget: select
+ multiple: false
+ remember: false
+ default_group: All
+ default_group_multiple: { }
+ group_items: { }
+ entity_type: node
+ entity_field: type
+ plugin_id: bundle
+ sorts:
+ weight:
+ id: weight
+ table: draggableviews_structure
+ field: weight
+ relationship: none
+ group_type: group
+ admin_label: ''
+ order: ASC
+ exposed: false
+ expose:
+ label: ''
+ plugin_id: standard
+ created:
+ id: created
+ table: node_field_data
+ field: created
+ order: DESC
+ entity_type: node
+ entity_field: created
+ plugin_id: date
+ relationship: none
+ group_type: group
+ admin_label: ''
+ exposed: false
+ expose:
+ label: ''
+ granularity: second
+ title: 'Draggableviews Demo Display Page'
+ header: { }
+ footer: { }
+ empty: { }
+ relationships: { }
+ arguments: { }
+ display_extenders: { }
+ cache_metadata:
+ max-age: 0
+ contexts:
+ - 'languages:language_content'
+ - 'languages:language_interface'
+ - url.query_args
+ - 'user.node_grants:view'
+ - user.permissions
+ tags: { }
+ draggableviews_demo_display:
+ display_plugin: page
+ id: draggableviews_demo_display
+ display_title: 'Display Page'
+ position: 1
+ display_options:
+ display_extenders: { }
+ path: draggableviews-demo
+ display_description: ''
+ fields:
+ title:
+ id: title
+ table: node_field_data
+ field: title
+ entity_type: node
+ entity_field: title
+ label: ''
+ alter:
+ alter_text: false
+ make_link: false
+ absolute: false
+ trim: false
+ word_boundary: false
+ ellipsis: false
+ strip_tags: false
+ html: false
+ hide_empty: false
+ empty_zero: false
+ settings:
+ link_to_entity: true
+ plugin_id: field
+ relationship: none
+ group_type: group
+ admin_label: ''
+ exclude: false
+ element_type: ''
+ element_class: ''
+ element_label_type: ''
+ element_label_class: ''
+ element_label_colon: true
+ element_wrapper_type: ''
+ element_wrapper_class: ''
+ element_default_classes: true
+ empty: ''
+ hide_alter_empty: true
+ click_sort_column: value
+ type: string
+ group_column: value
+ group_columns: { }
+ group_rows: true
+ delta_limit: 0
+ delta_offset: 0
+ delta_reversed: false
+ delta_first_last: false
+ multi_type: separator
+ separator: ', '
+ field_api_classes: false
+ weight:
+ id: weight
+ table: draggableviews_structure
+ field: weight
+ relationship: none
+ group_type: group
+ admin_label: ''
+ label: 'DraggableViews Weight'
+ exclude: false
+ alter:
+ alter_text: false
+ text: ''
+ make_link: false
+ path: ''
+ absolute: false
+ external: false
+ replace_spaces: false
+ path_case: none
+ trim_whitespace: false
+ alt: ''
+ rel: ''
+ link_class: ''
+ prefix: ''
+ suffix: ''
+ target: ''
+ nl2br: false
+ max_length: 0
+ word_boundary: true
+ ellipsis: true
+ more_link: false
+ more_link_text: ''
+ more_link_path: ''
+ strip_tags: false
+ trim: false
+ preserve_tags: ''
+ html: false
+ element_type: ''
+ element_class: ''
+ element_label_type: ''
+ element_label_class: ''
+ element_label_colon: true
+ element_wrapper_type: ''
+ element_wrapper_class: ''
+ element_default_classes: true
+ empty: ''
+ hide_empty: false
+ empty_zero: false
+ hide_alter_empty: true
+ set_precision: false
+ precision: 0
+ decimal: .
+ separator: ','
+ format_plural: false
+ format_plural_string: "1\x03@count"
+ prefix: ''
+ suffix: ''
+ plugin_id: numeric
+ defaults:
+ fields: false
+ cache_metadata:
+ max-age: -1
+ contexts:
+ - 'languages:language_content'
+ - 'languages:language_interface'
+ - url.query_args
+ - 'user.node_grants:view'
+ - user.permissions
+ tags: { }
+ draggableviews_demo_order:
+ display_plugin: page
+ id: draggableviews_demo_order
+ display_title: 'Order Page'
+ position: 2
+ display_options:
+ display_extenders: { }
+ path: draggableviews-demo/order
+ menu:
+ type: tab
+ title: 'Order Draggableviews Demo'
+ description: ''
+ expanded: false
+ parent: ''
+ weight: 0
+ context: '0'
+ menu_name: main
+ style:
+ type: table
+ options:
+ grouping: { }
+ row_class: ''
+ default_row_class: true
+ override: true
+ sticky: false
+ caption: ''
+ summary: ''
+ description: ''
+ columns:
+ title: title
+ info:
+ title:
+ sortable: false
+ default_sort_order: asc
+ align: ''
+ separator: ''
+ empty_column: false
+ responsive: ''
+ default: '-1'
+ empty_table: false
+ defaults:
+ style: false
+ row: false
+ title: false
+ access: false
+ row:
+ type: 'entity:node'
+ options:
+ view_mode: teaser
+ title: 'Draggableviews Demo Order Page'
+ access:
+ type: perm
+ options:
+ perm: 'access draggableviews'
+ cache_metadata:
+ max-age: 0
+ contexts:
+ - 'languages:language_content'
+ - 'languages:language_interface'
+ - url.query_args
+ - 'user.node_grants:view'
+ - user.permissions
+ tags: { }
diff --git a/web/modules/contrib/draggableviews/modules/draggableviews_demo/draggableviews_demo.info.yml b/web/modules/contrib/draggableviews/modules/draggableviews_demo/draggableviews_demo.info.yml
new file mode 100644
index 000000000..10a562c19
--- /dev/null
+++ b/web/modules/contrib/draggableviews/modules/draggableviews_demo/draggableviews_demo.info.yml
@@ -0,0 +1,22 @@
+name: Draggableviews Demo
+type: module
+description: 'Demo module for Draggableviews.'
+# core: 8.x
+dependencies:
+ - drupal:block
+ - drupal:draggableviews
+ - drupal:menu_ui
+ - drupal:node
+ - drupal:user
+ - drupal:views
+ - drupal:system
+ - drupal:filter
+ - drupal:field
+hidden: false
+package: Views
+
+# Information added by Drupal.org packaging script on 2018-11-06
+version: '8.x-1.2'
+core: '8.x'
+project: 'draggableviews'
+datestamp: 1541518687
diff --git a/web/modules/contrib/draggableviews/modules/draggableviews_demo/draggableviews_demo.install b/web/modules/contrib/draggableviews/modules/draggableviews_demo/draggableviews_demo.install
new file mode 100644
index 000000000..89a70d38d
--- /dev/null
+++ b/web/modules/contrib/draggableviews/modules/draggableviews_demo/draggableviews_demo.install
@@ -0,0 +1,6 @@
+ $row->getDestinationProperty('parent'),
];
$result = Database::getConnection()->insert('draggableviews_structure')->fields($record)->execute();
- return array($result);
+ return [$result];
}
/**
diff --git a/web/modules/contrib/draggableviews/src/Plugin/views/field/DraggableViewsField.php b/web/modules/contrib/draggableviews/src/Plugin/views/field/DraggableViewsField.php
index 4361e398a..8f1e6fff0 100755
--- a/web/modules/contrib/draggableviews/src/Plugin/views/field/DraggableViewsField.php
+++ b/web/modules/contrib/draggableviews/src/Plugin/views/field/DraggableViewsField.php
@@ -1,16 +1,15 @@
currentUser = $current_user;
+ return $this;
+ }
+
/**
* {@inheritdoc}
*/
- protected function defineOptions() {
- $options = parent::defineOptions();
- return $options;
+ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+ /** @var static $datasource */
+ $bulk_form = parent::create($container, $configuration, $plugin_id, $plugin_definition);
+ $bulk_form->setCurrentUser($container->get('current_user'));
+ return $bulk_form;
}
/**
* {@inheritdoc}
*/
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
+ $form['draggableview_help'] = [
+ '#markup' => $this->t("A draggable element will be added to the first table column. You do not have to set this field as the first column in your View."),
+ ];
parent::buildOptionsForm($form, $form_state);
+ // Remove all the fields that would break this or are completely ignored
+ // when rendering the drag interface.
+ unset($form['custom_label']);
+ unset($form['label']);
+ unset($form['element_label_colon']);
+ unset($form['action_title']);
+ unset($form['include_exclude']);
+ unset($form['selected_actions']);
+ unset($form['exclude']);
+ unset($form['alter']);
+ unset($form['empty_field_behavior']);
+ unset($form['empty']);
+ unset($form['empty_zero']);
+ unset($form['hide_empty']);
+ unset($form['hide_alter_empty']);
}
/**
@@ -55,33 +114,33 @@ class DraggableViewsField extends BulkForm {
$draggableviews = new DraggableViews($this->view);
foreach ($this->view->result as $row_index => $row) {
- $form[$this->options['id']][$row_index] = array(
+ $form[$this->options['id']][$row_index] = [
'#tree' => TRUE,
- );
+ ];
// Item to keep id of the entity.
- $form[$this->options['id']][$row_index]['id'] = array(
+ $form[$this->options['id']][$row_index]['id'] = [
'#type' => 'hidden',
- '#value' => $row->{$this->definition['entity field']},
- '#attributes' => array('class' => array('draggableviews-id')),
- );
+ '#value' => $this->getEntity($row)->id(),
+ '#attributes' => ['class' => ['draggableviews-id']],
+ ];
// Add parent.
- $form[$this->options['id']][$row_index]['parent'] = array(
+ $form[$this->options['id']][$row_index]['parent'] = [
'#type' => 'hidden',
'#default_value' => $draggableviews->getParent($row_index),
- '#attributes' => array('class' => array('draggableviews-parent')),
- );
+ '#attributes' => ['class' => ['draggableviews-parent']],
+ ];
}
- if (\Drupal::currentUser()->hasPermission('access draggableviews')) {
+ if ($this->currentUser->hasPermission('access draggableviews')) {
$options = [
'table_id' => $draggableviews->getHtmlId(),
'action' => 'match',
- 'relationship' => 'parent',
+ 'relationship' => 'group',
'group' => 'draggableviews-parent',
'subgroup' => 'draggableviews-parent',
- 'source' => 'draggableviews-id'
+ 'source' => 'draggableviews-id',
];
drupal_attach_tabledrag($form, $options);
}
diff --git a/web/modules/contrib/draggableviews/src/Plugin/views/field/DraggableViewsField.php.rej b/web/modules/contrib/draggableviews/src/Plugin/views/field/DraggableViewsField.php.rej
new file mode 100644
index 000000000..61481c06d
--- /dev/null
+++ b/web/modules/contrib/draggableviews/src/Plugin/views/field/DraggableViewsField.php.rej
@@ -0,0 +1,19 @@
+--- src/Plugin/views/field/DraggableViewsField.php
++++ src/Plugin/views/field/DraggableViewsField.php
+@@ -63,14 +63,14 @@ class DraggableViewsField extends BulkForm {
+ $form[$this->options['id']][$row_index]['id'] = array(
+ '#type' => 'hidden',
+ '#value' => $row->{$this->definition['entity field']},
+- '#attributes' => array('class' => 'draggableviews-id'),
++ '#attributes' => array('class' => array('draggableviews-id')),
+ );
+
+ // Add parent.
+ $form[$this->options['id']][$row_index]['parent'] = array(
+ '#type' => 'hidden',
+ '#default_value' => $draggableviews->getParent($row_index),
+- '#attributes' => array('class' => 'draggableviews-parent'),
++ '#attributes' => array('class' => array('draggableviews-parent')),
+ );
+ }
+
diff --git a/web/modules/contrib/draggableviews/tests/src/Functional/DraggableviewsTest.php b/web/modules/contrib/draggableviews/tests/src/Functional/DraggableviewsTest.php
new file mode 100644
index 000000000..ee3c1fd51
--- /dev/null
+++ b/web/modules/contrib/draggableviews/tests/src/Functional/DraggableviewsTest.php
@@ -0,0 +1,123 @@
+adminUser = $this->drupalCreateUser([
+ 'access administration pages',
+ 'view the administration theme',
+ 'administer permissions',
+ 'administer nodes',
+ 'administer content types',
+ 'access draggableviews',
+ ]);
+ $this->authUser = $this->drupalCreateUser([], 'authuser');
+
+ // Gather the test data.
+ $dataContent = $this->providerTestDataContent();
+
+ // Create nodes.
+ foreach ($dataContent as $datumContent) {
+ $node = $this->drupalCreateNode([
+ 'type' => 'draggableviews_demo',
+ 'title' => $datumContent[0],
+ ]);
+ $node->save();
+ }
+ }
+
+ /**
+ * Data provider for setUp.
+ *
+ * @return array
+ * Nested array of testing data, Arranged like this:
+ * - Title
+ * - Body
+ */
+ protected function providerTestDataContent() {
+ return [
+ [
+ 'Draggable Content 1',
+ 'Draggable Content Body 1',
+ ],
+ [
+ 'Draggable Content 2',
+ 'Draggable Content Body 2',
+ ],
+ [
+ 'Draggable Content 3',
+ 'Draggable Content Body 3',
+ ],
+ [
+ 'Draggable Content 4',
+ 'Draggable Content Body 4',
+ ],
+ [
+ 'Draggable Content 5',
+ 'Draggable Content Body 5',
+ ],
+ ];
+ }
+
+ /**
+ * A simple test.
+ */
+ public function testDraggableviewsContent() {
+ $assert_session = $this->assertSession();
+
+ $this->drupalGet('draggableviews-demo');
+ $this->assertSession()->statusCodeEquals(200);
+ // Verify that anonymous useres cannot access the order page.
+ $this->drupalGet('draggableviews-demo/order');
+ $this->assertSession()->statusCodeEquals(403);
+
+ // Verify that authorized user has access to display page.
+ $this->drupalLogin($this->adminUser);
+ $this->drupalGet('draggableviews-demo');
+ $this->assertSession()->statusCodeEquals(200);
+
+ // Verify that the page contains generated content.
+ $assert_session->pageTextContains(t('Draggable Content 4'));
+
+ // Verify that authorized user has access to order page.
+ $this->drupalGet('draggableviews-demo/order');
+ $this->assertSession()->statusCodeEquals(200);
+
+ // Verify that the page contains generated content.
+ $assert_session->pageTextContains(t('Draggable Content 5'));
+ }
+
+}
diff --git a/web/modules/contrib/entity/.travis.yml b/web/modules/contrib/entity/.travis.yml
deleted file mode 100644
index e48d5d7d3..000000000
--- a/web/modules/contrib/entity/.travis.yml
+++ /dev/null
@@ -1,58 +0,0 @@
-language: php
-sudo: false
-
-php:
- - 5.5
- - 5.6
- - 7
- - hhvm
-
-matrix:
- allow_failures:
- # We cannot use hhvm-nightly since that does not work in Travis CI's old
- # Ubuntu 12.04.
- - php: hhvm
- # Don't wait for the allowed failures to build.
- fast_finish: true
-
-mysql:
- database: entity
- username: root
- encoding: utf8
-
-before_script:
- # Remove Xdebug as we don't need it and it causes
- # PHP Fatal error: Maximum function nesting level of '256' reached.
- # We also don't care if that file exists or not on PHP 7.
- - phpenv config-rm xdebug.ini || true
-
- # Remember the current entity test directory for later use in the Drupal
- # installation.
- - TESTDIR=$(pwd)
- # Navigate out of module directory to prevent blown stack by recursive module
- # lookup.
- - cd ..
-
- # Create database.
- - mysql -e 'create database entity'
- # 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.5.x --depth 1 http://git.drupal.org/project/drupal.git
- - cd drupal
- - composer self-update
- - composer install -n
-
- # Reference entity in build site.
- - ln -s $TESTDIR modules/entity
-
- # Start a web server on port 8888, run in the background; wait for
- # initialization.
- - nohup php -S localhost:8888 > /dev/null 2>&1 &
-
- # Export web server URL for browser tests.
- - export SIMPLETEST_BASE_URL=http://localhost:8888
-
-script:
- # Run the PHPUnit tests which also include the kernel tests.
- - ./vendor/phpunit/phpunit/phpunit -c ./core/phpunit.xml.dist --verbose ./modules/entity
diff --git a/web/modules/contrib/entity/README.txt b/web/modules/contrib/entity/README.txt
deleted file mode 100644
index c19422cd3..000000000
--- a/web/modules/contrib/entity/README.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-Entity API module
------------------
-
-This module contains improvements and extensions to the Drupal 8 Entity system.
-The goal is to bring useful improvements to upcoming Drupal 8 minor releases
-(e.g. 8.1, 8.2, ..) while maintaining backwards compatibility in future Entity
-API module versions (based on the improvements which went into core).
-
-@todo: Explain version compatibility pattern.
-@todo: Add overview of all items and maintainers.
-
diff --git a/web/modules/contrib/entity/composer.json b/web/modules/contrib/entity/composer.json
deleted file mode 100644
index 538e0e559..000000000
--- a/web/modules/contrib/entity/composer.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "name": "drupal/entity",
- "type": "drupal-module",
- "description": "Provides expanded entity APIs, which will be moved to Drupal core one day.",
- "homepage": "http://drupal.org/project/entity",
- "license": "GPL-2.0+",
- "require": {
- "drupal/core": "~8.5"
- }
-}
diff --git a/web/modules/contrib/entity/config/schema/entity.schema.yml b/web/modules/contrib/entity/config/schema/entity.schema.yml
deleted file mode 100644
index b3c192358..000000000
--- a/web/modules/contrib/entity/config/schema/entity.schema.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-action.configuration.entity_delete_action:*:
- type: action_configuration_default
- label: 'Delete entity configuration'
-
-views.field.rendered_entity:
- type: views_field
- label: 'Rendered entity'
- mapping:
- view_mode:
- type: string
- label: 'View mode'
diff --git a/web/modules/contrib/entity/entity.info.yml b/web/modules/contrib/entity/entity.info.yml
deleted file mode 100644
index 54ca9636b..000000000
--- a/web/modules/contrib/entity/entity.info.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-name: Entity
-description: Provides expanded entity APIs, which will be moved to Drupal core one day.
-type: module
-# core: 8.x
-dependencies:
- - drupal:system (>=8.5.0)
-
-# Information added by Drupal.org packaging script on 2018-03-13
-version: '8.x-1.0-beta3'
-core: '8.x'
-project: 'entity'
-datestamp: 1520958515
diff --git a/web/modules/contrib/entity/entity.links.action.yml b/web/modules/contrib/entity/entity.links.action.yml
deleted file mode 100644
index 5e02edcd7..000000000
--- a/web/modules/contrib/entity/entity.links.action.yml
+++ /dev/null
@@ -1,2 +0,0 @@
-entity.entity_actions:
- deriver: Drupal\entity\Plugin\Derivative\EntityActionsDeriver
diff --git a/web/modules/contrib/entity/entity.links.task.yml b/web/modules/contrib/entity/entity.links.task.yml
deleted file mode 100644
index 8116ae326..000000000
--- a/web/modules/contrib/entity/entity.links.task.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-entity.revisions_overview:
- deriver: 'Drupal\entity\Plugin\Derivative\RevisionsOverviewDeriver'
- weight: 100
diff --git a/web/modules/contrib/entity/entity.module b/web/modules/contrib/entity/entity.module
deleted file mode 100644
index c15e3f7ed..000000000
--- a/web/modules/contrib/entity/entity.module
+++ /dev/null
@@ -1,88 +0,0 @@
-getDefinitions();
- $entity_types = array_filter($entity_types, function (EntityTypeInterface $entity_type) {
- return $entity_type->hasHandlerClass('bundle_plugin');
- });
-
- return $entity_types;
-}
-
-/**
- * Implements hook_entity_type_build().
- */
-function entity_entity_type_build(array &$entity_types) {
- foreach ($entity_types as $entity_type) {
- if ($entity_type->get('bundle_plugin_type')) {
- $entity_type->setHandlerClass('bundle_plugin', BundlePluginHandler::class);
- }
- }
-}
-
-/**
- * Implements hook_entity_bundle_info().
- */
-function entity_entity_bundle_info() {
- $bundles = [];
- foreach (entity_get_bundle_plugin_entity_types() as $entity_type) {
- /** @var \Drupal\entity\BundlePlugin\BundlePluginHandler $bundle_handler */
- $bundle_handler = \Drupal::entityTypeManager()->getHandler($entity_type->id(), 'bundle_plugin');
- $bundles[$entity_type->id()] = $bundle_handler->getBundleInfo();
- }
- return $bundles;
-}
-
-/**
- * Implements hook_entity_field_storage_info().
- */
-function entity_entity_field_storage_info(EntityTypeInterface $entity_type) {
- if ($entity_type->hasHandlerClass('bundle_plugin')) {
- /** @var \Drupal\entity\BundlePlugin\BundlePluginHandler $bundle_handler */
- $bundle_handler = \Drupal::entityTypeManager()->getHandler($entity_type->id(), 'bundle_plugin');
- return $bundle_handler->getFieldStorageDefinitions();
- }
-}
-
-/**
- * Implements hook_entity_bundle_field_info().
- */
-function entity_entity_bundle_field_info(EntityTypeInterface $entity_type, $bundle) {
- if ($entity_type->hasHandlerClass('bundle_plugin')) {
- /** @var \Drupal\entity\BundlePlugin\BundlePluginHandler $bundle_handler */
- $bundle_handler = \Drupal::entityTypeManager()->getHandler($entity_type->id(), 'bundle_plugin');
- return $bundle_handler->getFieldDefinitions($bundle);
- }
-}
-
-/**
- * Implements hook_modules_installed().
- */
-function entity_modules_installed($modules) {
- foreach (entity_get_bundle_plugin_entity_types() as $entity_type) {
- \Drupal::service('entity.bundle_plugin_installer')->installBundles($entity_type, $modules);
- }
-}
-
-/**
- * Implements hook_module_preuninstall().
- */
-function entity_module_preuninstall($module) {
- foreach (entity_get_bundle_plugin_entity_types() as $entity_type) {
- \Drupal::service('entity.bundle_plugin_installer')->uninstallBundles($entity_type, [$module]);
- }
-}
diff --git a/web/modules/contrib/entity/entity.permissions.yml b/web/modules/contrib/entity/entity.permissions.yml
deleted file mode 100644
index 1676e880b..000000000
--- a/web/modules/contrib/entity/entity.permissions.yml
+++ /dev/null
@@ -1,2 +0,0 @@
-permission_callbacks:
- - \Drupal\entity\EntityPermissions::buildPermissions
diff --git a/web/modules/contrib/entity/entity.services.yml b/web/modules/contrib/entity/entity.services.yml
deleted file mode 100644
index c4e5f83f5..000000000
--- a/web/modules/contrib/entity/entity.services.yml
+++ /dev/null
@@ -1,22 +0,0 @@
-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']
- tags:
- - { name: access_check, applies_to: _entity_access_revision }
-
- entity.bundle_plugin_installer:
- class: Drupal\entity\BundlePlugin\BundlePluginInstaller
- arguments: ['@entity_type.manager', '@entity_bundle.listener', '@field_storage_definition.listener', '@field_definition.listener']
-
- entity.bundle_plugin.uninstall_validator:
- class: \Drupal\entity\BundlePlugin\BundlePluginUninstallValidator
- tags:
- - { name: module_install.uninstall_validator }
- arguments: ['@entity_type.manager', '@string_translation']
diff --git a/web/modules/contrib/entity/entity.views.inc b/web/modules/contrib/entity/entity.views.inc
deleted file mode 100644
index 3074175c6..000000000
--- a/web/modules/contrib/entity/entity.views.inc
+++ /dev/null
@@ -1,32 +0,0 @@
-getDefinitions();
- $entity_types = array_filter($entity_types, function (EntityTypeInterface $entity_type) {
- return $entity_type->entityClassImplements(ContentEntityInterface::class);
- });
-
- $data = [];
- foreach ($entity_types as $entity_type) {
- /** @var \Drupal\Core\Entity\EntityTypeInterface $entity_type */
- $base_table = $entity_type->getBaseTable() ?: $entity_type->id();
-
- if ($entity_type->hasViewBuilderClass()) {
- $data[$base_table]['rendered_entity'] = [
- 'field' => [
- 'title' => t('Rendered entity'),
- 'help' => t('Renders an entity in a view mode.'),
- 'id' => 'rendered_entity',
- ],
- ];
- }
- }
-
- return $data;
-}
diff --git a/web/modules/contrib/entity/src/Access/EntityDeleteMultipleAccessCheck.php b/web/modules/contrib/entity/src/Access/EntityDeleteMultipleAccessCheck.php
deleted file mode 100644
index a04cda68c..000000000
--- a/web/modules/contrib/entity/src/Access/EntityDeleteMultipleAccessCheck.php
+++ /dev/null
@@ -1,87 +0,0 @@
-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/web/modules/contrib/entity/src/Access/EntityRevisionRouteAccessChecker.php b/web/modules/contrib/entity/src/Access/EntityRevisionRouteAccessChecker.php
deleted file mode 100644
index 84f431707..000000000
--- a/web/modules/contrib/entity/src/Access/EntityRevisionRouteAccessChecker.php
+++ /dev/null
@@ -1,162 +0,0 @@
-entityTypeManager = $entity_type_manager;
- $this->routeMatch = $route_match;
- }
-
- /**
- * {@inheritdoc}
- */
- public function access(Route $route, AccountInterface $account, RouteMatchInterface $route_match = NULL) {
- if (empty($route_match)) {
- $route_match = $this->routeMatch;
- }
-
- $operation = $route->getRequirement('_entity_access_revision');
- list($entity_type_id, $operation) = explode('.', $operation, 2);
-
- if ($operation === 'list') {
- $_entity = $route_match->getParameter($entity_type_id);
- return AccessResult::allowedIf($this->checkAccess($_entity, $account, $operation))->cachePerPermissions();
- }
- else {
- $_entity_revision = $route_match->getParameter($entity_type_id . '_revision');
- return AccessResult::allowedIf($_entity_revision && $this->checkAccess($_entity_revision, $account, $operation))->cachePerPermissions();
- }
- }
-
- protected function checkAccess(ContentEntityInterface $entity, AccountInterface $account, $operation = 'view') {
- $entity_type = $entity->getEntityType();
- $entity_type_id = $entity->getEntityTypeId();
- $entity_access = $this->entityTypeManager->getAccessControlHandler($entity_type_id);
-
- /** @var \Drupal\Core\Entity\EntityStorageInterface $entity_storage */
- $entity_storage = $this->entityTypeManager->getStorage($entity_type_id);
-
- $map = [
- 'view' => "view all $entity_type_id revisions",
- 'list' => "view all $entity_type_id revisions",
- 'update' => "revert all $entity_type_id revisions",
- 'delete' => "delete all $entity_type_id revisions",
- ];
- $bundle = $entity->bundle();
- $type_map = [
- 'view' => "view $entity_type_id $bundle revisions",
- 'list' => "view $entity_type_id $bundle revisions",
- 'update' => "revert $entity_type_id $bundle revisions",
- 'delete' => "delete $entity_type_id $bundle revisions",
- ];
-
- if (!$entity || !isset($map[$operation]) || !isset($type_map[$operation])) {
- // If there was no node to check against, or the $op was not one of the
- // supported ones, we return access denied.
- return FALSE;
- }
-
- // Statically cache access by revision ID, language code, user account ID,
- // and operation.
- $langcode = $entity->language()->getId();
- $cid = $entity->getRevisionId() . ':' . $langcode . ':' . $account->id() . ':' . $operation;
-
- if (!isset($this->accessCache[$cid])) {
- $admin_permission = $entity_type->getAdminPermission();
-
- // Perform basic permission checks first.
- if (!$account->hasPermission($map[$operation]) && !$account->hasPermission($type_map[$operation]) && ($admin_permission && !$account->hasPermission($admin_permission))) {
- $this->accessCache[$cid] = FALSE;
- return FALSE;
- }
-
- if (($admin_permission = $entity_type->getAdminPermission()) && $account->hasPermission($admin_permission)) {
- $this->accessCache[$cid] = TRUE;
- }
- else {
- // Entity access handlers are generally not aware of the "list" operation.
- $operation = $operation == 'list' ? 'view' : $operation;
- // First check the access to the default revision and finally, if the
- // node passed in is not the default revision then access to that, too.
- $this->accessCache[$cid] = $entity_access->access($entity_storage->load($entity->id()), $operation, $account) && ($entity->isDefaultRevision() || $entity_access->access($entity, $operation, $account));
- }
- }
-
- return $this->accessCache[$cid];
- }
-
-
- /**
- * Counts the number of revisions in the default language.
- *
- * @param \Drupal\Core\Entity\ContentEntityInterface $entity
- * The entity.
- * @param \Drupal\Core\Entity\EntityStorageInterface $entity_storage
- * The entity storage.
- *
- * @return int
- * The number of revisions in the default language.
- */
- protected function countDefaultLanguageRevisions(ContentEntityInterface $entity, EntityStorageInterface $entity_storage) {
- $entity_type = $entity->getEntityType();
- $count = $entity_storage->getQuery()
- ->allRevisions()
- ->condition($entity_type->getKey('id'), $entity->id())
- ->condition($entity_type->getKey('default_langcode'), 1)
- ->count()
- ->execute();
- return $count;
- }
-
- /**
- * Resets the access cache.
- *
- * @return $this
- */
- public function resetAccessCache() {
- $this->accessCache = [];
- return $this;
- }
-
-}
diff --git a/web/modules/contrib/entity/src/BundleFieldDefinition.php b/web/modules/contrib/entity/src/BundleFieldDefinition.php
deleted file mode 100644
index 9da74c87b..000000000
--- a/web/modules/contrib/entity/src/BundleFieldDefinition.php
+++ /dev/null
@@ -1,27 +0,0 @@
-entityType = $entity_type;
- $this->pluginManager = $plugin_manager;
- }
-
- /**
- * {@inheritdoc}
- */
- public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
- return new static(
- $entity_type,
- $container->get('plugin.manager.' . $entity_type->get('bundle_plugin_type'))
- );
- }
-
- /**
- * {@inheritdoc}
- */
- public function getBundleInfo() {
- $bundles = [];
- foreach ($this->pluginManager->getDefinitions() as $plugin_id => $definition) {
- $bundles[$plugin_id] = [
- 'label' => $definition['label'],
- 'description' => isset($definition['description']) ? $definition['description'] : '',
- 'translatable' => $this->entityType->isTranslatable(),
- 'provider' => $definition['provider'],
- ];
- }
- return $bundles;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getFieldStorageDefinitions() {
- $definitions = [];
- foreach (array_keys($this->pluginManager->getDefinitions()) as $plugin_id) {
- /** @var \Drupal\entity\BundlePlugin\BundlePluginInterface $plugin */
- $plugin = $this->pluginManager->createInstance($plugin_id);
- $definitions += $plugin->buildFieldDefinitions();
- }
- // Ensure the presence of required keys which aren't set by the plugin.
- foreach ($definitions as $field_name => $definition) {
- $definition->setName($field_name);
- $definition->setTargetEntityTypeId($this->entityType->id());
- $definitions[$field_name] = $definition;
- }
-
- return $definitions;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getFieldDefinitions($bundle) {
- /** @var \Drupal\entity\BundlePlugin\BundlePluginInterface $plugin */
- $plugin = $this->pluginManager->createInstance($bundle);
- $definitions = $plugin->buildFieldDefinitions();
- // Ensure the presence of required keys which aren't set by the plugin.
- foreach ($definitions as $field_name => $definition) {
- $definition->setName($field_name);
- $definition->setTargetEntityTypeId($this->entityType->id());
- $definition->setTargetBundle($bundle);
- $definitions[$field_name] = $definition;
- }
-
- return $definitions;
- }
-
-}
diff --git a/web/modules/contrib/entity/src/BundlePlugin/BundlePluginHandlerInterface.php b/web/modules/contrib/entity/src/BundlePlugin/BundlePluginHandlerInterface.php
deleted file mode 100644
index 5702fb58c..000000000
--- a/web/modules/contrib/entity/src/BundlePlugin/BundlePluginHandlerInterface.php
+++ /dev/null
@@ -1,37 +0,0 @@
-entityTypeManager = $entity_type_manager;
- $this->entityBundleListener = $entity_bundle_listener;
- $this->fieldStorageDefinitionListener = $field_storage_definition_listener;
- $this->fieldDefinitionListener = $field_definition_listener;
- }
-
- /**
- * {@inheritdoc}
- */
- public function installBundles(EntityTypeInterface $entity_type, array $modules) {
- $bundle_handler = $this->entityTypeManager->getHandler($entity_type->id(), 'bundle_plugin');
- $bundles = array_filter($bundle_handler->getBundleInfo(), function ($bundle_info) use ($modules) {
- return in_array($bundle_info['provider'], $modules, TRUE);
- });
- foreach (array_keys($bundles) as $bundle) {
- $this->entityBundleListener->onBundleCreate($bundle, $entity_type->id());
- foreach ($bundle_handler->getFieldDefinitions($bundle) as $definition) {
- $this->fieldStorageDefinitionListener->onFieldStorageDefinitionCreate($definition);
- $this->fieldDefinitionListener->onFieldDefinitionCreate($definition);
- }
- }
- }
-
- /**
- * {@inheritdoc}
- */
- public function uninstallBundles(EntityTypeInterface $entity_type, array $modules) {
- $bundle_handler = $this->entityTypeManager->getHandler($entity_type->id(), 'bundle_plugin');
- $bundles = array_filter($bundle_handler->getBundleInfo(), function ($bundle_info) use ($modules) {
- return in_array($bundle_info['provider'], $modules, TRUE);
- });
- foreach (array_keys($bundles) as $bundle) {
- $this->entityBundleListener->onBundleDelete($bundle, $entity_type->id());
- foreach ($bundle_handler->getFieldDefinitions($bundle) as $definition) {
- $this->fieldDefinitionListener->onFieldDefinitionDelete($definition);
- $this->fieldStorageDefinitionListener->onFieldStorageDefinitionDelete($definition);
- }
- }
- }
-
-}
diff --git a/web/modules/contrib/entity/src/BundlePlugin/BundlePluginInstallerInterface.php b/web/modules/contrib/entity/src/BundlePlugin/BundlePluginInstallerInterface.php
deleted file mode 100644
index afeacee48..000000000
--- a/web/modules/contrib/entity/src/BundlePlugin/BundlePluginInstallerInterface.php
+++ /dev/null
@@ -1,34 +0,0 @@
-entityTypeManager = $entity_type_manager;
- $this->stringTranslation = $string_translation;
- }
-
- /**
- * {@inheritdoc}
- */
- public function validate($module) {
- $reasons = [];
-
- foreach (entity_get_bundle_plugin_entity_types() as $entity_type) {
- /** @var \Drupal\entity\BundlePlugin\BundlePluginHandler $bundle_handler */
- $bundle_handler = $this->entityTypeManager->getHandler($entity_type->id(), 'bundle_plugin');
- $bundles = $bundle_handler->getBundleInfo();
-
- // We find all bundles which have to be removed due to the uninstallation.
- $bundles_filtered_by_module = array_filter($bundles, function ($bundle_info) use ($module) {
- return $module === $bundle_info['provider'];
- });
-
- if (!empty($bundles_filtered_by_module)) {
- $bundle_keys_with_content = array_filter(array_keys($bundles_filtered_by_module), function ($bundle) use ($entity_type) {
- $result = $this->entityTypeManager->getStorage($entity_type->id())->getQuery()
- ->condition($entity_type->getKey('bundle'), $bundle)
- ->range(0, 1)
- ->execute();
- return !empty($result);
- });
-
- $bundles_with_content = array_intersect_key($bundles_filtered_by_module, array_flip($bundle_keys_with_content));
-
- foreach ($bundles_with_content as $bundle) {
- $reasons[] = $this->t('There is data for the bundle @bundle on the entity type @entity_type. Please remove all content before uninstalling the module.', [
- '@bundle' => $bundle['label'],
- '@entity_type' => $entity_type->getLabel(),
- ]);
- }
- }
- }
-
- return $reasons;
- }
-
-}
diff --git a/web/modules/contrib/entity/src/Controller/RevisionControllerTrait.php b/web/modules/contrib/entity/src/Controller/RevisionControllerTrait.php
deleted file mode 100644
index 6be025a6e..000000000
--- a/web/modules/contrib/entity/src/Controller/RevisionControllerTrait.php
+++ /dev/null
@@ -1,192 +0,0 @@
-getEntityType();
- $result = $this->entityTypeManager()->getStorage($entity_type->id())->getQuery()
- ->allRevisions()
- ->condition($entity_type->getKey('id'), $entity->id())
- ->sort($entity_type->getKey('revision'), 'DESC')
- ->execute();
- return array_keys($result);
- }
-
- /**
- * Generates an overview table of older revisions of an entity.
- *
- * @param \Drupal\Core\Entity\ContentEntityInterface $entity
- * An entity object.
- *
- * @return array
- * A render array.
- */
- protected function revisionOverview(ContentEntityInterface $entity) {
- $langcode = $this->languageManager()
- ->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)
- ->getId();
- /** @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 = [];
- foreach ($entity_revisions as $revision) {
- $row = [];
- /** @var \Drupal\Core\Entity\ContentEntityInterface $revision */
- if ($revision->hasTranslation($langcode) && $revision->getTranslation($langcode)->isRevisionTranslationAffected()) {
- $row[] = $this->getRevisionDescription($revision, $revision->isDefaultRevision());
-
- if ($revision->isDefaultRevision()) {
- $row[] = [
- 'data' => [
- '#prefix' => '',
- '#markup' => $this->t('Current revision'),
- '#suffix' => '',
- ],
- ];
- foreach ($row as &$current) {
- $current['class'] = ['revision-current'];
- }
- }
- else {
- $links = $this->getOperationLinks($revision);
- $row[] = [
- 'data' => [
- '#type' => 'operations',
- '#links' => $links,
- ],
- ];
- }
- }
-
- $rows[] = $row;
- }
-
- $build[$entity->getEntityTypeId() . '_revisions_table'] = [
- '#theme' => 'table',
- '#rows' => $rows,
- '#header' => $header,
- ];
-
- // We have no clue about caching yet.
- $build['#cache']['max-age'] = 0;
-
- return $build;
- }
-
- /**
- * Get the links of the operations for an entity revision.
- *
- * @param \Drupal\Core\Entity\EntityInterface $entity_revision
- * The entity to build the revision links for.
- *
- * @return array
- * The operation links.
- */
- protected function getOperationLinks(EntityInterface $entity_revision) {
- $links = [];
- if ($this->hasRevertRevisionAccess($entity_revision)) {
- $links['revert'] = $this->buildRevertRevisionLink($entity_revision);
- }
-
- if ($this->hasDeleteRevisionAccess($entity_revision)) {
- $links['delete'] = $this->buildDeleteRevisionLink($entity_revision);
- }
-
- return array_filter($links);
- }
-
-}
diff --git a/web/modules/contrib/entity/src/Controller/RevisionOverviewController.php b/web/modules/contrib/entity/src/Controller/RevisionOverviewController.php
deleted file mode 100644
index 495b6a040..000000000
--- a/web/modules/contrib/entity/src/Controller/RevisionOverviewController.php
+++ /dev/null
@@ -1,160 +0,0 @@
-dateFormatter = $date_formatter;
- $this->renderer = $renderer;
- }
-
- /**
- * {@inheritdoc}
- */
- public static function create(ContainerInterface $container) {
- return new static($container->get('date.formatter'), $container->get('renderer'));
- }
-
- /**
- * {@inheritdoc}
- */
- protected function hasDeleteRevisionAccess(EntityInterface $entity) {
- return $this->currentUser()->hasPermission("delete all {$entity->id()} revisions");
- }
-
- /**
- * {@inheritdoc}
- */
- protected function buildRevertRevisionLink(EntityInterface $entity_revision) {
- if ($entity_revision->hasLinkTemplate('revision-revert-form')) {
- return [
- 'title' => t('Revert'),
- 'url' => $entity_revision->toUrl('revision-revert-form'),
- ];
- }
- }
-
- /**
- * {@inheritdoc}
- */
- protected function buildDeleteRevisionLink(EntityInterface $entity_revision) {
- if ($entity_revision->hasLinkTemplate('revision-delete-form')) {
- return [
- 'title' => t('Delete'),
- 'url' => $entity_revision->toUrl('revision-delete-form'),
- ];
- }
- }
-
- /**
- * Generates an overview table of older revisions of an entity.
- *
- * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
- * The route match.
- *
- * @return array
- * A render array.
- */
- public function revisionOverviewController(RouteMatchInterface $route_match) {
- return $this->revisionOverview($route_match->getParameter($route_match->getRouteObject()->getOption('entity_type_id')));
- }
-
- /**
- * {@inheritdoc}
- */
- protected function getRevisionDescription(ContentEntityInterface $revision, $is_default = FALSE) {
- /** @var \Drupal\Core\Entity\ContentEntityInterface|\Drupal\user\EntityOwnerInterface|\Drupal\Core\Entity\RevisionLogInterface $revision */
- if ($revision instanceof RevisionLogInterface) {
- // Use revision link to link to revisions that are not active.
- $date = $this->dateFormatter->format($revision->getRevisionCreationTime(), 'short');
- $link = $revision->toLink($date, 'revision');
-
- // @todo: Simplify this when https://www.drupal.org/node/2334319 lands.
- $username = [
- '#theme' => 'username',
- '#account' => $revision->getRevisionUser(),
- ];
- $username = $this->renderer->render($username);
- }
- else {
- $link = $revision->toLink($revision->label(), 'revision');
- $username = '';
-
- }
-
- $markup = '';
- if ($revision instanceof RevisionLogInterface) {
- $markup = $revision->getRevisionLogMessage();
- }
-
- if ($username) {
- $template = '{% trans %}{{ date }} by {{ username }}{% endtrans %}{% if message %}
{{ message }}
{% endif %}';
- }
- else {
- $template = '{% trans %} {{ date }} {% endtrans %}{% if message %}
{{ message }}
{% endif %}';
- }
-
- $column = [
- 'data' => [
- '#type' => 'inline_template',
- '#template' => $template,
- '#context' => [
- 'date' => $link->toString(),
- 'username' => $username,
- 'message' => ['#markup' => $markup, '#allowed_tags' => Xss::getHtmlTagList()],
- ],
- ],
- ];
- return $column;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function hasRevertRevisionAccess(EntityInterface $entity) {
- return AccessResult::allowedIfHasPermission($this->currentUser(), "revert all {$entity->getEntityTypeId()} revisions")->orIf(
- AccessResult::allowedIfHasPermission($this->currentUser(), "revert {$entity->bundle()} {$entity->getEntityTypeId()} revisions")
- );
- }
-
-}
diff --git a/web/modules/contrib/entity/src/Entity/RevisionableEntityBundleInterface.php b/web/modules/contrib/entity/src/Entity/RevisionableEntityBundleInterface.php
deleted file mode 100644
index 18d392a06..000000000
--- a/web/modules/contrib/entity/src/Entity/RevisionableEntityBundleInterface.php
+++ /dev/null
@@ -1,14 +0,0 @@
-hasHandlerClass('permission_provider') || !is_a($entity_type->getHandlerClass('permission_provider'), EntityPermissionProvider::class, TRUE)) {
- throw new \Exception("This entity access control handler requires the entity permissions provider: {EntityPermissionProvider::class}");
- }
- }
-
-
- /**
- * {@inheritdoc}
- */
- protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
- $account = $this->prepareUser($account);
- /** @var \Drupal\Core\Access\AccessResult $result */
- $result = parent::checkAccess($entity, $operation, $account);
-
- if ($result->isNeutral()) {
- if ($entity instanceof EntityOwnerInterface) {
- $result = $this->checkEntityOwnerPermissions($entity, $operation, $account);
- }
- else {
- $result = $this->checkEntityPermissions($entity, $operation, $account);
- }
- }
-
- // Ensure that access is evaluated again when the entity changes.
- return $result->addCacheableDependency($entity);
- }
-
- /**
- * Checks the entity operation and bundle permissions.
- *
- * @param \Drupal\Core\Entity\EntityInterface $entity
- * The entity for which to check access.
- * @param string $operation
- * The entity operation. Usually one of 'view', 'view label', 'update' or
- * 'delete'.
- * @param \Drupal\Core\Session\AccountInterface $account
- * The user for which to check access.
- *
- * @return \Drupal\Core\Access\AccessResultInterface
- * The access result.
- */
- protected function checkEntityPermissions(EntityInterface $entity, $operation, AccountInterface $account) {
- if ($operation === 'view') {
- $permissions = [
- "view {$entity->getEntityTypeId()}"
- ];
- }
- else {
- $permissions = [
- "$operation {$entity->getEntityTypeId()}",
- "$operation {$entity->bundle()} {$entity->getEntityTypeId()}",
- ];
- }
- return AccessResult::allowedIfHasPermissions($account, $permissions, 'OR');
- }
-
- /**
- * Checks the entity operation and bundle permissions, with owners.
- *
- * @param \Drupal\Core\Entity\EntityInterface $entity
- * The entity for which to check access.
- * @param string $operation
- * The entity operation. Usually one of 'view', 'view label', 'update' or
- * 'delete'.
- * @param \Drupal\Core\Session\AccountInterface $account
- * The user for which to check access.
- *
- * @return \Drupal\Core\Access\AccessResultInterface
- * The access result.
- */
- protected function checkEntityOwnerPermissions(EntityInterface $entity, $operation, AccountInterface $account) {
- if ($operation === 'view') {
- if ($entity instanceof EntityPublishedInterface && !$entity->isPublished()) {
- if (($account->id() == $entity->getOwnerId())) {
- $permissions = [
- "view own unpublished {$entity->getEntityTypeId()}",
- ];
- return AccessResult::allowedIfHasPermissions($account, $permissions)->cachePerUser();
- }
- return AccessResult::neutral()->cachePerUser();
- }
- else {
- return AccessResult::allowedIfHasPermissions($account, [
- "view {$entity->getEntityTypeId()}",
- ]);
- }
- }
- else {
- if (($account->id() == $entity->getOwnerId())) {
- $result = AccessResult::allowedIfHasPermissions($account, [
- "$operation own {$entity->getEntityTypeId()}",
- "$operation any {$entity->getEntityTypeId()}",
- "$operation own {$entity->bundle()} {$entity->getEntityTypeId()}",
- "$operation any {$entity->bundle()} {$entity->getEntityTypeId()}",
- ], 'OR');
- }
- else {
- $result = AccessResult::allowedIfHasPermissions($account, [
- "$operation any {$entity->getEntityTypeId()}",
- "$operation any {$entity->bundle()} {$entity->getEntityTypeId()}",
- ], 'OR');
- }
- return $result;
- }
- }
-
- /**
- * {@inheritdoc}
- */
- protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
- $result = parent::checkCreateAccess($account, $context, $entity_bundle);
- if ($result->isNeutral()) {
- $permissions = [
- 'administer ' . $this->entityTypeId,
- 'create ' . $this->entityTypeId,
- ];
- if ($entity_bundle) {
- $permissions[] = 'create ' . $entity_bundle . ' ' . $this->entityTypeId;
- }
-
- $result = AccessResult::allowedIfHasPermissions($account, $permissions, 'OR');
- }
-
- return $result;
- }
-
-}
diff --git a/web/modules/contrib/entity/src/EntityPermissionProvider.php b/web/modules/contrib/entity/src/EntityPermissionProvider.php
deleted file mode 100644
index 88c06ee10..000000000
--- a/web/modules/contrib/entity/src/EntityPermissionProvider.php
+++ /dev/null
@@ -1,59 +0,0 @@
-id();
- $plural_label = $entity_type->getPluralLabel();
-
- $permissions = parent::buildPermissions($entity_type);
-
- // View permissions are the same for both granularities.
- $permissions["view {$entity_type_id}"] = [
- 'title' => $this->t('View @type', [
- '@type' => $plural_label,
- ]),
- ];
-
- return $this->processPermissions($permissions, $entity_type);
- }
-
-
-}
diff --git a/web/modules/contrib/entity/src/EntityPermissionProviderBase.php b/web/modules/contrib/entity/src/EntityPermissionProviderBase.php
deleted file mode 100644
index 53d83f8ac..000000000
--- a/web/modules/contrib/entity/src/EntityPermissionProviderBase.php
+++ /dev/null
@@ -1,231 +0,0 @@
-entityTypeBundleInfo = $entity_type_bundle_info;
- }
-
- /**
- * {@inheritdoc}
- */
- public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
- return new static(
- $container->get('entity_type.bundle.info')
- );
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildPermissions(EntityTypeInterface $entity_type) {
- $entity_type_id = $entity_type->id();
- $has_owner = $entity_type->entityClassImplements(EntityOwnerInterface::class);
- $plural_label = $entity_type->getPluralLabel();
-
- $permissions = [];
- $permissions["administer {$entity_type_id}"] = [
- 'title' => $this->t('Administer @type', ['@type' => $plural_label]),
- 'restrict access' => TRUE,
- ];
- $permissions["access {$entity_type_id} overview"] = [
- 'title' => $this->t('Access the @type overview page', ['@type' => $plural_label]),
- ];
- if ($has_owner && $entity_type->entityClassImplements(EntityPublishedInterface::class)) {
- $permissions["view own unpublished {$entity_type_id}"] = [
- 'title' => $this->t('View own unpublished @type', [
- '@type' => $plural_label,
- ]),
- ];
- }
-
- // Generate the other permissions based on granularity.
- if ($entity_type->getPermissionGranularity() === 'entity_type') {
- $permissions += $this->buildEntityTypePermissions($entity_type);
- }
- else {
- $permissions += $this->buildBundlePermissions($entity_type);
- }
-
- return $this->processPermissions($permissions, $entity_type);
- }
-
- /**
- * Adds the provider and converts the titles to strings to allow sorting.
- *
- * @param array $permissions
- * The array of permissions
- * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
- * The entity type.
- *
- * @return array
- * An array of processed permissions.
- */
- protected function processPermissions(array $permissions, EntityTypeInterface $entity_type) {
- foreach ($permissions as $name => $permission) {
- // Permissions are grouped by provider on admin/people/permissions.
- $permissions[$name]['provider'] = $entity_type->getProvider();
- // TranslatableMarkup objects don't sort properly.
- $permissions[$name]['title'] = (string) $permission['title'];
- }
- return $permissions;
- }
-
- /**
- * Builds permissions for the entity_type granularity.
- *
- * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
- * The entity type.
- *
- * @return array
- * The permissions.
- */
- protected function buildEntityTypePermissions(EntityTypeInterface $entity_type) {
- $entity_type_id = $entity_type->id();
- $has_owner = $entity_type->entityClassImplements(EntityOwnerInterface::class);
- $singular_label = $entity_type->getSingularLabel();
- $plural_label = $entity_type->getPluralLabel();
-
- $permissions = [];
- $permissions["create {$entity_type_id}"] = [
- 'title' => $this->t('Create @type', [
- '@type' => $plural_label,
- ]),
- ];
- if ($has_owner) {
- $permissions["update any {$entity_type_id}"] = [
- 'title' => $this->t('Update any @type', [
- '@type' => $singular_label,
- ]),
- ];
- $permissions["update own {$entity_type_id}"] = [
- 'title' => $this->t('Update own @type', [
- '@type' => $plural_label,
- ]),
- ];
- $permissions["delete any {$entity_type_id}"] = [
- 'title' => $this->t('Delete any @type', [
- '@type' => $singular_label,
- ]),
- ];
- $permissions["delete own {$entity_type_id}"] = [
- 'title' => $this->t('Delete own @type', [
- '@type' => $plural_label,
- ]),
- ];
- }
- else {
- $permissions["update {$entity_type_id}"] = [
- 'title' => $this->t('Update @type', [
- '@type' => $plural_label,
- ]),
- ];
- $permissions["delete {$entity_type_id}"] = [
- 'title' => $this->t('Delete @type', [
- '@type' => $plural_label,
- ]),
- ];
- }
-
- return $permissions;
- }
-
- /**
- * Builds permissions for the bundle granularity.
- *
- * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
- * The entity type.
- *
- * @return array
- * The permissions.
- */
- protected function buildBundlePermissions(EntityTypeInterface $entity_type) {
- $entity_type_id = $entity_type->id();
- $bundles = $this->entityTypeBundleInfo->getBundleInfo($entity_type_id);
- $has_owner = $entity_type->entityClassImplements(EntityOwnerInterface::class);
- $singular_label = $entity_type->getSingularLabel();
- $plural_label = $entity_type->getPluralLabel();
-
- $permissions = [];
- foreach ($bundles as $bundle_name => $bundle_info) {
- $permissions["create {$bundle_name} {$entity_type_id}"] = [
- 'title' => $this->t('@bundle: Create @type', [
- '@bundle' => $bundle_info['label'],
- '@type' => $plural_label,
- ]),
- ];
-
- if ($has_owner) {
- $permissions["update any {$bundle_name} {$entity_type_id}"] = [
- 'title' => $this->t('@bundle: Update any @type', [
- '@bundle' => $bundle_info['label'],
- '@type' => $singular_label,
- ]),
- ];
- $permissions["update own {$bundle_name} {$entity_type_id}"] = [
- 'title' => $this->t('@bundle: Update own @type', [
- '@bundle' => $bundle_info['label'],
- '@type' => $plural_label,
- ]),
- ];
- $permissions["delete any {$bundle_name} {$entity_type_id}"] = [
- 'title' => $this->t('@bundle: Delete any @type', [
- '@bundle' => $bundle_info['label'],
- '@type' => $singular_label,
- ]),
- ];
- $permissions["delete own {$bundle_name} {$entity_type_id}"] = [
- 'title' => $this->t('@bundle: Delete own @type', [
- '@bundle' => $bundle_info['label'],
- '@type' => $plural_label,
- ]),
- ];
- }
- else {
- $permissions["update {$bundle_name} {$entity_type_id}"] = [
- 'title' => $this->t('@bundle: Update @type', [
- '@bundle' => $bundle_info['label'],
- '@type' => $plural_label,
- ]),
- ];
- $permissions["delete {$bundle_name} {$entity_type_id}"] = [
- 'title' => $this->t('@bundle: Delete @type', [
- '@bundle' => $bundle_info['label'],
- '@type' => $plural_label,
- ]),
- ];
- }
- }
-
- return $permissions;
- }
-
-}
diff --git a/web/modules/contrib/entity/src/EntityPermissionProviderInterface.php b/web/modules/contrib/entity/src/EntityPermissionProviderInterface.php
deleted file mode 100644
index 50f3ccaa9..000000000
--- a/web/modules/contrib/entity/src/EntityPermissionProviderInterface.php
+++ /dev/null
@@ -1,23 +0,0 @@
-entityTypeManager = $entity_type_manager;
- }
-
- /**
- * {@inheritdoc}
- */
- public static function create(ContainerInterface $container) {
- return new static(
- $container->get('entity_type.manager')
- );
- }
-
- /**
- * Builds a list of permissions for the participating entity types.
- *
- * @return array
- * The permissions.
- */
- public function buildPermissions() {
- $permissions = [];
- /** @var \Drupal\Core\Entity\EntityTypeInterface[] $entity_types */
- foreach ($this->entityTypeManager->getDefinitions() as $entity_type) {
- if ($entity_type->hasHandlerClass('permission_provider')) {
- $permission_provider_class = $entity_type->getHandlerClass('permission_provider');
- $permission_provider = $this->entityTypeManager->createHandlerInstance($permission_provider_class, $entity_type);
- $permissions += $permission_provider->buildPermissions($entity_type);
- }
- }
-
- return $permissions;
- }
-
-}
diff --git a/web/modules/contrib/entity/src/EntityViewBuilder.php b/web/modules/contrib/entity/src/EntityViewBuilder.php
deleted file mode 100644
index 1efe0ebe6..000000000
--- a/web/modules/contrib/entity/src/EntityViewBuilder.php
+++ /dev/null
@@ -1,17 +0,0 @@
- 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/web/modules/contrib/entity/src/Form/RevisionRevertForm.php b/web/modules/contrib/entity/src/Form/RevisionRevertForm.php
deleted file mode 100644
index c94c53a0c..000000000
--- a/web/modules/contrib/entity/src/Form/RevisionRevertForm.php
+++ /dev/null
@@ -1,167 +0,0 @@
-dateFormatter = $date_formatter;
- $this->bundleInformation = $bundle_information;
- }
-
- /**
- * {@inheritdoc}
- */
- public static function create(ContainerInterface $container) {
- return new static(
- $container->get('date.formatter'),
- $container->get('entity_type.bundle.info')
- );
- }
-
- /**
- * {@inheritdoc}
- */
- public function getFormId() {
- return 'entity_revision_revert_confirm';
- }
-
- /**
- * {@inheritdoc}
- */
- public function getQuestion() {
- if ($this->revision instanceof RevisionLogInterface) {
- return $this->t('Are you sure you want to revert to the revision from %revision-date?', ['%revision-date' => $this->dateFormatter->format($this->revision->getRevisionCreationTime())]);
- }
- return $this->t('Are you sure you want to revert the revision?');
- }
-
- /**
- * {@inheritdoc}
- */
- public function getCancelUrl() {
- if ($this->revision->getEntityType()->hasLinkTemplate('version-history')) {
- return $this->revision->toUrl('version-history');
- }
- return $this->revision->toUrl();
- }
-
- /**
- * {@inheritdoc}
- */
- public function getConfirmText() {
- return t('Revert');
- }
-
- /**
- * {@inheritdoc}
- */
- public function getDescription() {
- return '';
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildForm(array $form, FormStateInterface $form_state, $_entity_revision = NULL, Request $request = NULL) {
- $this->revision = $_entity_revision;
- $form = parent::buildForm($form, $form_state);
-
- return $form;
- }
-
- /**
- * {@inheritdoc}
- */
- public function submitForm(array &$form, FormStateInterface $form_state) {
- // The revision timestamp will be updated when the revision is saved. Keep
- // the original one for the confirmation message.
- $this->revision = $this->prepareRevision($this->revision);
- if ($this->revision instanceof RevisionLogInterface) {
- $original_revision_timestamp = $this->revision->getRevisionCreationTime();
-
- $this->revision->setRevisionLogMessage($this->t('Copy of the revision from %date.', ['%date' => $this->dateFormatter->format($original_revision_timestamp)]));
- drupal_set_message(t('@type %title has been reverted to the revision from %revision-date.', ['@type' => $this->getBundleLabel($this->revision), '%title' => $this->revision->label(), '%revision-date' => $this->dateFormatter->format($original_revision_timestamp)]));
- }
- else {
- drupal_set_message(t('@type %title has been reverted', ['@type' => $this->getBundleLabel($this->revision), '%title' => $this->revision->label()]));
- }
-
- $this->revision->save();
-
- $this->logger('content')->notice('@type: reverted %title revision %revision.', ['@type' => $this->revision->bundle(), '%title' => $this->revision->label(), '%revision' => $this->revision->getRevisionId()]);
- $form_state->setRedirect(
- "entity.{$this->revision->getEntityTypeId()}.version_history",
- [$this->revision->getEntityTypeId() => $this->revision->id()]
- );
- }
-
- /**
- * Prepares a revision to be reverted.
- *
- * @param \Drupal\Core\Entity\RevisionableInterface $revision
- * The revision to be reverted.
- *
- * @return \Drupal\Core\Entity\RevisionableInterface
- * The prepared revision ready to be stored.
- */
- protected function prepareRevision(RevisionableInterface $revision) {
- $revision->setNewRevision();
- $revision->isDefaultRevision(TRUE);
-
- return $revision;
- }
-
- /**
- * Returns a bundle label.
- *
- * @param \Drupal\Core\Entity\RevisionableInterface $revision
- * The entity revision.
- *
- * @return string
- */
- protected function getBundleLabel(RevisionableInterface $revision) {
- /** @var \Drupal\Core\Entity\EntityInterface|\Drupal\Core\Entity\RevisionableInterface $revision */
- $bundle_info = $this->bundleInformation->getBundleInfo($revision->getEntityTypeId());
- return $bundle_info[$revision->bundle()]['label'];
- }
-
-}
diff --git a/web/modules/contrib/entity/src/Form/RevisionableContentEntityForm.php b/web/modules/contrib/entity/src/Form/RevisionableContentEntityForm.php
deleted file mode 100644
index 9437aabcd..000000000
--- a/web/modules/contrib/entity/src/Form/RevisionableContentEntityForm.php
+++ /dev/null
@@ -1,164 +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/web/modules/contrib/entity/src/Menu/EntityAddLocalAction.php b/web/modules/contrib/entity/src/Menu/EntityAddLocalAction.php
deleted file mode 100644
index 8b7a04e7a..000000000
--- a/web/modules/contrib/entity/src/Menu/EntityAddLocalAction.php
+++ /dev/null
@@ -1,81 +0,0 @@
-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/web/modules/contrib/entity/src/Menu/EntityCollectionLocalActionProvider.php b/web/modules/contrib/entity/src/Menu/EntityCollectionLocalActionProvider.php
deleted file mode 100644
index b0103709d..000000000
--- a/web/modules/contrib/entity/src/Menu/EntityCollectionLocalActionProvider.php
+++ /dev/null
@@ -1,41 +0,0 @@
-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/web/modules/contrib/entity/src/Menu/EntityLocalActionProviderInterface.php b/web/modules/contrib/entity/src/Menu/EntityLocalActionProviderInterface.php
deleted file mode 100644
index bba16c328..000000000
--- a/web/modules/contrib/entity/src/Menu/EntityLocalActionProviderInterface.php
+++ /dev/null
@@ -1,23 +0,0 @@
-currentUser = $current_user;
- $this->tempStore = $temp_store_factory->get('entity_delete_multiple_confirm');
-
- parent::__construct($configuration, $plugin_id, $plugin_definition);
- }
-
- /**
- * {@inheritdoc}
- */
- public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
- return new static(
- $configuration,
- $plugin_id,
- $plugin_definition,
- $container->get('tempstore.private'),
- $container->get('current_user')
- );
- }
-
- /**
- * {@inheritdoc}
- */
- public function executeMultiple(array $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() . ':' . $this->getPluginDefinition()['type'], $selection);
- }
-
- /**
- * {@inheritdoc}
- */
- public function execute($object = NULL) {
- $this->executeMultiple([$object]);
- }
-
- /**
- * {@inheritdoc}
- */
- public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
- return $object->access('delete', $account, $return_as_object);
- }
-
-}
diff --git a/web/modules/contrib/entity/src/Plugin/Action/Derivative/DeleteActionDeriver.php b/web/modules/contrib/entity/src/Plugin/Action/Derivative/DeleteActionDeriver.php
deleted file mode 100644
index 1f7d76b8d..000000000
--- a/web/modules/contrib/entity/src/Plugin/Action/Derivative/DeleteActionDeriver.php
+++ /dev/null
@@ -1,78 +0,0 @@
-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 (empty($this->derivatives)) {
- $definitions = [];
- foreach ($this->getParticipatingEntityTypes() as $entity_type_id => $entity_type) {
- $definition = $base_plugin_definition;
- $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;
- }
- $this->derivatives = $definitions;
- }
-
- return parent::getDerivativeDefinitions($base_plugin_definition);
- }
-
- /**
- * Gets a list of participating entity types.
- *
- * The list consists of all content entity types with a delete-multiple-form
- * link template.
- *
- * @return \Drupal\Core\Entity\EntityTypeInterface[]
- * The participating entity types, keyed by entity type id.
- */
- protected function getParticipatingEntityTypes() {
- $entity_types = $this->entityTypeManager->getDefinitions();
- $entity_types = array_filter($entity_types, function (EntityTypeInterface $entity_type) {
- return $entity_type->entityClassImplements(ContentEntityInterface::class) && $entity_type->hasLinkTemplate('delete-multiple-form');
- });
-
- return $entity_types;
- }
-
-}
diff --git a/web/modules/contrib/entity/src/Plugin/Derivative/EntityActionsDeriver.php b/web/modules/contrib/entity/src/Plugin/Derivative/EntityActionsDeriver.php
deleted file mode 100644
index 568ad7e87..000000000
--- a/web/modules/contrib/entity/src/Plugin/Derivative/EntityActionsDeriver.php
+++ /dev/null
@@ -1,58 +0,0 @@
-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/web/modules/contrib/entity/src/Plugin/Derivative/RevisionsOverviewDeriver.php b/web/modules/contrib/entity/src/Plugin/Derivative/RevisionsOverviewDeriver.php
deleted file mode 100644
index b00b8ceb4..000000000
--- a/web/modules/contrib/entity/src/Plugin/Derivative/RevisionsOverviewDeriver.php
+++ /dev/null
@@ -1,68 +0,0 @@
-entityTypeManager = $entityTypeManager;
- }
-
- /**
- * {@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) {
- $exclude = ['node'];
-
- $this->derivatives = [];
- foreach ($this->entityTypeManager->getDefinitions() as $entity_type_id => $entity_type) {
- if (in_array($entity_type_id, $exclude)) {
- continue;
- }
-
- if (!$entity_type->hasLinkTemplate('version-history')) {
- continue;
- }
-
- $this->derivatives[$entity_type_id] = [
- 'route_name' => "entity.$entity_type_id.version_history",
- 'title' => t('Revisions'),
- 'base_route' => "entity.$entity_type_id.canonical",
- 'weight' => 20,
- ] + $base_plugin_definition;
- }
-
- return parent::getDerivativeDefinitions($base_plugin_definition);
- }
-
-}
diff --git a/web/modules/contrib/entity/src/Revision/RevisionableContentEntityBase.php b/web/modules/contrib/entity/src/Revision/RevisionableContentEntityBase.php
deleted file mode 100644
index f6dc11cb3..000000000
--- a/web/modules/contrib/entity/src/Revision/RevisionableContentEntityBase.php
+++ /dev/null
@@ -1,25 +0,0 @@
-getEntityType()->getLinkTemplate($rel), $this->getEntityTypeId() . '_revision') !== FALSE) {
- $uri_route_parameters[$this->getEntityTypeId() . '_revision'] = $this->getRevisionId();
- }
-
- return $uri_route_parameters;
- }
-
-}
diff --git a/web/modules/contrib/entity/src/Routing/AdminHtmlRouteProvider.php b/web/modules/contrib/entity/src/Routing/AdminHtmlRouteProvider.php
deleted file mode 100644
index 7ef2f6e18..000000000
--- a/web/modules/contrib/entity/src/Routing/AdminHtmlRouteProvider.php
+++ /dev/null
@@ -1,26 +0,0 @@
-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/web/modules/contrib/entity/src/Routing/DefaultHtmlRouteProvider.php b/web/modules/contrib/entity/src/Routing/DefaultHtmlRouteProvider.php
deleted file mode 100644
index 06a350400..000000000
--- a/web/modules/contrib/entity/src/Routing/DefaultHtmlRouteProvider.php
+++ /dev/null
@@ -1,26 +0,0 @@
-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/web/modules/contrib/entity/src/Routing/DeleteMultipleRouteProvider.php b/web/modules/contrib/entity/src/Routing/DeleteMultipleRouteProvider.php
deleted file mode 100644
index b8dced03f..000000000
--- a/web/modules/contrib/entity/src/Routing/DeleteMultipleRouteProvider.php
+++ /dev/null
@@ -1,47 +0,0 @@
-deleteMultipleFormRoute($entity_type)) {
- $routes->add('entity.' . $entity_type->id() . '.delete_multiple_form', $route);
- }
-
- return $routes;
- }
-
- /**
- * Returns the delete multiple form route.
- *
- * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
- * The entity type.
- *
- * @return \Symfony\Component\Routing\Route|null
- * The generated route, if available.
- */
- 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\DeleteMultipleForm');
- $route->setDefault('entity_type_id', $entity_type->id());
- $route->setRequirement('_entity_delete_multiple_access', $entity_type->id());
-
- return $route;
- }
- }
-
-}
diff --git a/web/modules/contrib/entity/src/Routing/RevisionRouteProvider.php b/web/modules/contrib/entity/src/Routing/RevisionRouteProvider.php
deleted file mode 100644
index e3412958c..000000000
--- a/web/modules/contrib/entity/src/Routing/RevisionRouteProvider.php
+++ /dev/null
@@ -1,127 +0,0 @@
-id();
- if ($view_route = $this->getRevisionViewRoute($entity_type)) {
- $collection->add("entity.$entity_type_id.revision", $view_route);
- }
- if ($view_route = $this->getRevisionRevertRoute($entity_type)) {
- $collection->add("entity.$entity_type_id.revision_revert_form", $view_route);
- }
-
- if ($view_route = $this->getRevisionHistoryRoute($entity_type)) {
- $collection->add("entity.$entity_type_id.version_history", $view_route);
- }
-
- return $collection;
- }
-
- /**
- * Gets the entity revision view route.
- *
- * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
- * The entity type.
- *
- * @return \Symfony\Component\Routing\Route|null
- * The generated route, if available.
- */
- protected function getRevisionViewRoute(EntityTypeInterface $entity_type) {
- if ($entity_type->hasLinkTemplate('revision')) {
- $entity_type_id = $entity_type->id();
- $route = new Route($entity_type->getLinkTemplate('revision'));
- $route->addDefaults([
- '_controller' => '\Drupal\Core\Entity\Controller\EntityViewController::viewRevision',
- '_title_callback' => '\Drupal\Core\Entity\Controller\EntityController::title',
- ]);
- $route->addRequirements([
- '_entity_access_revision' => "$entity_type_id.view",
- ]);
- $route->setOption('parameters', [
- $entity_type->id() => [
- 'type' => 'entity:' . $entity_type->id(),
- ],
- $entity_type->id() . '_revision' => [
- 'type' => 'entity_revision:' . $entity_type->id(),
- ],
- ]);
- return $route;
- }
- }
-
- /**
- * Gets the entity revision revert route.
- *
- * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
- * The entity type.
- *
- * @return \Symfony\Component\Routing\Route|null
- * The generated route, if available.
- */
- protected function getRevisionRevertRoute(EntityTypeInterface $entity_type) {
- if ($entity_type->hasLinkTemplate('revision-revert-form')) {
- $entity_type_id = $entity_type->id();
- $route = new Route($entity_type->getLinkTemplate('revision-revert-form'));
- $route->addDefaults([
- '_form' => '\Drupal\entity\Form\RevisionRevertForm',
- 'title' => 'Revert to earlier revision',
- ]);
- $route->addRequirements([
- '_entity_access_revision' => "$entity_type_id.update",
- ]);
- $route->setOption('parameters', [
- $entity_type->id() => [
- 'type' => 'entity:' . $entity_type->id(),
- ],
- $entity_type->id() . '_revision' => [
- 'type' => 'entity_revision:' . $entity_type->id(),
- ],
- ]);
- return $route;
- }
- }
-
- /**
- * Gets the entity revision version history route.
- *
- * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
- * The entity type.
- *
- * @return \Symfony\Component\Routing\Route|null
- * The generated route, if available.
- */
- protected function getRevisionHistoryRoute($entity_type) {
- if ($entity_type->hasLinkTemplate('version-history')) {
- $entity_type_id = $entity_type->id();
- $route = new Route($entity_type->getLinkTemplate('version-history'));
- $route->addDefaults([
- '_controller' => '\Drupal\entity\Controller\RevisionOverviewController::revisionOverviewController',
- '_title' => 'Revisions',
- ]);
- $route->setRequirement('_entity_access_revision', "$entity_type_id.list");
- $route->setOption('entity_type_id', $entity_type->id());
- $route->setOption('parameters', [
- $entity_type->id() => [
- 'type' => 'entity:' . $entity_type->id(),
- ],
- ]);
- return $route;
- }
- }
-
-}
diff --git a/web/modules/contrib/entity/src/UncacheableEntityAccessControlHandler.php b/web/modules/contrib/entity/src/UncacheableEntityAccessControlHandler.php
deleted file mode 100644
index df6a4001b..000000000
--- a/web/modules/contrib/entity/src/UncacheableEntityAccessControlHandler.php
+++ /dev/null
@@ -1,138 +0,0 @@
-hasHandlerClass('permission_provider') || !is_a($entity_type->getHandlerClass('permission_provider'), UncacheableEntityPermissionProvider::class, TRUE)) {
- throw new \Exception("This entity access control handler requires the entity permissions provider: {EntityPermissionProvider::class}");
- }
- }
-
-
- /**
- * {@inheritdoc}
- */
- protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
- $account = $this->prepareUser($account);
- /** @var \Drupal\Core\Access\AccessResult $result */
- $result = parent::checkAccess($entity, $operation, $account);
-
- if ($result->isNeutral()) {
- if ($entity instanceof EntityOwnerInterface) {
- $result = $this->checkEntityOwnerPermissions($entity, $operation, $account);
- }
- else {
- $result = $this->checkEntityPermissions($entity, $operation, $account);
- }
- }
-
- // Ensure that access is evaluated again when the entity changes.
- return $result->addCacheableDependency($entity);
- }
-
- /**
- * Checks the entity operation and bundle permissions.
- *
- * @param \Drupal\Core\Entity\EntityInterface $entity
- * The entity for which to check access.
- * @param string $operation
- * The entity operation. Usually one of 'view', 'view label', 'update' or
- * 'delete'.
- * @param \Drupal\Core\Session\AccountInterface $account
- * The user for which to check access.
- *
- * @return \Drupal\Core\Access\AccessResultInterface
- * The access result.
- */
- protected function checkEntityPermissions(EntityInterface $entity, $operation, AccountInterface $account) {
- return AccessResult::allowedIfHasPermissions($account, [
- "$operation {$entity->getEntityTypeId()}",
- "$operation {$entity->bundle()} {$entity->getEntityTypeId()}",
- ], 'OR');
- }
-
- /**
- * Checks the entity operation and bundle permissions, with owners.
- *
- * @param \Drupal\Core\Entity\EntityInterface $entity
- * The entity for which to check access.
- * @param string $operation
- * The entity operation. Usually one of 'view', 'view label', 'update' or
- * 'delete'.
- * @param \Drupal\Core\Session\AccountInterface $account
- * The user for which to check access.
- *
- * @return \Drupal\Core\Access\AccessResultInterface
- * The access result.
- */
- protected function checkEntityOwnerPermissions(EntityInterface $entity, $operation, AccountInterface $account) {
- /** @var \Drupal\Core\Entity\EntityInterface|\Drupal\user\EntityOwnerInterface $entity */
- if (($account->id() == $entity->getOwnerId())) {
- if ($operation === 'view' && $entity instanceof EntityPublishedInterface && !$entity->isPublished()) {
- $permissions = [
- "view own unpublished {$entity->getEntityTypeId()}",
- ];
- }
- else {
- $permissions = [
- "$operation own {$entity->getEntityTypeId()}",
- "$operation any {$entity->getEntityTypeId()}",
- "$operation own {$entity->bundle()} {$entity->getEntityTypeId()}",
- "$operation any {$entity->bundle()} {$entity->getEntityTypeId()}",
- ];
- }
- $result = AccessResult::allowedIfHasPermissions($account, $permissions, 'OR');
- }
- else {
- $result = AccessResult::allowedIfHasPermissions($account, [
- "$operation any {$entity->getEntityTypeId()}",
- "$operation any {$entity->bundle()} {$entity->getEntityTypeId()}",
- ], 'OR');
- }
-
- return $result->cachePerUser();
- }
-
- /**
- * {@inheritdoc}
- */
- protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
- $result = parent::checkCreateAccess($account, $context, $entity_bundle);
- if ($result->isNeutral()) {
- $permissions = [
- 'administer ' . $this->entityTypeId,
- 'create ' . $this->entityTypeId,
- ];
- if ($entity_bundle) {
- $permissions[] = 'create ' . $entity_bundle . ' ' . $this->entityTypeId;
- }
-
- $result = AccessResult::allowedIfHasPermissions($account, $permissions, 'OR');
- }
-
- return $result;
- }
-
-}
diff --git a/web/modules/contrib/entity/src/UncacheableEntityPermissionProvider.php b/web/modules/contrib/entity/src/UncacheableEntityPermissionProvider.php
deleted file mode 100644
index 4d105c0ae..000000000
--- a/web/modules/contrib/entity/src/UncacheableEntityPermissionProvider.php
+++ /dev/null
@@ -1,138 +0,0 @@
-id();
- $has_owner = $entity_type->entityClassImplements(EntityOwnerInterface::class);
- $plural_label = $entity_type->getPluralLabel();
-
- if ($has_owner) {
- $permissions["view any {$entity_type_id}"] = [
- 'title' => $this->t('View any @type', [
- '@type' => $plural_label,
- ]),
- ];
- $permissions["view own {$entity_type_id}"] = [
- 'title' => $this->t('View own @type', [
- '@type' => $plural_label,
- ]),
- ];
- }
- else {
- $permissions["view any {$entity_type_id}"] = [
- 'title' => $this->t('View any @type', [
- '@type' => $plural_label,
- ]),
- ];
- }
-
- return $permissions;
- }
-
- /**
- * Builds permissions for the bundle granularity.
- *
- * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
- * The entity type.
- *
- * @return array
- * The permissions.
- */
- protected function buildBundlePermissions(EntityTypeInterface $entity_type) {
- $permissions = parent::buildBundlePermissions($entity_type);
- $entity_type_id = $entity_type->id();
- $bundles = $this->entityTypeBundleInfo->getBundleInfo($entity_type_id);
- $has_owner = $entity_type->entityClassImplements(EntityOwnerInterface::class);
- $plural_label = $entity_type->getPluralLabel();
-
- $permissions["view any {$entity_type_id}"] = [
- 'title' => $this->t('View any @type', [
- '@type' => $plural_label,
- ]),
- ];
- if ($has_owner) {
- $permissions["view own {$entity_type_id}"] = [
- 'title' => $this->t('View own @type', [
- '@type' => $plural_label,
- ]),
- ];
- }
-
- foreach ($bundles as $bundle_name => $bundle_info) {
- if ($has_owner) {
- $permissions["view any {$bundle_name} {$entity_type_id}"] = [
- 'title' => $this->t('@bundle: View any @type', [
- '@bundle' => $bundle_info['label'],
- '@type' => $plural_label,
- ]),
- ];
- $permissions["view own {$bundle_name} {$entity_type_id}"] = [
- 'title' => $this->t('@bundle: View own @type', [
- '@bundle' => $bundle_info['label'],
- '@type' => $plural_label,
- ]),
- ];
- }
- else {
- $permissions["view any {$bundle_name} {$entity_type_id}"] = [
- 'title' => $this->t('@bundle: View any @type', [
- '@bundle' => $bundle_info['label'],
- '@type' => $plural_label,
- ]),
- ];
- }
- }
-
- return $permissions;
- }
-
-}
diff --git a/web/modules/contrib/entity/tests/Kernel/RevisionOverviewIntegrationTest.php b/web/modules/contrib/entity/tests/Kernel/RevisionOverviewIntegrationTest.php
deleted file mode 100644
index 118fea62f..000000000
--- a/web/modules/contrib/entity/tests/Kernel/RevisionOverviewIntegrationTest.php
+++ /dev/null
@@ -1,51 +0,0 @@
-installSchema('system', 'router');
-
- \Drupal::service('router.builder')->rebuild();
- }
-
- public function testIntegration() {
- /** @var \Drupal\Core\Menu\LocalTaskManagerInterface $local_tasks_manager */
- $local_tasks_manager = \Drupal::service('plugin.manager.menu.local_task');
-
- $tasks = $local_tasks_manager->getDefinitions();
- $this->assertArrayHasKey('entity.revisions_overview:entity_test_enhanced', $tasks);
- $this->assertArrayNotHasKey('entity.revisions_overview:node', $tasks, 'Node should have been excluded because it provides their own');
-
- $this->assertEquals('entity.entity_test_enhanced.version_history', $tasks['entity.revisions_overview:entity_test_enhanced']['route_name']);
- $this->assertEquals('entity.entity_test_enhanced.canonical', $tasks['entity.revisions_overview:entity_test_enhanced']['base_route']);
-
- /** @var \Drupal\Core\Routing\RouteProviderInterface $route_provider */
- $route_provider = \Drupal::service('router.route_provider');
-
- $route = $route_provider->getRouteByName('entity.entity_test_enhanced.version_history');
- $this->assertInstanceOf(Route::class, $route);
- $this->assertEquals('\Drupal\entity\Controller\RevisionOverviewController::revisionOverviewController', $route->getDefault('_controller'));
- }
-
-}
diff --git a/web/modules/contrib/entity/tests/modules/entity_module_bundle_plugin_examples_test/entity_module_bundle_plugin_examples_test.info.yml b/web/modules/contrib/entity/tests/modules/entity_module_bundle_plugin_examples_test/entity_module_bundle_plugin_examples_test.info.yml
deleted file mode 100644
index cd263ae9e..000000000
--- a/web/modules/contrib/entity/tests/modules/entity_module_bundle_plugin_examples_test/entity_module_bundle_plugin_examples_test.info.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-name: 'Entity bundle plugin examples test'
-type: module
-description: 'Module for testing bundle plugins.'
-package: Testing
-# core: 8.x
-dependencies:
- - entity
-
-# Information added by Drupal.org packaging script on 2018-03-13
-version: '8.x-1.0-beta3'
-core: '8.x'
-project: 'entity'
-datestamp: 1520958515
diff --git a/web/modules/contrib/entity/tests/modules/entity_module_bundle_plugin_examples_test/src/Plugin/BundlePluginTest/Second.php b/web/modules/contrib/entity/tests/modules/entity_module_bundle_plugin_examples_test/src/Plugin/BundlePluginTest/Second.php
deleted file mode 100644
index a047b6e81..000000000
--- a/web/modules/contrib/entity/tests/modules/entity_module_bundle_plugin_examples_test/src/Plugin/BundlePluginTest/Second.php
+++ /dev/null
@@ -1,31 +0,0 @@
-setLabel(t('Email'))
- ->setRequired(TRUE);
-
- return $fields;
- }
-
-}
diff --git a/web/modules/contrib/entity/tests/modules/entity_module_bundle_plugin_test/entity_module_bundle_plugin_test.info.yml b/web/modules/contrib/entity/tests/modules/entity_module_bundle_plugin_test/entity_module_bundle_plugin_test.info.yml
deleted file mode 100644
index f4fad5344..000000000
--- a/web/modules/contrib/entity/tests/modules/entity_module_bundle_plugin_test/entity_module_bundle_plugin_test.info.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-name: 'Entity bundle plugin test'
-type: module
-description: 'Module for testing bundle plugins.'
-package: Testing
-# core: 8.x
-dependencies:
- - entity
-
-# Information added by Drupal.org packaging script on 2018-03-13
-version: '8.x-1.0-beta3'
-core: '8.x'
-project: 'entity'
-datestamp: 1520958515
diff --git a/web/modules/contrib/entity/tests/modules/entity_module_bundle_plugin_test/entity_module_bundle_plugin_test.services.yml b/web/modules/contrib/entity/tests/modules/entity_module_bundle_plugin_test/entity_module_bundle_plugin_test.services.yml
deleted file mode 100644
index ead5cd39d..000000000
--- a/web/modules/contrib/entity/tests/modules/entity_module_bundle_plugin_test/entity_module_bundle_plugin_test.services.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-services:
- plugin.manager.bundle_plugin_test:
- class: Drupal\entity_module_bundle_plugin_test\BundlePluginTestManager
- parent: default_plugin_manager
diff --git a/web/modules/contrib/entity/tests/modules/entity_module_bundle_plugin_test/src/Annotation/BundlePluginTest.php b/web/modules/contrib/entity/tests/modules/entity_module_bundle_plugin_test/src/Annotation/BundlePluginTest.php
deleted file mode 100644
index f09f70eb2..000000000
--- a/web/modules/contrib/entity/tests/modules/entity_module_bundle_plugin_test/src/Annotation/BundlePluginTest.php
+++ /dev/null
@@ -1,34 +0,0 @@
-alterInfo('bundle_plugin_test_info');
- $this->setCacheBackend($cache_backend, 'bundle_plugin_test_plugins');
- }
-
-}
diff --git a/web/modules/contrib/entity/tests/modules/entity_module_bundle_plugin_test/src/Entity/EntityTestBundlePlugin.php b/web/modules/contrib/entity/tests/modules/entity_module_bundle_plugin_test/src/Entity/EntityTestBundlePlugin.php
deleted file mode 100644
index 1c75a477a..000000000
--- a/web/modules/contrib/entity/tests/modules/entity_module_bundle_plugin_test/src/Entity/EntityTestBundlePlugin.php
+++ /dev/null
@@ -1,27 +0,0 @@
-setLabel(t('Email'))
- ->setRequired(TRUE);
-
- return $fields;
- }
-
-}
diff --git a/web/modules/contrib/entity/tests/modules/entity_module_test/config/schema/entity_module_test.schema.yml b/web/modules/contrib/entity/tests/modules/entity_module_test/config/schema/entity_module_test.schema.yml
deleted file mode 100644
index eb1c5a089..000000000
--- a/web/modules/contrib/entity/tests/modules/entity_module_test/config/schema/entity_module_test.schema.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-entity_module_test.entity_test_enhanced_bundle.*:
- type: config_entity
- label: 'Entity test with enhancements - Bundle'
- mapping:
- id:
- type: string
- label: 'Type'
- label:
- type: label
- label: 'Label'
- description:
- type: text
- label: 'Description'
- new_revision:
- type: boolean
- label: 'New revision'
diff --git a/web/modules/contrib/entity/tests/modules/entity_module_test/entity_module_test.info.yml b/web/modules/contrib/entity/tests/modules/entity_module_test/entity_module_test.info.yml
deleted file mode 100644
index 486850130..000000000
--- a/web/modules/contrib/entity/tests/modules/entity_module_test/entity_module_test.info.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-name: Entity test
-type: module
-package: Testing
-# core: 8.x
-
-# Information added by Drupal.org packaging script on 2018-03-13
-version: '8.x-1.0-beta3'
-core: '8.x'
-project: 'entity'
-datestamp: 1520958515
diff --git a/web/modules/contrib/entity/tests/modules/entity_module_test/entity_module_test.links.task.yml b/web/modules/contrib/entity/tests/modules/entity_module_test/entity_module_test.links.task.yml
deleted file mode 100644
index e306c10c9..000000000
--- a/web/modules/contrib/entity/tests/modules/entity_module_test/entity_module_test.links.task.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-entity.entity_test_enhanced.canonical:
- title: View
- route_name: entity.entity_test_enhanced.canonical
- base_route: entity.entity_test_enhanced.canonical
-
-entity.entity_module_test.edit_form:
- title: Edit
- route_name: entity.entity_test_enhanced.edit_form
- base_route: entity.entity_test_enhanced.canonical
diff --git a/web/modules/contrib/entity/tests/modules/entity_module_test/entity_module_test.permissions.yml b/web/modules/contrib/entity/tests/modules/entity_module_test/entity_module_test.permissions.yml
deleted file mode 100644
index 8aa844ed4..000000000
--- a/web/modules/contrib/entity/tests/modules/entity_module_test/entity_module_test.permissions.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-'view all entity_test_enhanced revisions':
- title: 'View all entity_test_enhanced revisions'
- 'restrict access': TRUE
diff --git a/web/modules/contrib/entity/tests/modules/entity_module_test/src/Entity/EnhancedEntity.php b/web/modules/contrib/entity/tests/modules/entity_module_test/src/Entity/EnhancedEntity.php
deleted file mode 100644
index f9f7b9b6c..000000000
--- a/web/modules/contrib/entity/tests/modules/entity_module_test/src/Entity/EnhancedEntity.php
+++ /dev/null
@@ -1,89 +0,0 @@
-setLabel('Name')
- ->setRevisionable(TRUE)
- ->setDisplayOptions('view', [
- 'label' => 'hidden',
- 'type' => 'string',
- 'weight' => -5,
- ]);
-
- return $fields;
- }
-
-}
diff --git a/web/modules/contrib/entity/tests/modules/entity_module_test/src/Entity/EnhancedEntityBundle.php b/web/modules/contrib/entity/tests/modules/entity_module_test/src/Entity/EnhancedEntityBundle.php
deleted file mode 100644
index 48524a828..000000000
--- a/web/modules/contrib/entity/tests/modules/entity_module_test/src/Entity/EnhancedEntityBundle.php
+++ /dev/null
@@ -1,81 +0,0 @@
-description;
- }
-
- /**
- * {@inheritdoc}
- */
- public function setDescription($description) {
- $this->description = $description;
- return $this;
- }
-
- /**
- * {@inheritdoc}
- */
- public function shouldCreateNewRevision() {
- return $this->new_revision;
- }
-
-}
diff --git a/web/modules/contrib/entity/tests/src/Functional/CollectionRouteAccessTest.php b/web/modules/contrib/entity/tests/src/Functional/CollectionRouteAccessTest.php
deleted file mode 100644
index 5160ed402..000000000
--- a/web/modules/contrib/entity/tests/src/Functional/CollectionRouteAccessTest.php
+++ /dev/null
@@ -1,77 +0,0 @@
- '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/web/modules/contrib/entity/tests/src/Functional/DeleteMultipleFormTest.php b/web/modules/contrib/entity/tests/src/Functional/DeleteMultipleFormTest.php
deleted file mode 100644
index 1dc6931c6..000000000
--- a/web/modules/contrib/entity/tests/src/Functional/DeleteMultipleFormTest.php
+++ /dev/null
@@ -1,81 +0,0 @@
- 'default',
- 'label' => 'Default',
- ])->save();
- $this->account = $this->drupalCreateUser(['administer entity_test_enhanced']);
- $this->drupalLogin($this->account);
- }
-
- /**
- * Tests the add page.
- */
- public function testForm() {
- $entities = [];
- $selection = [];
- for ($i = 0; $i < 2; $i++) {
- $entity = EnhancedEntity::create([
- 'type' => 'default',
- ]);
- $entity->save();
- $entities[$entity->id()] = $entity;
-
- $langcode = $entity->language()->getId();
- $selection[$entity->id()][$langcode] = $langcode;
- }
- // Add the selection to the tempstore just like DeleteAction would.
- $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 enhanced entities?');
- $delete_button = $this->getSession()->getPage()->findButton('Delete');
- $delete_button->click();
- $assert = $this->assertSession();
- $assert->addressEquals('/entity_test_enhanced');
- $assert->responseContains('Deleted 2 items.');
-
- \Drupal::entityTypeManager()->getStorage('entity_test_enhanced')->resetCache();
- $remaining_entities = EnhancedEntity::loadMultiple(array_keys($selection));
- $this->assertEmpty($remaining_entities);
- }
-
-}
diff --git a/web/modules/contrib/entity/tests/src/Functional/Menu/EntityLocalActionTest.php b/web/modules/contrib/entity/tests/src/Functional/Menu/EntityLocalActionTest.php
deleted file mode 100644
index 4fb4faabe..000000000
--- a/web/modules/contrib/entity/tests/src/Functional/Menu/EntityLocalActionTest.php
+++ /dev/null
@@ -1,44 +0,0 @@
-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/web/modules/contrib/entity/tests/src/Functional/RevisionRouteAccessTest.php b/web/modules/contrib/entity/tests/src/Functional/RevisionRouteAccessTest.php
deleted file mode 100644
index f3c205a20..000000000
--- a/web/modules/contrib/entity/tests/src/Functional/RevisionRouteAccessTest.php
+++ /dev/null
@@ -1,97 +0,0 @@
- 'default',
- 'label' => 'Default',
- ])->save();
-
- $this->placeBlock('local_tasks_block');
- $this->placeBlock('system_breadcrumb_block');
-
- $this->account = $this->drupalCreateUser([
- 'administer entity_test_enhanced',
- 'view all entity_test_enhanced revisions',
- ]);
-
- $this->drupalLogin($this->account);
- }
-
- /**
- * Test enhanced entity revision routes access.
- */
- public function testRevisionRouteAccess() {
- $entity = EnhancedEntity::create([
- 'name' => 'rev 1',
- 'type' => 'default',
- ]);
- $entity->save();
-
- $revision = clone $entity;
- $revision->name->value = 'rev 2';
- $revision->setNewRevision(TRUE);
- $revision->isDefaultRevision(FALSE);
- $revision->save();
-
- $this->drupalGet('/entity_test_enhanced/1/revisions');
- $this->assertSession()->statusCodeEquals(200);
- $this->assertSession()->responseContains('Revisions');
- $collection_link = $this->getSession()->getPage()->findLink('Enhanced entities');
- $collection_link->click();
- $this->assertSession()->addressEquals('/entity_test_enhanced');
- $this->assertSession()->responseContains('Edit');
- $edit_link = $this->getSession()->getPage()->findLink('Edit');
- $edit_link->click();
- $this->assertSession()->addressEquals('/entity_test_enhanced/1/edit');
- // Check if we have revision tab link on edit page.
- $this->getSession()->getPage()->findLink('Revisions')->click();
- $this->assertSession()->addressEquals('/entity_test_enhanced/1/revisions');
- $this->drupalGet('/entity_test_enhanced/1/revisions/2/view');
- $this->assertSession()->statusCodeEquals(200);
- $this->assertSession()->responseContains('rev 2');
- $revisions_link = $this->getSession()->getPage()->findLink('Revisions');
- $revisions_link->click();
- $this->assertSession()->addressEquals('/entity_test_enhanced/1/revisions');
- $this->assertSession()->statusCodeEquals(200);
- }
-
-}
diff --git a/web/modules/contrib/entity/tests/src/Kernel/BundlePluginTest.php b/web/modules/contrib/entity/tests/src/Kernel/BundlePluginTest.php
deleted file mode 100644
index eeeb92384..000000000
--- a/web/modules/contrib/entity/tests/src/Kernel/BundlePluginTest.php
+++ /dev/null
@@ -1,146 +0,0 @@
-installSchema('system', 'router');
-
- // Install the modules properly. Putting them into static::$modules doesn't trigger the install
- // hooks, like hook_modules_installed, so entity_modules_installed is not triggered().
- /** @var \Drupal\Core\Extension\ModuleInstallerInterface $module_installer */
- $module_installer = \Drupal::service('module_installer');
- $module_installer->install(['entity_module_bundle_plugin_test', 'entity_module_bundle_plugin_examples_test']);
- }
-
- /**
- * Tests the bundle plugins.
- */
- public function testPluginBundles() {
- $bundled_entity_types = entity_get_bundle_plugin_entity_types();
- /** @var \Drupal\Core\Entity\EntityTypeInterface $entity_type */
- $entity_type = $bundled_entity_types['entity_test_bundle_plugin'];
- $this->assertEquals('entity_test_bundle_plugin', $entity_type->id());
- $this->assertTrue($entity_type->hasHandlerClass('bundle_plugin'));
-
- /** @var \Drupal\Core\Entity\EntityTypeBundleInfo $entity_type_bundle_info */
- $entity_type_bundle_info = \Drupal::service('entity_type.bundle.info');
- $bundle_info = $entity_type_bundle_info->getBundleInfo('entity_test_bundle_plugin');
- $this->assertEquals(2, count($bundle_info));
- $this->assertArrayHasKey('first', $bundle_info);
- $this->assertArrayHasKey('second', $bundle_info);
- $this->assertEquals('First', $bundle_info['first']['label']);
- $this->assertEquals('Some description', $bundle_info['first']['description']);
-
- /** @var \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager */
- $entity_field_manager = \Drupal::service('entity_field.manager');
- $field_storage_definitions = $entity_field_manager->getFieldStorageDefinitions('entity_test_bundle_plugin');
- $this->assertArrayHasKey('first_mail', $field_storage_definitions);
- $this->assertArrayHasKey('second_mail', $field_storage_definitions);
- $first_field_definitions = $entity_field_manager->getFieldDefinitions('entity_test_bundle_plugin', 'first');
- $this->assertArrayHasKey('first_mail', $first_field_definitions);
- $this->assertArrayNotHasKey('second_mail', $first_field_definitions);
- $second_field_definitions = $entity_field_manager->getFieldDefinitions('entity_test_bundle_plugin', 'second');
- $this->assertArrayNotHasKey('first_mail', $second_field_definitions);
- $this->assertArrayHasKey('second_mail', $second_field_definitions);
-
- $first_entity = EntityTestBundlePlugin::create([
- 'type' => 'first',
- 'first_mail' => 'admin@test.com',
- ]);
- $first_entity->save();
- $first_entity = EntityTestBundlePlugin::load($first_entity->id());
- $this->assertEquals('admin@test.com', $first_entity->first_mail->value);
-
- $second_entity = EntityTestBundlePlugin::create([
- 'type' => 'second',
- 'second_mail' => 'admin@example.com',
- ]);
- $second_entity->save();
- $second_entity = EntityTestBundlePlugin::load($second_entity->id());
- $this->assertEquals('admin@example.com', $second_entity->second_mail->value);
-
- // Also test entity queries.
- $result = \Drupal::entityTypeManager()->getStorage('entity_test_bundle_plugin')
- ->getQuery()
- ->condition('second_mail', 'admin@example.com')
- ->execute();
- $this->assertEquals([$second_entity->id() => $second_entity->id()], $result);
-
- $result = \Drupal::entityTypeManager()->getStorage('entity_test_bundle_plugin')
- ->getQuery()
- ->condition('type', 'first')
- ->execute();
- $this->assertEquals([$first_entity->id() => $first_entity->id()], $result);
-
- }
-
- /**
- * Tests the uninstallation for a bundle provided by a module.
- */
- public function testBundlePluginModuleUninstallation() {
- /** @var \Drupal\Core\Extension\ModuleInstallerInterface $module_installer */
- $module_installer = \Drupal::service('module_installer');
-
- // One should be possible to uninstall without any actual content.
- $violations = $module_installer->validateUninstall(['entity_module_bundle_plugin_examples_test']);
- $this->assertEmpty($violations);
-
- $first_entity = EntityTestBundlePlugin::create([
- 'type' => 'first',
- 'first_mail' => 'admin@test.com',
- ]);
- $first_entity->save();
- $second_entity = EntityTestBundlePlugin::create([
- 'type' => 'second',
- 'second_mail' => 'admin@example.com',
- ]);
- $second_entity->save();
-
- $violations = $module_installer->validateUninstall(['entity_module_bundle_plugin_examples_test']);
- $this->assertCount(1, $violations);
- $this->assertCount(1, $violations['entity_module_bundle_plugin_examples_test']);
- $this->assertEquals('There is data for the bundle Second on the entity type Entity test bundle plugin. Please remove all content before uninstalling the module.', $violations['entity_module_bundle_plugin_examples_test'][0]);
-
- $second_entity->delete();
-
- // The first entity is defined by entity_module_bundle_plugin_test, so it should be possible
- // to uninstall the module providing the second bundle plugin.
- $violations = $module_installer->validateUninstall(['entity_module_bundle_plugin_examples_test']);
- $this->assertEmpty($violations);
-
- $module_installer->uninstall(['entity_module_bundle_plugin_examples_test']);
-
- // The first entity is provided by entity_module_bundle_plugin_test which we cannot uninstall,
- // until all the entities are deleted.
- $violations = $module_installer->validateUninstall(['entity_module_bundle_plugin_test']);
- $this->assertNotEmpty($violations);
-
- $first_entity->delete();
- $violations = $module_installer->validateUninstall(['entity_module_bundle_plugin_test']);
- $this->assertEmpty($violations);
- }
-
-}
diff --git a/web/modules/contrib/entity/tests/src/Kernel/DeleteActionTest.php b/web/modules/contrib/entity/tests/src/Kernel/DeleteActionTest.php
deleted file mode 100644
index 68680f09d..000000000
--- a/web/modules/contrib/entity/tests/src/Kernel/DeleteActionTest.php
+++ /dev/null
@@ -1,83 +0,0 @@
-installEntitySchema('user');
- $this->installEntitySchema('entity_test_enhanced');
- $this->installSchema('system', ['key_value_expire', 'sequences']);
-
- $bundle = EnhancedEntityBundle::create([
- 'id' => 'default',
- 'label' => 'Default',
- ]);
- $bundle->save();
-
- $this->user = User::create([
- 'name' => 'username',
- 'status' => 1,
- ]);
- $this->user->save();
- \Drupal::service('current_user')->setAccount($this->user);
- }
-
- public function testAction() {
- /** @var \Drupal\system\ActionConfigEntityInterface $action */
- $action = Action::create([
- 'id' => 'enhanced_entity_delete_action',
- 'label' => 'Delete enhanced entity',
- 'plugin' => 'entity_delete_action:entity_test_enhanced',
- ]);
- $status = $action->save();
- $this->assertEquals(SAVED_NEW, $status);
- $this->assertInstanceOf(DeleteAction::class, $action->getPlugin());
-
- $entities = [];
- for ($i = 0; $i < 2; $i++) {
- $entity = EnhancedEntity::create([
- 'type' => 'default',
- ]);
- $entity->save();
- $entities[$entity->id()] = $entity;
- }
-
- $action->execute($entities);
- // Confirm that the entity ids and langcodes are now in the tempstore.
- $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/web/modules/contrib/entity/tests/src/Kernel/RevisionBasicUITest.php b/web/modules/contrib/entity/tests/src/Kernel/RevisionBasicUITest.php
deleted file mode 100644
index 1342848da..000000000
--- a/web/modules/contrib/entity/tests/src/Kernel/RevisionBasicUITest.php
+++ /dev/null
@@ -1,192 +0,0 @@
-installEntitySchema('user');
- $this->installEntitySchema('entity_test_enhanced');
- $this->installSchema('system', 'router');
- $this->installConfig(['system']);
-
- $bundle = EnhancedEntityBundle::create([
- 'id' => 'default',
- 'label' => 'Default',
- ]);
- $bundle->save();
-
- \Drupal::service('router.builder')->rebuild();
- }
-
- /**
- * Tests the revision history controller.
- */
- public function testRevisionHistory() {
- $entity = EnhancedEntity::create([
- 'name' => 'rev 1',
- 'type' => 'default',
- ]);
- $entity->save();
-
- $revision = clone $entity;
- $revision->name->value = 'rev 2';
- $revision->setNewRevision(TRUE);
- $revision->isDefaultRevision(FALSE);
- $revision->save();
-
- /** @var \Symfony\Component\HttpKernel\HttpKernelInterface $http_kernel */
- $http_kernel = \Drupal::service('http_kernel');
- $request = Request::create($revision->toUrl('version-history')->toString());
- $response = $http_kernel->handle($request);
- $this->assertEquals(403, $response->getStatusCode());
-
- $role_admin = Role::create(['id' => 'test_role_admin']);
- $role_admin->grantPermission('administer entity_test_enhanced');
- $role_admin->save();
-
- $role = Role::create(['id' => 'test_role']);
- $role->grantPermission('view all entity_test_enhanced revisions');
- $role->grantPermission('administer entity_test_enhanced');
- $role->save();
-
- $user_admin = User::create([
- 'name' => 'Test user admin',
- ]);
- $user_admin->addRole($role_admin->id());
- \Drupal::service('account_switcher')->switchTo($user_admin);
-
- $request = Request::create($revision->toUrl('version-history')->toString());
- $response = $http_kernel->handle($request);
- $this->assertEquals(200, $response->getStatusCode());
-
- $user = User::create([
- 'name' => 'Test user',
- ]);
- $user->addRole($role->id());
- \Drupal::service('account_switcher')->switchTo($user);
-
- $request = Request::create($revision->toUrl('version-history')->toString());
- $response = $http_kernel->handle($request);
- $this->assertEquals(200, $response->getStatusCode());
-
- // This ensures that the default revision is still the first revision.
- $this->assertTrue(strpos($response->getContent(), 'entity_test_enhanced/1/revisions/2/view') !== FALSE);
- $this->assertTrue(strpos($response->getContent(), 'entity_test_enhanced/1') !== FALSE);
-
- // Publish a new revision.
- $revision = clone $entity;
- $revision->name->value = 'rev 3';
- $revision->setNewRevision(TRUE);
- $revision->isDefaultRevision(TRUE);
- $revision->save();
-
- $request = Request::create($revision->toUrl('version-history')->toString());
- $response = $http_kernel->handle($request);
- $this->assertEquals(200, $response->getStatusCode());
-
- // The first revision row should now include a revert link.
- $this->assertTrue(strpos($response->getContent(), 'entity_test_enhanced/1/revisions/1/revert') !== FALSE);
- }
-
- public function testRevisionView() {
- $entity = EnhancedEntity::create([
- 'name' => 'rev 1',
- 'type' => 'default',
- ]);
- $entity->save();
-
- $revision = clone $entity;
- $revision->name->value = 'rev 2';
- $revision->setNewRevision(TRUE);
- $revision->isDefaultRevision(FALSE);
- $revision->save();
-
- /** @var \Symfony\Component\HttpKernel\HttpKernelInterface $http_kernel */
- $http_kernel = \Drupal::service('http_kernel');
- $request = Request::create($revision->toUrl('revision')->toString());
- $response = $http_kernel->handle($request);
- $this->assertEquals(403, $response->getStatusCode());
-
- $role_admin = Role::create(['id' => 'test_role_admin']);
- $role_admin->grantPermission('administer entity_test_enhanced');
- $role_admin->save();
-
- $role = Role::create(['id' => 'test_role']);
- $role->grantPermission('view all entity_test_enhanced revisions');
- $role->grantPermission('administer entity_test_enhanced');
- $role->save();
-
- $user_admin = User::create([
- 'name' => 'Test user admin',
- ]);
- $user_admin->addRole($role_admin->id());
- \Drupal::service('account_switcher')->switchTo($user_admin);
-
- $request = Request::create($revision->toUrl('version-history')->toString());
- $response = $http_kernel->handle($request);
- $this->assertEquals(200, $response->getStatusCode());
-
- $user = User::create([
- 'name' => 'Test user',
- ]);
- $user->addRole($role->id());
- \Drupal::service('account_switcher')->switchTo($user);
-
- $request = Request::create($revision->toUrl('revision')->toString());
- $response = $http_kernel->handle($request);
- $this->assertEquals(200, $response->getStatusCode());
- $this->assertNotContains('rev 1', $response->getContent());
- $this->assertContains('rev 2', $response->getContent());
- }
-
- public function testRevisionRevert() {
- $entity = EnhancedEntity::create([
- 'name' => 'rev 1',
- 'type' => 'entity_test_enhance',
- ]);
- $entity->save();
- $entity->name->value = 'rev 2';
- $entity->setNewRevision(TRUE);
- $entity->isDefaultRevision(TRUE);
- $entity->save();
-
- $role = Role::create(['id' => 'test_role']);
- $role->grantPermission('administer entity_test_enhanced');
- $role->grantPermission('revert all entity_test_enhanced revisions');
- $role->save();
-
- $user = User::create([
- 'name' => 'Test user',
- ]);
- $user->addRole($role->id());
- \Drupal::service('account_switcher')->switchTo($user);
-
- /** @var \Symfony\Component\HttpKernel\HttpKernelInterface $http_kernel */
- $http_kernel = \Drupal::service('http_kernel');
- $request = Request::create($entity->toUrl('revision-revert-form')->toString());
- $response = $http_kernel->handle($request);
- $this->assertEquals(200, $response->getStatusCode());
- }
-
-}
diff --git a/web/modules/contrib/entity/tests/src/Unit/EntityAccessControlHandlerTest.php b/web/modules/contrib/entity/tests/src/Unit/EntityAccessControlHandlerTest.php
deleted file mode 100644
index f90ade56a..000000000
--- a/web/modules/contrib/entity/tests/src/Unit/EntityAccessControlHandlerTest.php
+++ /dev/null
@@ -1,257 +0,0 @@
-prophesize(ModuleHandlerInterface::class);
- $module_handler->invokeAll(Argument::any(), Argument::any())->willReturn([]);
- $cache_contexts_manager = $this->prophesize(CacheContextsManager::class);
- $cache_contexts_manager->assertValidTokens(Argument::any())->willReturn(TRUE);
-
- $container = new ContainerBuilder();
- $container->set('module_handler', $module_handler->reveal());
- $container->set('cache_contexts_manager', $cache_contexts_manager->reveal());
- \Drupal::setContainer($container);
- }
-
- /**
- * @covers ::checkAccess
- * @covers ::checkEntityPermissions
- * @covers ::checkEntityOwnerPermissions
- * @covers ::checkCreateAccess
- *
- * @dataProvider accessProvider
- */
- public function testAccess(EntityInterface $entity, $operation, $account, $allowed) {
- $handler = new EntityAccessControlHandler($entity->getEntityType());
- $handler->setStringTranslation($this->getStringTranslationStub());
- $result = $handler->access($entity, $operation, $account);
- $this->assertEquals($allowed, $result);
- }
-
- /**
- * @covers ::checkCreateAccess
- *
- * @dataProvider createAccessProvider
- */
- public function testCreateAccess(EntityTypeInterface $entity_type, $bundle, $account, $allowed) {
- $handler = new EntityAccessControlHandler($entity_type);
- $handler->setStringTranslation($this->getStringTranslationStub());
- $result = $handler->createAccess($bundle, $account);
- $this->assertEquals($allowed, $result);
- }
-
- /**
- * Data provider for testAccess().
- *
- * @return array
- * A list of testAccess method arguments.
- */
- public function accessProvider() {
- $data = [];
-
- $entity_type = $this->prophesize(ContentEntityTypeInterface::class);
- $entity_type->id()->willReturn('green_entity');
- $entity_type->getAdminPermission()->willReturn('administer green_entity');
- $entity_type->hasHandlerClass('permission_provider')->willReturn(TRUE);
- $entity_type->getHandlerClass('permission_provider')->willReturn(EntityPermissionProvider::class);
-
- // User with the admin permission can do anything.
- $entity = $this->buildMockEntity($entity_type->reveal());
- $account = $this->prophesize(AccountInterface::class);
- $account->id()->willReturn(6);
- $account->hasPermission('administer green_entity')->willReturn(TRUE);
- $data[] = [$entity->reveal(), 'view', $account->reveal(), TRUE];
- $data[] = [$entity->reveal(), 'update', $account->reveal(), TRUE];
- $data[] = [$entity->reveal(), 'delete', $account->reveal(), TRUE];
-
- // Entity with no owner.
- $entity = $this->buildMockEntity($entity_type->reveal());
- // User who has access.
- $first_account = $this->prophesize(AccountInterface::class);
- $first_account->id()->willReturn(6);
- $first_account->hasPermission('view green_entity')->willReturn(TRUE);
- $first_account->hasPermission(Argument::any())->willReturn(FALSE);
- // User who doesn't have access.
- $second_account = $this->prophesize(AccountInterface::class);
- $second_account->id()->willReturn(7);
- $second_account->hasPermission('view green_entity')->willReturn(FALSE);
- $second_account->hasPermission(Argument::any())->willReturn(FALSE);
- $data[] = [$entity->reveal(), 'view', $first_account->reveal(), TRUE];
- $data[] = [$entity->reveal(), 'view', $second_account->reveal(), FALSE];
-
- // Entity with owner.
- $entity = $this->buildMockEntity($entity_type->reveal(), 6);
- // Owner.
- $first_account = $this->prophesize(AccountInterface::class);
- $first_account->id()->willReturn(6);
- $first_account->hasPermission('update own green_entity')->willReturn(TRUE);
- $first_account->hasPermission(Argument::any())->willReturn(FALSE);
- // Non-owner.
- $second_account = $this->prophesize(AccountInterface::class);
- $second_account->id()->willReturn(7);
- $second_account->hasPermission('update own green_entity')->willReturn(TRUE);
- $second_account->hasPermission(Argument::any())->willReturn(FALSE);
- // User who can update any.
- $third_account = $this->prophesize(AccountInterface::class);
- $third_account->id()->willReturn(8);
- $third_account->hasPermission('update any green_entity')->willReturn(TRUE);
- $third_account->hasPermission(Argument::any())->willReturn(FALSE);
- $data[] = [$entity->reveal(), 'update', $first_account->reveal(), TRUE];
- $data[] = [$entity->reveal(), 'update', $second_account->reveal(), FALSE];
- $data[] = [$entity->reveal(), 'update', $third_account->reveal(), TRUE];
-
- // Test the unpublished permissions.
- $entity_first_other_up = $this->buildMockEntity($entity_type->reveal(), 9999, 'first', FALSE);
- $entity_first_own_up = $this->buildMockEntity($entity_type->reveal(), 14, 'first', FALSE);
- $entity_first_own_bundle_up = $this->buildMockEntity($entity_type->reveal(), 15, 'first', FALSE);
-
- $entity_second_other_up = $this->buildMockEntity($entity_type->reveal(), 9999, 'second', FALSE);
- $entity_second_own_up = $this->buildMockEntity($entity_type->reveal(), 14, 'second', FALSE);
- $entity_second_own_bundle_up = $this->buildMockEntity($entity_type->reveal(), 15, 'second', FALSE);
-
- $user_view_own_up = $this->buildMockUser(14, 'view own unpublished green_entity');
- $user_view_other = $this->buildMockUser(15, 'view green_entity');
-
- $data['entity_first_other_up user_view_own_up'] = [$entity_first_other_up->reveal(), 'view', $user_view_own_up->reveal(), FALSE];
- $data['entity_first_own_up user_view_own_up'] = [$entity_first_own_up->reveal(), 'view', $user_view_own_up->reveal(), TRUE];
- $data['entity_first_own_bundle_up user_view_own_up'] = [$entity_first_own_bundle_up->reveal(), 'view', $user_view_own_up->reveal(), FALSE];
- $data['entity_second_other_up user_view_own_up'] = [$entity_second_other_up->reveal(), 'view', $user_view_own_up->reveal(), FALSE];
- $data['entity_second_own_up user_view_own_up'] = [$entity_second_own_up->reveal(), 'view', $user_view_own_up->reveal(), TRUE];
- $data['entity_second_own_bundle_up user_view_own_up'] = [$entity_second_own_bundle_up->reveal(), 'view', $user_view_own_up->reveal(), FALSE];
-
- $data['entity_first_other_up user_view_other'] = [$entity_first_other_up->reveal(), 'view', $user_view_other->reveal(), FALSE];
- $data['entity_first_own_up user_view_other'] = [$entity_first_own_up->reveal(), 'view', $user_view_other->reveal(), FALSE];
- $data['entity_first_own_bundle_up user_view_other'] = [$entity_first_own_bundle_up->reveal(), 'view', $user_view_other->reveal(), FALSE];
- $data['entity_second_other_up user_view_other'] = [$entity_second_other_up->reveal(), 'view', $user_view_other->reveal(), FALSE];
- $data['entity_second_own_up user_view_other'] = [$entity_second_own_up->reveal(), 'view', $user_view_other->reveal(), FALSE];
- $data['entity_second_own_bundle_up user_view_other'] = [$entity_second_own_bundle_up->reveal(), 'view', $user_view_other->reveal(), FALSE];
-
- return $data;
- }
-
- /**
- * Data provider for testCreateAccess().
- *
- * @return array
- * A list of testCreateAccess method arguments.
- */
- public function createAccessProvider() {
- $data = [];
-
- $entity_type = $this->prophesize(ContentEntityTypeInterface::class);
- $entity_type->id()->willReturn('green_entity');
- $entity_type->getAdminPermission()->willReturn('administer green_entity');
- $entity_type->hasHandlerClass('permission_provider')->willReturn(TRUE);
- $entity_type->getHandlerClass('permission_provider')->willReturn(EntityPermissionProvider::class);
-
- // User with the admin permission.
- $account = $this->prophesize(AccountInterface::class);
- $account->id()->willReturn(6);
- $account->hasPermission('administer green_entity')->willReturn(TRUE);
- $data[] = [$entity_type->reveal(), NULL, $account->reveal(), TRUE];
-
- // Ordinary user.
- $account = $this->prophesize(AccountInterface::class);
- $account->id()->willReturn(6);
- $account->hasPermission('create green_entity')->willReturn(TRUE);
- $account->hasPermission(Argument::any())->willReturn(FALSE);
- $data[] = [$entity_type->reveal(), NULL, $account->reveal(), TRUE];
-
- // Ordinary user, entity with a bundle.
- $account = $this->prophesize(AccountInterface::class);
- $account->id()->willReturn(6);
- $account->hasPermission('create first_bundle green_entity')->willReturn(TRUE);
- $account->hasPermission(Argument::any())->willReturn(FALSE);
- $data[] = [$entity_type->reveal(), 'first_bundle', $account->reveal(), TRUE];
-
- // User with no permissions.
- $account = $this->prophesize(AccountInterface::class);
- $account->id()->willReturn(6);
- $account->hasPermission(Argument::any())->willReturn(FALSE);
- $data[] = [$entity_type->reveal(), NULL, $account->reveal(), FALSE];
-
- return $data;
- }
-
- /**
- * Builds a mock entity.
- *
- * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
- * The entity type.
- * @param string $owner_id
- * The owner ID.
- *
- * @return \Prophecy\Prophecy\ObjectProphecy
- * The entity mock.
- */
- protected function buildMockEntity(EntityTypeInterface $entity_type, $owner_id = NULL, $bundle = NULL, $published = NULL) {
- $langcode = LanguageInterface::LANGCODE_NOT_SPECIFIED;
- $entity = $this->prophesize(ContentEntityInterface::class);
- if (isset($published)) {
- $entity->willImplement(EntityPublishedInterface::class);
- }
- if ($owner_id) {
- $entity->willImplement(EntityOwnerInterface::class);
- }
- if (isset($published)) {
- $entity->isPublished()->willReturn($published);
- }
- if ($owner_id) {
- $entity->getOwnerId()->willReturn($owner_id);
- }
-
- $entity->bundle()->willReturn($bundle ?: $entity_type->id());
- $entity->isNew()->willReturn(FALSE);
- $entity->uuid()->willReturn('fake uuid');
- $entity->id()->willReturn('fake id');
- $entity->getRevisionId()->willReturn(NULL);
- $entity->language()->willReturn(new Language(['id' => $langcode]));
- $entity->getEntityTypeId()->willReturn($entity_type->id());
- $entity->getEntityType()->willReturn($entity_type);
- $entity->getCacheContexts()->willReturn([]);
- $entity->getCacheTags()->willReturn([]);
- $entity->getCacheMaxAge()->willReturn(Cache::PERMANENT);
-
-
- return $entity;
- }
-
- protected function buildMockUser($uid, $permission) {
- $account = $this->prophesize(AccountInterface::class);
- $account->id()->willReturn($uid);
- $account->hasPermission($permission)->willReturn(TRUE);
- $account->hasPermission(Argument::any())->willReturn(FALSE);
- return $account;
- }
-
-}
diff --git a/web/modules/contrib/entity/tests/src/Unit/EntityPermissionProviderTest.php b/web/modules/contrib/entity/tests/src/Unit/EntityPermissionProviderTest.php
deleted file mode 100644
index e38021438..000000000
--- a/web/modules/contrib/entity/tests/src/Unit/EntityPermissionProviderTest.php
+++ /dev/null
@@ -1,177 +0,0 @@
-prophesize(EntityTypeBundleInfoInterface::class);
- $entity_type_bundle_info->getBundleInfo('white_entity')->willReturn([
- 'first' => ['label' => 'First'],
- 'second' => ['label' => 'Second'],
- ]);
- $entity_type_bundle_info->getBundleInfo('black_entity')->willReturn([
- 'third' => ['label' => 'Third'],
- ]);
- $entity_type_bundle_info->getBundleInfo('pink_entity')->willReturn([
- 'third' => ['label' => 'Third'],
- ]);
- $this->permissionProvider = new EntityPermissionProvider($entity_type_bundle_info->reveal());
- $this->permissionProvider->setStringTranslation($this->getStringTranslationStub());
- }
-
- /**
- * @covers ::buildPermissions
- *
- * @dataProvider entityTypeProvider
- */
- public function testBuildPermissions(EntityTypeInterface $entity_type, array $expected_permissions) {
- $permissions = $this->permissionProvider->buildPermissions($entity_type);
- $this->assertEquals(array_keys($expected_permissions), array_keys($permissions));
- foreach ($permissions as $name => $permission) {
- $this->assertEquals('entity_module_test', $permission['provider']);
- $this->assertEquals($expected_permissions[$name], $permission['title']);
- }
- }
-
- /**
- * Data provider for testBuildPermissions().
- *
- * @return array
- * A list of testBuildPermissions method arguments.
- */
- public function entityTypeProvider() {
- $data = [];
- // Content entity type.
- $entity_type = $this->prophesize(ContentEntityTypeInterface::class);
- $entity_type->getProvider()->willReturn('entity_module_test');
- $entity_type->id()->willReturn('green_entity');
- $entity_type->getSingularLabel()->willReturn('green entity');
- $entity_type->getPluralLabel()->willReturn('green entities');
- $entity_type->entityClassImplements(EntityOwnerInterface::class)->willReturn(FALSE);
- $entity_type->entityClassImplements(EntityPublishedInterface::class)->willReturn(FALSE);
- $entity_type->getPermissionGranularity()->willReturn('entity_type');
- $expected_permissions = [
- 'administer green_entity' => 'Administer green entities',
- 'access green_entity overview' => 'Access the green entities overview page',
- 'create green_entity' => 'Create green entities',
- 'update green_entity' => 'Update green entities',
- 'delete green_entity' => 'Delete green entities',
- 'view green_entity' => 'View green entities',
- ];
- $data[] = [$entity_type->reveal(), $expected_permissions];
-
- // Content entity type with owner.
- $entity_type = $this->prophesize(ContentEntityTypeInterface::class);
- $entity_type->getProvider()->willReturn('entity_module_test');
- $entity_type->id()->willReturn('blue_entity');
- $entity_type->getSingularLabel()->willReturn('blue entity');
- $entity_type->getPluralLabel()->willReturn('blue entities');
- $entity_type->entityClassImplements(EntityOwnerInterface::class)->willReturn(TRUE);
- $entity_type->entityClassImplements(EntityPublishedInterface::class)->willReturn(FALSE);
- $entity_type->getPermissionGranularity()->willReturn('entity_type');
- $expected_permissions = [
- 'administer blue_entity' => 'Administer blue entities',
- 'access blue_entity overview' => 'Access the blue entities overview page',
- 'create blue_entity' => 'Create blue entities',
- 'update any blue_entity' => 'Update any blue entity',
- 'update own blue_entity' => 'Update own blue entities',
- 'delete any blue_entity' => 'Delete any blue entity',
- 'delete own blue_entity' => 'Delete own blue entities',
- 'view blue_entity' => 'View blue entities',
- ];
- $data[] = [$entity_type->reveal(), $expected_permissions];
-
- // Content entity type with bundles.
- $entity_type = $this->prophesize(ContentEntityTypeInterface::class);
- $entity_type->getProvider()->willReturn('entity_module_test');
- $entity_type->id()->willReturn('white_entity');
- $entity_type->getSingularLabel()->willReturn('white entity');
- $entity_type->getPluralLabel()->willReturn('white entities');
- $entity_type->entityClassImplements(EntityOwnerInterface::class)->willReturn(FALSE);
- $entity_type->entityClassImplements(EntityPublishedInterface::class)->willReturn(FALSE);
- $entity_type->getPermissionGranularity()->willReturn('bundle');
- $expected_permissions = [
- 'administer white_entity' => 'Administer white entities',
- 'access white_entity overview' => 'Access the white entities overview page',
- 'create first white_entity' => 'First: Create white entities',
- 'update first white_entity' => 'First: Update white entities',
- 'delete first white_entity' => 'First: Delete white entities',
- 'create second white_entity' => 'Second: Create white entities',
- 'update second white_entity' => 'Second: Update white entities',
- 'delete second white_entity' => 'Second: Delete white entities',
- 'view white_entity' => 'View white entities',
- ];
- $data[] = [$entity_type->reveal(), $expected_permissions];
-
- // Content entity type with bundles and owner.
- $entity_type = $this->prophesize(ContentEntityTypeInterface::class);
- $entity_type->getProvider()->willReturn('entity_module_test');
- $entity_type->id()->willReturn('black_entity');
- $entity_type->getSingularLabel()->willReturn('black entity');
- $entity_type->getPluralLabel()->willReturn('black entities');
- $entity_type->entityClassImplements(EntityOwnerInterface::class)->willReturn(TRUE);
- $entity_type->entityClassImplements(EntityPublishedInterface::class)->willReturn(FALSE);
- $entity_type->getPermissionGranularity()->willReturn('bundle');
- $expected_permissions = [
- 'administer black_entity' => 'Administer black entities',
- 'access black_entity overview' => 'Access the black entities overview page',
- 'create third black_entity' => 'Third: Create black entities',
- 'update any third black_entity' => 'Third: Update any black entity',
- 'update own third black_entity' => 'Third: Update own black entities',
- 'delete any third black_entity' => 'Third: Delete any black entity',
- 'delete own third black_entity' => 'Third: Delete own black entities',
- 'view black_entity' => 'View black entities',
- ];
- $data[] = [$entity_type->reveal(), $expected_permissions];
-
- // Content entity type with bundles and owner and entity published.
- $entity_type = $this->prophesize(ContentEntityTypeInterface::class);
- $entity_type->getProvider()->willReturn('entity_module_test');
- $entity_type->id()->willReturn('pink_entity');
- $entity_type->getSingularLabel()->willReturn('pink entity');
- $entity_type->getPluralLabel()->willReturn('pink entities');
- $entity_type->entityClassImplements(EntityOwnerInterface::class)->willReturn(TRUE);
- $entity_type->entityClassImplements(EntityPublishedInterface::class)->willReturn(TRUE);
- $entity_type->getPermissionGranularity()->willReturn('bundle');
- $expected_permissions = [
- 'administer pink_entity' => 'Administer pink entities',
- 'access pink_entity overview' => 'Access the pink entities overview page',
- 'view own unpublished pink_entity' => 'View own unpublished pink entities',
- 'create third pink_entity' => 'Third: Create pink entities',
- 'update any third pink_entity' => 'Third: Update any pink entity',
- 'update own third pink_entity' => 'Third: Update own pink entities',
- 'delete any third pink_entity' => 'Third: Delete any pink entity',
- 'delete own third pink_entity' => 'Third: Delete own pink entities',
- 'view pink_entity' => 'View pink entities',
- ];
- $data[] = [$entity_type->reveal(), $expected_permissions];
-
- return $data;
- }
-
-}
diff --git a/web/modules/contrib/entity/tests/src/Unit/UncacheableEntityAccessControlHandlerTest.php b/web/modules/contrib/entity/tests/src/Unit/UncacheableEntityAccessControlHandlerTest.php
deleted file mode 100644
index c788a5b48..000000000
--- a/web/modules/contrib/entity/tests/src/Unit/UncacheableEntityAccessControlHandlerTest.php
+++ /dev/null
@@ -1,299 +0,0 @@
-prophesize(ModuleHandlerInterface::class);
- $module_handler->invokeAll(Argument::any(), Argument::any())->willReturn([]);
- $cache_contexts_manager = $this->prophesize(CacheContextsManager::class);
- $cache_contexts_manager->assertValidTokens(Argument::any())->willReturn(TRUE);
-
- $container = new ContainerBuilder();
- $container->set('module_handler', $module_handler->reveal());
- $container->set('cache_contexts_manager', $cache_contexts_manager->reveal());
- \Drupal::setContainer($container);
- }
-
- /**
- * @covers ::checkAccess
- * @covers ::checkEntityPermissions
- * @covers ::checkEntityOwnerPermissions
- * @covers ::checkCreateAccess
- *
- * @dataProvider accessProvider
- */
- public function testAccess(EntityInterface $entity, $operation, $account, $allowed) {
- $handler = new UncacheableEntityAccessControlHandler($entity->getEntityType());
- $handler->setStringTranslation($this->getStringTranslationStub());
- $result = $handler->access($entity, $operation, $account);
- $this->assertEquals($allowed, $result);
- }
-
- /**
- * @covers ::checkCreateAccess
- *
- * @dataProvider createAccessProvider
- */
- public function testCreateAccess(EntityTypeInterface $entity_type, $bundle, $account, $allowed) {
- $handler = new UncacheableEntityAccessControlHandler($entity_type);
- $handler->setStringTranslation($this->getStringTranslationStub());
- $result = $handler->createAccess($bundle, $account);
- $this->assertEquals($allowed, $result);
- }
-
- /**
- * Data provider for testAccess().
- *
- * @return array
- * A list of testAccess method arguments.
- */
- public function accessProvider() {
- $data = [];
-
- $entity_type = $this->prophesize(ContentEntityTypeInterface::class);
- $entity_type->id()->willReturn('green_entity');
- $entity_type->getAdminPermission()->willReturn('administer green_entity');
- $entity_type->hasHandlerClass('permission_provider')->willReturn(TRUE);
- $entity_type->getHandlerClass('permission_provider')->willReturn(UncacheableEntityPermissionProvider::class);
-
- // User with the admin permission can do anything.
- $entity = $this->buildMockEntity($entity_type->reveal());
- $account = $this->prophesize(AccountInterface::class);
- $account->id()->willReturn(6);
- $account->hasPermission('administer green_entity')->willReturn(TRUE);
- $data[] = [$entity->reveal(), 'view', $account->reveal(), TRUE];
- $data[] = [$entity->reveal(), 'update', $account->reveal(), TRUE];
- $data[] = [$entity->reveal(), 'delete', $account->reveal(), TRUE];
-
- // Entity with no owner.
- $entity = $this->buildMockEntity($entity_type->reveal());
- // User who has access.
- $first_account = $this->prophesize(AccountInterface::class);
- $first_account->id()->willReturn(6);
- $first_account->hasPermission('view green_entity')->willReturn(TRUE);
- $first_account->hasPermission(Argument::any())->willReturn(FALSE);
- // User who doesn't have access.
- $second_account = $this->prophesize(AccountInterface::class);
- $second_account->id()->willReturn(7);
- $second_account->hasPermission('view green_entity')->willReturn(FALSE);
- $second_account->hasPermission(Argument::any())->willReturn(FALSE);
- $data[] = [$entity->reveal(), 'view', $first_account->reveal(), TRUE];
- $data[] = [$entity->reveal(), 'view', $second_account->reveal(), FALSE];
-
- // Entity with owner.
- $entity = $this->buildMockEntity($entity_type->reveal(), 6);
- // Owner.
- $first_account = $this->prophesize(AccountInterface::class);
- $first_account->id()->willReturn(6);
- $first_account->hasPermission('update own green_entity')->willReturn(TRUE);
- $first_account->hasPermission(Argument::any())->willReturn(FALSE);
- // Non-owner.
- $second_account = $this->prophesize(AccountInterface::class);
- $second_account->id()->willReturn(7);
- $second_account->hasPermission('update own green_entity')->willReturn(TRUE);
- $second_account->hasPermission(Argument::any())->willReturn(FALSE);
- // User who can update any.
- $third_account = $this->prophesize(AccountInterface::class);
- $third_account->id()->willReturn(8);
- $third_account->hasPermission('update any green_entity')->willReturn(TRUE);
- $third_account->hasPermission(Argument::any())->willReturn(FALSE);
- $data[] = [$entity->reveal(), 'update', $first_account->reveal(), TRUE];
- $data[] = [$entity->reveal(), 'update', $second_account->reveal(), FALSE];
- $data[] = [$entity->reveal(), 'update', $third_account->reveal(), TRUE];
-
- // Per bundle permissions.
- $entity_first_other = $this->buildMockEntity($entity_type->reveal(), 9999, 'first');
- $entity_first_own = $this->buildMockEntity($entity_type->reveal(), 10, 'first');
- $entity_first_own_bundle = $this->buildMockEntity($entity_type->reveal(), 12, 'first');
-
- $entity_second_other = $this->buildMockEntity($entity_type->reveal(), 9999, 'second');
- $entity_second_own = $this->buildMockEntity($entity_type->reveal(), 10, 'second');
- $entity_second_own_bundle = $this->buildMockEntity($entity_type->reveal(), 12, 'second');
-
- $user_view_any = $this->buildMockUser(9, 'view any green_entity');
- $user_view_own = $this->buildMockUser(10, 'view own green_entity');
- $user_view_bundle_any = $this->buildMockUser(11, 'view any first green_entity');
- $user_view_bundle_own = $this->buildMockUser(12, 'view own first green_entity');
-
- $data['entity_first_other user_view_any'] = [$entity_first_other->reveal(), 'view', $user_view_any->reveal(), TRUE];
- $data['entity_first_own user_view_any'] = [$entity_first_own->reveal(), 'view', $user_view_any->reveal(), TRUE];
- $data['entity_first_own_bundle user_view_any'] = [$entity_first_own_bundle->reveal(), 'view', $user_view_any->reveal(), TRUE];
- $data['entity_second_other user_view_any'] = [$entity_second_other->reveal(), 'view', $user_view_any->reveal(), TRUE];
- $data['entity_second_own user_view_any'] = [$entity_second_own->reveal(), 'view', $user_view_any->reveal(), TRUE];
- $data['entity_second_own_bundle user_view_any'] = [$entity_second_own_bundle->reveal(), 'view', $user_view_any->reveal(), TRUE];
-
- $data['entity_first_other user_view_own'] = [$entity_first_other->reveal(), 'view', $user_view_own->reveal(), FALSE];
- $data['entity_first_own user_view_own'] = [$entity_first_own->reveal(), 'view', $user_view_own->reveal(), TRUE];
- $data['entity_first_own_bundle user_view_own'] = [$entity_first_own_bundle->reveal(), 'view', $user_view_own->reveal(), FALSE];
- $data['entity_second_other user_view_own'] = [$entity_second_other->reveal(), 'view', $user_view_own->reveal(), FALSE];
- $data['entity_second_own user_view_own'] = [$entity_second_own->reveal(), 'view', $user_view_own->reveal(), TRUE];
- $data['entity_second_own_bundle user_view_own'] = [$entity_second_own_bundle->reveal(), 'view', $user_view_own->reveal(), FALSE];
-
- $data['entity_first_other user_view_bundle_any'] = [$entity_first_other->reveal(), 'view', $user_view_bundle_any->reveal(), TRUE];
- $data['entity_first_own user_view_bundle_any'] = [$entity_first_own->reveal(), 'view', $user_view_bundle_any->reveal(), TRUE];
- $data['entity_first_own_bundle user_view_bundle_any'] = [$entity_first_own_bundle->reveal(), 'view', $user_view_bundle_any->reveal(), TRUE];
- $data['entity_second_other user_view_bundle_any'] = [$entity_second_other->reveal(), 'view', $user_view_bundle_any->reveal(), FALSE];
- $data['entity_second_own user_view_bundle_any'] = [$entity_second_own->reveal(), 'view', $user_view_bundle_any->reveal(), FALSE];
- $data['entity_second_own_bundle user_view_bundle_any'] = [$entity_second_own_bundle->reveal(), 'view', $user_view_bundle_any->reveal(), FALSE];
-
- $data['entity_first_other user_view_bundle_any'] = [$entity_first_other->reveal(), 'view', $user_view_bundle_own->reveal(), FALSE];
- $data['entity_first_own user_view_bundle_any'] = [$entity_first_own->reveal(), 'view', $user_view_bundle_own->reveal(), FALSE];
- $data['entity_first_own_bundle user_view_bundle_any'] = [$entity_first_own_bundle->reveal(), 'view', $user_view_bundle_own->reveal(), TRUE];
- $data['entity_second_other user_view_bundle_any'] = [$entity_second_other->reveal(), 'view', $user_view_bundle_own->reveal(), FALSE];
- $data['entity_second_own user_view_bundle_any'] = [$entity_second_own->reveal(), 'view', $user_view_bundle_own->reveal(), FALSE];
- $data['entity_second_own_bundle user_view_bundle_any'] = [$entity_second_own_bundle->reveal(), 'view', $user_view_bundle_own->reveal(), FALSE];
-
- // Test the unpublished permissions.
- $entity_first_other_up = $this->buildMockEntity($entity_type->reveal(), 9999, 'first', FALSE);
- $entity_first_own_up = $this->buildMockEntity($entity_type->reveal(), 14, 'first', FALSE);
- $entity_first_own_bundle_up = $this->buildMockEntity($entity_type->reveal(), 15, 'first', FALSE);
-
- $entity_second_other_up = $this->buildMockEntity($entity_type->reveal(), 9999, 'second', FALSE);
- $entity_second_own_up = $this->buildMockEntity($entity_type->reveal(), 14, 'second', FALSE);
- $entity_second_own_bundle_up = $this->buildMockEntity($entity_type->reveal(), 15, 'second', FALSE);
-
- $user_view_own_up = $this->buildMockUser(14, 'view own unpublished green_entity');
- $user_view_other = $this->buildMockUser(15, 'view green_entity');
-
- $data['entity_first_other_up user_view_own_up'] = [$entity_first_other_up->reveal(), 'view', $user_view_own_up->reveal(), FALSE];
- $data['entity_first_own_up user_view_own_up'] = [$entity_first_own_up->reveal(), 'view', $user_view_own_up->reveal(), TRUE];
- $data['entity_first_own_bundle_up user_view_own_up'] = [$entity_first_own_bundle_up->reveal(), 'view', $user_view_own_up->reveal(), FALSE];
- $data['entity_second_other_up user_view_own_up'] = [$entity_second_other_up->reveal(), 'view', $user_view_own_up->reveal(), FALSE];
- $data['entity_second_own_up user_view_own_up'] = [$entity_second_own_up->reveal(), 'view', $user_view_own_up->reveal(), TRUE];
- $data['entity_second_own_bundle_up user_view_own_up'] = [$entity_second_own_bundle_up->reveal(), 'view', $user_view_own_up->reveal(), FALSE];
-
- $data['entity_first_other_up user_view_other'] = [$entity_first_other_up->reveal(), 'view', $user_view_other->reveal(), FALSE];
- $data['entity_first_own_up user_view_other'] = [$entity_first_own_up->reveal(), 'view', $user_view_other->reveal(), FALSE];
- $data['entity_first_own_bundle_up user_view_other'] = [$entity_first_own_bundle_up->reveal(), 'view', $user_view_other->reveal(), FALSE];
- $data['entity_second_other_up user_view_other'] = [$entity_second_other_up->reveal(), 'view', $user_view_other->reveal(), FALSE];
- $data['entity_second_own_up user_view_other'] = [$entity_second_own_up->reveal(), 'view', $user_view_other->reveal(), FALSE];
- $data['entity_second_own_bundle_up user_view_other'] = [$entity_second_own_bundle_up->reveal(), 'view', $user_view_other->reveal(), FALSE];
-
- return $data;
- }
-
- /**
- * Data provider for testCreateAccess().
- *
- * @return array
- * A list of testCreateAccess method arguments.
- */
- public function createAccessProvider() {
- $data = [];
-
- $entity_type = $this->prophesize(ContentEntityTypeInterface::class);
- $entity_type->id()->willReturn('green_entity');
- $entity_type->getAdminPermission()->willReturn('administer green_entity');
- $entity_type->hasHandlerClass('permission_provider')->willReturn(TRUE);
- $entity_type->getHandlerClass('permission_provider')->willReturn(UncacheableEntityPermissionProvider::class);
-
- // User with the admin permission.
- $account = $this->prophesize(AccountInterface::class);
- $account->id()->willReturn(6);
- $account->hasPermission('administer green_entity')->willReturn(TRUE);
- $data[] = [$entity_type->reveal(), NULL, $account->reveal(), TRUE];
-
- // Ordinary user.
- $account = $this->prophesize(AccountInterface::class);
- $account->id()->willReturn(6);
- $account->hasPermission('create green_entity')->willReturn(TRUE);
- $account->hasPermission(Argument::any())->willReturn(FALSE);
- $data[] = [$entity_type->reveal(), NULL, $account->reveal(), TRUE];
-
- // Ordinary user, entity with a bundle.
- $account = $this->prophesize(AccountInterface::class);
- $account->id()->willReturn(6);
- $account->hasPermission('create first_bundle green_entity')->willReturn(TRUE);
- $account->hasPermission(Argument::any())->willReturn(FALSE);
- $data[] = [$entity_type->reveal(), 'first_bundle', $account->reveal(), TRUE];
-
- // User with no permissions.
- $account = $this->prophesize(AccountInterface::class);
- $account->id()->willReturn(6);
- $account->hasPermission(Argument::any())->willReturn(FALSE);
- $data[] = [$entity_type->reveal(), NULL, $account->reveal(), FALSE];
-
- return $data;
- }
-
- /**
- * Builds a mock entity.
- *
- * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
- * The entity type.
- * @param string $owner_id
- * The owner ID.
- *
- * @return \Prophecy\Prophecy\ObjectProphecy
- * The entity mock.
- */
- protected function buildMockEntity(EntityTypeInterface $entity_type, $owner_id = NULL, $bundle = NULL, $published = NULL) {
- $langcode = LanguageInterface::LANGCODE_NOT_SPECIFIED;
- $entity = $this->prophesize(ContentEntityInterface::class);
- if (isset($published)) {
- $entity->willImplement(EntityPublishedInterface::class);
- }
- if ($owner_id) {
- $entity->willImplement(EntityOwnerInterface::class);
- }
- if (isset($published)) {
- $entity->isPublished()->willReturn($published);
- }
- if ($owner_id) {
- $entity->getOwnerId()->willReturn($owner_id);
- }
-
- $entity->bundle()->willReturn($bundle ?: $entity_type->id());
- $entity->isNew()->willReturn(FALSE);
- $entity->uuid()->willReturn('fake uuid');
- $entity->id()->willReturn('fake id');
- $entity->getRevisionId()->willReturn(NULL);
- $entity->language()->willReturn(new Language(['id' => $langcode]));
- $entity->getEntityTypeId()->willReturn($entity_type->id());
- $entity->getEntityType()->willReturn($entity_type);
- $entity->getCacheContexts()->willReturn([]);
- $entity->getCacheTags()->willReturn([]);
- $entity->getCacheMaxAge()->willReturn(Cache::PERMANENT);
-
-
- return $entity;
- }
-
- protected function buildMockUser($uid, $permission) {
- $account = $this->prophesize(AccountInterface::class);
- $account->id()->willReturn($uid);
- $account->hasPermission($permission)->willReturn(TRUE);
- $account->hasPermission(Argument::any())->willReturn(FALSE);
- return $account;
- }
-
-}
diff --git a/web/modules/contrib/entity/tests/src/Unit/UncacheableEntityPermissionProviderTest.php b/web/modules/contrib/entity/tests/src/Unit/UncacheableEntityPermissionProviderTest.php
deleted file mode 100644
index afaab7ce2..000000000
--- a/web/modules/contrib/entity/tests/src/Unit/UncacheableEntityPermissionProviderTest.php
+++ /dev/null
@@ -1,186 +0,0 @@
-prophesize(EntityTypeBundleInfoInterface::class);
- $entity_type_bundle_info->getBundleInfo('white_entity')->willReturn([
- 'first' => ['label' => 'First'],
- 'second' => ['label' => 'Second'],
- ]);
- $entity_type_bundle_info->getBundleInfo('black_entity')->willReturn([
- 'third' => ['label' => 'Third'],
- ]);
- $entity_type_bundle_info->getBundleInfo('pink_entity')->willReturn([
- 'third' => ['label' => 'Third'],
- ]);
- $this->permissionProvider = new UncacheableEntityPermissionProvider($entity_type_bundle_info->reveal());
- $this->permissionProvider->setStringTranslation($this->getStringTranslationStub());
- }
-
- /**
- * @covers ::buildPermissions
- *
- * @dataProvider entityTypeProvider
- */
- public function testBuildPermissions(EntityTypeInterface $entity_type, array $expected_permissions) {
- $permissions = $this->permissionProvider->buildPermissions($entity_type);
- $this->assertEquals(array_keys($expected_permissions), array_keys($permissions));
- foreach ($permissions as $name => $permission) {
- $this->assertEquals('entity_module_test', $permission['provider']);
- $this->assertEquals($expected_permissions[$name], $permission['title']);
- }
- }
-
- /**
- * Data provider for testBuildPermissions().
- *
- * @return array
- * A list of testBuildPermissions method arguments.
- */
- public function entityTypeProvider() {
- $data = [];
- // Content entity type.
- $entity_type = $this->prophesize(ContentEntityTypeInterface::class);
- $entity_type->getProvider()->willReturn('entity_module_test');
- $entity_type->id()->willReturn('green_entity');
- $entity_type->getSingularLabel()->willReturn('green entity');
- $entity_type->getPluralLabel()->willReturn('green entities');
- $entity_type->entityClassImplements(EntityOwnerInterface::class)->willReturn(FALSE);
- $entity_type->entityClassImplements(EntityPublishedInterface::class)->willReturn(FALSE);
- $entity_type->getPermissionGranularity()->willReturn('entity_type');
- $expected_permissions = [
- 'administer green_entity' => 'Administer green entities',
- 'access green_entity overview' => 'Access the green entities overview page',
- 'create green_entity' => 'Create green entities',
- 'update green_entity' => 'Update green entities',
- 'delete green_entity' => 'Delete green entities',
- 'view any green_entity' => 'View any green entities',
- ];
- $data[] = [$entity_type->reveal(), $expected_permissions];
-
- // Content entity type with owner.
- $entity_type = $this->prophesize(ContentEntityTypeInterface::class);
- $entity_type->getProvider()->willReturn('entity_module_test');
- $entity_type->id()->willReturn('blue_entity');
- $entity_type->getSingularLabel()->willReturn('blue entity');
- $entity_type->getPluralLabel()->willReturn('blue entities');
- $entity_type->entityClassImplements(EntityOwnerInterface::class)->willReturn(TRUE);
- $entity_type->entityClassImplements(EntityPublishedInterface::class)->willReturn(FALSE);
- $entity_type->getPermissionGranularity()->willReturn('entity_type');
- $expected_permissions = [
- 'administer blue_entity' => 'Administer blue entities',
- 'access blue_entity overview' => 'Access the blue entities overview page',
- 'create blue_entity' => 'Create blue entities',
- 'update any blue_entity' => 'Update any blue entity',
- 'update own blue_entity' => 'Update own blue entities',
- 'delete any blue_entity' => 'Delete any blue entity',
- 'delete own blue_entity' => 'Delete own blue entities',
- 'view any blue_entity' => 'View any blue entities',
- 'view own blue_entity' => 'View own blue entities',
- ];
- $data[] = [$entity_type->reveal(), $expected_permissions];
-
- // Content entity type with bundles.
- $entity_type = $this->prophesize(ContentEntityTypeInterface::class);
- $entity_type->getProvider()->willReturn('entity_module_test');
- $entity_type->id()->willReturn('white_entity');
- $entity_type->getSingularLabel()->willReturn('white entity');
- $entity_type->getPluralLabel()->willReturn('white entities');
- $entity_type->entityClassImplements(EntityOwnerInterface::class)->willReturn(FALSE);
- $entity_type->entityClassImplements(EntityPublishedInterface::class)->willReturn(FALSE);
- $entity_type->getPermissionGranularity()->willReturn('bundle');
- $expected_permissions = [
- 'administer white_entity' => 'Administer white entities',
- 'access white_entity overview' => 'Access the white entities overview page',
- 'create first white_entity' => 'First: Create white entities',
- 'update first white_entity' => 'First: Update white entities',
- 'delete first white_entity' => 'First: Delete white entities',
- 'create second white_entity' => 'Second: Create white entities',
- 'update second white_entity' => 'Second: Update white entities',
- 'delete second white_entity' => 'Second: Delete white entities',
- 'view any white_entity' => 'View any white entities',
- 'view any first white_entity' => 'First: View any white entities',
- 'view any second white_entity' => 'Second: View any white entities',
- ];
- $data[] = [$entity_type->reveal(), $expected_permissions];
-
- // Content entity type with bundles and owner.
- $entity_type = $this->prophesize(ContentEntityTypeInterface::class);
- $entity_type->getProvider()->willReturn('entity_module_test');
- $entity_type->id()->willReturn('black_entity');
- $entity_type->getSingularLabel()->willReturn('black entity');
- $entity_type->getPluralLabel()->willReturn('black entities');
- $entity_type->entityClassImplements(EntityOwnerInterface::class)->willReturn(TRUE);
- $entity_type->entityClassImplements(EntityPublishedInterface::class)->willReturn(FALSE);
- $entity_type->getPermissionGranularity()->willReturn('bundle');
- $expected_permissions = [
- 'administer black_entity' => 'Administer black entities',
- 'access black_entity overview' => 'Access the black entities overview page',
- 'create third black_entity' => 'Third: Create black entities',
- 'update any third black_entity' => 'Third: Update any black entity',
- 'update own third black_entity' => 'Third: Update own black entities',
- 'delete any third black_entity' => 'Third: Delete any black entity',
- 'delete own third black_entity' => 'Third: Delete own black entities',
- 'view any black_entity' => 'View any black entities',
- 'view own black_entity' => 'View own black entities',
- 'view any third black_entity' => 'Third: View any black entities',
- 'view own third black_entity' => 'Third: View own black entities',
- ];
- $data[] = [$entity_type->reveal(), $expected_permissions];
-
- // Content entity type with bundles and owner and entity published.
- $entity_type = $this->prophesize(ContentEntityTypeInterface::class);
- $entity_type->getProvider()->willReturn('entity_module_test');
- $entity_type->id()->willReturn('pink_entity');
- $entity_type->getSingularLabel()->willReturn('pink entity');
- $entity_type->getPluralLabel()->willReturn('pink entities');
- $entity_type->entityClassImplements(EntityOwnerInterface::class)->willReturn(TRUE);
- $entity_type->entityClassImplements(EntityPublishedInterface::class)->willReturn(TRUE);
- $entity_type->getPermissionGranularity()->willReturn('bundle');
- $expected_permissions = [
- 'administer pink_entity' => 'Administer pink entities',
- 'access pink_entity overview' => 'Access the pink entities overview page',
- 'view own unpublished pink_entity' => 'View own unpublished pink entities',
- 'create third pink_entity' => 'Third: Create pink entities',
- 'update any third pink_entity' => 'Third: Update any pink entity',
- 'update own third pink_entity' => 'Third: Update own pink entities',
- 'delete any third pink_entity' => 'Third: Delete any pink entity',
- 'delete own third pink_entity' => 'Third: Delete own pink entities',
- 'view any pink_entity' => 'View any pink entities',
- 'view own pink_entity' => 'View own pink entities',
- 'view any third pink_entity' => 'Third: View any pink entities',
- 'view own third pink_entity' => 'Third: View own pink entities',
- ];
- $data[] = [$entity_type->reveal(), $expected_permissions];
-
- return $data;
- }
-
-}
diff --git a/web/modules/contrib/entity_browser/config/schema/entity_browser.schema.yml b/web/modules/contrib/entity_browser/config/schema/entity_browser.schema.yml
index 741679929..cf2c9ec95 100644
--- a/web/modules/contrib/entity_browser/config/schema/entity_browser.schema.yml
+++ b/web/modules/contrib/entity_browser/config/schema/entity_browser.schema.yml
@@ -169,6 +169,9 @@ field.widget.settings.entity_browser_entity_reference:
field_widget_remove:
type: boolean
label: 'Field widget remove'
+ field_widget_replace:
+ type: boolean
+ label: 'Field widget replace'
open:
type: boolean
label: 'Open'
@@ -211,6 +214,9 @@ field.widget.settings.entity_browser_file:
field_widget_remove:
type: boolean
label: 'Field widget remove'
+ field_widget_replace:
+ type: boolean
+ label: 'Field widget replace'
open:
type: boolean
label: 'Open'
diff --git a/web/modules/contrib/entity_browser/entity_browser.info.yml b/web/modules/contrib/entity_browser/entity_browser.info.yml
index 5b6653b66..a2f8d429b 100644
--- a/web/modules/contrib/entity_browser/entity_browser.info.yml
+++ b/web/modules/contrib/entity_browser/entity_browser.info.yml
@@ -11,8 +11,8 @@ test_dependencies:
- paragraphs:paragraphs
configure: entity.entity_browser.collection
-# Information added by Drupal.org packaging script on 2017-11-30
-version: '8.x-1.4'
+# Information added by Drupal.org packaging script on 2018-09-07
+version: '8.x-1.6'
core: '8.x'
project: 'entity_browser'
-datestamp: 1512033788
+datestamp: 1536328688
diff --git a/web/modules/contrib/entity_browser/entity_browser.views.inc b/web/modules/contrib/entity_browser/entity_browser.views.inc
index 934fde06a..b2bb86de3 100644
--- a/web/modules/contrib/entity_browser/entity_browser.views.inc
+++ b/web/modules/contrib/entity_browser/entity_browser.views.inc
@@ -22,4 +22,19 @@ function entity_browser_views_data_alter(&$data) {
];
}
}
+ if (\Drupal::moduleHandler()->moduleExists('search_api')) {
+ /** @var \Drupal\search_api\IndexInterface $index */
+ foreach (\Drupal\search_api\Entity\Index::loadMultiple() as $index) {
+ $key = 'search_api_index_' . $index->id();
+ $data[$key]['entity_browser_select'] = [
+ 'title' => t('Entity browser bulk select form for Search API views'),
+ 'help' => t('Add a form element that lets you use a view as a base to select entities in entity browser.'),
+ 'field' => [
+ 'id' => 'entity_browser_search_api_select',
+ 'real field' => 'id',
+ ],
+ ];
+ }
+ }
+
}
diff --git a/web/modules/contrib/entity_browser/js/entity_browser.entity_reference.js b/web/modules/contrib/entity_browser/js/entity_browser.entity_reference.js
index 882799afb..9034de6ad 100644
--- a/web/modules/contrib/entity_browser/js/entity_browser.entity_reference.js
+++ b/web/modules/contrib/entity_browser/js/entity_browser.entity_reference.js
@@ -19,6 +19,21 @@
stop: Drupal.entityBrowserEntityReference.entitiesReordered
});
});
+ // The AJAX callback will give us a flag when we need to re-open the
+ // browser, most likely due to a "Replace" button being clicked.
+ if (typeof drupalSettings.entity_browser_reopen_browser !== 'undefined' && drupalSettings.entity_browser_reopen_browser) {
+ var data_drupal_selector = '[data-drupal-selector^="edit-' + drupalSettings.entity_browser_reopen_browser.replace(/_/g, '-') + '-entity-browser-entity-browser-' + '"]';
+ var $launch_browser_element = $(context).find(data_drupal_selector);
+ if (!drupalSettings.entity_browser.iframe[$launch_browser_element.attr('data-uuid')].auto_open) {
+ $launch_browser_element.click();
+ }
+ // In case this is inside a fieldset closed by default, open it so the
+ // user doesn't need to guess the browser is open but hidden there.
+ var $fieldset_summary = $launch_browser_element.closest('details').find('summary');
+ if ($fieldset_summary.length && $fieldset_summary.attr('aria-expanded') === 'false') {
+ $fieldset_summary.click();
+ }
+ }
}
};
diff --git a/web/modules/contrib/entity_browser/modules/entity_form/entity_browser_entity_form.info.yml b/web/modules/contrib/entity_browser/modules/entity_form/entity_browser_entity_form.info.yml
index 3cf4ba739..10500a3aa 100644
--- a/web/modules/contrib/entity_browser/modules/entity_form/entity_browser_entity_form.info.yml
+++ b/web/modules/contrib/entity_browser/modules/entity_form/entity_browser_entity_form.info.yml
@@ -7,8 +7,8 @@ dependencies:
- entity_browser:entity_browser
- inline_entity_form:inline_entity_form
-# Information added by Drupal.org packaging script on 2017-11-30
-version: '8.x-1.4'
+# Information added by Drupal.org packaging script on 2018-09-07
+version: '8.x-1.6'
core: '8.x'
project: 'entity_browser'
-datestamp: 1512033788
+datestamp: 1536328688
diff --git a/web/modules/contrib/entity_browser/modules/entity_form/src/Plugin/EntityBrowser/Widget/EntityForm.php b/web/modules/contrib/entity_browser/modules/entity_form/src/Plugin/EntityBrowser/Widget/EntityForm.php
index 6ecfa7561..7901925a2 100644
--- a/web/modules/contrib/entity_browser/modules/entity_form/src/Plugin/EntityBrowser/Widget/EntityForm.php
+++ b/web/modules/contrib/entity_browser/modules/entity_form/src/Plugin/EntityBrowser/Widget/EntityForm.php
@@ -239,4 +239,13 @@ class EntityForm extends WidgetBase {
$this->configuration['form_mode'] = $this->configuration['form_mode']['form_select'];
}
+ /**
+ * {@inheritdoc}
+ */
+ public function access() {
+ return $this->entityTypeManager
+ ->getAccessControlHandler($this->configuration['entity_type'])
+ ->createAccess($this->configuration['bundle'], NULL, [], TRUE);
+ }
+
}
diff --git a/web/modules/contrib/entity_browser/modules/entity_form/tests/modules/entity_browser_entity_form_test/entity_browser_entity_form_test.info.yml b/web/modules/contrib/entity_browser/modules/entity_form/tests/modules/entity_browser_entity_form_test/entity_browser_entity_form_test.info.yml
index b8919bf9f..13f683a81 100644
--- a/web/modules/contrib/entity_browser/modules/entity_form/tests/modules/entity_browser_entity_form_test/entity_browser_entity_form_test.info.yml
+++ b/web/modules/contrib/entity_browser/modules/entity_form/tests/modules/entity_browser_entity_form_test/entity_browser_entity_form_test.info.yml
@@ -8,8 +8,8 @@ dependencies:
- entity_browser_entity_form
- views
-# Information added by Drupal.org packaging script on 2017-11-30
-version: '8.x-1.4'
+# Information added by Drupal.org packaging script on 2018-09-07
+version: '8.x-1.6'
core: '8.x'
project: 'entity_browser'
-datestamp: 1512033788
+datestamp: 1536328688
diff --git a/web/modules/contrib/entity_browser/modules/entity_form/tests/src/FunctionalJavascript/EntityFormWidgetTest.php b/web/modules/contrib/entity_browser/modules/entity_form/tests/src/FunctionalJavascript/EntityFormWidgetTest.php
index aef8ebb34..75913914f 100644
--- a/web/modules/contrib/entity_browser/modules/entity_form/tests/src/FunctionalJavascript/EntityFormWidgetTest.php
+++ b/web/modules/contrib/entity_browser/modules/entity_form/tests/src/FunctionalJavascript/EntityFormWidgetTest.php
@@ -75,6 +75,7 @@ class EntityFormWidgetTest extends JavascriptTestBase {
$account = $this->drupalCreateUser([
'access entity_browser_test_entity_form entity browser pages',
'create foo content',
+ 'create article content',
'access content',
]);
$this->drupalLogin($account);
@@ -148,6 +149,16 @@ class EntityFormWidgetTest extends JavascriptTestBase {
$parent_node = current($parent_node);
$this->assertEquals(1, $parent_node->get('field_reference')->count(), 'There is one child node.');
$this->assertEquals('War is peace', $parent_node->field_reference->entity->label(), 'Child node has correct title.');
+
+ // Make sure entity create access is respected.
+ $account = $this->drupalCreateUser([
+ 'access entity_browser_test_entity_form entity browser pages',
+ 'create foo content',
+ 'access content',
+ ]);
+ $this->drupalLogin($account);
+ $this->drupalGet('entity-browser/iframe/entity_browser_test_entity_form');
+ $this->assertSession()->pageTextContains('No widgets are available.');
}
}
diff --git a/web/modules/contrib/entity_browser/modules/example/config/install/core.entity_form_display.node.entity_browser_test.default.yml b/web/modules/contrib/entity_browser/modules/example/config/install/core.entity_form_display.node.entity_browser_test.default.yml
index de7d83cbc..0bf7b37fd 100644
--- a/web/modules/contrib/entity_browser/modules/example/config/install/core.entity_form_display.node.entity_browser_test.default.yml
+++ b/web/modules/contrib/entity_browser/modules/example/config/install/core.entity_form_display.node.entity_browser_test.default.yml
@@ -44,6 +44,7 @@ content:
open: false
field_widget_edit: true
field_widget_remove: true
+ field_widget_replace: false
third_party_settings: { }
field_files1:
type: entity_browser_entity_reference
@@ -55,6 +56,7 @@ content:
open: false
field_widget_edit: true
field_widget_remove: true
+ field_widget_replace: false
third_party_settings: { }
field_files_over_ajax:
weight: 36
@@ -63,6 +65,7 @@ content:
field_widget_display: label
field_widget_edit: true
field_widget_remove: true
+ field_widget_replace: false
selection_mode: selection_edit
open: false
field_widget_display_settings: { }
@@ -74,6 +77,7 @@ content:
entity_browser: test_files
field_widget_edit: true
field_widget_remove: true
+ field_widget_replace: false
open: false
third_party_settings: { }
type: entity_browser_file
@@ -87,6 +91,7 @@ content:
open: false
field_widget_edit: true
field_widget_remove: true
+ field_widget_replace: false
third_party_settings: { }
path:
type: path
diff --git a/web/modules/contrib/entity_browser/modules/example/entity_browser_example.info.yml b/web/modules/contrib/entity_browser/modules/example/entity_browser_example.info.yml
index efc31b4f5..019ee6d19 100644
--- a/web/modules/contrib/entity_browser/modules/example/entity_browser_example.info.yml
+++ b/web/modules/contrib/entity_browser/modules/example/entity_browser_example.info.yml
@@ -11,8 +11,8 @@ dependencies:
- drupal:node
- drupal:image
-# Information added by Drupal.org packaging script on 2017-11-30
-version: '8.x-1.4'
+# Information added by Drupal.org packaging script on 2018-09-07
+version: '8.x-1.6'
core: '8.x'
project: 'entity_browser'
-datestamp: 1512033788
+datestamp: 1536328688
diff --git a/web/modules/contrib/entity_browser/src/Controllers/EntityBrowserController.php b/web/modules/contrib/entity_browser/src/Controllers/EntityBrowserController.php
index aebb4be80..c3788809d 100644
--- a/web/modules/contrib/entity_browser/src/Controllers/EntityBrowserController.php
+++ b/web/modules/contrib/entity_browser/src/Controllers/EntityBrowserController.php
@@ -29,8 +29,16 @@ class EntityBrowserController extends ControllerBase {
* containing the edit form.
*/
public function entityBrowserEdit(EntityInterface $entity, Request $request) {
+
+ // Use edit form class if it exists, otherwise use default form class.
+ $operation = 'default';
+ $entity_type = $entity->getEntityType();
+ if ($entity_type->getFormClass('edit')) {
+ $operation = 'edit';
+ }
+
// Build the entity edit form.
- $form_object = $this->entityTypeManager()->getFormObject($entity->getEntityTypeId(), 'edit');
+ $form_object = $this->entityTypeManager()->getFormObject($entity->getEntityTypeId(), $operation);
$form_object->setEntity($entity);
$form_state = (new FormState())
->setFormObject($form_object)
diff --git a/web/modules/contrib/entity_browser/src/Entity/EntityBrowser.php b/web/modules/contrib/entity_browser/src/Entity/EntityBrowser.php
index 53bc9f2af..be75e6c2d 100644
--- a/web/modules/contrib/entity_browser/src/Entity/EntityBrowser.php
+++ b/web/modules/contrib/entity_browser/src/Entity/EntityBrowser.php
@@ -303,6 +303,14 @@ class EntityBrowser extends ConfigEntityBase implements EntityBrowserInterface,
*/
public function getFirstWidget() {
$instance_ids = $this->getWidgets()->getInstanceIds();
+ $instance_ids = array_filter($instance_ids, function ($id) {
+ return $this->getWidget($id)->access()->isAllowed();
+ });
+
+ if (empty($instance_ids)) {
+ return NULL;
+ }
+
return reset($instance_ids);
}
diff --git a/web/modules/contrib/entity_browser/src/EntityBrowserFormInterface.php b/web/modules/contrib/entity_browser/src/EntityBrowserFormInterface.php
index 335fe96ab..d274b6ec1 100644
--- a/web/modules/contrib/entity_browser/src/EntityBrowserFormInterface.php
+++ b/web/modules/contrib/entity_browser/src/EntityBrowserFormInterface.php
@@ -17,4 +17,12 @@ interface EntityBrowserFormInterface extends FormInterface {
*/
public function setEntityBrowser(EntityBrowserInterface $entity_browser);
+ /**
+ * Gets entity browser entity,
+ *
+ * @return \Drupal\entity_browser\EntityBrowserInterface
+ * Entity browser entity.
+ */
+ public function getEntityBrowser();
+
}
diff --git a/web/modules/contrib/entity_browser/src/EntityBrowserInterface.php b/web/modules/contrib/entity_browser/src/EntityBrowserInterface.php
index cfad3254a..09a5e8673 100644
--- a/web/modules/contrib/entity_browser/src/EntityBrowserInterface.php
+++ b/web/modules/contrib/entity_browser/src/EntityBrowserInterface.php
@@ -123,8 +123,8 @@ interface EntityBrowserInterface extends ConfigEntityInterface {
/**
* Gets first widget based on weights.
*
- * @return string
- * First widget instance ID.
+ * @return string|null
+ * First widget instance ID or NULL if no widgets are available.
*/
public function getFirstWidget();
diff --git a/web/modules/contrib/entity_browser/src/Form/EntityBrowserForm.php b/web/modules/contrib/entity_browser/src/Form/EntityBrowserForm.php
index 340e425fd..bcecac1be 100644
--- a/web/modules/contrib/entity_browser/src/Form/EntityBrowserForm.php
+++ b/web/modules/contrib/entity_browser/src/Form/EntityBrowserForm.php
@@ -11,6 +11,7 @@ use Drupal\entity_browser\DisplayAjaxInterface;
use Drupal\entity_browser\EntityBrowserFormInterface;
use Drupal\entity_browser\EntityBrowserInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
+use Drupal\Core\Render\RendererInterface;
/**
* The entity browser form.
@@ -38,6 +39,13 @@ class EntityBrowserForm extends FormBase implements EntityBrowserFormInterface {
*/
protected $selectionStorage;
+ /**
+ * The renderer service.
+ *
+ * @var \Drupal\Core\Render\RendererInterface
+ */
+ protected $renderer;
+
/**
* Constructs a EntityBrowserForm object.
*
@@ -45,10 +53,13 @@ class EntityBrowserForm extends FormBase implements EntityBrowserFormInterface {
* The UUID generator service.
* @param \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface $selection_storage
* Selection storage.
+ * @param \Drupal\Core\Render\RendererInterface $renderer
+ * The renderer service.
*/
- public function __construct(UuidInterface $uuid_generator, KeyValueStoreExpirableInterface $selection_storage) {
+ public function __construct(UuidInterface $uuid_generator, KeyValueStoreExpirableInterface $selection_storage, RendererInterface $renderer) {
$this->uuidGenerator = $uuid_generator;
$this->selectionStorage = $selection_storage;
+ $this->renderer = $renderer;
}
/**
@@ -57,7 +68,8 @@ class EntityBrowserForm extends FormBase implements EntityBrowserFormInterface {
public static function create(ContainerInterface $container) {
return new static(
$container->get('uuid'),
- $container->get('entity_browser.selection_storage')
+ $container->get('entity_browser.selection_storage'),
+ $container->get('renderer')
);
}
@@ -75,6 +87,13 @@ class EntityBrowserForm extends FormBase implements EntityBrowserFormInterface {
$this->entityBrowser = $entity_browser;
}
+ /**
+ * {@inheritdoc}
+ */
+ public function getEntityBrowser() {
+ return $this->entityBrowser;
+ }
+
/**
* Initializes form state.
*
@@ -124,16 +143,33 @@ class EntityBrowserForm extends FormBase implements EntityBrowserFormInterface {
'widget' => 'widget',
'selection_display' => 'selection_display',
];
+
+ if (!($current_widget_id = $this->getCurrentWidget($form_state))) {
+ drupal_set_message($this->t('No widgets are available.'), 'warning');
+ return $form;
+ }
+
$this->entityBrowser
->getWidgetSelector()
- ->setDefaultWidget($this->getCurrentWidget($form_state));
+ ->setDefaultWidget($current_widget_id);
$form[$form['#browser_parts']['widget_selector']] = $this->entityBrowser
->getWidgetSelector()
->getForm($form, $form_state);
- $form[$form['#browser_parts']['widget']] = $this->entityBrowser
- ->getWidgets()
- ->get($this->getCurrentWidget($form_state))
- ->getForm($form, $form_state, $this->entityBrowser->getAdditionalWidgetParameters());
+
+ $widget = $this->entityBrowser->getWidget($current_widget_id);
+ if ($widget->access()->isAllowed()) {
+ $form[$form['#browser_parts']['widget']] = $widget->getForm($form, $form_state, $this->entityBrowser->getAdditionalWidgetParameters());
+ }
+ else {
+ drupal_set_message($this->t('Access to the widget forbidden.'), 'warning');
+ }
+
+ // Add cache access cache metadata from the widgets to the form directly as
+ // it is affected.
+ foreach ($this->entityBrowser->getWidgets() as $widget) {
+ /** @var \Drupal\entity_browser\WidgetInterface $widget */
+ $this->renderer->addCacheableDependency($form, $widget->access());
+ }
$form[$form['#browser_parts']['selection_display']] = $this->entityBrowser
->getSelectionDisplay()
diff --git a/web/modules/contrib/entity_browser/src/Plugin/EntityBrowser/Widget/View.php b/web/modules/contrib/entity_browser/src/Plugin/EntityBrowser/Widget/View.php
index f0aaa19e3..111f9b777 100644
--- a/web/modules/contrib/entity_browser/src/Plugin/EntityBrowser/Widget/View.php
+++ b/web/modules/contrib/entity_browser/src/Plugin/EntityBrowser/Widget/View.php
@@ -3,6 +3,7 @@
namespace Drupal\entity_browser\Plugin\EntityBrowser\Widget;
use Drupal\Component\Plugin\Exception\PluginNotFoundException;
+use Drupal\Core\Access\AccessResult;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element;
use Drupal\entity_browser\WidgetBase;
@@ -135,7 +136,7 @@ class View extends WidgetBase implements ContainerFactoryPluginInterface {
// When rebuilding makes no sense to keep checkboxes that were previously
// selected.
- if (!empty($form['view']['entity_browser_select']) && $form_state->isRebuilding()) {
+ if (!empty($form['view']['entity_browser_select'])) {
foreach (Element::children($form['view']['entity_browser_select']) as $child) {
$form['view']['entity_browser_select'][$child]['#process'][] = ['\Drupal\entity_browser\Plugin\EntityBrowser\Widget\View', 'processCheckbox'];
$form['view']['entity_browser_select'][$child]['#process'][] = ['\Drupal\Core\Render\Element\Checkbox', 'processAjaxForm'];
@@ -158,7 +159,10 @@ class View extends WidgetBase implements ContainerFactoryPluginInterface {
* @see \Drupal\Core\Render\Element\Checkbox::processCheckbox()
*/
public static function processCheckbox(&$element, FormStateInterface $form_state, &$complete_form) {
- $element['#checked'] = FALSE;
+ if ($form_state->isRebuilding()) {
+ $element['#checked'] = FALSE;
+ }
+
return $element;
}
@@ -279,4 +283,20 @@ class View extends WidgetBase implements ContainerFactoryPluginInterface {
return $dependencies;
}
+ /**
+ * {@inheritdoc}
+ */
+ public function access() {
+ // Mark the widget as not visible if the user has no access to the view.
+ /** @var \Drupal\views\ViewExecutable $view */
+ $view = $this->entityTypeManager
+ ->getStorage('view')
+ ->load($this->configuration['view'])
+ ->getExecutable();
+
+
+ // Check if the current user has access to this view.
+ return AccessResult::allowedIf($view->access($this->configuration['view_display']));
+ }
+
}
diff --git a/web/modules/contrib/entity_browser/src/Plugin/EntityBrowser/WidgetSelector/DropDown.php b/web/modules/contrib/entity_browser/src/Plugin/EntityBrowser/WidgetSelector/DropDown.php
index d5d32d518..ef3315a58 100644
--- a/web/modules/contrib/entity_browser/src/Plugin/EntityBrowser/WidgetSelector/DropDown.php
+++ b/web/modules/contrib/entity_browser/src/Plugin/EntityBrowser/WidgetSelector/DropDown.php
@@ -24,9 +24,19 @@ class DropDown extends WidgetSelectorBase {
$form['#prefix'] = '
';
$form['#suffix'] = '
';
+ /** @var \Drupal\entity_browser\EntityBrowserInterface $browser */
+ $browser = $form_state->getFormObject()->getEntityBrowser();
+
+ $widget_ids = [];
+ foreach ($this->widget_ids as $widget_id => $widget_name) {
+ if ($browser->getWidget($widget_id)->access()->isAllowed()) {
+ $widget_ids[$widget_id] = $widget_name;
+ }
+ }
+
$element['widget'] = [
'#type' => 'select',
- '#options' => $this->widget_ids,
+ '#options' => $widget_ids,
'#default_value' => $this->getDefaultWidget(),
'#executes_submit_callback' => TRUE,
'#limit_validation_errors' => [['widget']],
diff --git a/web/modules/contrib/entity_browser/src/Plugin/EntityBrowser/WidgetSelector/Tabs.php b/web/modules/contrib/entity_browser/src/Plugin/EntityBrowser/WidgetSelector/Tabs.php
index e6d511d44..0128b2907 100644
--- a/web/modules/contrib/entity_browser/src/Plugin/EntityBrowser/WidgetSelector/Tabs.php
+++ b/web/modules/contrib/entity_browser/src/Plugin/EntityBrowser/WidgetSelector/Tabs.php
@@ -21,6 +21,8 @@ class Tabs extends WidgetSelectorBase {
*/
public function getForm(array &$form = [], FormStateInterface &$form_state = NULL) {
$element = [];
+ /** @var \Drupal\entity_browser\EntityBrowserInterface $browser */
+ $browser = $form_state->getFormObject()->getEntityBrowser();
foreach ($this->widget_ids as $id => $label) {
$name = 'tab_selector_' . $id;
$element[$name] = [
@@ -34,6 +36,7 @@ class Tabs extends WidgetSelectorBase {
'#submit' => [],
'#name' => $name,
'#widget_id' => $id,
+ '#access' => $browser->getWidget($id)->access(),
];
}
diff --git a/web/modules/contrib/entity_browser/src/Plugin/Field/FieldWidget/EntityReferenceBrowserWidget.php b/web/modules/contrib/entity_browser/src/Plugin/Field/FieldWidget/EntityReferenceBrowserWidget.php
index c2096b556..719869ca6 100644
--- a/web/modules/contrib/entity_browser/src/Plugin/Field/FieldWidget/EntityReferenceBrowserWidget.php
+++ b/web/modules/contrib/entity_browser/src/Plugin/Field/FieldWidget/EntityReferenceBrowserWidget.php
@@ -136,6 +136,7 @@ class EntityReferenceBrowserWidget extends WidgetBase implements ContainerFactor
'field_widget_display' => 'label',
'field_widget_edit' => TRUE,
'field_widget_remove' => TRUE,
+ 'field_widget_replace' => FALSE,
'field_widget_display_settings' => [],
'selection_mode' => EntityBrowserElement::SELECTION_MODE_APPEND,
] + parent::defaultSettings();
@@ -201,6 +202,13 @@ class EntityReferenceBrowserWidget extends WidgetBase implements ContainerFactor
'#default_value' => $this->getSetting('field_widget_remove'),
];
+ $element['field_widget_replace'] = [
+ '#title' => $this->t('Display Replace button'),
+ '#description' => $this->t('This button will only be displayed if there is a single entity in the current selection.'),
+ '#type' => 'checkbox',
+ '#default_value' => $this->getSetting('field_widget_replace'),
+ ];
+
$element['open'] = [
'#title' => $this->t('Show widget details as open by default'),
'#description' => $this->t('If marked, the fieldset container that wraps the browser on the entity form will be loaded initially expanded.'),
@@ -420,18 +428,29 @@ class EntityReferenceBrowserWidget extends WidgetBase implements ContainerFactor
*/
public static function updateWidgetCallback(array &$form, FormStateInterface $form_state) {
$trigger = $form_state->getTriggeringElement();
+ $reopen_browser = FALSE;
// AJAX requests can be triggered by hidden "target_id" element when
// entities are added or by one of the "Remove" buttons. Depending on that
// we need to figure out where root of the widget is in the form structure
// and use this information to return correct part of the form.
+ $parents = [];
if (!empty($trigger['#ajax']['event']) && $trigger['#ajax']['event'] == 'entity_browser_value_updated') {
$parents = array_slice($trigger['#array_parents'], 0, -1);
}
elseif ($trigger['#type'] == 'submit' && strpos($trigger['#name'], '_remove_')) {
$parents = array_slice($trigger['#array_parents'], 0, -static::$deleteDepth);
}
+ elseif ($trigger['#type'] == 'submit' && strpos($trigger['#name'], '_replace_')) {
+ $parents = array_slice($trigger['#array_parents'], 0, -static::$deleteDepth);
+ // We need to re-open the browser. Instead of just passing "TRUE", send
+ // to the JS the unique part of the button's name that needs to be clicked
+ // on to relaunch the browser.
+ $reopen_browser = implode("-", array_slice($trigger['#parents'], 0, -static::$deleteDepth));
+ }
- return NestedArray::getValue($form, $parents);
+ $parents = NestedArray::getValue($form, $parents);
+ $parents['#attached']['drupalSettings']['entity_browser_reopen_browser'] = $reopen_browser;
+ return $parents;
}
/**
@@ -504,11 +523,15 @@ class EntityReferenceBrowserWidget extends WidgetBase implements ContainerFactor
$classes[] = 'sortable';
}
+ // The "Replace" button will only be shown if this setting is enabled in the
+ // widget, and there is only one entity in the current selection.
+ $replace_button_access = $this->getSetting('field_widget_replace') && (count($entities) === 1);
+
return [
'#theme_wrappers' => ['container'],
'#attributes' => ['class' => $classes],
'items' => array_map(
- function (ContentEntityInterface $entity, $row_id) use ($field_widget_display, $details_id, $field_parents) {
+ function (ContentEntityInterface $entity, $row_id) use ($field_widget_display, $details_id, $field_parents, $replace_button_access) {
$display = $field_widget_display->view($entity);
$edit_button_access = $this->getSetting('field_widget_edit') && $entity->access('update', $this->currentUser);
if ($entity->getEntityTypeId() == 'file') {
@@ -541,9 +564,27 @@ class EntityReferenceBrowserWidget extends WidgetBase implements ContainerFactor
'#attributes' => [
'data-entity-id' => $entity->getEntityTypeId() . ':' . $entity->id(),
'data-row-id' => $row_id,
+ 'class' => ['remove-button'],
],
'#access' => (bool) $this->getSetting('field_widget_remove'),
],
+ 'replace_button' => [
+ '#type' => 'submit',
+ '#value' => $this->t('Replace'),
+ '#ajax' => [
+ 'callback' => [get_class($this), 'updateWidgetCallback'],
+ 'wrapper' => $details_id,
+ ],
+ '#submit' => [[get_class($this), 'removeItemSubmit']],
+ '#name' => $this->fieldDefinition->getName() . '_replace_' . $entity->id() . '_' . $row_id . '_' . md5(json_encode($field_parents)),
+ '#limit_validation_errors' => [array_merge($field_parents, [$this->fieldDefinition->getName()])],
+ '#attributes' => [
+ 'data-entity-id' => $entity->getEntityTypeId() . ':' . $entity->id(),
+ 'data-row-id' => $row_id,
+ 'class' => ['replace-button'],
+ ],
+ '#access' => $replace_button_access,
+ ],
'edit_button' => [
'#type' => 'submit',
'#value' => $this->t('Edit'),
@@ -560,6 +601,9 @@ class EntityReferenceBrowserWidget extends WidgetBase implements ContainerFactor
],
],
],
+ '#attributes' => [
+ 'class' => ['edit-button'],
+ ],
'#access' => $edit_button_access,
],
];
diff --git a/web/modules/contrib/entity_browser/src/Plugin/Field/FieldWidget/FileBrowserWidget.php b/web/modules/contrib/entity_browser/src/Plugin/Field/FieldWidget/FileBrowserWidget.php
index 6db9c8d47..d883f1569 100644
--- a/web/modules/contrib/entity_browser/src/Plugin/Field/FieldWidget/FileBrowserWidget.php
+++ b/web/modules/contrib/entity_browser/src/Plugin/Field/FieldWidget/FileBrowserWidget.php
@@ -239,7 +239,7 @@ class FileBrowserWidget extends EntityReferenceBrowserWidget {
// Add the remaining columns.
$current['#header'][] = $this->t('Metadata');
- $current['#header'][] = ['data' => $this->t('Operations'), 'colspan' => 2];
+ $current['#header'][] = ['data' => $this->t('Operations'), 'colspan' => 3];
$current['#header'][] = $this->t('Order', [], ['context' => 'Sort order']);
/** @var \Drupal\file\FileInterface[] $entities */
@@ -253,6 +253,10 @@ class FileBrowserWidget extends EntityReferenceBrowserWidget {
$edit_button_access = $can_edit && $entity->access('update', $this->currentUser);
}
+ // The "Replace" button will only be shown if this setting is enabled in
+ // the widget, and there is only one entity in the current selection.
+ $replace_button_access = $this->getSetting('field_widget_replace') && (count($entities) === 1);
+
$entity_id = $entity->id();
// Find the default description.
@@ -356,9 +360,27 @@ class FileBrowserWidget extends EntityReferenceBrowserWidget {
'#attributes' => [
'data-entity-id' => $entity->getEntityTypeId() . ':' . $entity->id(),
'data-row-id' => $delta,
+ 'class' => ['edit-button'],
],
'#access' => $edit_button_access,
],
+ 'replace_button' => [
+ '#type' => 'submit',
+ '#value' => $this->t('Replace'),
+ '#ajax' => [
+ 'callback' => [get_class($this), 'updateWidgetCallback'],
+ 'wrapper' => $details_id,
+ ],
+ '#submit' => [[get_class($this), 'removeItemSubmit']],
+ '#name' => $field_machine_name . '_replace_' . $entity_id . '_' . md5(json_encode($field_parents)),
+ '#limit_validation_errors' => [array_merge($field_parents, [$field_machine_name, 'target_id'])],
+ '#attributes' => [
+ 'data-entity-id' => $entity->getEntityTypeId() . ':' . $entity->id(),
+ 'data-row-id' => $delta,
+ 'class' => ['replace-button'],
+ ],
+ '#access' => $replace_button_access,
+ ],
'remove_button' => [
'#type' => 'submit',
'#value' => $this->t('Remove'),
@@ -372,6 +394,7 @@ class FileBrowserWidget extends EntityReferenceBrowserWidget {
'#attributes' => [
'data-entity-id' => $entity->getEntityTypeId() . ':' . $entity->id(),
'data-row-id' => $delta,
+ 'class' => ['remove-button'],
],
'#access' => (bool) $widget_settings['field_widget_remove'],
],
diff --git a/web/modules/contrib/entity_browser/src/Plugin/views/field/SearchApiSelectForm.php b/web/modules/contrib/entity_browser/src/Plugin/views/field/SearchApiSelectForm.php
new file mode 100644
index 000000000..a75ef1ee8
--- /dev/null
+++ b/web/modules/contrib/entity_browser/src/Plugin/views/field/SearchApiSelectForm.php
@@ -0,0 +1,22 @@
+_object->getValue();
+ return $entity->getEntityTypeId() . ':' . $entity->id();
+ }
+
+}
diff --git a/web/modules/contrib/entity_browser/src/Tests/ConfigUITest.php b/web/modules/contrib/entity_browser/src/Tests/ConfigUITest.php
index da58a79d6..335843941 100644
--- a/web/modules/contrib/entity_browser/src/Tests/ConfigUITest.php
+++ b/web/modules/contrib/entity_browser/src/Tests/ConfigUITest.php
@@ -55,7 +55,7 @@ class ConfigUITest extends WebTestBase {
$this->drupalLogin($this->adminUser);
$this->drupalGet('/admin/config/content/entity_browser');
$this->assertResponse(200, 'Admin user is able to navigate to the entity browser listing page.');
- $this->assertText('There is no Entity browser yet.', 'Entity browsers table is empty.');
+ $this->assertText('There are no entity browser entities yet.', 'Entity browsers table is empty.');
// Add page.
$this->clickLink('Add Entity browser');
@@ -275,7 +275,7 @@ class ConfigUITest extends WebTestBase {
$this->drupalPostForm(NULL, [], 'Delete Entity Browser');
$this->assertText('Entity browser Test entity browser was deleted.', 'Confirmation message found.');
- $this->assertText('There is no Entity browser yet.', 'Entity browsers table is empty.');
+ $this->assertText('There are no entity browser entities yet.', 'Entity browsers table is empty.');
$this->drupalLogout();
}
diff --git a/web/modules/contrib/entity_browser/src/WidgetBase.php b/web/modules/contrib/entity_browser/src/WidgetBase.php
index da094e4cf..f5d2ea7a8 100644
--- a/web/modules/contrib/entity_browser/src/WidgetBase.php
+++ b/web/modules/contrib/entity_browser/src/WidgetBase.php
@@ -3,6 +3,7 @@
namespace Drupal\entity_browser;
use Drupal\Component\Utility\NestedArray;
+use Drupal\Core\Access\AccessResult;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Plugin\PluginBase;
use Drupal\Core\Form\FormStateInterface;
@@ -372,4 +373,11 @@ abstract class WidgetBase extends PluginBase implements WidgetInterface, Contain
}
}
+ /**
+ * {@inheritdoc}
+ */
+ public function access() {
+ return AccessResult::allowed();
+ }
+
}
diff --git a/web/modules/contrib/entity_browser/src/WidgetInterface.php b/web/modules/contrib/entity_browser/src/WidgetInterface.php
index 0a1140f7a..c88f4b82d 100644
--- a/web/modules/contrib/entity_browser/src/WidgetInterface.php
+++ b/web/modules/contrib/entity_browser/src/WidgetInterface.php
@@ -118,4 +118,12 @@ interface WidgetInterface extends PluginInspectionInterface, ConfigurablePluginI
*/
public function requiresJsCommands();
+ /**
+ * Defines if the widget is visible / accessible in a given context.
+ *
+ * @return \Drupal\Core\Access\AccessResultInterface
+ * The access result.
+ */
+ public function access();
+
}
diff --git a/web/modules/contrib/entity_browser/tests/modules/entity_browser_ief_test/config/install/core.entity_form_display.media.ief_media_bundle.default.yml b/web/modules/contrib/entity_browser/tests/modules/entity_browser_ief_test/config/install/core.entity_form_display.media.ief_media_bundle.default.yml
index 6288723e9..f2ab14433 100644
--- a/web/modules/contrib/entity_browser/tests/modules/entity_browser_ief_test/config/install/core.entity_form_display.media.ief_media_bundle.default.yml
+++ b/web/modules/contrib/entity_browser/tests/modules/entity_browser_ief_test/config/install/core.entity_form_display.media.ief_media_bundle.default.yml
@@ -18,6 +18,7 @@ content:
field_widget_display: label
field_widget_edit: true
field_widget_remove: true
+ field_widget_replace: false
open: true
selection_mode: selection_edit
field_widget_display_settings: { }
diff --git a/web/modules/contrib/entity_browser/tests/modules/entity_browser_ief_test/entity_browser_ief_test.info.yml b/web/modules/contrib/entity_browser/tests/modules/entity_browser_ief_test/entity_browser_ief_test.info.yml
index e332fec4c..f6de948d3 100644
--- a/web/modules/contrib/entity_browser/tests/modules/entity_browser_ief_test/entity_browser_ief_test.info.yml
+++ b/web/modules/contrib/entity_browser/tests/modules/entity_browser_ief_test/entity_browser_ief_test.info.yml
@@ -12,8 +12,8 @@ dependencies:
- inline_entity_form
- views
-# Information added by Drupal.org packaging script on 2017-11-30
-version: '8.x-1.4'
+# Information added by Drupal.org packaging script on 2018-09-07
+version: '8.x-1.6'
core: '8.x'
project: 'entity_browser'
-datestamp: 1512033788
+datestamp: 1536328688
diff --git a/web/modules/contrib/entity_browser/tests/modules/entity_browser_test/config/install/entity_browser.browser.test_entity_browser_file.yml b/web/modules/contrib/entity_browser/tests/modules/entity_browser_test/config/install/entity_browser.browser.test_entity_browser_file.yml
index 65178f0e2..d75ba00ea 100644
--- a/web/modules/contrib/entity_browser/tests/modules/entity_browser_test/config/install/entity_browser.browser.test_entity_browser_file.yml
+++ b/web/modules/contrib/entity_browser/tests/modules/entity_browser_test/config/install/entity_browser.browser.test_entity_browser_file.yml
@@ -35,3 +35,10 @@ widgets:
weight: -10
label: view
id: view
+ cbc59500-04ab-4395-b063-c561f0e3bf80:
+ id: dummy
+ label: dummy
+ weight: -8
+ uuid: cbc59500-04ab-4395-b063-c561f0e3bf80
+ settings:
+ text: 'This is dummy widget.'
diff --git a/web/modules/contrib/entity_browser/tests/modules/entity_browser_test/entity_browser_test.info.yml b/web/modules/contrib/entity_browser/tests/modules/entity_browser_test/entity_browser_test.info.yml
index 97dfafe3d..391f392e2 100644
--- a/web/modules/contrib/entity_browser/tests/modules/entity_browser_test/entity_browser_test.info.yml
+++ b/web/modules/contrib/entity_browser/tests/modules/entity_browser_test/entity_browser_test.info.yml
@@ -10,8 +10,8 @@ dependencies:
- node
- views
-# Information added by Drupal.org packaging script on 2017-11-30
-version: '8.x-1.4'
+# Information added by Drupal.org packaging script on 2018-09-07
+version: '8.x-1.6'
core: '8.x'
project: 'entity_browser'
-datestamp: 1512033788
+datestamp: 1536328688
diff --git a/web/modules/contrib/entity_browser/tests/modules/entity_browser_test/entity_browser_test.services.yml b/web/modules/contrib/entity_browser/tests/modules/entity_browser_test/entity_browser_test.services.yml
new file mode 100644
index 000000000..17e1f17d6
--- /dev/null
+++ b/web/modules/contrib/entity_browser/tests/modules/entity_browser_test/entity_browser_test.services.yml
@@ -0,0 +1,5 @@
+services:
+ cache_context.eb_dummy:
+ class: Drupal\entity_browser_test\Cache\Context\DummyCacheContext
+ tags:
+ - { name: cache.context}
diff --git a/web/modules/contrib/entity_browser/tests/modules/entity_browser_test/src/Cache/Context/DummyCacheContext.php b/web/modules/contrib/entity_browser/tests/modules/entity_browser_test/src/Cache/Context/DummyCacheContext.php
new file mode 100644
index 000000000..ee539059d
--- /dev/null
+++ b/web/modules/contrib/entity_browser/tests/modules/entity_browser_test/src/Cache/Context/DummyCacheContext.php
@@ -0,0 +1,36 @@
+getValue('dummy_entities', []);
}
+ /**
+ * {@inheritdoc}
+ */
+ public function access() {
+ if (\Drupal::state()->get('eb_test_dummy_widget_access', TRUE)) {
+ $access = AccessResult::allowed();
+ $access->addCacheContexts(['eb_dummy']);
+ }
+ else {
+ $access = AccessResult::forbidden();
+ $access->addCacheContexts(['eb_dummy']);
+ }
+ return $access;
+ }
+
}
diff --git a/web/modules/contrib/entity_browser/tests/modules/entity_browser_test_paragraphs/config/install/core.entity_form_display.paragraph.content_embed.default.yml b/web/modules/contrib/entity_browser/tests/modules/entity_browser_test_paragraphs/config/install/core.entity_form_display.paragraph.content_embed.default.yml
index 5732c92ea..d09edbbd8 100644
--- a/web/modules/contrib/entity_browser/tests/modules/entity_browser_test_paragraphs/config/install/core.entity_form_display.paragraph.content_embed.default.yml
+++ b/web/modules/contrib/entity_browser/tests/modules/entity_browser_test_paragraphs/config/install/core.entity_form_display.paragraph.content_embed.default.yml
@@ -20,6 +20,7 @@ content:
field_widget_display: label
field_widget_edit: true
field_widget_remove: true
+ field_widget_replace: false
selection_mode: selection_append
open: true
field_widget_display_settings: { }
diff --git a/web/modules/contrib/entity_browser/tests/modules/entity_browser_test_paragraphs/config/install/core.entity_form_display.paragraph.nested_paragrah.default.yml b/web/modules/contrib/entity_browser/tests/modules/entity_browser_test_paragraphs/config/install/core.entity_form_display.paragraph.nested_paragraph.default.yml
similarity index 95%
rename from web/modules/contrib/entity_browser/tests/modules/entity_browser_test_paragraphs/config/install/core.entity_form_display.paragraph.nested_paragrah.default.yml
rename to web/modules/contrib/entity_browser/tests/modules/entity_browser_test_paragraphs/config/install/core.entity_form_display.paragraph.nested_paragraph.default.yml
index 50848f71c..2a817a9c4 100644
--- a/web/modules/contrib/entity_browser/tests/modules/entity_browser_test_paragraphs/config/install/core.entity_form_display.paragraph.nested_paragrah.default.yml
+++ b/web/modules/contrib/entity_browser/tests/modules/entity_browser_test_paragraphs/config/install/core.entity_form_display.paragraph.nested_paragraph.default.yml
@@ -19,6 +19,7 @@ content:
field_widget_display: label
field_widget_edit: true
field_widget_remove: true
+ field_widget_replace: false
selection_mode: selection_append
open: true
field_widget_display_settings: { }
diff --git a/web/modules/contrib/entity_browser/tests/modules/entity_browser_test_paragraphs/entity_browser_test_paragraphs.info.yml b/web/modules/contrib/entity_browser/tests/modules/entity_browser_test_paragraphs/entity_browser_test_paragraphs.info.yml
index 11882beba..cfba3cfd9 100644
--- a/web/modules/contrib/entity_browser/tests/modules/entity_browser_test_paragraphs/entity_browser_test_paragraphs.info.yml
+++ b/web/modules/contrib/entity_browser/tests/modules/entity_browser_test_paragraphs/entity_browser_test_paragraphs.info.yml
@@ -14,8 +14,8 @@ dependencies:
- views
- user
-# Information added by Drupal.org packaging script on 2017-11-30
-version: '8.x-1.4'
+# Information added by Drupal.org packaging script on 2018-09-07
+version: '8.x-1.6'
core: '8.x'
project: 'entity_browser'
-datestamp: 1512033788
+datestamp: 1536328688
diff --git a/web/modules/contrib/entity_browser/tests/src/FunctionalJavascript/EntityBrowserTest.php b/web/modules/contrib/entity_browser/tests/src/FunctionalJavascript/EntityBrowserTest.php
index e8add2cef..857d2c17c 100644
--- a/web/modules/contrib/entity_browser/tests/src/FunctionalJavascript/EntityBrowserTest.php
+++ b/web/modules/contrib/entity_browser/tests/src/FunctionalJavascript/EntityBrowserTest.php
@@ -78,6 +78,7 @@ class EntityBrowserTest extends EntityBrowserJavascriptTestBase {
$this->getSession()->switchToIFrame('entity_browser_iframe_test_entity_browser_file');
+ $this->assertSession()->linkExists('dummy');
$this->assertSession()->linkExists('view');
$this->assertSession()->linkExists('upload');
@@ -102,6 +103,26 @@ class EntityBrowserTest extends EntityBrowserJavascriptTestBase {
// 'files[upload][]' => $this->container->get('file_system')->realpath($image2->getFileUri()),
//];
// $this->drupalPostForm(NULL, $edit, 'Select files');.
+
+ \Drupal::state()->set('eb_test_dummy_widget_access', FALSE);
+ $this->drupalGet('entity-browser/iframe/test_entity_browser_file');
+ $this->assertSession()->linkNotExists('dummy');
+ $this->assertSession()->linkExists('view');
+ $this->assertSession()->linkExists('upload');
+ $this->assertSession()->responseHeaderContains('X-Drupal-Cache-Contexts', 'eb_dummy');
+
+ // Move dummy widget to the first place and make sure it does not appear.
+ $browser = $this->container->get('entity_type.manager')
+ ->getStorage('entity_browser')
+ ->load('test_entity_browser_file');
+ $browser->getWidget('cbc59500-04ab-4395-b063-c561f0e3bf80')->setWeight(-15);
+ $browser->save();
+ $this->drupalGet('entity-browser/iframe/test_entity_browser_file');
+ $this->assertSession()->linkNotExists('dummy');
+ $this->assertSession()->linkExists('view');
+ $this->assertSession()->linkExists('upload');
+ $this->assertSession()->pageTextNotContains('This is dummy widget.');
+ $this->assertSession()->responseHeaderContains('X-Drupal-Cache-Contexts', 'eb_dummy');
}
/**
@@ -130,6 +151,9 @@ class EntityBrowserTest extends EntityBrowserJavascriptTestBase {
$this->getSession()->switchToIFrame('entity_browser_iframe_test_entity_browser_file');
$this->assertSession()->selectExists('widget');
+ $this->assertSession()->optionExists('widget', 'cbc59500-04ab-4395-b063-c561f0e3bf80'); // Dummy
+ $this->assertSession()->optionExists('widget', '2dc1ab07-2f8f-42c9-aab7-7eef7f8b7d87'); // Upload
+ $this->assertSession()->optionExists('widget', '774798f1-5ec5-4b63-84bd-124cd51ec07d'); // View
// Selects the view widget.
$this->getSession()->getPage()->selectFieldOption('widget', '774798f1-5ec5-4b63-84bd-124cd51ec07d');
@@ -148,10 +172,30 @@ class EntityBrowserTest extends EntityBrowserJavascriptTestBase {
// Causes a fatal.
// Selects the upload widget.
// $this->getSession()->getPage()->selectFieldOption('widget', '2dc1ab07-2f8f-42c9-aab7-7eef7f8b7d87');.
+
+ \Drupal::state()->set('eb_test_dummy_widget_access', FALSE);
+ $this->drupalGet('entity-browser/iframe/test_entity_browser_file');
+ $this->assertSession()->optionNotExists('widget', 'cbc59500-04ab-4395-b063-c561f0e3bf80'); // Dummy
+ $this->assertSession()->optionExists('widget', '2dc1ab07-2f8f-42c9-aab7-7eef7f8b7d87'); // Upload
+ $this->assertSession()->optionExists('widget', '774798f1-5ec5-4b63-84bd-124cd51ec07d'); // View
+ $this->assertSession()->responseHeaderContains('X-Drupal-Cache-Contexts', 'eb_dummy');
+
+ // Move dummy widget to the first place and make sure it does not appear.
+ $browser = $this->container->get('entity_type.manager')
+ ->getStorage('entity_browser')
+ ->load('test_entity_browser_file');
+ $browser->getWidget('cbc59500-04ab-4395-b063-c561f0e3bf80')->setWeight(-15);
+ $browser->save();
+ $this->drupalGet('entity-browser/iframe/test_entity_browser_file');
+ $this->assertSession()->optionNotExists('widget', 'cbc59500-04ab-4395-b063-c561f0e3bf80'); // Dummy
+ $this->assertSession()->optionExists('widget', '2dc1ab07-2f8f-42c9-aab7-7eef7f8b7d87'); // Upload
+ $this->assertSession()->optionExists('widget', '774798f1-5ec5-4b63-84bd-124cd51ec07d'); // View
+ $this->assertSession()->pageTextNotContains('This is dummy widget.');
+ $this->assertSession()->responseHeaderContains('X-Drupal-Cache-Contexts', 'eb_dummy');
}
/**
- * Tests wievs selection display.
+ * Tests views selection display.
*/
public function testViewsSelectionDisplayWidget() {
diff --git a/web/modules/contrib/entity_browser/tests/src/FunctionalJavascript/EntityBrowserViewsWidgetTest.php b/web/modules/contrib/entity_browser/tests/src/FunctionalJavascript/EntityBrowserViewsWidgetTest.php
index f6e8d6d31..5f4c8c130 100644
--- a/web/modules/contrib/entity_browser/tests/src/FunctionalJavascript/EntityBrowserViewsWidgetTest.php
+++ b/web/modules/contrib/entity_browser/tests/src/FunctionalJavascript/EntityBrowserViewsWidgetTest.php
@@ -86,6 +86,21 @@ class EntityBrowserViewsWidgetTest extends EntityBrowserJavascriptTestBase {
$check_new = $this->assertSession()->fieldExists($new_field);
// Compare value attributes of checkboxes and assert they not equal.
$this->assertNotEquals($check_old->getAttribute('value'), $check_new->getAttribute('value'));
+
+ $uuid = \Drupal::service('uuid')->generate();
+ \Drupal::service('entity_browser.selection_storage')->setWithExpire(
+ $uuid,
+ ['validators' => ['cardinality' => ['cardinality' => 1]]],
+ 21600
+ );
+ $this->drupalGet('/entity-browser/iframe/test_entity_browser_file', ['query' => ['uuid' => $uuid]]);
+ $this->getSession()->getPage()->fillField('entity_browser_select[file:1]', TRUE);
+ $this->getSession()->getPage()->fillField('entity_browser_select[file:2]', TRUE);
+ $this->getSession()->getPage()->pressButton('Select entities');
+
+ $this->assertSession()->pageTextContains('You can not select more than 1 entity.');
+ $this->assertSession()->checkboxNotChecked('entity_browser_select[file:1]');
+ $this->assertSession()->checkboxNotChecked('entity_browser_select[file:2]');
}
}
diff --git a/web/modules/contrib/entity_browser/tests/src/FunctionalJavascript/EntityReferenceWidgetTest.php b/web/modules/contrib/entity_browser/tests/src/FunctionalJavascript/EntityReferenceWidgetTest.php
index c760cce7d..1fe6d17ff 100644
--- a/web/modules/contrib/entity_browser/tests/src/FunctionalJavascript/EntityReferenceWidgetTest.php
+++ b/web/modules/contrib/entity_browser/tests/src/FunctionalJavascript/EntityReferenceWidgetTest.php
@@ -24,8 +24,11 @@ class EntityReferenceWidgetTest extends EntityBrowserJavascriptTestBase {
/** @var \Drupal\user\RoleInterface $role */
$role = Role::load('authenticated');
- $this->grantPermissions($role, ['access test_entity_browser_iframe_node_view entity browser pages']);
- $this->grantPermissions($role, ['bypass node access']);
+ $this->grantPermissions($role, [
+ 'access test_entity_browser_iframe_node_view entity browser pages',
+ 'bypass node access',
+ 'administer node form display',
+ ]);
}
@@ -33,12 +36,12 @@ class EntityReferenceWidgetTest extends EntityBrowserJavascriptTestBase {
* Tests Entity Reference widget.
*/
public function testEntityReferenceWidget() {
-
- $page = $this->getSession()->getPage();
+ $session = $this->getSession();
+ $page = $session->getPage();
$assert_session = $this->assertSession();
// Create an entity_reference field to test the widget.
- FieldStorageConfig::create([
+ $field_storage = FieldStorageConfig::create([
'field_name' => 'field_entity_reference1',
'type' => 'entity_reference',
'entity_type' => 'node',
@@ -46,15 +49,17 @@ class EntityReferenceWidgetTest extends EntityBrowserJavascriptTestBase {
'settings' => [
'target_type' => 'node',
],
- ])->save();
+ ]);
+ $field_storage->save();
- FieldConfig::create([
+ $field = FieldConfig::create([
'field_name' => 'field_entity_reference1',
'entity_type' => 'node',
'bundle' => 'article',
'label' => 'Referenced articles',
'settings' => [],
- ])->save();
+ ]);
+ $field->save();
/** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display */
$form_display = $this->container->get('entity_type.manager')
@@ -68,6 +73,7 @@ class EntityReferenceWidgetTest extends EntityBrowserJavascriptTestBase {
'open' => TRUE,
'field_widget_edit' => TRUE,
'field_widget_remove' => TRUE,
+ 'field_widget_replace' => FALSE,
'selection_mode' => EntityBrowserElement::SELECTION_MODE_APPEND,
'field_widget_display' => 'label',
'field_widget_display_settings' => [],
@@ -83,11 +89,11 @@ class EntityReferenceWidgetTest extends EntityBrowserJavascriptTestBase {
$this->drupalGet('/node/add/article');
$page->fillField('title[0][value]', 'Referencing node 1');
- $this->getSession()->switchToIFrame('entity_browser_iframe_test_entity_browser_iframe_node_view');
+ $session->switchToIFrame('entity_browser_iframe_test_entity_browser_iframe_node_view');
$this->waitForAjaxToFinish();
$page->checkField('edit-entity-browser-select-node1');
$page->pressButton('Select entities');
- $this->getSession()->switchToIFrame();
+ $session->switchToIFrame();
$this->waitForAjaxToFinish();
$page->pressButton('Save');
@@ -110,6 +116,7 @@ class EntityReferenceWidgetTest extends EntityBrowserJavascriptTestBase {
'open' => TRUE,
'field_widget_edit' => FALSE,
'field_widget_remove' => FALSE,
+ 'field_widget_replace' => FALSE,
'selection_mode' => EntityBrowserElement::SELECTION_MODE_APPEND,
'field_widget_display' => 'label',
'field_widget_display_settings' => [],
@@ -127,31 +134,174 @@ class EntityReferenceWidgetTest extends EntityBrowserJavascriptTestBase {
'open' => TRUE,
'field_widget_edit' => TRUE,
'field_widget_remove' => TRUE,
+ 'field_widget_replace' => FALSE,
'selection_mode' => EntityBrowserElement::SELECTION_MODE_APPEND,
'field_widget_display' => 'label',
'field_widget_display_settings' => [],
],
])->save();
$this->drupalGet('node/' . $nid . '/edit');
- $assert_session->buttonExists('edit-field-entity-reference1-current-items-0-remove-button');
- $assert_session->buttonExists('edit-field-entity-reference1-current-items-0-edit-button');
+ $remove_button = $assert_session->buttonExists('edit-field-entity-reference1-current-items-0-remove-button');
+ $this->assertEquals('Remove', $remove_button->getValue());
+ $this->assertTrue($remove_button->hasClass('remove-button'));
+ $edit_button = $assert_session->buttonExists('edit-field-entity-reference1-current-items-0-edit-button');
+ $this->assertEquals('Edit', $edit_button->getValue());
+ $this->assertTrue($edit_button->hasClass('edit-button'));
+ // Make sure the "Replace" button is not there.
+ $assert_session->buttonNotExists('edit-field-entity-reference1-current-items-0-replace-button');
// Test the "Remove" button on the widget works.
$page->pressButton('Remove');
$this->waitForAjaxToFinish();
$assert_session->pageTextNotContains('Target example node 1');
+ // Test the "Replace" button functionality.
+ $form_display->setComponent('field_entity_reference1', [
+ 'type' => 'entity_browser_entity_reference',
+ 'settings' => [
+ 'entity_browser' => 'test_entity_browser_iframe_node_view',
+ 'open' => TRUE,
+ 'field_widget_edit' => TRUE,
+ 'field_widget_remove' => TRUE,
+ 'field_widget_replace' => TRUE,
+ 'selection_mode' => EntityBrowserElement::SELECTION_MODE_APPEND,
+ 'field_widget_display' => 'label',
+ 'field_widget_display_settings' => [],
+ ],
+ ])->save();
+ // In order to ensure the replace button opens the browser, it needs to be
+ // closed.
+ /** @var \Drupal\entity_browser\EntityBrowserInterface $browser */
+ $browser = $this->container->get('entity_type.manager')
+ ->getStorage('entity_browser')
+ ->load('test_entity_browser_iframe_node_view');
+ $browser->getDisplay()
+ ->setConfiguration([
+ 'width' => 650,
+ 'height' => 500,
+ 'link_text' => 'Select entities',
+ 'auto_open' => FALSE,
+ ]);
+ $browser->save();
+ // We'll need a third node to be able to make a new selection.
+ $target_node2 = Node::create([
+ 'title' => 'Target example node 2',
+ 'type' => 'article',
+ ]);
+ $target_node2->save();
+ $this->drupalGet('node/' . $nid . '/edit');
+ // If there is only one entity in the current selection the button should
+ // show up.
+ $replace_button = $assert_session->buttonExists('edit-field-entity-reference1-current-items-0-replace-button');
+ $this->assertEquals('Replace', $replace_button->getValue());
+ $this->assertTrue($replace_button->hasClass('replace-button'));
+ // Clicking on the button should empty the selection and automatically
+ // open the browser again.
+ $replace_button->click();
+ $this->waitForAjaxToFinish();
+ $session->switchToIFrame('entity_browser_iframe_test_entity_browser_iframe_node_view');
+ $this->waitForAjaxToFinish();
+ $page->checkField('edit-entity-browser-select-node3');
+ $page->pressButton('Select entities');
+ $session->wait(1000);
+ $session->switchToIFrame();
+ $this->waitForAjaxToFinish();
+ // Even in the AJAX-built markup for the newly selected element, the replace
+ // button should be there.
+ $assert_session->elementExists('css', 'input[data-drupal-selector="edit-field-entity-reference1-current-items-0-replace-button"]');
+ // Adding a new node to the selection, however, should make it disappear.
+ $open_iframe_link = $assert_session->elementExists('css', 'a[data-drupal-selector="edit-field-entity-reference1-entity-browser-entity-browser-link"]');
+ $open_iframe_link->click();
+ $this->waitForAjaxToFinish();
+ $session->switchToIFrame('entity_browser_iframe_test_entity_browser_iframe_node_view');
+ $this->waitForAjaxToFinish();
+ $page->checkField('edit-entity-browser-select-node1');
+ $page->pressButton('Select entities');
+ $session->wait(1000);
+ $session->switchToIFrame();
+ $this->waitForAjaxToFinish();
+ $assert_session->elementNotExists('css', 'input[data-drupal-selector="edit-field-entity-reference1-current-items-0-replace-button"]');
+ $page->pressButton('Save');
+ $assert_session->pageTextContains('Article Referencing node 1 has been updated.');
+
+ // Test the replace button again with different field cardinalities.
+ FieldStorageConfig::load('node.field_entity_reference1')->setCardinality(1)->save();
+ $this->drupalGet('/node/add/article');
+ $page->fillField('title[0][value]', 'Referencing node 2');
+ $open_iframe_link = $assert_session->elementExists('css', 'a[data-drupal-selector="edit-field-entity-reference1-entity-browser-entity-browser-link"]');
+ $open_iframe_link->click();
+ $this->waitForAjaxToFinish();
+ $session->switchToIFrame('entity_browser_iframe_test_entity_browser_iframe_node_view');
+ $this->waitForAjaxToFinish();
+ $page->checkField('edit-entity-browser-select-node1');
+ $page->pressButton('Select entities');
+ $session->wait(1000);
+ $session->switchToIFrame();
+ $this->waitForAjaxToFinish();
+ $assert_session->elementContains('css', '#edit-field-entity-reference1-wrapper', 'Target example node 1');
+ // All three buttons should be visible.
+ $assert_session->elementExists('css', 'input[data-drupal-selector="edit-field-entity-reference1-current-items-0-remove-button"]');
+ $assert_session->elementExists('css', 'input[data-drupal-selector="edit-field-entity-reference1-current-items-0-edit-button"]');
+ $replace_button = $assert_session->elementExists('css', 'input[data-drupal-selector="edit-field-entity-reference1-current-items-0-replace-button"]');
+ // Clicking on the button should empty the selection and automatically
+ // open the browser again.
+ $replace_button->click();
+ $this->waitForAjaxToFinish();
+ $session->switchToIFrame('entity_browser_iframe_test_entity_browser_iframe_node_view');
+ $this->waitForAjaxToFinish();
+ $page->checkField('edit-entity-browser-select-node2');
+ $page->pressButton('Select entities');
+ $session->wait(1000);
+ $session->switchToIFrame();
+ $this->waitForAjaxToFinish();
+ $assert_session->elementContains('css', '#edit-field-entity-reference1-wrapper', 'Referencing node 1');
+
+ // Do the same as above but now with cardinality 2.
+ FieldStorageConfig::load('node.field_entity_reference1')->setCardinality(2)->save();
+ $this->drupalGet('/node/add/article');
+ $page->fillField('title[0][value]', 'Referencing node 3');
+ $open_iframe_link = $assert_session->elementExists('css', 'a[data-drupal-selector="edit-field-entity-reference1-entity-browser-entity-browser-link"]');
+ $open_iframe_link->click();
+ $this->waitForAjaxToFinish();
+ $session->switchToIFrame('entity_browser_iframe_test_entity_browser_iframe_node_view');
+ $this->waitForAjaxToFinish();
+ $page->checkField('edit-entity-browser-select-node1');
+ $page->pressButton('Select entities');
+ $session->wait(1000);
+ $session->switchToIFrame();
+ $this->waitForAjaxToFinish();
+ $assert_session->elementContains('css', '#edit-field-entity-reference1-wrapper', 'Target example node 1');
+ // All three buttons should be visible.
+ $assert_session->elementExists('css', 'input[data-drupal-selector="edit-field-entity-reference1-current-items-0-remove-button"]');
+ $assert_session->elementExists('css', 'input[data-drupal-selector="edit-field-entity-reference1-current-items-0-edit-button"]');
+ $replace_button = $assert_session->elementExists('css', 'input[data-drupal-selector="edit-field-entity-reference1-current-items-0-replace-button"]');
+ // Clicking on the button should empty the selection and automatically
+ // open the browser again.
+ $replace_button->click();
+ $this->waitForAjaxToFinish();
+ $session->switchToIFrame('entity_browser_iframe_test_entity_browser_iframe_node_view');
+ $this->waitForAjaxToFinish();
+ $page->checkField('edit-entity-browser-select-node2');
+ $page->pressButton('Select entities');
+ $session->wait(1000);
+ $session->switchToIFrame();
+ $this->waitForAjaxToFinish();
+ $assert_session->elementContains('css', '#edit-field-entity-reference1-wrapper', 'Referencing node 1');
+
// Verify that if the user cannot edit the entity, the "Edit" button does
// not show up, even if configured to.
/** @var \Drupal\user\RoleInterface $role */
$role = Role::load('authenticated');
$role->revokePermission('bypass node access')->trustData()->save();
$this->drupalGet('node/add/article');
- $this->getSession()->switchToIFrame('entity_browser_iframe_test_entity_browser_iframe_node_view');
+ $open_iframe_link = $assert_session->elementExists('css', 'a[data-drupal-selector="edit-field-entity-reference1-entity-browser-entity-browser-link"]');
+ $open_iframe_link->click();
+ $this->waitForAjaxToFinish();
+ $session->switchToIFrame('entity_browser_iframe_test_entity_browser_iframe_node_view');
$this->waitForAjaxToFinish();
$page->checkField('edit-entity-browser-select-node1');
$page->pressButton('Select entities');
- $this->getSession()->switchToIFrame();
+ $session->switchToIFrame();
$this->waitForAjaxToFinish();
$assert_session->buttonNotExists('edit-field-entity-reference1-current-items-0-edit-button');
diff --git a/web/modules/contrib/entity_browser/tests/src/FunctionalJavascript/ImageFieldTest.php b/web/modules/contrib/entity_browser/tests/src/FunctionalJavascript/ImageFieldTest.php
index a08781a48..40bab0893 100644
--- a/web/modules/contrib/entity_browser/tests/src/FunctionalJavascript/ImageFieldTest.php
+++ b/web/modules/contrib/entity_browser/tests/src/FunctionalJavascript/ImageFieldTest.php
@@ -70,6 +70,7 @@ class ImageFieldTest extends EntityBrowserJavascriptTestBase {
'open' => TRUE,
'field_widget_edit' => FALSE,
'field_widget_remove' => TRUE,
+ 'field_widget_replace' => TRUE,
'selection_mode' => EntityBrowserElement::SELECTION_MODE_APPEND,
'view_mode' => 'default',
'preview_image_style' => 'thumbnail',
@@ -149,6 +150,25 @@ class ImageFieldTest extends EntityBrowserJavascriptTestBase {
// Image filename should not be present.
$this->assertSession()->pageTextNotContains('example.jpg');
$this->assertSession()->linkExists('Select entities');
+ // Test the Replace functionality.
+ file_unmanaged_copy(\Drupal::root() . '/core/modules/simpletest/files/image-test.jpg', 'public://example2.jpg');
+ $image2 = File::create(['uri' => 'public://example2.jpg']);
+ $image2->save();
+ \Drupal::service('file.usage')->add($image2, 'entity_browser', 'test', '1');
+ $this->drupalGet('node/1/edit');
+ $this->assertSession()->buttonExists('Replace');
+ $this->getSession()->getPage()->pressButton('Replace');
+ $this->waitForAjaxToFinish();
+ $this->getSession()->switchToIFrame('entity_browser_iframe_test_entity_browser_iframe_view');
+ $this->getSession()->getPage()->checkField('entity_browser_select[file:' . $image2->id() . ']');
+ $this->getSession()->getPage()->pressButton('Select entities');
+ $this->getSession()->getPage()->pressButton('Use selected');
+ $this->getSession()->wait(1000);
+ $this->getSession()->switchToIFrame();
+ $this->waitForAjaxToFinish();
+ // Initial image should not be present, the new one should be there instead.
+ $this->assertSession()->pageTextNotContains('example.jpg');
+ $this->assertSession()->pageTextContains('example2.jpg');
}
/**
diff --git a/web/modules/contrib/entity_browser/tests/src/Kernel/Extension/EntityBrowserTest.php b/web/modules/contrib/entity_browser/tests/src/Kernel/Extension/EntityBrowserTest.php
index d737f04e8..018f17dbc 100644
--- a/web/modules/contrib/entity_browser/tests/src/Kernel/Extension/EntityBrowserTest.php
+++ b/web/modules/contrib/entity_browser/tests/src/Kernel/Extension/EntityBrowserTest.php
@@ -13,6 +13,7 @@ use Drupal\entity_browser\WidgetInterface;
use Drupal\entity_browser\WidgetSelectorInterface;
use Drupal\entity_browser\SelectionDisplayInterface;
use Drupal\KernelTests\KernelTestBase;
+use Drupal\user\Entity\User;
use Drupal\views\Entity\View;
/**
@@ -467,4 +468,41 @@ class EntityBrowserTest extends KernelTestBase {
$this->assertEmpty($form_state->getErrors(), t('Validation succeeded where expected'));
}
+ /**
+ * Tests view widget access.
+ */
+ public function testViewWidgetAccess() {
+ $this->installConfig(['entity_browser_test']);
+ $this->installEntitySchema('user');
+ $this->installEntitySchema('user_role');
+
+ /** @var \Drupal\entity_browser\EntityBrowserInterface $entity */
+ $entity = $this->controller->load('test_entity_browser_file');
+
+ $this->assertFalse($entity->getWidget('774798f1-5ec5-4b63-84bd-124cd51ec07d')->access()->isAllowed());
+
+ // Create a user that has permission to access the view and try with it.
+ /** @var \Drupal\user\RoleInterface $role */
+ $role = $this->container->get('entity_type.manager')
+ ->getStorage('user_role')
+ ->create([
+ 'name' => $this->randomString(),
+ 'id' => $this->randomMachineName(),
+ ]);
+ $role->grantPermission('access content');
+ $role->save();
+
+ $user = $this->container->get('entity_type.manager')
+ ->getStorage('user')
+ ->create([
+ 'name' => $this->randomString(),
+ 'mail' => 'info@example.com',
+ 'roles' => $role->id(),
+ ]);
+ $user->save();
+ \Drupal::currentUser()->setAccount($user);
+
+ $this->assertTrue($entity->getWidget('774798f1-5ec5-4b63-84bd-124cd51ec07d')->access()->isAllowed());
+ }
+
}
diff --git a/web/modules/contrib/entity_reference_revisions/LICENSE.txt b/web/modules/contrib/entity_reference_revisions/LICENSE.txt
deleted file mode 100644
index d159169d1..000000000
--- a/web/modules/contrib/entity_reference_revisions/LICENSE.txt
+++ /dev/null
@@ -1,339 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-
- Copyright (C)
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- , 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.
diff --git a/web/modules/contrib/entity_reference_revisions/config/schema/entity_reference_revisions.schema.yml b/web/modules/contrib/entity_reference_revisions/config/schema/entity_reference_revisions.schema.yml
deleted file mode 100644
index 75a216aec..000000000
--- a/web/modules/contrib/entity_reference_revisions/config/schema/entity_reference_revisions.schema.yml
+++ /dev/null
@@ -1,69 +0,0 @@
-# Schema for the configuration files of the Entity Reference module.
-
-entity_reference_revisions.default.handler_settings:
- type: mapping
- label: 'View handler settings'
- mapping:
- target_bundles:
- type: sequence
- label: 'types'
- sequence:
- - type: string
- label: 'Type'
- sort:
- type: mapping
- label: 'Sort settings'
- mapping:
- field:
- type: string
- label: 'Sort by'
- direction:
- type: string
- label: 'Sort direction'
- filter:
- type: mapping
- label: 'Filter settings'
- mapping:
- type:
- type: string
- label: 'Filter by'
- role:
- type: sequence
- label: 'Restrict to the selected roles'
- sequence:
- - type: string
- label: 'Role'
- auto_create:
- type: boolean
- label: 'Create referenced entities if they don''t already exist'
-
-field.storage_settings.entity_reference_revisions:
- type: field.storage_settings.entity_reference
-
-field.value.entity_reference_revisions:
- type: field.value.entity_reference
- label: 'Default value'
- mapping:
- target_id:
- type: integer
- label: 'Value'
- target_revision_id:
- type: integer
- label: 'Revision ID'
- target_uuid:
- type: string
- label: 'Target UUID'
-
-field.field_settings.entity_reference_revisions:
- type: field.field_settings.entity_reference
-
-field.widget.settings.entity_reference_revisions_autocomplete:
- type: field.widget.settings.entity_reference_autocomplete
-
-field.formatter.settings.entity_reference_revisions_entity_view:
- type: mapping
- mapping:
- view_mode:
- type: string
- link:
- type: string
diff --git a/web/modules/contrib/entity_reference_revisions/config/schema/entity_reference_revisions.views.schema.yml b/web/modules/contrib/entity_reference_revisions/config/schema/entity_reference_revisions.views.schema.yml
deleted file mode 100644
index afbad6375..000000000
--- a/web/modules/contrib/entity_reference_revisions/config/schema/entity_reference_revisions.views.schema.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-# Schema for the views plugins of the Entity Reference module.
-
-views.display.entity_reference_revisions:
- type: views_display
- label: 'Entity Reference Revisions'
-
-views.row.entity_reference_revisions:
- type: views.row.fields
- label: 'Entity Reference Revisions inline fields'
-
-views.style.entity_reference_revisions:
- type: views_style
- label: 'Entity Reference Revisions list'
- mapping:
- search_fields:
- type: sequence
- label: 'Search fields'
- sequence:
- - type: string
- label: 'Search field'
diff --git a/web/modules/contrib/entity_reference_revisions/entity_reference_revisions.info.yml b/web/modules/contrib/entity_reference_revisions/entity_reference_revisions.info.yml
deleted file mode 100644
index 9110e1db1..000000000
--- a/web/modules/contrib/entity_reference_revisions/entity_reference_revisions.info.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-name: Entity Reference Revisions
-type: module
-description: Adds a Entity Reference field type with revision support.
-# core: 8.x
-package: Field types
-
-test_dependencies:
- - diff:diff
-
-# Information added by Drupal.org packaging script on 2018-01-05
-version: '8.x-1.4'
-core: '8.x'
-project: 'entity_reference_revisions'
-datestamp: 1515143887
diff --git a/web/modules/contrib/entity_reference_revisions/entity_reference_revisions.module b/web/modules/contrib/entity_reference_revisions/entity_reference_revisions.module
deleted file mode 100644
index ba9ac496f..000000000
--- a/web/modules/contrib/entity_reference_revisions/entity_reference_revisions.module
+++ /dev/null
@@ -1,220 +0,0 @@
-' . t('About') . '';
- $output .= '
' . t('The Entity Reference Revisions module allows you to create fields that contain links to other entities (such as content items, taxonomy terms, etc.) within the site. This allows you, for example, to include a link to a user within a content item. For more information, see the online documentation for the Entity Reference Revisions module and the Field module help page.', [':field_help' => Url::fromRoute('help.page', ['name' => 'field'])->toString(), ':er_do' => 'https://drupal.org/documentation/modules/entity_reference_revisions']) . '
';
- $output .= '
' . t('Uses') . '
';
- $output .= '
';
- $output .= '
' . t('Managing and displaying entity reference fields') . '
';
- $output .= '
' . t('The settings and the display of the entity reference field can be configured separately. See the Field UI help for more information on how to manage fields and their display.', [':field_ui' => Url::fromRoute('help.page', ['name' => 'field_ui'])->toString()]) . '
';
- $output .= '
' . t('Selecting reference type') . '
';
- $output .= '
' . t('In the field settings you can select which entity type you want to create a reference to.') . '
';
- $output .= '
' . t('Filtering and sorting reference fields') . '
';
- $output .= '
' . t('Depending on the chosen entity type, additional filtering and sorting options are available for the list of entities that can be referred to, in the field settings. For example, the list of users can be filtered by role and sorted by name or ID.') . '
';
- $output .= '
' . t('Displaying a reference') . '
';
- $output .= '
' . t('An entity reference can be displayed as a simple label with or without a link to the entity. Alternatively, the referenced entity can be displayed as a teaser (or any other available view mode) inside the referencing entity.') . '
';
- $output .= '
';
- return $output;
- }
-}
-
-/**
- * Implements hook_field_widget_info_alter().
- */
-function entity_reference_revisions_field_widget_info_alter(&$info) {
- if (isset($info['options_select'])) {
- $info['options_select']['field_types'][] = 'entity_reference_revisions';
- }
- if (isset($info['options_buttons'])) {
- $info['options_buttons']['field_types'][] = 'entity_reference_revisions';
- }
-}
-
-/**
- * Implements hook_ENTITY_TYPE_update() for 'field_storage_config'.
- *
- * Reset the instance handler settings, when the target type is changed.
- */
-function entity_reference_revisions_field_storage_config_update(FieldStorageConfigInterface $field_storage) {
- if ($field_storage->getType() != 'entity_reference_revisions') {
- // Only act on entity reference fields.
- return;
- }
-
- if ($field_storage->isSyncing()) {
- // Don't change anything during a configuration sync.
- return;
- }
-
- if ($field_storage->getSetting('target_type') == $field_storage->original->getSetting('target_type')) {
- // Target type didn't change.
- return;
- }
-
- if (empty($field_storage->bundles)) {
- // Field storage has no fields.
- return;
- }
-
- $field_name = $field_storage->getName();
-
- foreach ($field_storage->bundles() as $entity_type => $bundles) {
- foreach ($bundles as $bundle) {
- $field = FieldConfig::loadByName($entity_type, $bundle, $field_name);
- $field->setSetting('handler_settings', []);
- $field->save();
- }
- }
-}
-
-/**
- * Render API callback: Processes the field settings form and allows access to
- * the form state.
- *
- * @see entity_reference_revisions_field_field_settings_form()
- */
-function _entity_reference_revisions_field_field_settings_ajax_process($form, FormStateInterface $form_state) {
- _entity_reference_revisions_field_field_settings_ajax_process_element($form, $form);
- return $form;
-}
-
-/**
- * Adds entity_reference specific properties to AJAX form elements from the
- * field settings form.
- *
- * @see _entity_reference_revisions_field_field_settings_ajax_process()
- */
-function _entity_reference_revisions_field_field_settings_ajax_process_element(&$element, $main_form) {
- if (!empty($element['#ajax'])) {
- $element['#ajax'] = [
- 'callback' => 'entity_reference_revisions_settings_ajax',
- 'wrapper' => $main_form['#id'],
- 'element' => $main_form['#array_parents'],
- ];
- }
-
- foreach (Element::children($element) as $key) {
- _entity_reference_revisions_field_field_settings_ajax_process_element($element[$key], $main_form);
- }
-}
-
-/**
- * Render API callback: Moves entity_reference specific Form API elements
- * (i.e. 'handler_settings') up a level for easier processing by the validation
- * and submission handlers.
- *
- * @see _entity_reference_revisions_field_settings_process()
- */
-function _entity_reference_revisions_form_process_merge_parent($element) {
- $parents = $element['#parents'];
- array_pop($parents);
- $element['#parents'] = $parents;
- return $element;
-}
-
-/**
- * Form element validation handler; Filters the #value property of an element.
- */
-function _entity_reference_revisions_element_validate_filter(&$element, FormStateInterface $form_state) {
- $element['#value'] = array_filter($element['#value']);
- $form_state->setValueForElement($element, $element['#value']);
-}
-
-/**
- * Ajax callback for the handler settings form.
- *
- * @see entity_reference_revisions_field_field_settings_form()
- */
-function entity_reference_revisions_settings_ajax($form, FormStateInterface $form_state) {
- return NestedArray::getValue($form, $form_state->getTriggeringElement()['#ajax']['element']);
-}
-
-/**
- * Submit handler for the non-JS case.
- *
- * @see entity_reference_revisions_field_field_settings_form()
- */
-function entity_reference_revisions_settings_ajax_submit($form, FormStateInterface $form_state) {
- $form_state->setRebuild();
-}
-
-/**
- * Creates a field of an entity reference revisions field storage on the specified bundle.
- *
- * @param string $entity_type
- * The type of entity the field will be attached to.
- * @param string $bundle
- * The bundle name of the entity the field will be attached to.
- * @param string $field_name
- * The name of the field; if it already exists, a new instance of the existing
- * field will be created.
- * @param string $field_label
- * The label of the field.
- * @param string $target_entity_type
- * The type of the referenced entity.
- * @param string $selection_handler
- * The selection handler used by this field.
- * @param array $selection_handler_settings
- * An array of settings supported by the selection handler specified above.
- * (e.g. 'target_bundles', 'sort', 'auto_create', etc).
- * @param int $cardinality
- * The cardinality of the field.
- *
- * @see \Drupal\Core\Entity\Plugin\EntityReferenceSelection\SelectionBase::buildConfigurationForm()
- */
-function entity_reference_revisions_create_field($entity_type, $bundle, $field_name, $field_label, $target_entity_type, $selection_handler = 'default', $selection_handler_settings = [], $cardinality = 1) {
- // Look for or add the specified field to the requested entity bundle.
- if (!FieldStorageConfig::loadByName($entity_type, $field_name)) {
- \Drupal::entityTypeManager()->getStorage('field_storage_config')->create([
- 'field_name' => $field_name,
- 'type' => 'entity_reference_revisions',
- 'entity_type' => $entity_type,
- 'cardinality' => $cardinality,
- 'settings' => [
- 'target_type' => $target_entity_type,
- ],
- ])->save();
- }
- if (!FieldConfig::loadByName($entity_type, $bundle, $field_name)) {
- \Drupal::entityTypeManager()->getStorage('field_config')->create([
- 'field_name' => $field_name,
- 'entity_type' => $entity_type,
- 'bundle' => $bundle,
- 'label' => $field_label,
- 'settings' => [
- 'handler' => $selection_handler,
- 'handler_settings' => $selection_handler_settings,
- ],
- ])->save();
- }
-}
-
-/**
- * Implements hook_form_FORM_ID_alter() for 'field_ui_field_storage_add_form'.
- */
-function entity_reference_revisions_form_field_ui_field_storage_add_form_alter(array &$form) {
- // Move the "Entity reference revisions" option to the end of the list and rename it to
- // "Other".
- unset($form['add']['new_storage_type']['#options'][(string) t('Reference revisions')]['entity_reference_revisions']);
- $form['add']['new_storage_type']['#options'][(string) t('Reference revisions')]['entity_reference_revisions'] = t('Otherâ¦');
-}
diff --git a/web/modules/contrib/entity_reference_revisions/entity_reference_revisions.views.inc b/web/modules/contrib/entity_reference_revisions/entity_reference_revisions.views.inc
deleted file mode 100644
index 9d351b376..000000000
--- a/web/modules/contrib/entity_reference_revisions/entity_reference_revisions.views.inc
+++ /dev/null
@@ -1,73 +0,0 @@
- $table_data) {
- // Add a relationship to the target entity type.
- $target_entity_type_id = $field_storage->getSetting('target_type');
- $target_entity_type = $entity_manager->getDefinition($target_entity_type_id);
- $entity_type_id = $field_storage->getTargetEntityTypeId();
- $entity_type = $entity_manager->getDefinition($entity_type_id);
- $target_base_table = $target_entity_type->getDataTable() ?: $target_entity_type->getBaseTable();
- $field_name = $field_storage->getName();
-
- // Provide a relationship for the entity type with the entity reference
- // revisions field.
- $args = array(
- '@label' => $target_entity_type->getLabel(),
- '@field_name' => $field_name,
- );
- $data[$table_name][$field_name]['relationship'] = array(
- 'title' => t('@label referenced from @field_name', $args),
- 'label' => t('@field_name: @label', $args),
- 'group' => $entity_type->getLabel(),
- 'help' => t('Appears in: @bundles.', array('@bundles' => implode(', ', $field_storage->getBundles()))),
- 'id' => 'standard',
- 'base' => $target_base_table,
- 'entity type' => $target_entity_type_id,
- 'base field' => $target_entity_type->getKey('revision'),
- 'relationship field' => $field_name . '_target_revision_id',
- );
-
- // Provide a reverse relationship for the entity type that is referenced by
- // the field.
- $args['@entity'] = $entity_type->getLabel();
- $args['@label'] = $target_entity_type->getLowercaseLabel();
- $pseudo_field_name = 'reverse__' . $entity_type_id . '__' . $field_name;
- /** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */
- $table_mapping = $entity_manager->getStorage($entity_type_id)->getTableMapping();
- $data[$target_base_table][$pseudo_field_name]['relationship'] = array(
- 'title' => t('@entity using @field_name', $args),
- 'label' => t('@field_name', array('@field_name' => $field_name)),
- 'group' => $target_entity_type->getLabel(),
- 'help' => t('Relate each @entity with a @field_name set to the @label.', $args),
- 'id' => 'entity_reverse',
- 'base' => $entity_type->getDataTable() ?: $entity_type->getBaseTable(),
- 'entity_type' => $entity_type_id,
- 'base field' => $entity_type->getKey('revision'),
- 'field_name' => $field_name,
- 'field table' => $table_mapping->getDedicatedDataTableName($field_storage),
- 'field field' => $field_name . '_target_revision_id',
- 'join_extra' => array(
- array(
- 'field' => 'deleted',
- 'value' => 0,
- 'numeric' => TRUE,
- ),
- ),
- );
- }
-
- return $data;
-}
diff --git a/web/modules/contrib/entity_reference_revisions/src/EntityNeedsSaveInterface.php b/web/modules/contrib/entity_reference_revisions/src/EntityNeedsSaveInterface.php
deleted file mode 100644
index 1513aa3dd..000000000
--- a/web/modules/contrib/entity_reference_revisions/src/EntityNeedsSaveInterface.php
+++ /dev/null
@@ -1,17 +0,0 @@
-needsSave;
- }
-
- /**
- * {@inheritdoc}
- */
- public function setNeedsSave($needs_save) {
- $this->needsSave = $needs_save;
- }
-
- /**
- * {@inheritdoc}
- */
- public function postSave(EntityStorageInterface $storage, $update = TRUE) {
- parent::postSave($storage, $update);
- $this->setNeedsSave(FALSE);
- }
-}
diff --git a/web/modules/contrib/entity_reference_revisions/src/EntityReferenceRevisionsFieldItemList.php b/web/modules/contrib/entity_reference_revisions/src/EntityReferenceRevisionsFieldItemList.php
deleted file mode 100644
index ba907277a..000000000
--- a/web/modules/contrib/entity_reference_revisions/src/EntityReferenceRevisionsFieldItemList.php
+++ /dev/null
@@ -1,125 +0,0 @@
-list)) {
- return array();
- }
-
- // Collect the IDs of existing entities to load, and directly grab the
- // "autocreate" entities that are already populated in $item->entity.
- $target_entities = $ids = array();
- foreach ($this->list as $delta => $item) {
- if ($item->hasNewEntity()) {
- $target_entities[$delta] = $item->entity;
- }
- elseif ($item->target_revision_id !== NULL) {
- $ids[$delta] = $item->target_revision_id;
- }
- }
-
- // Load and add the existing entities.
- if ($ids) {
- $target_type = $this->getFieldDefinition()->getSetting('target_type');
- foreach ($ids as $delta => $target_id) {
- $entity = \Drupal::entityTypeManager()->getStorage($target_type)->loadRevision($target_id);
- if ($entity) {
- $target_entities[$delta] = $entity;
- }
- }
- // Ensure the returned array is ordered by deltas.
- ksort($target_entities);
- }
-
- return $target_entities;
- }
-
- /**
- * {@inheritdoc}
- */
- public static function processDefaultValue($default_value, FieldableEntityInterface $entity, FieldDefinitionInterface $definition) {
- $default_value = parent::processDefaultValue($default_value, $entity, $definition);
-
- if ($default_value) {
- // Convert UUIDs to numeric IDs.
- $uuids = array();
- foreach ($default_value as $delta => $properties) {
- if (isset($properties['target_uuid'])) {
- $uuids[$delta] = $properties['target_uuid'];
- }
- }
- if ($uuids) {
- $target_type = $definition->getSetting('target_type');
- $entity_ids = \Drupal::entityQuery($target_type)
- ->condition('uuid', $uuids, 'IN')
- ->execute();
- $entities = \Drupal::entityTypeManager()
- ->getStorage($target_type)
- ->loadMultiple($entity_ids);
-
- $entity_uuids = array();
- foreach ($entities as $id => $entity) {
- $entity_uuids[$entity->uuid()] = $id;
- }
- foreach ($uuids as $delta => $uuid) {
- if (isset($entity_uuids[$uuid])) {
- $default_value[$delta]['target_id'] = $entity_uuids[$uuid];
- unset($default_value[$delta]['target_uuid']);
- }
- else {
- unset($default_value[$delta]);
- }
- }
- }
-
- // Ensure we return consecutive deltas, in case we removed unknown UUIDs.
- $default_value = array_values($default_value);
- }
-
- return $default_value;
- }
-
- /**
- * {@inheritdoc}
- */
- public function defaultValuesFormSubmit(array $element, array &$form, FormStateInterface $form_state) {
- $default_value = parent::defaultValuesFormSubmit($element, $form, $form_state);
-
- // Convert numeric IDs to UUIDs to ensure config deployability.
- $ids = array();
- foreach ($default_value as $delta => $properties) {
- $ids[] = $properties['target_revision_id'];
- }
-
- $entities = array();
- foreach($ids as $id) {
- $entities[$id] = \Drupal::entityTypeManager()
- ->getStorage($this->getSetting('target_type'))
- ->loadRevision($id);
- }
-
- foreach ($default_value as $delta => $properties) {
- $default_value[$delta] = array(
- 'target_uuid' => $entities[$properties['target_revision_id']]->uuid(),
- 'target_revision_id' => $properties['target_revision_id'],
- );
- }
- return $default_value;
- }
-
-}
diff --git a/web/modules/contrib/entity_reference_revisions/src/EntityReferenceRevisionsServiceProvider.php b/web/modules/contrib/entity_reference_revisions/src/EntityReferenceRevisionsServiceProvider.php
deleted file mode 100644
index 65db78508..000000000
--- a/web/modules/contrib/entity_reference_revisions/src/EntityReferenceRevisionsServiceProvider.php
+++ /dev/null
@@ -1,35 +0,0 @@
-getParameter('container.modules');
- if (isset($modules['hal'])) {
- // Hal module is enabled, add our new normalizer for entity reference
- // revision items.
- $service_definition = new Definition('Drupal\entity_reference_revisions\Normalizer\EntityReferenceRevisionItemNormalizer', array(
- new Reference('hal.link_manager'),
- new Reference('serializer.entity_resolver'),
- ));
- // The priority must be higher than that of
- // serializer.normalizer.entity_reference_item.hal in
- // hal.services.yml.
- $service_definition->addTag('normalizer', array('priority' => 20));
- $container->setDefinition('serializer.normalizer.entity_reference_revision_item', $service_definition);
- }
- }
-
-}
diff --git a/web/modules/contrib/entity_reference_revisions/src/Normalizer/EntityReferenceRevisionItemNormalizer.php b/web/modules/contrib/entity_reference_revisions/src/Normalizer/EntityReferenceRevisionItemNormalizer.php
deleted file mode 100644
index 5c63cf2df..000000000
--- a/web/modules/contrib/entity_reference_revisions/src/Normalizer/EntityReferenceRevisionItemNormalizer.php
+++ /dev/null
@@ -1,43 +0,0 @@
-getParent()->getName();
- $entity = $field_item->getEntity();
- $field_uri = $this->linkManager->getRelationUri($entity->getEntityTypeId(), $entity->bundle(), $field_name, $context);
- $data['_embedded'][$field_uri][0]['target_revision_id'] = $field_item->target_revision_id;
- return $data;
- }
-
-}
diff --git a/web/modules/contrib/entity_reference_revisions/src/Plugin/DataType/EntityReferenceRevisions.php b/web/modules/contrib/entity_reference_revisions/src/Plugin/DataType/EntityReferenceRevisions.php
deleted file mode 100644
index c9e66ac66..000000000
--- a/web/modules/contrib/entity_reference_revisions/src/Plugin/DataType/EntityReferenceRevisions.php
+++ /dev/null
@@ -1,123 +0,0 @@
-addConstraint('Bundle', $bundle);
- * \Drupal\Core\TypedData\DataReferenceDefinition::create('entity_revision')
- * ->setTargetDefinition($definition);
- * @endcode
- *
- * @DataType(
- * id = "entity_revision_reference",
- * label = @Translation("Entity reference revisions"),
- * definition_class = "\Drupal\Core\TypedData\DataReferenceDefinition"
- * )
- */
-class EntityReferenceRevisions extends EntityReference {
-
- /**
- * The entity revision ID.
- *
- * @var integer|string
- */
- protected $revision_id;
-
- /**
- * The entity ID.
- *
- * @var integer|string
- */
- protected $id;
-
- /**
- * Returns the definition of the referenced entity.
- *
- * @return \Drupal\Core\Entity\TypedData\EntityDataDefinitionInterface
- * The reference target's definition.
- */
- public function getTargetDefinition() {
- return $this->definition->getTargetDefinition();
- }
-
- /**
- * Checks whether the target entity has not been saved yet.
- *
- * @return bool
- * TRUE if the entity is new, FALSE otherwise.
- */
- public function isTargetNew() {
- // If only an ID is given, the reference cannot be a new entity.
- return !isset($this->id) && isset($this->target) && $this->target->getValue()->isNew();
- }
-
- /**
- * {@inheritdoc}
- */
- public function getTarget() {
- if (!isset($this->target) && isset($this->revision_id)) {
- // If we have a valid reference, return the entity's TypedData adapter.
- $entity = \Drupal::entityTypeManager()->getStorage($this->getTargetDefinition()->getEntityTypeId())->loadRevision($this->revision_id);
- $this->target = isset($entity) ? $entity->getTypedData() : NULL;
- }
- return $this->target;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getTargetIdentifier() {
- if (isset($this->id)) {
- return $this->id;
- }
- elseif ($entity = $this->getValue()) {
- return $entity->id();
- }
- }
-
- /**
- * {@inheritdoc}
- */
- public function setValue($value, $notify = TRUE) {
- unset($this->target);
- unset($this->id);
- unset($this->revision_id);
-
- // Both the entity ID and the entity object may be passed as value. The
- // reference may also be unset by passing NULL as value.
- if (!isset($value)) {
- $this->target = NULL;
- }
- elseif (is_object($value) && $value instanceof EntityInterface) {
- $this->target = $value->getTypedData();
- }
- elseif (!is_scalar($value['target_id']) || !is_scalar($value['target_revision_id']) || $this->getTargetDefinition()->getEntityTypeId() === NULL) {
- throw new \InvalidArgumentException('Value is not a valid entity.');
- }
- else {
- $this->id = $value['target_id'];
- $this->revision_id = $value['target_revision_id'];
- }
- // Notify the parent of any changes.
- if ($notify && isset($this->parent)) {
- $this->parent->onChange($this->name);
- }
- }
-}
diff --git a/web/modules/contrib/entity_reference_revisions/src/Plugin/DataType/EntityRevisionsAdapter.php b/web/modules/contrib/entity_reference_revisions/src/Plugin/DataType/EntityRevisionsAdapter.php
deleted file mode 100644
index 461fd539e..000000000
--- a/web/modules/contrib/entity_reference_revisions/src/Plugin/DataType/EntityRevisionsAdapter.php
+++ /dev/null
@@ -1,27 +0,0 @@
-entityDefinitions as $entityType => $entityInfo) {
- if ($entityInfo->getKey('revision')) {
- $this->derivatives[$entityType] = [
- 'id' => "entity_reference_revisions:$entityType",
- 'class' => EntityReferenceRevisions::class,
- 'requirements_met' => 1,
- 'provider' => $entityInfo->getProvider(),
- ];
- }
- }
- return $this->derivatives;
- }
-
-}
diff --git a/web/modules/contrib/entity_reference_revisions/src/Plugin/Field/FieldFormatter/EntityReferenceRevisionsEntityFormatter.php b/web/modules/contrib/entity_reference_revisions/src/Plugin/Field/FieldFormatter/EntityReferenceRevisionsEntityFormatter.php
deleted file mode 100644
index 5d23ec47e..000000000
--- a/web/modules/contrib/entity_reference_revisions/src/Plugin/Field/FieldFormatter/EntityReferenceRevisionsEntityFormatter.php
+++ /dev/null
@@ -1,164 +0,0 @@
-loggerFactory = $logger_factory;
- $this->entityDisplayRepository = $entity_display_repository;
- }
-
- /**
- * {@inheritdoc}
- */
- public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
- return new static(
- $plugin_id,
- $plugin_definition,
- $configuration['field_definition'],
- $configuration['settings'],
- $configuration['label'],
- $configuration['view_mode'],
- $configuration['third_party_settings'],
- $container->get('logger.factory'),
- $container->get('entity_display.repository')
- );
- }
-
- /**
- * {@inheritdoc}
- */
- public static function defaultSettings() {
- return array(
- 'view_mode' => 'default',
- 'link' => FALSE,
- ) + parent::defaultSettings();
- }
-
- /**
- * {@inheritdoc}
- */
- public function settingsForm(array $form, FormStateInterface $form_state) {
- $elements['view_mode'] = array(
- '#type' => 'select',
- '#options' => $this->entityDisplayRepository->getViewModeOptions($this->getFieldSetting('target_type')),
- '#title' => $this->t('View mode'),
- '#default_value' => $this->getSetting('view_mode'),
- '#required' => TRUE,
- );
-
- return $elements;
- }
-
- /**
- * {@inheritdoc}
- */
- public function settingsSummary() {
- $summary = array();
-
- $view_modes = $this->entityDisplayRepository->getViewModeOptions($this->getFieldSetting('target_type'));
- $view_mode = $this->getSetting('view_mode');
- $summary[] = $this->t('Rendered as @mode', array('@mode' => isset($view_modes[$view_mode]) ? $view_modes[$view_mode] : $view_mode));
-
- return $summary;
- }
-
- /**
- * {@inheritdoc}
- */
- public function viewElements(FieldItemListInterface $items, $langcode) {
- $view_mode = $this->getSetting('view_mode');
- $elements = array();
-
- foreach ($this->getEntitiesToView($items, $langcode) as $delta => $entity) {
- // Protect ourselves from recursive rendering.
- static $depth = 0;
- $depth++;
- if ($depth > 20) {
- $this->loggerFactory->get('entity')->error('Recursive rendering detected when rendering entity @entity_type @entity_id. Aborting rendering.', array('@entity_type' => $entity->getEntityTypeId(), '@entity_id' => $entity->id()));
- return $elements;
- }
- $view_builder = \Drupal::entityTypeManager()->getViewBuilder($entity->getEntityTypeId());
- $elements[$delta] = $view_builder->view($entity, $view_mode, $entity->language()->getId());
-
- // Add a resource attribute to set the mapping property's value to the
- // entity's url. Since we don't know what the markup of the entity will
- // be, we shouldn't rely on it for structured data such as RDFa.
- if (!empty($items[$delta]->_attributes) && !$entity->isNew() && $entity->hasLinkTemplate('canonical')) {
- $items[$delta]->_attributes += array('resource' => $entity->toUrl()->toString());
- }
- $depth = 0;
- }
-
- return $elements;
- }
-
- /**
- * {@inheritdoc}
- */
- public static function isApplicable(FieldDefinitionInterface $field_definition) {
- // This formatter is only available for entity types that have a view
- // builder.
- $target_type = $field_definition->getFieldStorageDefinition()->getSetting('target_type');
- return \Drupal::entityTypeManager()->getDefinition($target_type)->hasViewBuilderClass();
- }
-
-}
diff --git a/web/modules/contrib/entity_reference_revisions/src/Plugin/Field/FieldFormatter/EntityReferenceRevisionsFormatterBase.php b/web/modules/contrib/entity_reference_revisions/src/Plugin/Field/FieldFormatter/EntityReferenceRevisionsFormatterBase.php
deleted file mode 100644
index e098f5280..000000000
--- a/web/modules/contrib/entity_reference_revisions/src/Plugin/Field/FieldFormatter/EntityReferenceRevisionsFormatterBase.php
+++ /dev/null
@@ -1,30 +0,0 @@
-entity) {
- $item->_loaded = TRUE;
- }
- }
- }
- }
-
-}
diff --git a/web/modules/contrib/entity_reference_revisions/src/Plugin/Field/FieldType/EntityReferenceRevisionsItem.php b/web/modules/contrib/entity_reference_revisions/src/Plugin/Field/FieldType/EntityReferenceRevisionsItem.php
deleted file mode 100644
index 9146df4ea..000000000
--- a/web/modules/contrib/entity_reference_revisions/src/Plugin/Field/FieldType/EntityReferenceRevisionsItem.php
+++ /dev/null
@@ -1,477 +0,0 @@
-getDefinitions();
- $options = array();
- foreach ($entity_types as $entity_type) {
- if ($entity_type->isRevisionable()) {
- $options[$entity_type->id()] = $entity_type->getLabel();
- }
- }
-
- $element['target_type'] = array(
- '#type' => 'select',
- '#title' => $this->t('Type of item to reference'),
- '#options' => $options,
- '#default_value' => $this->getSetting('target_type'),
- '#required' => TRUE,
- '#disabled' => $has_data,
- '#size' => 1,
- );
-
- return $element;
- }
-
- /**
- * {@inheritdoc}
- */
- public static function getPreconfiguredOptions() {
- $options = array();
-
- // Add all the commonly referenced entity types as distinct pre-configured
- // options.
- $entity_types = \Drupal::entityTypeManager()->getDefinitions();
- $common_references = array_filter($entity_types, function (EntityTypeInterface $entity_type) {
- return $entity_type->get('common_reference_revisions_target') && $entity_type->isRevisionable();
- });
-
- /** @var \Drupal\Core\Entity\EntityTypeInterface $entity_type */
- foreach ($common_references as $entity_type) {
-
- $options[$entity_type->id()] = [
- 'label' => $entity_type->getLabel(),
- 'field_storage_config' => [
- 'settings' => [
- 'target_type' => $entity_type->id(),
- ]
- ]
- ];
- $default_reference_settings = $entity_type->get('default_reference_revision_settings');
- if (is_array($default_reference_settings)) {
- $options[$entity_type->id()] = array_merge($options[$entity_type->id()], $default_reference_settings);
- }
- }
-
- return $options;
- }
-
- /**
- * {@inheritdoc}
- */
- public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
- $settings = $field_definition->getSettings();
- $target_type_info = \Drupal::entityTypeManager()->getDefinition($settings['target_type']);
-
- $properties = parent::propertyDefinitions($field_definition);
-
- if ($target_type_info->getKey('revision')) {
- $target_revision_id_definition = DataReferenceTargetDefinition::create('integer')
- ->setLabel(t('@label revision ID', array('@label' => $target_type_info->getLabel())))
- ->setSetting('unsigned', TRUE);
-
- $target_revision_id_definition->setRequired(TRUE);
- $properties['target_revision_id'] = $target_revision_id_definition;
- }
-
- $properties['entity'] = DataReferenceDefinition::create('entity_revision')
- ->setLabel($target_type_info->getLabel())
- ->setDescription(t('The referenced entity revision'))
- // The entity object is computed out of the entity ID.
- ->setComputed(TRUE)
- ->setReadOnly(FALSE)
- ->setTargetDefinition(EntityDataDefinition::create($settings['target_type']));
-
- return $properties;
- }
-
- /**
- * {@inheritdoc}
- */
- public static function schema(FieldStorageDefinitionInterface $field_definition) {
- $target_type = $field_definition->getSetting('target_type');
- $target_type_info = \Drupal::entityTypeManager()->getDefinition($target_type);
-
- $schema = parent::schema($field_definition);
-
- if ($target_type_info->getKey('revision')) {
- $schema['columns']['target_revision_id'] = array(
- 'description' => 'The revision ID of the target entity.',
- 'type' => 'int',
- 'unsigned' => TRUE,
- );
- $schema['indexes']['target_revision_id'] = array('target_revision_id');
- }
-
- return $schema;
- }
-
- /**
- * {@inheritdoc}
- */
- public function setValue($values, $notify = TRUE) {
- if (isset($values) && !is_array($values)) {
- // If either a scalar or an object was passed as the value for the item,
- // assign it to the 'entity' property since that works for both cases.
- $this->set('entity', $values, $notify);
- }
- else {
- parent::setValue($values, FALSE);
- // Support setting the field item with only one property, but make sure
- // values stay in sync if only property is passed.
- // NULL is a valid value, so we use array_key_exists().
- if (is_array($values) && array_key_exists('target_id', $values) && !isset($values['entity'])) {
- $this->onChange('target_id', FALSE);
- }
- elseif (is_array($values) && array_key_exists('target_revision_id', $values) && !isset($values['entity'])) {
- $this->onChange('target_revision_id', FALSE);
- }
- elseif (is_array($values) && !array_key_exists('target_id', $values) && !array_key_exists('target_revision_id', $values) && isset($values['entity'])) {
- $this->onChange('entity', FALSE);
- }
- elseif (is_array($values) && array_key_exists('target_id', $values) && isset($values['entity'])) {
- // If both properties are passed, verify the passed values match. The
- // only exception we allow is when we have a new entity: in this case
- // its actual id and target_id will be different, due to the new entity
- // marker.
- $entity_id = $this->get('entity')->getTargetIdentifier();
- // If the entity has been saved and we're trying to set both the
- // target_id and the entity values with a non-null target ID, then the
- // value for target_id should match the ID of the entity value.
- if (!$this->entity->isNew() && $values['target_id'] !== NULL && ($entity_id != $values['target_id'])) {
- throw new \InvalidArgumentException('The target id and entity passed to the entity reference item do not match.');
- }
- }
- // Notify the parent if necessary.
- if ($notify && $this->getParent()) {
- $this->getParent()->onChange($this->getName());
- }
- }
-
- }
-
- /**
- * {@inheritdoc}
- */
- public function getValue() {
- $values = parent::getValue();
- if ($this->entity instanceof EntityNeedsSaveInterface && $this->entity->needsSave()) {
- $values['entity'] = $this->entity;
- }
- return $values;
- }
-
- /**
- * {@inheritdoc}
- */
- public function onChange($property_name, $notify = TRUE) {
- // Make sure that the target ID and the target property stay in sync.
- if ($property_name == 'entity') {
- $property = $this->get('entity');
- $target_id = $property->isTargetNew() ? NULL : $property->getTargetIdentifier();
- $this->writePropertyValue('target_id', $target_id);
- $this->writePropertyValue('target_revision_id', $property->getValue()->getRevisionId());
- }
- elseif ($property_name == 'target_id' && $this->target_id != NULL && $this->target_revision_id) {
- $this->writePropertyValue('entity', array(
- 'target_id' => $this->target_id,
- 'target_revision_id' => $this->target_revision_id,
- ));
- }
- elseif ($property_name == 'target_revision_id' && $this->target_revision_id && $this->target_id) {
- $this->writePropertyValue('entity', array(
- 'target_id' => $this->target_id,
- 'target_revision_id' => $this->target_revision_id,
- ));
- }
- if ($notify && isset($this->parent)) {
- $this->parent->onChange($this->name);
- }
- }
-
- /**
- * {@inheritdoc}
- */
- public function isEmpty() {
- // Avoid loading the entity by first checking the 'target_id'.
- if ($this->target_id !== NULL && $this->target_revision_id !== NULL) {
- return FALSE;
- }
- if ($this->entity && $this->entity instanceof EntityInterface) {
- return FALSE;
- }
- return TRUE;
- }
-
- /**
- * {@inheritdoc}
- */
- public function preSave() {
- $has_new = $this->hasNewEntity();
-
- // If it is a new entity, parent will save it.
- parent::preSave();
-
- if (!$has_new) {
- // Create a new revision if it is a composite entity in a host with a new
- // revision.
-
- $host = $this->getEntity();
- $needs_save = $this->entity instanceof EntityNeedsSaveInterface && $this->entity->needsSave();
- if (!$host->isNew() && $host->isNewRevision() && $this->entity && $this->entity->getEntityType()->get('entity_revision_parent_id_field')) {
- $this->entity->setNewRevision();
- if ($host->isDefaultRevision()) {
- $this->entity->isDefaultRevision(TRUE);
- }
- $needs_save = TRUE;
- }
- if ($needs_save) {
- $this->entity->save();
- }
- }
- if ($this->entity) {
- $this->target_revision_id = $this->entity->getRevisionId();
- }
- }
-
- /**
- * {@inheritdoc}
- */
- public function postSave($update) {
- parent::postSave($update);
-
- $needs_save = FALSE;
- // If any of entity, parent type or parent id is missing then return.
- if (!$this->entity || !$this->entity->getEntityType()->get('entity_revision_parent_type_field') || !$this->entity->getEntityType()->get('entity_revision_parent_id_field')) {
- return;
- }
-
- $entity = $this->entity;
- $parent_entity = $this->getEntity();
-
- // If the entity has a parent field name get the key.
- if ($entity->getEntityType()->get('entity_revision_parent_field_name_field')) {
- $parent_field_name = $entity->getEntityType()->get('entity_revision_parent_field_name_field');
-
- // If parent field name has changed then set it.
- if ($entity->get($parent_field_name)->value != $this->getFieldDefinition()->getName()) {
- $entity->set($parent_field_name, $this->getFieldDefinition()->getName());
- $needs_save = TRUE;
- }
- }
-
- $parent_type = $entity->getEntityType()->get('entity_revision_parent_type_field');
- $parent_id = $entity->getEntityType()->get('entity_revision_parent_id_field');
-
- // If the parent type has changed then set it.
- if ($entity->get($parent_type)->value != $parent_entity->getEntityTypeId()) {
- $entity->set($parent_type, $parent_entity->getEntityTypeId());
- $needs_save = TRUE;
- }
- // If the parent id has changed then set it.
- if ($entity->get($parent_id)->value != $parent_entity->id()) {
- $entity->set($parent_id, $parent_entity->id());
- $needs_save = TRUE;
- }
-
- if ($needs_save) {
- // Check if any of the keys has changed, save it, do not create a new
- // revision.
- $entity->setNewRevision(FALSE);
- $entity->save();
- }
- }
-
- /**
- * {@inheritdoc}
- */
- public function deleteRevision() {
- $child = $this->entity;
- if ($child->isDefaultRevision()) {
- // Do not delete if it is the default revision.
- return;
- }
-
- $host = $this->getEntity();
- $field_name = $this->getFieldDefinition()->getName() . '.target_revision_id';
- $all_revisions = \Drupal::entityQuery($host->getEntityTypeId())
- ->condition($field_name, $child->getRevisionId())
- ->allRevisions()
- ->execute();
-
- if (count($all_revisions) > 1) {
- // Do not delete if there is more than one usage of this revision.
- return;
- }
-
- \Drupal::entityTypeManager()->getStorage($child->getEntityTypeId())->deleteRevision($child->getRevisionId());
- }
-
- /**
- * {@inheritdoc}
- */
- public function delete() {
- parent::delete();
-
- if ($this->entity && $this->entity->getEntityType()->get('entity_revision_parent_type_field') && $this->entity->getEntityType()->get('entity_revision_parent_id_field')) {
- // Only delete composite entities if the host field is not translatable.
- if (!$this->getFieldDefinition()->isTranslatable()) {
- $this->entity->delete();
- }
- }
- }
-
- /**
- * {@inheritdoc}
- */
- public static function onDependencyRemoval(FieldDefinitionInterface $field_definition, array $dependencies) {
- $changed = FALSE;
- $entity_manager = \Drupal::entityManager();
- $target_entity_type = $entity_manager->getDefinition($field_definition->getFieldStorageDefinition()
- ->getSetting('target_type'));
- $handler_settings = $field_definition->getSetting('handler_settings');
-
- // Update the 'target_bundles' handler setting if a bundle config dependency
- // has been removed.
- if (!empty($handler_settings['target_bundles'])) {
- if ($bundle_entity_type_id = $target_entity_type->getBundleEntityType()) {
- if ($storage = $entity_manager->getStorage($bundle_entity_type_id)) {
- foreach ($storage->loadMultiple($handler_settings['target_bundles']) as $bundle) {
- if (isset($dependencies[$bundle->getConfigDependencyKey()][$bundle->getConfigDependencyName()])) {
- unset($handler_settings['target_bundles'][$bundle->id()]);
- $changed = TRUE;
-
- // In case we deleted the only target bundle allowed by the field
- // we can log a message because the behaviour of the field will
- // have changed.
- if ($handler_settings['target_bundles'] === []) {
- \Drupal::logger('entity_reference_revisions')
- ->notice('The %target_bundle bundle (entity type: %target_entity_type) was deleted. As a result, the %field_name entity reference revisions field (entity_type: %entity_type, bundle: %bundle) no longer specifies a specific target bundle. The field will now accept any bundle and may need to be adjusted.', [
- '%target_bundle' => $bundle->label(),
- '%target_entity_type' => $bundle->getEntityType()
- ->getBundleOf(),
- '%field_name' => $field_definition->getName(),
- '%entity_type' => $field_definition->getTargetEntityTypeId(),
- '%bundle' => $field_definition->getTargetBundle()
- ]);
- }
- }
- }
- }
- }
- }
-
- if ($changed) {
- $field_definition->setSetting('handler_settings', $handler_settings);
- }
-
- return $changed;
- }
-
- /**
- * {@inheritdoc}
- */
- public static function generateSampleValue(FieldDefinitionInterface $field_definition) {
- $selection_manager = \Drupal::service('plugin.manager.entity_reference_selection');
- $entity_manager = \Drupal::entityTypeManager();
-
- // Bail if there are no referenceable entities.
- if (!$selection_manager->getSelectionHandler($field_definition)->getReferenceableEntities()) {
- return;
- }
-
- // ERR field values are never cross referenced so we need to generate new
- // target entities. First, find the target entity type.
- $target_type_id = $field_definition->getFieldStorageDefinition()->getSetting('target_type');
- $target_type = $entity_manager->getDefinition($target_type_id);
- $handler_settings = $field_definition->getSetting('handler_settings');
-
- // Determine referenceable bundles.
- $bundle_manager = \Drupal::service('entity_type.bundle.info');
- if (isset($handler_settings['target_bundles']) && is_array($handler_settings['target_bundles'])) {
- $bundles = $handler_settings['target_bundles'];
- }
- else {
- $bundles = $bundle_manager->getBundleInfo($target_type_id);
- }
- $bundle = array_rand($bundles);
-
- $label = NULL;
- if ($label_key = $target_type->getKey('label')) {
- $random = new Random();
- // @TODO set the length somehow less arbitrary.
- $label = $random->word(mt_rand(1, 10));
- }
-
- // Create entity stub.
- $entity = $selection_manager->getSelectionHandler($field_definition)->createNewEntity($target_type_id, $bundle, $label, 0);
-
- // Populate entity values and save.
- $instances = $entity_manager
- ->getStorage('field_config')
- ->loadByProperties([
- 'entity_type' => $target_type_id,
- 'bundle' => $bundle,
- ]);
-
- foreach ($instances as $instance) {
- $field_storage = $instance->getFieldStorageDefinition();
- $max = $cardinality = $field_storage->getCardinality();
- if ($cardinality == FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED) {
- // Just an arbitrary number for 'unlimited'
- $max = rand(1, 5);
- }
- $field_name = $field_storage->getName();
- $entity->{$field_name}->generateSampleItems($max);
- }
-
- $entity->save();
-
- return [
- 'target_id' => $entity->id(),
- 'target_revision_id' => $entity->getRevisionId(),
- ];
- }
-
-}
diff --git a/web/modules/contrib/entity_reference_revisions/src/Plugin/Field/FieldWidget/EntityReferenceRevisionsAutocompleteWidget.php b/web/modules/contrib/entity_reference_revisions/src/Plugin/Field/FieldWidget/EntityReferenceRevisionsAutocompleteWidget.php
deleted file mode 100644
index faad139ab..000000000
--- a/web/modules/contrib/entity_reference_revisions/src/Plugin/Field/FieldWidget/EntityReferenceRevisionsAutocompleteWidget.php
+++ /dev/null
@@ -1,44 +0,0 @@
-fieldDefinition->getFieldStorageDefinition()->getSetting('target_type');
- foreach ($values as $key => $value) {
- if($value['target_id']) {
- $entity = \Drupal::entityTypeManager()->getStorage($entity_type)->load($value['target_id']);
- // Add the current revision ID.
- $values[$key]['target_revision_id'] = $entity->getRevisionId();
- }
- // The entity_autocomplete form element returns an array when an entity
- // was "autocreated", so we need to move it up a level.
- if (is_array($value['target_id'])) {
- unset($values[$key]['target_id']);
- $values[$key] += $value['target_id'];
- }
- }
- return $values;
- }
-
-}
diff --git a/web/modules/contrib/entity_reference_revisions/src/Plugin/diff/Field/EntityReferenceRevisionsFieldDiffBuilder.php b/web/modules/contrib/entity_reference_revisions/src/Plugin/diff/Field/EntityReferenceRevisionsFieldDiffBuilder.php
deleted file mode 100644
index 0df05077a..000000000
--- a/web/modules/contrib/entity_reference_revisions/src/Plugin/diff/Field/EntityReferenceRevisionsFieldDiffBuilder.php
+++ /dev/null
@@ -1,59 +0,0 @@
- $field_item) {
- if (!$field_item->isEmpty() && $field_item->entity) {
- $parsed_text = $this->entityParser->parseEntity($field_item->entity);
- if (is_array($parsed_text)) {
- foreach ($parsed_text as $field_id => $field) {
- foreach ($field as $id => $text) {
- $result_text[$item_counter + $id] = $text;
- }
- $item_counter = $item_counter + $id + 1;
- }
- }
- }
- }
- return $result_text;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getEntitiesToDiff(FieldItemListInterface $field_items) {
- /** @var \Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem $field_item */
- $entities = [];
- foreach ($field_items as $field_key => $field_item) {
- if (!$field_item->isEmpty() && $field_item->entity) {
- $entities[$field_key] = $field_item->entity;
- }
- }
- return $entities;
- }
-
-}
diff --git a/web/modules/contrib/entity_reference_revisions/src/Plugin/migrate/destination/EntityReferenceRevisions.php b/web/modules/contrib/entity_reference_revisions/src/Plugin/migrate/destination/EntityReferenceRevisions.php
deleted file mode 100644
index a50f5a767..000000000
--- a/web/modules/contrib/entity_reference_revisions/src/Plugin/migrate/destination/EntityReferenceRevisions.php
+++ /dev/null
@@ -1,153 +0,0 @@
-save();
-
- return [
- $this->getKey('id') => $entity->id(),
- $this->getKey('revision') => $entity->getRevisionId(),
- ];
- }
-
- /**
- * {@inheritdoc}
- */
- public function getIds() {
- if ($revision_key = $this->getKey('revision')) {
- $id_key = $this->getKey('id');
- $ids[$id_key]['type'] = 'integer';
-
- // TODO: Improve after https://www.drupal.org/node/2783715 is finished.
- $ids[$revision_key]['type'] = 'integer';
-
- if ($this->isTranslationDestination()) {
- if ($revision_key = $this->getKey('langcode')) {
- $ids[$revision_key]['type'] = 'string';
- }
- else {
- throw new MigrateException('This entity type does not support translation.');
- }
- }
-
- return $ids;
- }
- throw new MigrateException('This entity type does not support revisions.');
- }
-
- /**
- * {@inheritdoc}
- */
- protected function getEntity(Row $row, array $oldDestinationIdValues) {
- $revision_id = $oldDestinationIdValues ?
- array_pop($oldDestinationIdValues) :
- $row->getDestinationProperty($this->getKey('revision'));
- if (!empty($revision_id) && ($entity = $this->storage->loadRevision($revision_id))) {
- $entity->setNewRevision(FALSE);
- }
- else {
- // Attempt to ensure we always have a bundle.
- if ($bundle = $this->getBundle($row)) {
- $row->setDestinationProperty($this->getKey('bundle'), $bundle);
- }
-
- // Stubs might need some required fields filled in.
- if ($row->isStub()) {
- $this->processStubRow($row);
- }
- $entity = $this->storage->create($row->getDestination())
- ->enforceIsNew(TRUE);
- $entity->setNewRevision(TRUE);
- }
- $entity = $this->updateEntity($entity, $row) ?: $entity;
- $this->rollbackAction = MigrateIdMapInterface::ROLLBACK_DELETE;
- return $entity;
- }
-
- /**
- * {@inheritdoc}
- */
- public function rollback(array $destination_identifiers) {
- if ($this->isTranslationDestination()) {
- $this->rollbackTranslation($destination_identifiers);
- }
- else {
- $this->rollbackNonTranslation($destination_identifiers);
- }
- }
-
- /**
- * Rollback translation destinations.
- *
- * @param array $destination_identifiers
- * The IDs of the destination object to delete.
- */
- protected function rollbackTranslation(array $destination_identifiers) {
- $entity = $this->storage->loadRevision(array_pop($destination_identifiers));
- if ($entity && $entity instanceof TranslatableInterface) {
- if ($key = $this->getKey('langcode')) {
- if (isset($destination_identifier[$key])) {
- $langcode = $destination_identifier[$key];
- if ($entity->hasTranslation($langcode)) {
- // Make sure we don't remove the default translation.
- $translation = $entity->getTranslation($langcode);
- if (!$translation->isDefaultTranslation()) {
- $entity->removeTranslation($langcode);
- $entity->save();
- }
- }
- }
- }
- }
- }
-
- /**
- * Rollback non-translation destinations.
- *
- * @param array $destination_identifiers
- * The IDs of the destination object to delete.
- */
- protected function rollbackNonTranslation(array $destination_identifiers) {
- $revision_id = array_pop($destination_identifiers);
- $entity = $this->storage->loadRevision($revision_id);
- if ($entity) {
- if ($entity->isDefaultRevision()) {
- $entity->delete();
- }
- else {
- $this->storage->deleteRevision($revision_id);
- }
- }
- }
-}
diff --git a/web/modules/contrib/entity_reference_revisions/src/Plugin/views/display/EntityReferenceRevisions.php b/web/modules/contrib/entity_reference_revisions/src/Plugin/views/display/EntityReferenceRevisions.php
deleted file mode 100644
index 3c738564d..000000000
--- a/web/modules/contrib/entity_reference_revisions/src/Plugin/views/display/EntityReferenceRevisions.php
+++ /dev/null
@@ -1,176 +0,0 @@
- 'entity_reference_revisions');
- $options['defaults']['default']['style'] = FALSE;
- $options['row']['contains']['type'] = array('default' => 'entity_reference_revisions');
- $options['defaults']['default']['row'] = FALSE;
-
- // Make sure the query is not cached.
- $options['defaults']['default']['cache'] = FALSE;
-
- // Set the display title to an empty string (not used in this display type).
- $options['title']['default'] = '';
- $options['defaults']['default']['title'] = FALSE;
-
- return $options;
- }
-
- /**
- * Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase::optionsSummary().
- *
- * Disable 'cache' and 'title' so it won't be changed.
- */
- public function optionsSummary(&$categories, &$options) {
- parent::optionsSummary($categories, $options);
- unset($options['query']);
- unset($options['title']);
- }
-
- /**
- * {@inheritdoc}
- */
- public function getType() {
- return 'entity_reference_revisions';
- }
-
- /**
- * Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase::execute().
- */
- public function execute() {
- return $this->view->render($this->display['id']);
- }
-
- /**
- * Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase::render().
- */
- public function render() {
- if (!empty($this->view->result) && $this->view->style_plugin->evenEmpty()) {
- return $this->view->style_plugin->render($this->view->result);
- }
- return '';
- }
-
- /**
- * Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase::usesExposed().
- */
- public function usesExposed() {
- return FALSE;
- }
-
- /**
- * Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase::query().
- */
- public function query() {
- if (!empty($this->view->live_preview)) {
- return;
- }
-
- // Make sure the id field is included in the results.
- $id_field = $this->view->storage->get('base_field');
- $this->id_field_alias = $this->view->query->addField($this->view->storage->get('base_table'), $id_field);
-
- $options = $this->getOption('entity_reference_revisions_options');
-
- // Restrict the autocomplete options based on what's been typed already.
- if (isset($options['match'])) {
- $style_options = $this->getOption('style');
- $value = db_like($options['match']) . '%';
- if ($options['match_operator'] != 'STARTS_WITH') {
- $value = '%' . $value;
- }
-
- // Multiple search fields are OR'd together.
- $conditions = db_or();
-
- // Build the condition using the selected search fields.
- foreach ($style_options['options']['search_fields'] as $field_alias) {
- if (!empty($field_alias)) {
- // Get the table and field names for the checked field.
- $field = $this->view->query->fields[$this->view->field[$field_alias]->field_alias];
- // Add an OR condition for the field.
- $conditions->condition($field['table'] . '.' . $field['field'], $value, 'LIKE');
- }
- }
-
- $this->view->query->addWhere(0, $conditions);
- }
-
- // Add an IN condition for validation.
- if (!empty($options['ids'])) {
- $this->view->query->addWhere(0, $id_field, $options['ids']);
- }
-
- $this->view->setItemsPerPage($options['limit']);
- }
-
- /**
- * Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase::validate().
- */
- public function validate() {
- $errors = parent::validate();
- // Verify that search fields are set up.
- $style = $this->getOption('style');
- if (!isset($style['options']['search_fields'])) {
- $errors[] = $this->t('Display "@display" needs a selected search fields to work properly. See the settings for the Entity Reference Revisions list format.', array('@display' => $this->display['display_title']));
- }
- else {
- // Verify that the search fields used actually exist.
- $fields = array_keys($this->handlers['field']);
- foreach ($style['options']['search_fields'] as $field_alias => $enabled) {
- if ($enabled && !in_array($field_alias, $fields)) {
- $errors[] = $this->t('Display "@display" uses field %field as search field, but the field is no longer present. See the settings for the Entity Reference Revisions list format.', array('@display' => $this->display['display_title'], '%field' => $field_alias));
- }
- }
- }
- return $errors;
- }
-}
diff --git a/web/modules/contrib/entity_reference_revisions/src/Plugin/views/row/EntityReferenceRevisions.php b/web/modules/contrib/entity_reference_revisions/src/Plugin/views/row/EntityReferenceRevisions.php
deleted file mode 100644
index fe25de202..000000000
--- a/web/modules/contrib/entity_reference_revisions/src/Plugin/views/row/EntityReferenceRevisions.php
+++ /dev/null
@@ -1,57 +0,0 @@
- '-');
-
- return $options;
- }
-
- /**
- * Overrides \Drupal\views\Plugin\views\row\Fields::buildOptionsForm().
- */
- public function buildOptionsForm(&$form, FormStateInterface $form_state) {
- parent::buildOptionsForm($form, $form_state);
-
- // Expand the description of the 'Inline field' checkboxes.
- $form['inline']['#description'] .= ' ' . $this->t("Note: In 'Entity Reference' displays, all fields will be displayed inline unless an explicit selection of inline fields is made here." );
- }
-
- /**
- * {@inheritdoc}
- */
- public function preRender($row) {
- // Force all fields to be inline by default.
- if (empty($this->options['inline'])) {
- $fields = $this->view->getHandlers('field', $this->displayHandler->display['id']);
- $names = array_keys($fields);
- $this->options['inline'] = array_combine($names, $names);
- }
-
- return parent::preRender($row);
- }
-}
diff --git a/web/modules/contrib/entity_reference_revisions/src/Plugin/views/style/EntityReferenceRevisions.php b/web/modules/contrib/entity_reference_revisions/src/Plugin/views/style/EntityReferenceRevisions.php
deleted file mode 100644
index 376491ee7..000000000
--- a/web/modules/contrib/entity_reference_revisions/src/Plugin/views/style/EntityReferenceRevisions.php
+++ /dev/null
@@ -1,103 +0,0 @@
- NULL);
-
- return $options;
- }
-
- /**
- * Overrides \Drupal\views\Plugin\views\style\StylePluginBase\StylePluginBase::buildOptionsForm().
- */
- public function buildOptionsForm(&$form, FormStateInterface $form_state) {
- parent::buildOptionsForm($form, $form_state);
-
- $options = $this->displayHandler->getFieldLabels(TRUE);
- $form['search_fields'] = array(
- '#type' => 'checkboxes',
- '#title' => $this->t('Search fields'),
- '#options' => $options,
- '#required' => TRUE,
- '#default_value' => $this->options['search_fields'],
- '#description' => $this->t('Select the field(s) that will be searched when using the autocomplete widget.'),
- '#weight' => -3,
- );
- }
-
- /**
- * Overrides \Drupal\views\Plugin\views\style\StylePluginBase\StylePluginBase::render().
- */
- public function render() {
- if (!empty($this->view->live_preview)) {
- return parent::render();
- }
-
- // Group the rows according to the grouping field, if specified.
- $sets = $this->renderGrouping($this->view->result, $this->options['grouping']);
-
- // Grab the alias of the 'id' field added by
- // entity_reference_plugin_display.
- $id_field_alias = $this->view->storage->get('base_field');
-
- // @todo We don't display grouping info for now. Could be useful for select
- // widget, though.
- $results = array();
- foreach ($sets as $records) {
- foreach ($records as $values) {
- // Sanitize HTML, remove line breaks and extra whitespace.
- $output = $this->view->rowPlugin->render($values);
- $output = \Drupal::service('renderer')->render($output);
- $results[$values->{$id_field_alias}] = Xss::filterAdmin(preg_replace('/\s\s+/', ' ', str_replace("\n", '', $output)));
- }
- }
- return $results;
- }
-
- /**
- * {@inheritdoc}
- */
- public function evenEmpty() {
- return TRUE;
- }
-}
diff --git a/web/modules/contrib/entity_reference_revisions/src/Tests/EntityReferenceRevisionsAdminTest.php b/web/modules/contrib/entity_reference_revisions/src/Tests/EntityReferenceRevisionsAdminTest.php
deleted file mode 100644
index cc7caeddb..000000000
--- a/web/modules/contrib/entity_reference_revisions/src/Tests/EntityReferenceRevisionsAdminTest.php
+++ /dev/null
@@ -1,184 +0,0 @@
-drupalCreateContentType(array('type' => 'entity_revisions', 'name' => 'Entity revisions'));
- $this->drupalCreateContentType(array('type' => 'article', 'name' => 'Article'));
- // Place the breadcrumb, tested in fieldUIAddNewField().
- $this->drupalPlaceBlock('system_breadcrumb_block');
- $admin_user = $this->drupalCreateUser(array(
- 'administer site configuration',
- 'administer nodes',
- 'create article content',
- 'administer content types',
- 'administer node fields',
- 'administer node display',
- 'administer node form display',
- 'edit any article content',
- ));
- $this->drupalLogin($admin_user);
- }
-
- /**
- * Tests the entity reference revisions configuration.
- */
- public function testEntityReferenceRevisions() {
- // Create a test target node used as entity reference by another test node.
- $node_target = Node::create([
- 'title' => 'Target node',
- 'type' => 'article',
- 'body' => 'Target body text',
- 'uuid' => '2d04c2b4-9c3d-4fa6-869e-ecb6fa5c9410',
- ]);
- $node_target->save();
-
- // Add an entity reference revisions field to entity_revisions content type
- // with $node_target as default value.
- $storage_edit = ['settings[target_type]' => 'node', 'cardinality' => '-1'];
- $field_edit = [
- 'settings[handler_settings][target_bundles][article]' => TRUE,
- 'default_value_input[field_entity_reference_revisions][0][target_id]' => $node_target->label() . ' (' . $node_target->id() . ')',
- ];
- static::fieldUIAddNewField('admin/structure/types/manage/entity_revisions', 'entity_reference_revisions', 'Entity reference revisions', 'entity_reference_revisions', $storage_edit, $field_edit);
- \Drupal::service('entity_field.manager')->clearCachedFieldDefinitions();
- $this->assertText('Saved Entity reference revisions configuration.');
-
- // Resave the target node, so that the default revision is not the one we
- // want to use.
- $revision_id = $node_target->getRevisionId();
- $node_target_after = Node::load($node_target->id());
- $node_target_after->setNewRevision();
- $node_target_after->save();
- $this->assertTrue($node_target_after->getRevisionId() != $revision_id);
-
- // Create an article.
- $title = $this->randomMachineName();
- $edit = array(
- 'title[0][value]' => $title,
- 'body[0][value]' => 'Revision 1',
- );
- $this->drupalPostNodeForm('node/add/article', $edit, t('Save and publish'));
- $this->assertText($title);
- $this->assertText('Revision 1');
- $node = $this->drupalGetNodeByTitle($title);
-
- // Check if when creating an entity revisions content the default entity
- // reference is set, add also the above article as a new reference.
- $this->drupalGet('node/add/entity_revisions');
- $this->assertFieldByName('field_entity_reference_revisions[0][target_id]', $node_target->label() . ' (' . $node_target->id() . ')');
- $edit = [
- 'title[0][value]' => 'Entity reference revision content',
- 'field_entity_reference_revisions[1][target_id]' => $node->label() . ' (' . $node->id() . ')',
- ];
- $this->drupalPostNodeForm(NULL, $edit, t('Save and publish'));
- $this->assertLinkByHref('node/' . $node_target->id());
- $this->assertText('Entity revisions Entity reference revision content has been created.');
- $this->assertText('Entity reference revision content');
- $this->assertText($title);
- $this->assertText('Revision 1');
-
- // Create 2nd revision of the article.
- $edit = array(
- 'body[0][value]' => 'Revision 2',
- 'revision' => TRUE,
- );
- $this->drupalPostNodeForm('node/' . $node->id() . '/edit', $edit, t('Save and keep published'));
- $this->assertText($title);
- $this->assertText('Revision 2');
-
- // View the Entity reference content and make sure it still has revision 1.
- $node = $this->drupalGetNodeByTitle('Entity reference revision content');
- $this->drupalGet('node/' . $node->id());
- $this->assertText($title);
- $this->assertText('Revision 1');
- $this->assertNoText('Revision 2');
-
- // Make sure the non-revisionable entities are not selectable as referenced
- // entities.
- $edit = array(
- 'new_storage_type' => 'entity_reference_revisions',
- 'label' => 'Entity reference revisions field',
- 'field_name' => 'entity_ref_revisions_field',
- );
- $this->drupalPostForm('admin/structure/types/manage/entity_revisions/fields/add-field', $edit, t('Save and continue'));
- $this->assertNoOption('edit-settings-target-type', 'user');
- $this->assertOption('edit-settings-target-type', 'node');
-
- // Check ERR default value and property definitions label are set properly.
- $field_definition = $node->getFieldDefinition('field_entity_reference_revisions');
- $default_value = $field_definition->toArray()['default_value'];
- $this->assertEqual($default_value[0]['target_uuid'], $node_target->uuid());
- $this->assertEqual($default_value[0]['target_revision_id'], $revision_id);
- $properties = $field_definition->getFieldStorageDefinition()->getPropertyDefinitions();
- $this->assertEqual((string) $properties['target_revision_id']->getLabel(), 'Content revision ID');
- $this->assertEqual((string) $properties['target_id']->getLabel(), 'Content ID');
- $this->assertEqual((string) $properties['entity']->getLabel(), 'Content');
- }
-
- /**
- * Tests target bundle settings for an entity reference revisions field.
- */
- public function testMultipleTargetBundles() {
- // Create a couple of content types for the ERR field to point to.
- $target_types = [];
- for ($i = 0; $i < 2; $i++) {
- $target_types[$i] = $this->drupalCreateContentType([
- 'type' => strtolower($this->randomMachineName()),
- 'name' => 'Test type ' . $i
- ]);
- }
-
- // Create a new field that can point to either target content type.
- $node_type_path = 'admin/structure/types/manage/entity_revisions';
-
- // Generate a random field name, must be only lowercase characters.
- $field_name = strtolower($this->randomMachineName());
-
- $field_edit = [];
- $storage_edit = ['settings[target_type]' => 'node', 'cardinality' => '-1'];
- $field_edit['settings[handler_settings][target_bundles][' . $target_types[0]->id() . ']'] = TRUE;
- $field_edit['settings[handler_settings][target_bundles][' . $target_types[1]->id() . ']'] = TRUE;
-
- $this->fieldUIAddNewField($node_type_path, $field_name, 'Entity reference revisions', 'entity_reference_revisions', $storage_edit, $field_edit);
-
- // Deleting one of these content bundles at this point should only delete
- // that bundle's body field. Test that there is no second field that will
- // be deleted.
- $this->drupalGet('/admin/structure/types/manage/' . $target_types[0]->id() . '/delete');
- $this->assertNoFieldByXPath('(//details[@id="edit-entity-deletes"]//ul[@data-drupal-selector="edit-field-config"]/li)[2]');
- }
-
-}
diff --git a/web/modules/contrib/entity_reference_revisions/src/Tests/EntityReferenceRevisionsAutocompleteTest.php b/web/modules/contrib/entity_reference_revisions/src/Tests/EntityReferenceRevisionsAutocompleteTest.php
deleted file mode 100644
index a80c615e5..000000000
--- a/web/modules/contrib/entity_reference_revisions/src/Tests/EntityReferenceRevisionsAutocompleteTest.php
+++ /dev/null
@@ -1,147 +0,0 @@
-drupalCreateContentType(array('type' => 'article', 'name' => 'Article'));
- // Place the breadcrumb, tested in fieldUIAddNewField().
- $this->drupalPlaceBlock('system_breadcrumb_block');
- }
-
- /**
- * Test for autocomplete processing.
- *
- * Tests that processing does not crash when the entity types of the
- * referenced entity and of the entity the field is attached to are different.
- */
- public function testEntityReferenceRevisionsAutocompleteProcessing() {
- $admin_user = $this->drupalCreateUser(array(
- 'administer site configuration',
- 'administer nodes',
- 'administer blocks',
- 'create article content',
- 'administer content types',
- 'administer node fields',
- 'administer node display',
- 'administer node form display',
- 'edit any article content',
- ));
- $this->drupalLogin($admin_user);
-
- // Create a custom block content bundle.
- $this->createBlockContentType(array('type' => 'customblockcontent', 'name' => 'Custom Block Content'));
-
- // Create entity reference revisions field attached to article.
- static::fieldUIAddNewField(
- 'admin/structure/types/manage/article',
- 'entity_reference_revisions',
- 'Entity reference revisions',
- 'entity_reference_revisions',
- array('settings[target_type]' => 'block_content', 'cardinality' => '-1'),
- array('settings[handler_settings][target_bundles][customblockcontent]' => TRUE)
- );
-
- // Create custom block.
- $block_label = $this->randomMachineName();
- $block_content = $this->randomString();
- $edit = array(
- 'info[0][value]' => $block_label,
- 'body[0][value]' => $block_content,
- );
- $this->drupalPostForm('block/add', $edit, t('Save'));
- $block = $this->drupalGetBlockByInfo($block_label);
-
- // Create an article.
- $title = $this->randomMachineName();
- $edit = array(
- 'title[0][value]' => $title,
- 'body[0][value]' => 'Revision 1',
- 'field_entity_reference_revisions[0][target_id]' => $block_label . ' (' . $block->id() . ')',
- );
- $this->drupalPostNodeForm('node/add/article', $edit, t('Save and publish'));
- $this->assertText($title);
- $this->assertText(Html::escape($block_content));
-
- // Check if the block content is not deleted since there is no composite
- // relationship.
- $node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
- $node = Node::load($node->id());
- $node->delete();
- $this->assertNotNull(BlockContent::load($block->id()));
- }
-
- /**
- * Get a custom block from the database based on its title.
- *
- * @param $info
- * A block title, usually generated by $this->randomMachineName().
- * @param $reset
- * (optional) Whether to reset the entity cache.
- *
- * @return \Drupal\block\BlockInterface
- * A block entity matching $info.
- */
- function drupalGetBlockByInfo($info, $reset = FALSE) {
- if ($reset) {
- \Drupal::entityTypeManager()->getStorage('block_content')->resetCache();
- }
- $blocks = \Drupal::entityTypeManager()->getStorage('block_content')->loadByProperties(array('info' => $info));
- // Get the first block returned from the database.
- $returned_block = reset($blocks);
- return $returned_block;
- }
-
- /**
- * Create a block_content bundle.
- *
- * @param $parameters
- * An assoc array with name (human readable) and type (bundle machine name)
- * as keys.
- */
- function createBlockContentType($parameters) {
- $label = $parameters['name'];
- $machine_name = $parameters['type'];
- $edit = array(
- 'label' => $label,
- 'id' => $machine_name,
- 'revision' => TRUE,
- );
- $this->drupalPostForm('admin/structure/block/block-content/types/add', $edit, t('Save'));
- $this->assertText($label);
- }
-
-}
diff --git a/web/modules/contrib/entity_reference_revisions/src/Tests/EntityReferenceRevisionsCoreVersionUiTestTrait.php b/web/modules/contrib/entity_reference_revisions/src/Tests/EntityReferenceRevisionsCoreVersionUiTestTrait.php
deleted file mode 100644
index 596d9416f..000000000
--- a/web/modules/contrib/entity_reference_revisions/src/Tests/EntityReferenceRevisionsCoreVersionUiTestTrait.php
+++ /dev/null
@@ -1,35 +0,0 @@
- 8.4 Save (and (un)publish) node button change.
- *
- * @see \Drupal\simpletest\WebTestBase::drupalPostForm
- * @see https://www.drupal.org/node/2847274
- */
- protected function drupalPostNodeForm($path, $edit, $submit, array $options = [], array $headers = [], $form_html_id = NULL, $extra_post = NULL) {
- $drupal_version = (float) substr(\Drupal::VERSION, 0, 3);
- if ($drupal_version > 8.3) {
-
- switch ($submit) {
- case t('Save and unpublish'):
- $edit['status[value]'] = FALSE;
- break;
-
- case t('Save and publish'):
- $edit['status[value]'] = TRUE;
- break;
- }
-
- $submit = t('Save');
- }
- parent::drupalPostForm($path, $edit, $submit, $options, $headers, $form_html_id, $extra_post);
- }
-
-}
diff --git a/web/modules/contrib/entity_reference_revisions/src/Tests/EntityReferenceRevisionsDiffTest.php b/web/modules/contrib/entity_reference_revisions/src/Tests/EntityReferenceRevisionsDiffTest.php
deleted file mode 100644
index d4f236abe..000000000
--- a/web/modules/contrib/entity_reference_revisions/src/Tests/EntityReferenceRevisionsDiffTest.php
+++ /dev/null
@@ -1,121 +0,0 @@
-drupalCreateContentType(['type' => 'article', 'name' => 'Article']);
-
- // Disable visual inline diff.
- $config = $this->config('diff.settings')
- ->set('general_settings.layout_plugins.visual_inline.enabled', FALSE);
- $config->save();
-
- $admin_user = $this->drupalCreateUser([
- 'administer site configuration',
- 'administer nodes',
- 'administer content types',
- 'administer node fields',
- 'administer node display',
- 'administer node form display',
- 'view all revisions',
- 'edit any article content',
- ]);
- $this->drupalLogin($admin_user);
- $this->drupalPlaceBlock('system_breadcrumb_block');
- }
-
- /**
- * Test for diff plugin of ERR.
- *
- * Tests that the diff is displayed when changes are made in an ERR field.
- */
- public function testEntityReferenceRevisionsDiff() {
- // Add an entity_reference_revisions field.
- static::fieldUIAddNewField('admin/structure/types/manage/article', 'err_field', 'err_field', 'entity_reference_revisions', [
- 'settings[target_type]' => 'node',
- 'cardinality' => '-1',
- ], [
- 'settings[handler_settings][target_bundles][article]' => TRUE,
- ]);
-
- // Create first referenced node.
- $title_node_1 = 'referenced_node_1';
- $edit = [
- 'title[0][value]' => $title_node_1,
- 'body[0][value]' => 'body_node_1',
- ];
- $this->drupalPostNodeForm('node/add/article', $edit, t('Save and publish'));
-
- // Create second referenced node.
- $title_node_2 = 'referenced_node_2';
- $edit = [
- 'title[0][value]' => $title_node_2,
- 'body[0][value]' => 'body_node_2',
- ];
- $this->drupalPostNodeForm('node/add/article', $edit, t('Save and publish'));
-
- // Create referencing node.
- $title = 'referencing_node';
- $node = $this->drupalGetNodeByTitle($title_node_1);
- $edit = [
- 'title[0][value]' => $title,
- 'field_err_field[0][target_id]' => $title_node_1 . ' (' . $node->id() . ')',
- ];
- $this->drupalPostNodeForm('node/add/article', $edit, t('Save and publish'));
-
- // Check the plugin is set.
- $this->drupalGet('admin/config/content/diff/fields');
- $this->drupalPostForm(NULL, ['fields[node.field_err_field][plugin][type]' => 'entity_reference_revisions_field_diff_builder'], t('Save'));
-
- // Update the referenced node of the err field and create a new revision.
- $node = $this->drupalGetNodeByTitle($title);
- $referenced_node_new = $this->drupalGetNodeByTitle($title_node_2);
- $edit = [
- 'field_err_field[0][target_id]' => $title_node_2 . ' (' . $referenced_node_new->id() . ')',
- 'revision' => TRUE,
- ];
- $this->drupalPostNodeForm('node/' . $node->id() . '/edit', $edit, t('Save and keep published'));
-
- // Compare the revisions of the referencing node.
- $this->drupalPostForm('node/' . $node->id() . '/revisions', [], t('Compare selected revisions'));
-
- // Assert the field changes.
- $this->assertRaw('class="diff-context diff-deletedline">' . $title_node_1);
- $this->assertRaw('class="diff-context diff-addedline">' . $title_node_2);
- }
-
-}
diff --git a/web/modules/contrib/entity_reference_revisions/src/Tests/EntityReferenceRevisionsNormalizerTest.php b/web/modules/contrib/entity_reference_revisions/src/Tests/EntityReferenceRevisionsNormalizerTest.php
deleted file mode 100644
index ea5bcaf9e..000000000
--- a/web/modules/contrib/entity_reference_revisions/src/Tests/EntityReferenceRevisionsNormalizerTest.php
+++ /dev/null
@@ -1,106 +0,0 @@
-drupalCreateContentType(array('type' => 'entity_revisions', 'name' => 'Entity revisions'));
- $this->drupalCreateContentType(array('type' => 'article', 'name' => 'Article'));
- // Place the breadcrumb, tested in fieldUIAddNewField().
- $this->drupalPlaceBlock('system_breadcrumb_block');
- }
-
- /**
- * Tests the entity reference revisions configuration.
- */
- public function testEntityReferenceRevisions() {
- $admin_user = $this->drupalCreateUser(array(
- 'administer site configuration',
- 'administer nodes',
- 'create article content',
- 'administer content types',
- 'administer node fields',
- 'administer node display',
- 'administer node form display',
- 'edit any article content',
- ));
- $this->drupalLogin($admin_user);
- // Create entity reference revisions field.
- static::fieldUIAddNewField('admin/structure/types/manage/entity_revisions', 'entity_reference_revisions', 'Entity reference revisions', 'entity_reference_revisions', array('settings[target_type]' => 'node', 'cardinality' => '-1'), array('settings[handler_settings][target_bundles][article]' => TRUE));
- $this->assertText('Saved Entity reference revisions configuration.');
-
- // Create an article.
- $title = $this->randomMachineName();
- $edit = array(
- 'title[0][value]' => $title,
- 'body[0][value]' => 'Revision 1',
- );
- $this->drupalPostNodeForm('node/add/article', $edit, t('Save and publish'));
- $this->assertText($title);
- $this->assertText('Revision 1');
- $node = $this->drupalGetNodeByTitle($title);
-
- // Create entity revisions content that includes the above article.
- $err_title = 'Entity reference revision content';
- $edit = array(
- 'title[0][value]' => $err_title,
- 'field_entity_reference_revisions[0][target_id]' => $node->label() . ' (' . $node->id() . ')',
- );
- $this->drupalPostNodeForm('node/add/entity_revisions', $edit, t('Save and publish'));
- $this->assertText('Entity revisions Entity reference revision content has been created.');
- $err_node = $this->drupalGetNodeByTitle($err_title);
-
- $this->assertText($err_title);
- $this->assertText($title);
- $this->assertText('Revision 1');
-
- // Create 2nd revision of the article.
- $edit = array(
- 'body[0][value]' => 'Revision 2',
- 'revision' => TRUE,
- );
- $this->drupalPostNodeForm('node/' . $node->id() . '/edit', $edit, t('Save and keep published'));
- $serializer = $this->container->get('serializer');
- $normalized = $serializer->normalize($err_node, 'hal_json');
- $request = \Drupal::request();
- $link_domain = $request->getSchemeAndHttpHost() . $request->getBasePath();
- $this->assertEqual($err_node->field_entity_reference_revisions->target_revision_id, $normalized['_embedded'][$link_domain . '/rest/relation/node/entity_revisions/field_entity_reference_revisions'][0]['target_revision_id']);
- $new_err_node = $serializer->denormalize($normalized, Node::class, 'hal_json');
- $this->assertEqual($err_node->field_entity_reference_revisions->target_revision_id, $new_err_node->field_entity_reference_revisions->target_revision_id);
- }
-
-}
diff --git a/web/modules/contrib/entity_reference_revisions/src/TypedData/EntityRevisionDataDefinition.php b/web/modules/contrib/entity_reference_revisions/src/TypedData/EntityRevisionDataDefinition.php
deleted file mode 100644
index 7ffac7d8f..000000000
--- a/web/modules/contrib/entity_reference_revisions/src/TypedData/EntityRevisionDataDefinition.php
+++ /dev/null
@@ -1,50 +0,0 @@
-setEntityTypeId($parts[1]);
- }
- if (isset($parts[2])) {
- $definition->setBundles(array($parts[2]));
- }
- return $definition;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getDataType() {
- $type = 'entity_revision';
- if ($entity_type = $this->getEntityTypeId()) {
- $type .= ':' . $entity_type;
- // Append the bundle only if we know it for sure and it is not the default
- // bundle.
- if (($bundles = $this->getBundles()) && count($bundles) == 1) {
- $bundle = reset($bundles);
- if ($bundle != $entity_type) {
- $type .= ':' . $bundle;
- }
- }
- }
- return $type;
- }
-}
diff --git a/web/modules/contrib/entity_reference_revisions/tests/modules/entity_composite_relationship_test/entity_composite_relationship_test.info.yml b/web/modules/contrib/entity_reference_revisions/tests/modules/entity_composite_relationship_test/entity_composite_relationship_test.info.yml
deleted file mode 100644
index f0054190a..000000000
--- a/web/modules/contrib/entity_reference_revisions/tests/modules/entity_composite_relationship_test/entity_composite_relationship_test.info.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-name: 'ERR Composite relationship test'
-type: module
-description: 'Entity with parent type and ID.'
-package: Testing
-# core: 8.x
-
-dependencies:
- - entity_reference_revisions
- - entity_test
-# Information added by Drupal.org packaging script on 2018-01-05
-version: '8.x-1.4'
-core: '8.x'
-project: 'entity_reference_revisions'
-datestamp: 1515143887
diff --git a/web/modules/contrib/entity_reference_revisions/tests/modules/entity_composite_relationship_test/entity_composite_relationship_test.permissions.yml b/web/modules/contrib/entity_reference_revisions/tests/modules/entity_composite_relationship_test/entity_composite_relationship_test.permissions.yml
deleted file mode 100644
index c9be8a03b..000000000
--- a/web/modules/contrib/entity_reference_revisions/tests/modules/entity_composite_relationship_test/entity_composite_relationship_test.permissions.yml
+++ /dev/null
@@ -1,2 +0,0 @@
-administer entity_test composite relationship:
- title: administer entity_test composite relationship
diff --git a/web/modules/contrib/entity_reference_revisions/tests/modules/entity_composite_relationship_test/src/Entity/EntityTestCompositeRelationship.php b/web/modules/contrib/entity_reference_revisions/tests/modules/entity_composite_relationship_test/src/Entity/EntityTestCompositeRelationship.php
deleted file mode 100644
index fb61ad159..000000000
--- a/web/modules/contrib/entity_reference_revisions/tests/modules/entity_composite_relationship_test/src/Entity/EntityTestCompositeRelationship.php
+++ /dev/null
@@ -1,60 +0,0 @@
-setLabel(t('Parent ID'))
- ->setDescription(t('The ID of the parent entity of which this entity is referenced.'));
-
- $fields['parent_type'] = BaseFieldDefinition::create('string')
- ->setLabel(t('Parent type'))
- ->setDescription(t('The entity parent type to which this entity is referenced.'));
-
- $fields['parent_field_name'] = BaseFieldDefinition::create('string')
- ->setLabel(t('Parent field name'))
- ->setDescription(t('The entity parent field name to which this entity is referenced.'));
-
- return $fields;
- }
-
-}
diff --git a/web/modules/contrib/entity_reference_revisions/tests/src/Kernel/EntityReferenceRevisionsCompositeTest.php b/web/modules/contrib/entity_reference_revisions/tests/src/Kernel/EntityReferenceRevisionsCompositeTest.php
deleted file mode 100644
index e92bfbe2b..000000000
--- a/web/modules/contrib/entity_reference_revisions/tests/src/Kernel/EntityReferenceRevisionsCompositeTest.php
+++ /dev/null
@@ -1,407 +0,0 @@
-installEntitySchema('entity_test_composite');
- $this->installSchema('node', ['node_access']);
-
- // Create article content type.
- NodeType::create(['type' => 'article', 'name' => 'Article'])->save();
-
- // Create the reference to the composite entity test.
- $field_storage = FieldStorageConfig::create(array(
- 'field_name' => 'composite_reference',
- 'entity_type' => 'node',
- 'type' => 'entity_reference_revisions',
- 'settings' => array(
- 'target_type' => 'entity_test_composite'
- ),
- ));
- $field_storage->save();
- $field = FieldConfig::create(array(
- 'field_storage' => $field_storage,
- 'bundle' => 'article',
- 'translatable' => FALSE,
- ));
- $field->save();
-
- // Inject database connection and entity type manager for the tests.
- $this->database = \Drupal::database();
- $this->entityTypeManager = \Drupal::entityTypeManager();
- }
-
- /**
- * Test for maintaining composite relationship.
- *
- * Tests that the referenced entity saves the parent type and id when saving.
- */
- public function testEntityReferenceRevisionsCompositeRelationship() {
- // Create the test composite entity.
- $composite = EntityTestCompositeRelationship::create(array(
- 'uuid' => $this->randomMachineName(),
- 'name' => $this->randomMachineName(),
- ));
- $composite->save();
-
- // Assert that there is only 1 revision of the composite entity.
- $composite_revisions_count = \Drupal::entityQuery('entity_test_composite')->condition('uuid', $composite->uuid())->allRevisions()->count()->execute();
- $this->assertEquals(1, $composite_revisions_count);
-
- // Create a node with a reference to the test composite entity.
- $node = Node::create(array(
- 'title' => $this->randomMachineName(),
- 'type' => 'article',
- 'composite_reference' => $composite,
- ));
- $node->save();
-
- // Assert that there is only 1 revision when creating a node.
- $node_revisions_count = \Drupal::entityQuery('node')->condition('nid', $node->id())->allRevisions()->count()->execute();
- $this->assertEqual($node_revisions_count, 1);
- // Assert there is no new composite revision after creating a host entity.
- $composite_revisions_count = \Drupal::entityQuery('entity_test_composite')->condition('uuid', $composite->uuid())->allRevisions()->count()->execute();
- $this->assertEquals(1, $composite_revisions_count);
-
- // Verify the value of parent type and id after create a node.
- $composite = EntityTestCompositeRelationship::load($composite->id());
- $this->assertEqual($composite->parent_type->value, $node->getEntityTypeId());
- $this->assertEqual($composite->parent_id->value, $node->id());
- $this->assertEqual($composite->parent_field_name->value, 'composite_reference');
- // Create second revision of the node.
- $original_composite_revision = $node->composite_reference[0]->target_revision_id;
- $original_node_revision = $node->getRevisionId();
- $node->setTitle('2nd revision');
- $node->setNewRevision();
- $node->save();
- $node = node_load($node->id(), TRUE);
- // Check the revision of the node.
- $this->assertEqual('2nd revision', $node->getTitle(), 'New node revision has changed data.');
- $this->assertNotEqual($original_composite_revision, $node->composite_reference[0]->target_revision_id, 'Composite entity got new revision when its host did.');
-
- // Make sure that there are only 2 revisions.
- $node_revisions_count = \Drupal::entityQuery('node')->condition('nid', $node->id())->allRevisions()->count()->execute();
- $this->assertEqual($node_revisions_count, 2);
-
- // Revert to first revision of the node.
- $node = $this->entityTypeManager->getStorage('node')->loadRevision($original_node_revision);
- $node->setNewRevision();
- $node->isDefaultRevision(TRUE);
- $node->save();
- $node = node_load($node->id(), TRUE);
- // Check the revision of the node.
- $this->assertNotEqual('2nd revision', $node->getTitle(), 'Node did not keep changed title after reversion.');
- $this->assertNotEqual($original_composite_revision, $node->composite_reference[0]->target_revision_id, 'Composite entity got new revision when its host reverted to an old revision.');
-
- // Test that the composite entity is deleted when its parent is deleted.
- $node->delete();
- $this->assertNull(EntityTestCompositeRelationship::load($composite->id()));
- }
-
- /**
- * Tests composite relationship with translations and an untranslatable field.
- */
- function testCompositeRelationshipWithTranslationNonTranslatableField() {
-
- ConfigurableLanguage::createFromLangcode('de')->save();
-
- // Create the test composite entity with a translation.
- $composite = EntityTestCompositeRelationship::create(array(
- 'uuid' => $this->randomMachineName(),
- 'name' => $this->randomMachineName(),
- ));
- $composite->addTranslation('de', $composite->toArray());
- $composite->save();
-
-
- // Create a node with a reference to the test composite entity.
- $node = Node::create(array(
- 'title' => $this->randomMachineName(),
- 'type' => 'article',
- 'composite_reference' => $composite,
- ));
- $node->addTranslation('de', $node->toArray());
- $node->save();
-
- // Verify the value of parent type and id after create a node.
- $composite = EntityTestCompositeRelationship::load($composite->id());
- $this->assertEqual($composite->parent_type->value, $node->getEntityTypeId());
- $this->assertEqual($composite->parent_id->value, $node->id());
- $this->assertEqual($composite->parent_field_name->value, 'composite_reference');
- $this->assertTrue($composite->hasTranslation('de'));
-
- // Test that the composite entity is not when the german translation of the
- // parent is deleted.
- $node->removeTranslation('de');
- $node->save();
- $composite = EntityTestCompositeRelationship::load($composite->id());
- $this->assertNotNull($composite);
- // @todo Support deleting translations of a composite reference.
- // @see https://www.drupal.org/node/2834314.
- //$this->assertFalse($composite->hasTranslation('de'));
-
- // Test that the composite entity is deleted when its parent is deleted.
- $node->delete();
- $composite = EntityTestCompositeRelationship::load($composite->id());
- $this->assertNull($composite);
- }
-
- /**
- * Tests composite relationship with translations and a translatable field.
- */
- function testCompositeRelationshipWithTranslationTranslatableField() {
- $field_config = FieldConfig::loadByName('node', 'article', 'composite_reference');
- $field_config->setTranslatable(TRUE);
- $field_config->save();
-
- ConfigurableLanguage::createFromLangcode('de')->save();
-
- // Create the test composite entity with a translation.
- $composite = EntityTestCompositeRelationship::create(array(
- 'uuid' => $this->randomMachineName(),
- 'name' => $this->randomMachineName(),
- ));
- $composite->addTranslation('de', $composite->toArray());
- $composite->save();
-
- // Create a node with a reference to the test composite entity.
- $node = Node::create(array(
- 'title' => $this->randomMachineName(),
- 'type' => 'article',
- 'composite_reference' => $composite,
- ));
- $node->addTranslation('de', $node->toArray());
- $node->save();
-
- // Verify the value of parent type and id after create a node.
- $composite = EntityTestCompositeRelationship::load($composite->id());
- $this->assertEqual($composite->parent_type->value, $node->getEntityTypeId());
- $this->assertEqual($composite->parent_id->value, $node->id());
- $this->assertEqual($composite->parent_field_name->value, 'composite_reference');
-
- // Test that the composite entity is not when the german translation of the parent is deleted.
- $node->removeTranslation('de');
- $node->save();
- //$this->entityTypeManager->getStorage('entity_test_composite')->resetCache();
- $composite = EntityTestCompositeRelationship::load($composite->id());
- $this->assertNotNull($composite);
-
- // Test that the composite entity is deleted when its parent is deleted.
- $node->delete();
- $composite = EntityTestCompositeRelationship::load($composite->id());
- // @todo Support deletions for translatable fields.
- // @see https://www.drupal.org/node/2834374
- // $this->assertNull($composite);
- }
-
- /**
- * Tests composite relationship with revisions.
- */
- function testCompositeRelationshipWithRevisions() {
-
- // Create the test composite entity with a translation.
- $composite = EntityTestCompositeRelationship::create(array(
- 'uuid' => $this->randomMachineName(),
- 'name' => $this->randomMachineName(),
- ));
- $composite->save();
-
- // Create a node with a reference to the test composite entity.
- $node = Node::create(array(
- 'title' => $this->randomMachineName(),
- 'type' => 'article',
- 'composite_reference' => $composite,
- ));
- $node->save();
-
-
- // Verify the value of parent type and id after create a node.
- $composite = EntityTestCompositeRelationship::load($composite->id());
- $composite_original_revision_id = $composite->getRevisionId();
- $node_original_revision_id = $node->getRevisionId();
- $this->assertEqual($composite->parent_type->value, $node->getEntityTypeId());
- $this->assertEqual($composite->parent_id->value, $node->id());
- $this->assertEqual($composite->parent_field_name->value, 'composite_reference');
-
- $node->setNewRevision(TRUE);
- $node->save();
- // Ensure that we saved a new revision ID.
- $composite = EntityTestCompositeRelationship::load($composite->id());
- $this->assertNotEqual($composite->getRevisionId(), $composite_original_revision_id);
-
- // Test that deleting the first revision does not delete the composite.
- $this->entityTypeManager->getStorage('node')->deleteRevision($node_original_revision_id);
- $composite = EntityTestCompositeRelationship::load($composite->id());
- $this->assertNotNull($composite);
-
- // Ensure that the composite revision was deleted as well.
- $composite_revision = $this->entityTypeManager->getStorage('entity_test_composite')->loadRevision($composite_original_revision_id);
- $this->assertNull($composite_revision);
-
- // Test that the composite entity is deleted when its parent is deleted.
- $node->delete();
- $composite = EntityTestCompositeRelationship::load($composite->id());
- $this->assertNull($composite);
- }
-
- /**
- * Tests that the composite revision is not deleted if it is the default one.
- */
- function testCompositeRelationshipDefaultRevision() {
- // Create a node with a reference to a test composite entity.
- $composite = EntityTestCompositeRelationship::create([
- 'uuid' => $this->randomMachineName(),
- 'name' => $this->randomMachineName(),
- ]);
- $composite->save();
- $node = Node::create([
- 'title' => $this->randomMachineName(),
- 'type' => 'article',
- 'composite_reference' => $composite,
- ]);
- $node->save();
-
- $composite = EntityTestCompositeRelationship::load($composite->id());
- $composite_original_revision_id = $composite->getRevisionId();
- $node_original_revision_id = $node->getRevisionId();
-
- // Set a new revision, composite entity should have a new revision as well.
- $node->setNewRevision(TRUE);
- $node->save();
- // Ensure that we saved a new revision ID.
- $composite2 = EntityTestCompositeRelationship::load($composite->id());
- $composite2_rev_id = $composite2->getRevisionId();
- $this->assertNotEquals($composite2_rev_id, $composite_original_revision_id);
-
- // Revert default composite entity revision to the original revision.
- $composite_original = $this->entityTypeManager->getStorage('entity_test_composite')->loadRevision($composite_original_revision_id);
- $composite_original->isDefaultRevision(TRUE);
- $composite_original->save();
- // Check the default composite revision is the original composite revision.
- $this->assertEquals($composite_original_revision_id, $composite_original->getrevisionId());
-
- // Test deleting the first node revision, referencing to the default
- // composite revision, does not delete the default composite revision.
- $this->entityTypeManager->getStorage('node')->deleteRevision($node_original_revision_id);
- $composite_default = EntityTestCompositeRelationship::load($composite_original->id());
- $this->assertNotNull($composite_default);
- $composite_default_revision = $this->entityTypeManager->getStorage('entity_test_composite')->loadRevision($composite_original->getrevisionId());
- $this->assertNotNull($composite_default_revision);
- // Ensure the second revision still exists.
- $composite2_revision = $this->entityTypeManager->getStorage('entity_test_composite')->loadRevision($composite2_rev_id);
- $this->assertNotNull($composite2_revision);
- }
-
- /**
- * Tests that the composite revision is not deleted if it is still in use.
- */
- function testCompositeRelationshipDuplicatedRevisions() {
- // Create a node with a reference to a test composite entity.
- $composite = EntityTestCompositeRelationship::create([
- 'uuid' => $this->randomMachineName(),
- 'name' => $this->randomMachineName(),
- ]);
- $composite->save();
- $node = Node::create([
- 'title' => $this->randomMachineName(),
- 'type' => 'article',
- 'composite_reference' => $composite,
- ]);
- $node->save();
-
- $composite = EntityTestCompositeRelationship::load($composite->id());
- $composite_original_revision_id = $composite->getRevisionId();
- $node_original_revision_id = $node->getRevisionId();
-
- // Set a new revision, composite entity should have a new revision as well.
- $node->setNewRevision(TRUE);
- $node->save();
- // Ensure that we saved a new revision ID.
- $composite2 = EntityTestCompositeRelationship::load($composite->id());
- $composite2_rev_id = $composite2->getRevisionId();
- $this->assertNotEquals($composite2_rev_id, $composite_original_revision_id);
-
- // Set the new node revision to reference to the original composite
- // revision as well to test this composite revision will not be deleted.
- $this->database->update('node__composite_reference')
- ->fields(['composite_reference_target_revision_id' => $composite_original_revision_id])
- ->condition('revision_id', $node->getRevisionId())
- ->execute();
- $this->database->update('node_revision__composite_reference')
- ->fields(['composite_reference_target_revision_id' => $composite_original_revision_id])
- ->condition('revision_id', $node->getRevisionId())
- ->execute();
-
- // Test deleting the first revision does not delete the composite.
- $this->entityTypeManager->getStorage('node')->deleteRevision($node_original_revision_id);
- $composite2 = EntityTestCompositeRelationship::load($composite2->id());
- $this->assertNotNull($composite2);
-
- // Ensure the original composite revision is not deleted because it is
- // still referenced by the second node revision.
- $composite_original_revision = $this->entityTypeManager->getStorage('entity_test_composite')->loadRevision($composite_original_revision_id);
- $this->assertNotNull($composite_original_revision);
- // Ensure the second revision still exists.
- $composite2_revision = $this->entityTypeManager->getStorage('entity_test_composite')->loadRevision($composite2_rev_id);
- $this->assertNotNull($composite2_revision);
-
- // Test that the composite entity is deleted when its parent is deleted.
- $node->delete();
- $composite = EntityTestCompositeRelationship::load($composite2->id());
- $this->assertNull($composite);
- }
-
-}
diff --git a/web/modules/contrib/entity_reference_revisions/tests/src/Kernel/EntityReferenceRevisionsFormatterTest.php b/web/modules/contrib/entity_reference_revisions/tests/src/Kernel/EntityReferenceRevisionsFormatterTest.php
deleted file mode 100644
index 430d06e62..000000000
--- a/web/modules/contrib/entity_reference_revisions/tests/src/Kernel/EntityReferenceRevisionsFormatterTest.php
+++ /dev/null
@@ -1,106 +0,0 @@
- 'article', 'name' => 'Article'];
- $node_type = NodeType::create($values);
- $node_type->save();
- $this->installEntitySchema('user');
- $this->installEntitySchema('node');
- $this->installEntitySchema('entity_test_composite');
- $this->installSchema('system', ['sequences']);
- $this->installSchema('node', ['node_access']);
-
- // Add the entity_reference_revisions field to article.
- $field_storage = FieldStorageConfig::create([
- 'field_name' => 'composite_reference',
- 'entity_type' => 'node',
- 'type' => 'entity_reference_revisions',
- 'settings' => [
- 'target_type' => 'entity_test_composite'
- ],
- ]);
- $field_storage->save();
- $field = FieldConfig::create([
- 'field_storage' => $field_storage,
- 'bundle' => 'article',
- ]);
- $field->save();
-
- $user = $this->createUser(['administer entity_test composite relationship']);
- \Drupal::currentUser()->setAccount($user);
- }
-
- public function testFormatterWithDeletedReference() {
- // Create the test composite entity.
- $text = 'Dummy text';
- $entity_test = EntityTestCompositeRelationship::create([
- 'uuid' => $text,
- 'name' => $text,
- ]);
- $entity_test->save();
-
- $text = 'Clever text';
- // Set the name to a new text.
- /** @var \Drupal\entity_composite_relationship_test\Entity\EntityTestCompositeRelationship $entity_test */
- $entity_test->name = $text;
- $entity_test->setNeedsSave(TRUE);
-
- $node = Node::create([
- 'title' => $this->randomMachineName(),
- 'type' => 'article',
- 'composite_reference' => $entity_test,
- ]);
- $node->save();
-
- // entity_reference_revisions_entity_view
- $result = $node->composite_reference->view(['type' => 'entity_reference_revisions_entity_view']);
- $this->setRawContent($this->render($result));
- $this->assertText('Clever text');
-
- // Remove the referenced entity.
- $entity_test->delete();
-
- $node = Node::load($node->id());
- $result = $node->composite_reference->view(['type' => 'entity_reference_revisions_entity_view']);
- $this->render($result);
- $this->assertNoText('Clever text');
- }
-
-}
diff --git a/web/modules/contrib/entity_reference_revisions/tests/src/Kernel/EntityReferenceRevisionsSaveTest.php b/web/modules/contrib/entity_reference_revisions/tests/src/Kernel/EntityReferenceRevisionsSaveTest.php
deleted file mode 100644
index e73a2dddc..000000000
--- a/web/modules/contrib/entity_reference_revisions/tests/src/Kernel/EntityReferenceRevisionsSaveTest.php
+++ /dev/null
@@ -1,266 +0,0 @@
- 'article', 'name' => 'Article'];
- $node_type = NodeType::create($values);
- $node_type->save();
- $this->installEntitySchema('user');
- $this->installEntitySchema('node');
- $this->installEntitySchema('entity_test_composite');
- $this->installSchema('system', ['sequences']);
- $this->installSchema('node', ['node_access']);
- }
-
- /**
- * Test for NeedsSaveInterface implementation.
- *
- * Tests that the referenced entity is saved when needsSave() is TRUE.
- */
- public function testNeedsSave() {
-
- // Add the entity_reference_revisions field to article.
- $field_storage = FieldStorageConfig::create(array(
- 'field_name' => 'composite_reference',
- 'entity_type' => 'node',
- 'type' => 'entity_reference_revisions',
- 'settings' => array(
- 'target_type' => 'entity_test_composite'
- ),
- ));
- $field_storage->save();
- $field = FieldConfig::create(array(
- 'field_storage' => $field_storage,
- 'bundle' => 'article',
- ));
- $field->save();
-
- $text = 'Dummy text';
- // Create the test composite entity.
- $entity_test = EntityTestCompositeRelationship::create(array(
- 'uuid' => $text,
- 'name' => $text,
- ));
- $entity_test->save();
-
- $text = 'Clever text';
- // Set the name to a new text.
- /** @var \Drupal\entity_composite_relationship_test\Entity\EntityTestCompositeRelationship $entity_test */
- $entity_test->name = $text;
- $entity_test->setNeedsSave(TRUE);
- // Create a node with a reference to the test entity and save.
- $node = Node::create([
- 'title' => $this->randomMachineName(),
- 'type' => 'article',
- 'composite_reference' => $entity_test,
- ]);
- // Check the name is properly set.
- $values = $node->composite_reference->getValue();
- $this->assertTrue(isset($values[0]['entity']));
- static::assertEquals($values[0]['entity']->name->value, $text);
- $node->composite_reference->setValue($values);
- static::assertEquals($node->composite_reference->entity->name->value, $text);
- $node->save();
-
- // Check that the name has been updated when the parent has been saved.
- /** @var \Drupal\entity_composite_relationship_test\Entity\EntityTestCompositeRelationship $entity_test_after */
- $entity_test_after = EntityTestCompositeRelationship::load($entity_test->id());
- static::assertEquals($entity_test_after->name->value, $text);
-
- $new_text = 'Dummy text again';
- // Set the name again.
- $entity_test->name = $new_text;
- $entity_test->setNeedsSave(FALSE);
-
- // Load the Node and check the composite reference field is not set.
- $node = Node::load($node->id());
- $values = $node->composite_reference->getValue();
- $this->assertFalse(isset($values[0]['entity']));
- $node->composite_reference = $entity_test;
- $node->save();
-
- // Check the name is not updated.
- $entity_test_after = EntityTestCompositeRelationship::load($entity_test->id());
- static::assertEquals($entity_test_after->name->value, $text);
-
- // Test if after delete the referenced entity there are no problems setting
- // the referencing values to the parent.
- $entity_test->delete();
- $node = Node::load($node->id());
- $node->save();
-
- // Test if the needs save variable is set as false after saving.
- $entity_needs_save = EntityTestCompositeRelationship::create([
- 'uuid' => $text,
- 'name' => $text,
- ]);
- $entity_needs_save->setNeedsSave(TRUE);
- $entity_needs_save->save();
- $this->assertFalse($entity_needs_save->needsSave());
- }
-
- /**
- * Test for NeedsSaveInterface implementation.
- *
- * Tests that the fields in the parent are properly updated.
- */
- public function testSaveNewEntity() {
- // Add the entity_reference_revisions field to article.
- $field_storage = FieldStorageConfig::create(array(
- 'field_name' => 'composite_reference',
- 'entity_type' => 'node',
- 'type' => 'entity_reference_revisions',
- 'settings' => array(
- 'target_type' => 'entity_test_composite'
- ),
- ));
- $field_storage->save();
- $field = FieldConfig::create(array(
- 'field_storage' => $field_storage,
- 'bundle' => 'article',
- ));
- $field->save();
-
- $text = 'Dummy text';
- // Create the test entity.
- $entity_test = EntityTestCompositeRelationship::create(array(
- 'uuid' => $text,
- 'name' => $text,
- ));
-
- // Create a node with a reference to the test entity and save.
- $node = Node::create([
- 'title' => $this->randomMachineName(),
- 'type' => 'article',
- 'composite_reference' => $entity_test,
- ]);
- $validate = $node->validate();
- $this->assertEmpty($validate);
- $node->save();
-
- // Test that the fields on node are properly set.
- $node_after = Node::load($node->id());
- static::assertEquals($node_after->composite_reference[0]->target_id, $entity_test->id());
- static::assertEquals($node_after->composite_reference[0]->target_revision_id, $entity_test->getRevisionId());
- // Check that the entity is not new after save parent.
- $this->assertFalse($entity_test->isNew());
-
- // Create a new test entity.
- $text = 'Smart text';
- $second_entity_test = EntityTestCompositeRelationship::create(array(
- 'uuid' => $text,
- 'name' => $text,
- ));
- $second_entity_test->save();
-
- // Set the new test entity to the node field.
- $node_after->composite_reference = $second_entity_test;
- // Check the fields have been updated.
- static::assertEquals($node_after->composite_reference[0]->target_id, $second_entity_test->id());
- static::assertEquals($node_after->composite_reference[0]->target_revision_id, $second_entity_test->getRevisionId());
- }
-
- /**
- * Tests entity_reference_revisions default value and config dependencies.
- */
- public function testEntityReferenceRevisionsDefaultValue() {
-
- // Create a test target node used as entity reference by another test node.
- $node_target = Node::create([
- 'title' => 'Target node',
- 'type' => 'article',
- 'body' => 'Target body text',
- 'uuid' => '2d04c2b4-9c3d-4fa6-869e-ecb6fa5c9410',
- ]);
- $node_target->save();
-
- // Create an entity reference field to reference to the test target node.
- /** @var \Drupal\field\Entity\FieldStorageConfig $field_storage */
- $field_storage = FieldStorageConfig::create([
- 'field_name' => 'target_node_reference',
- 'entity_type' => 'node',
- 'type' => 'entity_reference_revisions',
- 'settings' => ['target_type' => 'node'],
- ]);
- $field_storage->save();
- /** @var \Drupal\field\Entity\FieldConfig $field */
- $field = FieldConfig::create([
- 'field_storage' => $field_storage,
- 'bundle' => 'article',
- 'required' => FALSE,
- 'settings' => ['handler_settings' => ['target_bundles' => ['article' => 'article']]],
- ]);
- // Add reference values to field config that will be used as default value.
- $default_value = [
- [
- 'target_id' => $node_target->id(),
- 'target_revision_id' => $node_target->getRevisionId(),
- 'target_uuid' => $node_target->uuid(),
- ],
- ];
- $field->setDefaultValue($default_value)->save();
-
- // Resave the target node, so that the default revision is not the one we
- // want to use.
- $revision_id = $node_target->getRevisionId();
- $node_target_after = Node::load($node_target->id());
- $node_target_after->setNewRevision();
- $node_target_after->save();
- $this->assertTrue($node_target_after->getRevisionId() != $revision_id);
-
- // Create another node.
- $node_host = Node::create([
- 'title' => 'Host node',
- 'type' => 'article',
- 'body' => 'Host body text',
- 'target_node_reference' => $node_target,
- ]);
- $node_host->save();
-
- // Check if the ERR default values are properly created.
- $node_host_after = Node::load($node_host->id());
- $this->assertEquals($node_host_after->target_node_reference->target_id, $node_target->id());
- $this->assertEquals($node_host_after->target_node_reference->target_revision_id, $revision_id);
-
- // Check if the configuration dependencies are properly created.
- $dependencies = $field->calculateDependencies()->getDependencies();
- $this->assertEquals($dependencies['content'][0], 'node:article:2d04c2b4-9c3d-4fa6-869e-ecb6fa5c9410');
- $this->assertEquals($dependencies['config'][0], 'field.storage.node.target_node_reference');
- $this->assertEquals($dependencies['config'][1], 'node.type.article');
- $this->assertEquals($dependencies['module'][0], 'entity_reference_revisions');
- }
-}
diff --git a/web/modules/contrib/entity_reference_revisions/tests/src/Kernel/Plugin/Derivative/EntityReferenceRevisionsDeriverTest.php b/web/modules/contrib/entity_reference_revisions/tests/src/Kernel/Plugin/Derivative/EntityReferenceRevisionsDeriverTest.php
deleted file mode 100644
index e68cf058c..000000000
--- a/web/modules/contrib/entity_reference_revisions/tests/src/Kernel/Plugin/Derivative/EntityReferenceRevisionsDeriverTest.php
+++ /dev/null
@@ -1,46 +0,0 @@
-installConfig($this->modules);
- }
-
- /**
- * Tests deriver.
- *
- * @covers ::getDerivativeDefinitions
- */
- public function testDestinationDeriver() {
- /** @var MigrateDestinationPluginManager $migrationDestinationManager */
- $migrationDestinationManager = \Drupal::service('plugin.manager.migrate.destination');
-
- $destination = $migrationDestinationManager->getDefinition('entity_reference_revisions:entity_test_composite');
- $this->assertEquals(EntityReferenceRevisions::class, $destination['class']);
- }
-
-
-
-}
diff --git a/web/modules/contrib/entity_reference_revisions/tests/src/Kernel/Plugin/migrate/destination/EntityReferenceRevisionsDestinationTest.php b/web/modules/contrib/entity_reference_revisions/tests/src/Kernel/Plugin/migrate/destination/EntityReferenceRevisionsDestinationTest.php
deleted file mode 100644
index 02e02ec58..000000000
--- a/web/modules/contrib/entity_reference_revisions/tests/src/Kernel/Plugin/migrate/destination/EntityReferenceRevisionsDestinationTest.php
+++ /dev/null
@@ -1,484 +0,0 @@
-installEntitySchema('entity_test_composite');
- $this->installSchema('system', ['sequences']);
- $this->installConfig($this->modules);
-
- $this->migrationPluginManager = \Drupal::service('plugin.manager.migration');
- }
-
- /**
- * Tests get entity type id.
- *
- * @dataProvider getEntityTypeIdDataProvider
- *
- * @covers ::getEntityTypeId
- */
- public function testGetEntityTypeId(array $definition, $expected) {
- /** @var Migration $migration */
- $migration = $this->migrationPluginManager->createStubMigration($definition);
- /** @var EntityReferenceRevisions $destination */
- $destination = $migration->getDestinationPlugin();
-
- /** @var EntityStorageBase $storage */
- $storage = $this->readAttribute($destination, 'storage');
- $actual = $this->readAttribute($storage, 'entityTypeId');
-
- $this->assertEquals($expected, $actual);
- }
-
- /**
- * Provides multiple migration definitions for "getEntityTypeId" test.
- */
- public function getEntityTypeIdDataProvider() {
- $datas = $this->getEntityDataProvider();
-
- foreach ($datas as &$data) {
- $data['expected'] = 'entity_test_composite';
- }
-
- return $datas;
- }
-
- /**
- * Tests get entity.
- *
- * @dataProvider getEntityDataProvider
- *
- * @covers ::getEntity
- * @covers ::rollback
- * @covers ::rollbackNonTranslation
- */
- public function testGetEntity(array $definition, array $expected) {
- /** @var Migration $migration */
- $migration = $this->migrationPluginManager->createStubMigration($definition);
- $migrationExecutable = (new MigrateExecutable($migration, $this));
- /** @var EntityStorageBase $storage */
- $storage = $this->readAttribute($migration->getDestinationPlugin(), 'storage');
- // Test inserting and updating by looping twice.
- for ($i = 0; $i < 2; $i++) {
- $migrationExecutable->import();
- $migration->getIdMap()->prepareUpdate();
- foreach ($expected as $data) {
- $entity = $storage->loadRevision($data['id']);
- $this->assertEquals($data['label'], $entity->label());
- }
- }
- $migrationExecutable->rollback();
- foreach ($expected as $data) {
- $entity = $storage->loadRevision($data['id']);
- $this->assertEmpty($entity);
- }
- }
-
- /**
- * Provides multiple migration definitions for "getEntity" test.
- */
- public function getEntityDataProvider() {
- return [
- 'without keys' => [
- 'definition' => [
- 'source' => [
- 'plugin' => 'embedded_data',
- 'data_rows' => [
- ['id' => 1, 'name' => 'content item 1a'],
- ['id' => 1, 'name' => 'content item 1b'],
- ['id' => 2, 'name' => 'content item 2'],
- ],
- 'ids' => [
- 'id' => ['type' => 'integer'],
- 'name' => ['type' => 'text'],
- ],
- ],
- 'process' => [
- 'name' => 'name',
- ],
- 'destination' => [
- 'plugin' => 'entity_reference_revisions:entity_test_composite',
- ],
- ],
- 'expected' => [
- ['id' => 1, 'label' => 'content item 1a'],
- ['id' => 2, 'label' => 'content item 1b'],
- ['id' => 3, 'label' => 'content item 2'],
- ],
- ],
- 'with keys' => [
- 'definition' => [
- 'source' => [
- 'plugin' => 'embedded_data',
- 'data_rows' => [
- ['id' => 1, 'revision_id' => 1, 'name' => 'content item 1'],
- ['id' => 2, 'revision_id' => 2, 'name' => 'content item 2'],
- ['id' => 3, 'revision_id' => 3, 'name' => 'content item 3'],
- ],
- 'ids' => [
- 'id' => ['type' => 'integer'],
- 'name' => ['type' => 'text'],
- ],
- ],
- 'process' => [
- 'id' => 'id',
- 'revision_id' => 'revision_id',
- 'name' => 'name',
- ],
- 'destination' => [
- 'plugin' => 'entity_reference_revisions:entity_test_composite',
- ],
- ],
- 'expected' => [
- ['id' => 1, 'label' => 'content item 1'],
- ['id' => 2, 'label' => 'content item 2'],
- ['id' => 3, 'label' => 'content item 3'],
- ],
- ],
- ];
- }
-
- /**
- * Tests multi-value and single-value destination field linkage.
- *
- * @dataProvider destinationFieldMappingDataProvider
- *
- */
- public function testDestinationFieldMapping(array $datas) {
- $this->enableModules(['node', 'field']);
- $this->installEntitySchema('node');
- $this->installEntitySchema('user');
- $this->installSchema('node', ['node_access']);
-
- // Create new content type.
- $values = ['type' => 'article', 'name' => 'Article'];
- $node_type = NodeType::create($values);
- $node_type->save();
-
- // Add the field_err_single field to the node type.
- $field_storage = FieldStorageConfig::create([
- 'field_name' => 'field_err_single',
- 'entity_type' => 'node',
- 'type' => 'entity_reference_revisions',
- 'settings' => [
- 'target_type' => 'entity_test_composite'
- ],
- 'cardinality' => 1,
- ]);
- $field_storage->save();
- $field = FieldConfig::create([
- 'field_storage' => $field_storage,
- 'bundle' => 'article',
- ]);
- $field->save();
-
- // Add the field_err_multiple field to the node type.
- $field_storage = FieldStorageConfig::create([
- 'field_name' => 'field_err_multiple',
- 'entity_type' => 'node',
- 'type' => 'entity_reference_revisions',
- 'settings' => [
- 'target_type' => 'entity_test_composite'
- ],
- 'cardinality' => -1,
- ]);
- $field_storage->save();
- $field = FieldConfig::create([
- 'field_storage' => $field_storage,
- 'bundle' => 'article',
- ]);
- $field->save();
-
- $definitions = [];
- $instances = [];
- foreach ($datas as $data) {
- $definitions[$data['definition']['id']] = $data['definition'];
- $instances[$data['definition']['id']] = $this->migrationPluginManager->createStubMigration($data['definition']);
- }
-
- // Reflection is easier than mocking. We need to use createInstance for
- // purposes of registering the migration for the migration process plugin.
- $reflector = new \ReflectionObject($this->migrationPluginManager);
- $property = $reflector->getProperty('definitions');
- $property->setAccessible(TRUE);
- $property->setValue($this->migrationPluginManager, $definitions);
- $this->container->set('plugin.manager.migration', $this->migrationPluginManager);
-
- foreach ($datas as $data) {
- $migration = $this->migrationPluginManager->createInstance($data['definition']['id']);
- $migrationExecutable = (new MigrateExecutable($migration, $this));
- /** @var EntityStorageBase $storage */
- $storage = $this->readAttribute($migration->getDestinationPlugin(), 'storage');
- $migrationExecutable->import();
- foreach ($data['expected'] as $expected) {
- $entity = $storage->loadRevision($expected['id']);
- $properties = array_diff_key($expected, array_flip(['id']));
- foreach ($properties as $property => $value) {
- if (is_array($value)) {
- foreach ($value as $delta => $text) {
- $this->assertNotEmpty($entity->{$property}[$delta]->entity, "Entity property $property with $delta is empty");
- $this->assertEquals($text, $entity->{$property}[$delta]->entity->label());
- }
- }
- else {
- $this->assertNotEmpty($entity, 'Entity with label ' . $expected[$property] .' is empty');
- $this->assertEquals($expected[$property], $entity->label());
- }
- }
- }
- }
- }
-
- /**
- * Provides multiple migration definitions for "getEntity" test.
- */
- public function destinationFieldMappingDataProvider() {
- return [
- 'scenario 1' => [
- [
- 'single err' => [
- 'definition' => [
- 'id' => 'single_err',
- 'class' => Migration::class,
- 'source' => [
- 'plugin' => 'embedded_data',
- 'data_rows' => [
- [
- 'id' => 1,
- 'photo' => 'Photo1 here',
- ],
- [
- 'id' => 2,
- 'photo' => 'Photo2 here',
- ],
- ],
- 'ids' => [
- 'id' => ['type' => 'integer'],
- ],
- ],
- 'process' => [
- 'name' => 'photo',
- ],
- 'destination' => [
- 'plugin' => 'entity_reference_revisions:entity_test_composite',
- ],
- ],
- 'expected' => [
- ['id' => 1, 'name' => 'Photo1 here'],
- ['id' => 2, 'name' => 'Photo2 here'],
- ],
- ],
- 'multiple err author1' => [
- 'definition' => [
- 'id' => 'multiple_err_author1',
- 'class' => Migration::class,
- 'source' => [
- 'plugin' => 'embedded_data',
- 'data_rows' => [
- [
- 'id' => 1,
- 'author' => 'Author 1',
- ],
- [
- 'id' => 2,
- 'author' => 'Author 2',
- ],
- ],
- 'ids' => [
- 'author' => ['type' => 'text'],
- ],
- ],
- 'process' => [
- 'name' => 'author',
- ],
- 'destination' => [
- 'plugin' => 'entity_reference_revisions:entity_test_composite',
- ],
- ],
- 'expected' => [
- ['id' => 3, 'name' => 'Author 1'],
- ['id' => 4, 'name' => 'Author 2'],
- ],
- ],
- 'multiple err author 2' => [
- 'definition' => [
- 'id' => 'multiple_err_author2',
- 'class' => Migration::class,
- 'source' => [
- 'plugin' => 'embedded_data',
- 'data_rows' => [
- [
- 'id' => 1,
- 'author' => 'Author 3',
- ],
- [
- 'id' => 2,
- 'author' => 'Author 4',
- ],
- ],
- 'ids' => [
- 'author' => ['type' => 'text'],
- ],
- ],
- 'process' => [
- 'name' => 'author',
- ],
- 'destination' => [
- 'plugin' => 'entity_reference_revisions:entity_test_composite',
- ],
- ],
- 'expected' => [
- ['id' => 5, 'name' => 'Author 3'],
- ['id' => 6, 'name' => 'Author 4'],
- ],
- ],
- 'destination entity' => [
- 'definition' => [
- 'id' => 'node_migration',
- 'class' => Migration::class,
- 'source' => [
- 'plugin' => 'embedded_data',
- 'data_rows' => [
- [
- 'id' => 1,
- 'title' => 'Article 1',
- 'photo' => 'Photo1 here',
- 'author' => ['Author 1', 'Author 3'],
- ],
- [
- 'id' => 2,
- 'title' => 'Article 2',
- 'photo' => 'Photo2 here',
- 'author' => ['Author 2', 'Author 4'],
- ],
- ],
- 'ids' => [
- 'id' => ['type' => 'integer'],
- ],
- ],
- 'process' => [
- 'title' => 'title',
- 'type' => [
- 'plugin' => 'default_value',
- 'default_value' => 'article',
- ],
- 'field_err_single/target_id' => [
- [
- 'plugin' => 'migration',
- 'migration' => ['single_err'],
- 'no_stub' => TRUE,
- 'source' => 'id',
- ],
- [
- 'plugin' => 'extract',
- 'index' => [
- '0',
- ],
- ],
- ],
- 'field_err_single/target_revision_id' => [
- [
- 'plugin' => 'migration',
- 'migration' => ['single_err'],
- 'no_stub' => TRUE,
- 'source' => 'id',
- ],
- [
- 'plugin' => 'extract',
- 'index' => [
- 1,
- ],
- ],
- ],
- 'field_err_multiple' => [
- [
- 'plugin' => 'migration',
- 'migration' => [
- 'multiple_err_author1',
- 'multiple_err_author2',
- ],
- 'no_stub' => TRUE,
- 'source' => 'author',
- ],
- [
- 'plugin' => 'iterator',
- 'process' => [
- 'target_id' => '0',
- 'target_revision_id' => '1',
- ],
- ],
- ],
- ],
- 'destination' => [
- 'plugin' => 'entity:node',
- ],
- ],
- 'expected' => [
- [
- 'id' => 1,
- 'title' => 'Article 1',
- 'field_err_single' => ['Photo1 here'],
- 'field_err_multiple' => ['Author 1', 'Author 3'],
- ],
- [
- 'id' => 2,
- 'title' => 'Article 2',
- 'field_err_single' => ['Photo2 here'],
- 'field_err_multiple' => ['Author 2', 'Author 4'],
- ],
- ],
- ],
- ],
- ],
- ];
- }
-
- /**
- * {@inheritdoc}
- */
- public function display($message, $type = 'status') {
- $this->assertTrue($type == 'status', $message);
- }
-
-}
diff --git a/web/modules/contrib/entityqueue/composer.json b/web/modules/contrib/entityqueue/composer.json
new file mode 100644
index 000000000..f51e48ad8
--- /dev/null
+++ b/web/modules/contrib/entityqueue/composer.json
@@ -0,0 +1,26 @@
+{
+ "name": "drupal/entityqueue",
+ "description": "The Entityqueue module allows users to create queues of any entity type.",
+ "type": "drupal-module",
+ "license": "GPL-2.0+",
+ "homepage": "https://www.drupal.org/project/entityqueue",
+ "minimum-stability": "dev",
+ "authors": [
+ {
+ "name": "Andrei Mateescu",
+ "homepage": "https://www.drupal.org/u/amateescu",
+ "role": "Maintainer"
+ },
+ {
+ "name": "Jonathan Jordan",
+ "homepage": "https://www.drupal.org/u/jojonaloha",
+ "role": "Maintainer"
+ }
+ ],
+ "support": {
+ "issues": "https://www.drupal.org/project/issues/entityqueue",
+ "irc": "irc://irc.freenode.org/drupal-contribute",
+ "source": "http://cgit.drupalcode.org/entityqueue"
+ },
+ "require": { }
+}
diff --git a/web/modules/contrib/entityqueue/config/schema/entityqueue.schema.yml b/web/modules/contrib/entityqueue/config/schema/entityqueue.schema.yml
index fd21d8560..7024d9c81 100644
--- a/web/modules/contrib/entityqueue/config/schema/entityqueue.schema.yml
+++ b/web/modules/contrib/entityqueue/config/schema/entityqueue.schema.yml
@@ -11,9 +11,8 @@ entityqueue.entity_queue.*:
handler:
type: string
label: 'Queue handler'
-#TODO: Provide a schema for queue handler plugins.
handler_configuration:
- type: ignore
+ type: entityqueue_handler_configuration.[%parent.handler]
label: 'Queue handler configuration'
entity_settings:
type: mapping
@@ -44,3 +43,20 @@ entityqueue.entity_queue.*:
reverse_in_admin:
type: boolean
label: 'Reverse order in admin view'
+
+# Base schema for all entity queue handler schemas.
+entityqueue_handler_configuration:
+ type: mapping
+ label: 'Entity queue handler configuration'
+
+# Schema for all entity queue handlers that are not providing a specific schema.
+entityqueue_handler_configuration.*:
+ type: entityqueue_handler_configuration
+
+views.relationship.entity_queue:
+ type: views_relationship
+ label: 'Entity queue'
+ mapping:
+ limit_queue:
+ type: string
+ label: 'Limit to a specific entity queue'
diff --git a/web/modules/contrib/entityqueue/entityqueue.info.yml b/web/modules/contrib/entityqueue/entityqueue.info.yml
index bc428d9c6..9955a589a 100644
--- a/web/modules/contrib/entityqueue/entityqueue.info.yml
+++ b/web/modules/contrib/entityqueue/entityqueue.info.yml
@@ -5,8 +5,8 @@ package: Entityqueue
# core: 8.x
configure: entity.entity_queue.collection
-# Information added by Drupal.org packaging script on 2017-10-01
-version: '8.x-1.0-alpha7'
+# Information added by Drupal.org packaging script on 2018-09-05
+version: '8.x-1.0-alpha8'
core: '8.x'
project: 'entityqueue'
-datestamp: 1506839349
+datestamp: 1536140287
diff --git a/web/modules/contrib/entityqueue/entityqueue.links.task.yml b/web/modules/contrib/entityqueue/entityqueue.links.task.yml
new file mode 100644
index 000000000..598915770
--- /dev/null
+++ b/web/modules/contrib/entityqueue/entityqueue.links.task.yml
@@ -0,0 +1,3 @@
+entityqueue.entities:
+ class: \Drupal\Core\Menu\LocalTaskDefault
+ deriver: \Drupal\entityqueue\Plugin\Derivative\EntityqueueLocalTask
diff --git a/web/modules/contrib/entityqueue/entityqueue.module b/web/modules/contrib/entityqueue/entityqueue.module
index 117a264fb..9a76f70cb 100644
--- a/web/modules/contrib/entityqueue/entityqueue.module
+++ b/web/modules/contrib/entityqueue/entityqueue.module
@@ -39,11 +39,6 @@ function entityqueue_views_pre_render(ViewExecutable $view) {
return;
}
- // Proceed only if there is entityqueue sort criteria available.
- if (!$sort_key = entityqueue_get_entityqueue_sort($view)) {
- return;
- }
-
// Allow to disable the contextual links.
if (!$view->display_handler->getOption('show_admin_links')) {
return;
@@ -76,37 +71,16 @@ function entityqueue_views_pre_render(ViewExecutable $view) {
* Change Entityqueue on views into offcanvas links if available.
*/
function entityqueue_contextual_links_view_alter(&$element, $items) {
- if (\Drupal::moduleHandler()->moduleExists('outside_in') && isset($element['#links']['entityentity-subqueueedit-form'])) {
+ if (\Drupal::moduleHandler()->moduleExists('settings_tray') && isset($element['#links']['entityentity-subqueueedit-form'])) {
$element['#links']['entityentity-subqueueedit-form']['attributes'] = [
'class' => ['use-ajax'],
'data-dialog-type' => 'dialog',
- 'data-dialog-renderer' => 'offcanvas',
- 'data-outside-in-edit' => TRUE,
+ 'data-dialog-renderer' => 'off_canvas',
+ 'data-settings-tray-edit' => TRUE,
];
-
- $element['#attached']['library'][] = 'outside_in/drupal.off_canvas';
}
}
-/**
- * Get the entityqueue position sort of a view if there is one and return its
- * ID. If there are multiple of these sorts the first is returned.
- *
- * @param $view
- * The view object.
- *
- * @return
- * The ID of the sort or FALSE if there isn't one.
- */
-function entityqueue_get_entityqueue_sort($view) {
- foreach ($view->sort as $id => $sort) {
- if ($sort->definition['id'] == 'entity_queue_position') {
- return $id;
- }
- }
- return FALSE;
-}
-
/**
* Implements hook_entity_delete().
*
@@ -116,23 +90,20 @@ function entityqueue_entity_delete(EntityInterface $entity) {
// Get all the entity queues referencing the targets entity type.
$queues = EntityQueue::loadMultipleByTargetType($entity->getEntityTypeId());
foreach ($queues as $queue) {
- $entity_settings = $queue->getEntitySettings();
-
- // Check if the queue's bundle also matches that of the target entity.
- if (is_array($entity_settings['handler_settings']['target_bundles']) && in_array($entity->bundle(), $entity_settings['handler_settings']['target_bundles'])) {
- // Get subqueues.
- $query = \Drupal::entityQuery('entity_subqueue')->condition('queue', $queue->id());
- $result = $query->execute();
- $subqueues = EntitySubqueue::loadMultiple($result);
+ // Get all the subqueues which are referencing the deleted entity.
+ $query = \Drupal::entityQuery('entity_subqueue')
+ ->condition('queue', $queue->id())
+ ->condition('items', $entity->id());
+ $result = $query->execute();
+ $subqueues = EntitySubqueue::loadMultiple($result);
- // Check if the entity is referenced in a subqueue.
- foreach ($subqueues as $subqueue) {
- $items = $subqueue->get('items')->getValue();
- if (($item_key = array_search($entity->id(), array_column($items, 'target_id'))) !== FALSE) {
- unset($items[$item_key]);
- $subqueue->set('items', $items);
- $subqueue->save();
- }
+ // Check if the entity is referenced in a subqueue.
+ foreach ($subqueues as $subqueue) {
+ $items = $subqueue->get('items')->getValue();
+ if (($item_key = array_search($entity->id(), array_column($items, 'target_id'))) !== FALSE) {
+ unset($items[$item_key]);
+ $subqueue->set('items', $items);
+ $subqueue->save();
}
}
}
diff --git a/web/modules/contrib/entityqueue/entityqueue.routing.yml b/web/modules/contrib/entityqueue/entityqueue.routing.yml
index 91c445940..8d23d8434 100644
--- a/web/modules/contrib/entityqueue/entityqueue.routing.yml
+++ b/web/modules/contrib/entityqueue/entityqueue.routing.yml
@@ -20,7 +20,7 @@ entity.entity_queue.edit_form:
_entity_form: 'entity_queue.edit'
_title: 'Edit Entity Queue'
requirements:
- _permission: 'administer entityqueue+manipulate entityqueues+manipulate all entityqueues'
+ _permission: 'administer entityqueue'
entity.entity_queue.delete_form:
path: '/admin/structure/entityqueue/{entity_queue}/delete'
@@ -28,7 +28,7 @@ entity.entity_queue.delete_form:
_entity_form: 'entity_queue.delete'
_title: 'Delete Entity Queue'
requirements:
- _permission: 'administer entityqueue+manipulate entityqueues+manipulate all entityqueues'
+ _permission: 'administer entityqueue'
entity.entity_queue.enable:
path: '/admin/structure/entityqueue/{entity_queue}/enable'
@@ -63,3 +63,21 @@ entity.entity_subqueue.add_form:
_title: 'Add subqueue'
requirements:
_entity_create_access: 'entity_subqueue:{entity_queue}'
+
+entity.entity_subqueue.add_item:
+ path: '/admin/structure/entityqueue/{entity_queue}/{entity_subqueue}/{entity}/add-item'
+ defaults:
+ _controller: '\Drupal\entityqueue\Controller\EntityQueueUIController::subqueueAjaxOperation'
+ op: addItem
+ requirements:
+ _permission: 'administer entityqueue+manipulate entityqueues+manipulate all entityqueues'
+ _csrf_token: 'TRUE'
+
+entity.entity_subqueue.remove_item:
+ path: '/admin/structure/entityqueue/{entity_queue}/{entity_subqueue}/{entity}/remove-item'
+ defaults:
+ _controller: '\Drupal\entityqueue\Controller\EntityQueueUIController::subqueueAjaxOperation'
+ op: removeItem
+ requirements:
+ _permission: 'administer entityqueue+manipulate entityqueues+manipulate all entityqueues'
+ _csrf_token: 'TRUE'
diff --git a/web/modules/contrib/entityqueue/entityqueue.services.yml b/web/modules/contrib/entityqueue/entityqueue.services.yml
index 4d8893593..e314177b0 100644
--- a/web/modules/contrib/entityqueue/entityqueue.services.yml
+++ b/web/modules/contrib/entityqueue/entityqueue.services.yml
@@ -2,3 +2,8 @@ services:
plugin.manager.entityqueue.handler:
class: Drupal\entityqueue\EntityQueueHandlerManager
arguments: ['@container.namespaces', '@cache.default', '@module_handler']
+ entityqueue.route_subscriber:
+ class: Drupal\entityqueue\Routing\RouteSubscriber
+ arguments: ['@entity_type.manager']
+ tags:
+ - { name: event_subscriber }
diff --git a/web/modules/contrib/entityqueue/entityqueue.views.inc b/web/modules/contrib/entityqueue/entityqueue.views.inc
index aa2026ca6..a4f63efe6 100644
--- a/web/modules/contrib/entityqueue/entityqueue.views.inc
+++ b/web/modules/contrib/entityqueue/entityqueue.views.inc
@@ -57,38 +57,55 @@ function entityqueue_views_data_alter(array &$data) {
'field field' => $columns['target_id'],
];
- $data[$target_base_table]['entityqueue_relationship']['sort'] = array(
+ $data[$target_base_table]['entityqueue_relationship_in_queue']['sort'] = [
+ 'id' => 'entity_queue_in_queue',
+ 'group' => t('Entityqueue'),
+ 'title' => t('In @target_label queue', [
+ '@target_label' => $entity_type->getLabel(),
+ ]),
+ 'label' => t('In @target_label queue', [
+ '@target_label' => $entity_type->getLabel(),
+ ]),
+ 'help' => t('Filter to ensure a(n) @target_label IS or IS NOT in the related queue', [
+ '@target_label' => $entity_type->getLabel(),
+ ]),
+ 'field' => 'delta',
+ 'field table' => $subqueue_items_table_name,
+ 'field_name' => $field_name,
+ ];
+
+ $data[$target_base_table]['entityqueue_relationship']['sort'] = [
'id' => 'entity_queue_position',
'group' => t('Entityqueue'),
- 'title' => t('@target_label Queue Position', array(
+ 'title' => t('@target_label Queue Position', [
'@target_label' => $entity_type->getLabel(),
- )),
- 'label' => t('@target_label Queue Position', array(
+ ]),
+ 'label' => t('@target_label Queue Position', [
'@target_label' => $entity_type->getLabel(),
- )),
- 'help' => t('Position of item in the @target_label queue.', array(
+ ]),
+ 'help' => t('Position of item in the @target_label queue.', [
'@target_label' => $entity_type->getLabel(),
- )),
+ ]),
'field' => 'delta',
'field table' => $subqueue_items_table_name,
'field_name' => $field_name,
- );
+ ];
- $data[$target_base_table]['entityqueue_relationship']['filter'] = array(
+ $data[$target_base_table]['entityqueue_relationship']['filter'] = [
'id' => 'entity_queue_in_queue',
'type' => 'yes-no',
'group' => t('Entityqueue'),
- 'title' => t('@target_label In Queue', array(
+ 'title' => t('@target_label In Queue', [
'@target_label' => $entity_type->getLabel(),
- )),
- 'label' => t('@target_label In Queue', array(
+ ]),
+ 'label' => t('@target_label In Queue', [
'@target_label' => $entity_type->getLabel(),
- )),
- 'help' => t('Filter for entities that are available or not in the @target_label entity queue.', array(
+ ]),
+ 'help' => t('Filter for entities that are available or not in the @target_label entity queue.', [
'@target_label' => $entity_type->getLabel(),
- )),
+ ]),
'field table' => $subqueue_items_table_name,
'field field' => $columns['target_id'],
- );
+ ];
}
}
diff --git a/web/modules/contrib/entityqueue/plugins/entityreference/selection/EntityReference_SelectionHandler_EntityQueue.class.php b/web/modules/contrib/entityqueue/plugins/entityreference/selection/EntityReference_SelectionHandler_EntityQueue.class.php
deleted file mode 100644
index 026976216..000000000
--- a/web/modules/contrib/entityqueue/plugins/entityreference/selection/EntityReference_SelectionHandler_EntityQueue.class.php
+++ /dev/null
@@ -1,85 +0,0 @@
-queue)) {
- $queue_name = $entity->queue;
- }
- elseif (!empty($instance['bundle'])) {
- $queue_name = $instance['bundle'];
- }
- if (!empty($queue_name)) {
- $this->queue = entityqueue_queue_load($queue_name);
- }
-
- // Override the entityreference settings with our own.
- $this->field['settings']['handler_settings']['target_bundles'] = NULL;
- }
-
- /**
- * Overrides EntityReference_SelectionHandler_Generic::buildEntityFieldQuery().
- */
- public function buildEntityFieldQuery($match = NULL, $match_operator = 'CONTAINS') {
- $handler = EntityReference_SelectionHandler_Generic::getInstance($this->field, $this->instance, $this->entity_type, $this->entity);
- $query = $handler->buildEntityFieldQuery($match, $match_operator);
-
- if (!empty($this->queue->settings['target_bundles'])) {
- $query->entityCondition('bundle', $this->queue->settings['target_bundles'], 'IN');
- }
-
- return $query;
- }
-
- /**
- * Implements EntityReferenceHandler::validateReferencableEntities().
- */
- public function validateReferencableEntities(array $ids) {
- $referencable = parent::validateReferencableEntities($ids);
- // Allow users to save the queue even if they don't have access to an
- // existing entity in the queue. See https://www.drupal.org/node/2383903
- $existing = $this->getCurrentlyReferencedEntityIds();
-
- return array_unique(array_merge($referencable, $existing));
- }
-
- /**
- * Gets ids of existing entities in the queue.
- *
- * @return array
- * Entity ids that are currently referenced by the entity.
- */
- public function getCurrentlyReferencedEntityIds() {
- $ret = array();
- if (isset($this->entity) && isset($this->field)) {
- $entity_type = $this->entity_type;
- $field_name = $this->field['field_name'];
- $wrapper = entity_metadata_wrapper($entity_type, $this->entity);
- $ret = $wrapper->{$field_name}->raw();
- }
-
- return $ret;
- }
-
-}
diff --git a/web/modules/contrib/entityqueue/plugins/entityreference/selection/entityqueue.inc b/web/modules/contrib/entityqueue/plugins/entityreference/selection/entityqueue.inc
deleted file mode 100644
index c43b6e114..000000000
--- a/web/modules/contrib/entityqueue/plugins/entityreference/selection/entityqueue.inc
+++ /dev/null
@@ -1,13 +0,0 @@
- t('Entityqueue'),
- 'class' => 'EntityReference_SelectionHandler_EntityQueue',
- 'weight' => 0,
-);
diff --git a/web/modules/contrib/entityqueue/src/Controller/EntityQueueUIController.php b/web/modules/contrib/entityqueue/src/Controller/EntityQueueUIController.php
index 58be72fd2..b32630611 100644
--- a/web/modules/contrib/entityqueue/src/Controller/EntityQueueUIController.php
+++ b/web/modules/contrib/entityqueue/src/Controller/EntityQueueUIController.php
@@ -3,13 +3,19 @@
namespace Drupal\entityqueue\Controller;
use Drupal\Core\Controller\ControllerBase;
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Routing\RouteMatch;
use Drupal\entityqueue\EntityQueueInterface;
use Symfony\Component\HttpFoundation\Request;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\ReplaceCommand;
+use Drupal\entityqueue\EntitySubqueueInterface;
+use Drupal\Core\Url;
+use Drupal\Core\Routing\RouteMatchInterface;
+use Drupal\Core\Access\AccessResult;
/**
- * Returns responses for Views UI routes.
+ * Returns responses for Entityqueue UI routes.
*/
class EntityQueueUIController extends ControllerBase {
@@ -29,6 +35,87 @@ class EntityQueueUIController extends ControllerBase {
return $list_builder->render();
}
+ /**
+ * Provides a list of subqueues where an entity can be added.
+ *
+ * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
+ * The route match.
+ * @param string $entity_type_id
+ * (optional) The entity type ID.
+ * @param \Drupal\Core\Entity\EntityInterface $entity
+ * (optional) An entity object.
+ *
+ * @return array
+ * Array of page elements to render.
+ */
+ public function subqueueListForEntity(RouteMatchInterface $route_match, $entity_type_id = NULL, EntityInterface $entity = NULL) {
+ if (!$entity) {
+ $entity = $route_match->getParameter($entity_type_id);
+ }
+
+ $queues = $this->getAvailableQueuesForEntity($entity);
+ $subqueues = $this->entityTypeManager()->getStorage('entity_subqueue')->loadByProperties(['queue' => array_keys($queues)]);
+ $list_builder = $this->entityTypeManager()->getListBuilder('entity_subqueue');
+
+ $build['#title'] = $this->t('Entityqueues for %title', ['%title' => $entity->label()]);
+ $build['#type'] = 'container';
+ $build['#attributes']['id'] = 'entity-subqueue-list';
+ $build['#attached']['library'][] = 'core/drupal.ajax';
+ $build['table'] = [
+ '#type' => 'table',
+ '#header' => $list_builder->buildHeader(),
+ '#rows' => [],
+ '#cache' => [],
+ '#empty' => $this->t('There are no queues available.'),
+ ];
+
+ /** @var \Drupal\entityqueue\EntitySubqueueInterface $subqueue */
+ foreach ($subqueues as $subqueue_id => $subqueue) {
+ $row = $list_builder->buildRow($subqueue);
+
+ // Check if entity is in queue
+ $subqueue_items = $subqueue->get('items')->getValue();
+ if (in_array($entity->id(), array_column($subqueue_items, 'target_id'), TRUE)) {
+ $row['operations']['data']['#links'] = [
+ 'remove-item' => [
+ 'title' => $this->t('Remove from queue'),
+ 'url' => Url::fromRoute('entity.entity_subqueue.remove_item', ['entity_queue' => $queues[$subqueue->bundle()]->id(), 'entity_subqueue' => $subqueue_id, 'entity' => $entity->id()]),
+ 'attributes' => [
+ 'class' => ['use-ajax'],
+ ],
+ ],
+ ];
+ }
+ else {
+ $row['operations']['data']['#links'] = [
+ 'add-item' => [
+ 'title' => $this->t('Add to queue'),
+ 'url' => Url::fromRoute('entity.entity_subqueue.add_item', ['entity_queue' => $queues[$subqueue->bundle()]->id(), 'entity_subqueue' => $subqueue_id, 'entity' => $entity->id()]),
+ 'attributes' => [
+ 'class' => ['use-ajax'],
+ ],
+ ],
+ ];
+ }
+
+ // Add an operation for editing the subqueue items.
+ // First, compute the destination to send the user back to the
+ // entityqueue tab they're currently on. We can't rely on
+ // since if any of the AJAX links are used and the page is rebuilt,
+ // will point to the most recent AJAX callback, not the
+ // original entityqueue tab.
+ $destination = Url::fromRoute("entity.$entity_type_id.entityqueue", [$entity_type_id => $entity->id()])->toString();
+ $row['operations']['data']['#links']['edit-subqueue-items'] = [
+ 'title' => $this->t('Edit subqueue items'),
+ 'url' => $subqueue->toUrl('edit-form', ['query' => ['destination' => $destination]]),
+ ];
+
+ $build['table']['#rows'][$subqueue->id()] = $row;
+ }
+
+ return $build;
+ }
+
/**
* Returns a form to add a new subqeue.
*
@@ -73,4 +160,88 @@ class EntityQueueUIController extends ControllerBase {
return $this->redirect('entity.entity_queue.collection');
}
+ /**
+ * Calls a method on an entity subqueue page and reloads the page.
+ *
+ * @param \Drupal\entityqueue\EntitySubqueueInterface $entity_subqueue
+ * The subqueue being acted upon.
+ * @param string $op
+ * The operation to perform, e.g., 'addItem' or 'removeItem'.
+ * @param \Symfony\Component\HttpFoundation\Request $request
+ * The current request.
+ *
+ * @return \Drupal\Core\Ajax\AjaxResponse|\Symfony\Component\HttpFoundation\RedirectResponse
+ * Either returns a rebuilt listing page as an AJAX response, or redirects
+ * back to the current page.
+ */
+ public function subqueueAjaxOperation(EntitySubqueueInterface $entity_subqueue, $op, Request $request) {
+ $entity_id = $request->get('entity');
+ $entity = $this->entityTypeManager()->getStorage($entity_subqueue->getQueue()->getTargetEntityTypeId())->load($entity_id);
+
+ // Perform the operation.
+ $entity_subqueue->$op($entity)->save();
+
+ // If the request is via AJAX, return the rendered list as JSON.
+ if ($request->request->get('js')) {
+ $route_match = RouteMatch::createFromRequest($request);
+ $list = $this->subqueueListForEntity($route_match, $entity->getEntityTypeId(), $entity);
+ $response = new AjaxResponse();
+ $response->addCommand(new ReplaceCommand('#entity-subqueue-list', $list));
+ return $response;
+ }
+
+ // Otherwise, redirect back to the page.
+ return $this->redirect('');
+ }
+
+ /**
+ * Checks access for a specific request.
+ *
+ * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
+ * The route match.
+ * @param string $entity_type_id
+ * (optional) The entity type ID.
+ *
+ * @return \Drupal\Core\Access\AccessResultInterface
+ * The access result.
+ */
+ public function access(RouteMatchInterface $route_match, $entity_type_id = NULL) {
+ /** @var \Drupal\Core\Entity\EntityInterface $entity */
+ $entity = $route_match->getParameter($entity_type_id);
+
+ if ($this->getAvailableQueuesForEntity($entity)) {
+ return AccessResult::allowed();
+ }
+
+ return AccessResult::forbidden();
+ }
+
+ /**
+ * Gets a list of queues which can hold this entity.
+ *
+ * @param \Drupal\Core\Entity\EntityInterface $entity
+ * An entity object.
+ *
+ * @return \Drupal\entityqueue\EntityQueueInterface[]
+ * An array of entity queues which can hold this entity.
+ */
+ protected function getAvailableQueuesForEntity(EntityInterface $entity) {
+ $storage = $this->entityTypeManager()->getStorage('entity_queue');
+
+ $queue_ids = $storage->getQuery()
+ ->condition('entity_settings.target_type', $entity->getEntityTypeId(), '=')
+ ->condition('status', TRUE)
+ ->execute();
+
+ $queues = $storage->loadMultiple($queue_ids);
+ $queues = array_filter($queues, function ($queue) use ($entity) {
+ /** @var \Drupal\entityqueue\EntityQueueInterface $queue */
+ $queue_settings = $queue->getEntitySettings();
+ $target_bundles = &$queue_settings['handler_settings']['target_bundles'];
+ return ($target_bundles === NULL || in_array($entity->bundle(), $target_bundles, TRUE));
+ });
+
+ return $queues;
+ }
+
}
diff --git a/web/modules/contrib/entityqueue/src/Entity/EntityQueue.php b/web/modules/contrib/entityqueue/src/Entity/EntityQueue.php
index 706bd14c0..8455bac7d 100644
--- a/web/modules/contrib/entityqueue/src/Entity/EntityQueue.php
+++ b/web/modules/contrib/entityqueue/src/Entity/EntityQueue.php
@@ -22,7 +22,8 @@ use Drupal\entityqueue\EntityQueueInterface;
* "add" = "Drupal\entityqueue\Form\EntityQueueForm",
* "edit" = "Drupal\entityqueue\Form\EntityQueueForm",
* "delete" = "Drupal\Core\Entity\EntityDeleteForm"
- * }
+ * },
+ * "access" = "Drupal\entityqueue\EntityQueueAccessControlHandler",
* },
* admin_permission = "administer entityqueue",
* config_prefix = "entity_queue",
@@ -174,9 +175,16 @@ class EntityQueue extends ConfigEntityBundleBase implements EntityQueueInterface
/**
* {@inheritdoc}
*/
- public function setHandler($handler) {
- $this->handler = $handler;
- $this->getPluginCollection()->addInstanceID($handler, []);
+ public function getHandlerConfiguration() {
+ return $this->handler_configuration;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setHandler($handler_id) {
+ $this->handler = $handler_id;
+ $this->getPluginCollection()->addInstanceID($handler_id, []);
return $this;
}
@@ -188,6 +196,15 @@ class EntityQueue extends ConfigEntityBundleBase implements EntityQueueInterface
return $this->getPluginCollection()->get($this->handler);
}
+ /**
+ * {@inheritdoc}
+ */
+ public function setHandlerPlugin($handler) {
+ $this->getPluginCollection()->set($handler->getPluginId(), $handler);
+
+ return $this;
+ }
+
/**
* {@inheritdoc}
*/
diff --git a/web/modules/contrib/entityqueue/src/Entity/EntitySubqueue.php b/web/modules/contrib/entityqueue/src/Entity/EntitySubqueue.php
index 349ab962e..ba7b5fdd9 100644
--- a/web/modules/contrib/entityqueue/src/Entity/EntitySubqueue.php
+++ b/web/modules/contrib/entityqueue/src/Entity/EntitySubqueue.php
@@ -5,6 +5,7 @@ namespace Drupal\entityqueue\Entity;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Entity\ContentEntityBase;
use Drupal\Core\Entity\EntityChangedTrait;
+use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\BaseFieldDefinition;
@@ -168,15 +169,16 @@ class EntitySubqueue extends ContentEntityBase implements EntitySubqueueInterfac
->setLabel(t('Title'))
->setRequired(TRUE)
->setSetting('max_length', 191)
- ->setDisplayOptions('view', array(
+ ->setDisplayOptions('view', [
'label' => 'hidden',
'type' => 'string',
'weight' => -10,
- ))
- ->setDisplayOptions('form', array(
+ ])
+ ->setDisplayConfigurable('view', TRUE)
+ ->setDisplayOptions('form', [
'type' => 'string_textfield',
'weight' => -10,
- ))
+ ])
->setDisplayConfigurable('form', TRUE);
$fields['items'] = BaseFieldDefinition::create('entity_reference')
@@ -187,33 +189,33 @@ class EntitySubqueue extends ContentEntityBase implements EntitySubqueueInterfac
// entity type that uses strings IDs, in order to allow both integers and
// strings to be stored by the default entity reference field storage.
->setSetting('target_type', 'entity_subqueue')
- ->setDisplayOptions('view', array(
+ ->setDisplayOptions('view', [
'label' => 'hidden',
'type' => 'entity_reference_label',
'weight' => 0,
- ))
- ->setDisplayOptions('form', array(
+ ])
+ ->setDisplayOptions('form', [
'type' => 'entity_reference_autocomplete',
'weight' => 5,
- 'settings' => array(
+ 'settings' => [
'match_operator' => 'CONTAINS',
'size' => '60',
'placeholder' => '',
- ),
- ))
+ ],
+ ])
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE);
$fields['langcode'] = BaseFieldDefinition::create('language')
->setLabel(t('Language'))
->setDescription(t('The subqueue language code.'))
- ->setDisplayOptions('view', array(
+ ->setDisplayOptions('view', [
'type' => 'hidden',
- ))
- ->setDisplayOptions('form', array(
+ ])
+ ->setDisplayOptions('form', [
'type' => 'language_select',
'weight' => 2,
- ));
+ ]);
$fields['uid'] = BaseFieldDefinition::create('entity_reference')
->setLabel(t('Authored by'))
@@ -277,6 +279,28 @@ class EntitySubqueue extends ContentEntityBase implements EntitySubqueueInterfac
return $this;
}
+ /**
+ * {@inheritdoc}
+ */
+ public function addItem(EntityInterface $entity) {
+ $this->get('items')->appendItem($entity->id());
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function removeItem(EntityInterface $entity) {
+ $subqueue_items = $this->get('items')->getValue();
+ foreach ($subqueue_items as $key => $item) {
+ if ($item['target_id'] == $entity->id()) {
+ unset($subqueue_items[$key]);
+ }
+ }
+ $this->get('items')->setValue($subqueue_items);
+ return $this;
+ }
+
/**
* Default value callback for 'uid' base field definition.
*
@@ -286,7 +310,7 @@ class EntitySubqueue extends ContentEntityBase implements EntitySubqueueInterfac
* An array of default values.
*/
public static function getCurrentUserId() {
- return array(\Drupal::currentUser()->id());
+ return [\Drupal::currentUser()->id()];
}
/**
diff --git a/web/modules/contrib/entityqueue/src/EntityQueueAccessControlHandler.php b/web/modules/contrib/entityqueue/src/EntityQueueAccessControlHandler.php
new file mode 100644
index 000000000..6151dc07b
--- /dev/null
+++ b/web/modules/contrib/entityqueue/src/EntityQueueAccessControlHandler.php
@@ -0,0 +1,48 @@
+id()} entityqueue", 'manipulate all entityqueues', 'administer entityqueue'], 'OR');
+ break;
+
+ case 'delete':
+ return AccessResult::allowedIfHasPermissions($account, ["delete {$entity->id()} entityqueue", 'manipulate all entityqueues', 'administer entityqueue'], 'OR');
+ break;
+
+ default:
+ // No opinion.
+ return AccessResult::neutral();
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
+ return AccessResult::allowedIfHasPermission($account, 'administer entityqueue');
+ }
+
+}
diff --git a/web/modules/contrib/entityqueue/src/EntityQueueHandlerBase.php b/web/modules/contrib/entityqueue/src/EntityQueueHandlerBase.php
index 94cc9d2c7..cd989a153 100644
--- a/web/modules/contrib/entityqueue/src/EntityQueueHandlerBase.php
+++ b/web/modules/contrib/entityqueue/src/EntityQueueHandlerBase.php
@@ -3,6 +3,7 @@
namespace Drupal\entityqueue;
use Drupal\Component\Plugin\PluginBase;
+use Drupal\Component\Utility\NestedArray;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Form\FormStateInterface;
@@ -28,7 +29,7 @@ abstract class EntityQueueHandlerBase extends PluginBase implements EntityQueueH
*/
public function __construct(array $configuration, $plugin_id, array $plugin_definition) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
- $this->configuration += $this->defaultConfiguration();
+ $this->setConfiguration($configuration);
}
/**
@@ -42,7 +43,7 @@ abstract class EntityQueueHandlerBase extends PluginBase implements EntityQueueH
* {@inheritdoc}
*/
public function setConfiguration(array $configuration) {
- $this->configuration = $configuration;
+ $this->configuration = NestedArray::mergeDeep($this->defaultConfiguration(), $configuration);
}
/**
@@ -106,26 +107,26 @@ abstract class EntityQueueHandlerBase extends PluginBase implements EntityQueueH
/**
* {@inheritdoc}
*/
- public function onQueuePreSave(EntityQueueInterface $queue, EntityStorageInterface $storage) { }
+ public function onQueuePreSave(EntityQueueInterface $queue, EntityStorageInterface $storage) {}
/**
* {@inheritdoc}
*/
- public function onQueuePostSave(EntityQueueInterface $queue, EntityStorageInterface $storage, $update = TRUE) { }
+ public function onQueuePostSave(EntityQueueInterface $queue, EntityStorageInterface $storage, $update = TRUE) {}
/**
* {@inheritdoc}
*/
- public function onQueuePreDelete(EntityQueueInterface $queue, EntityStorageInterface $storage) { }
+ public function onQueuePreDelete(EntityQueueInterface $queue, EntityStorageInterface $storage) {}
/**
* {@inheritdoc}
*/
- public function onQueuePostDelete(EntityQueueInterface $queue, EntityStorageInterface $storage) { }
+ public function onQueuePostDelete(EntityQueueInterface $queue, EntityStorageInterface $storage) {}
/**
* {@inheritdoc}
*/
- public function onQueuePostLoad(EntityQueueInterface $queue, EntityStorageInterface $storage) { }
+ public function onQueuePostLoad(EntityQueueInterface $queue, EntityStorageInterface $storage) {}
}
diff --git a/web/modules/contrib/entityqueue/src/EntityQueueHandlerInterface.php b/web/modules/contrib/entityqueue/src/EntityQueueHandlerInterface.php
index 0731c0886..650c22467 100644
--- a/web/modules/contrib/entityqueue/src/EntityQueueHandlerInterface.php
+++ b/web/modules/contrib/entityqueue/src/EntityQueueHandlerInterface.php
@@ -2,6 +2,8 @@
namespace Drupal\entityqueue;
+use Drupal\Component\Plugin\DerivativeInspectionInterface;
+use Drupal\Component\Plugin\PluginInspectionInterface;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Plugin\PluginFormInterface;
use Drupal\Component\Plugin\ConfigurablePluginInterface;
@@ -14,7 +16,7 @@ use Drupal\Component\Plugin\ConfigurablePluginInterface;
* @see \Drupal\entityqueue\EntityQueueHandlerBase
* @see plugin_api
*/
-interface EntityQueueHandlerInterface extends PluginFormInterface, ConfigurablePluginInterface {
+interface EntityQueueHandlerInterface extends PluginFormInterface, ConfigurablePluginInterface, PluginInspectionInterface, DerivativeInspectionInterface {
/**
* Sets the entity queue that is using this plugin.
@@ -55,7 +57,7 @@ interface EntityQueueHandlerInterface extends PluginFormInterface, ConfigurableP
/**
* Acts on an entity queue before the presave hook is invoked.
*
- * @param \Drupal\entityqueue\EntityQueueInterface
+ * @param \Drupal\entityqueue\EntityQueueInterface $queue
* The entity queue object.
* @param \Drupal\Core\Entity\EntityStorageInterface $storage
* The entity storage object.
@@ -65,7 +67,7 @@ interface EntityQueueHandlerInterface extends PluginFormInterface, ConfigurableP
/**
* Acts on an entity queue before the insert or update hook is invoked.
*
- * @param \Drupal\entityqueue\EntityQueueInterface
+ * @param \Drupal\entityqueue\EntityQueueInterface $queue
* The entity queue object.
* @param \Drupal\Core\Entity\EntityStorageInterface $storage
* The entity storage object.
@@ -77,7 +79,7 @@ interface EntityQueueHandlerInterface extends PluginFormInterface, ConfigurableP
/**
* Acts on entity queues before they are deleted and before hooks are invoked.
*
- * @param \Drupal\entityqueue\EntityQueueInterface
+ * @param \Drupal\entityqueue\EntityQueueInterface $queue
* The entity queue object.
* @param \Drupal\Core\Entity\EntityStorageInterface $storage
* The entity storage object.
@@ -87,7 +89,7 @@ interface EntityQueueHandlerInterface extends PluginFormInterface, ConfigurableP
/**
* Acts on deleted entity queues before the delete hook is invoked.
*
- * @param \Drupal\entityqueue\EntityQueueInterface
+ * @param \Drupal\entityqueue\EntityQueueInterface $queue
* The entity queue object.
* @param \Drupal\Core\Entity\EntityStorageInterface $storage
* The entity storage object.
@@ -97,7 +99,7 @@ interface EntityQueueHandlerInterface extends PluginFormInterface, ConfigurableP
/**
* Acts on loaded entity queues.
*
- * @param \Drupal\entityqueue\EntityQueueInterface
+ * @param \Drupal\entityqueue\EntityQueueInterface $queue
* The entity queue object.
* @param \Drupal\Core\Entity\EntityStorageInterface $storage
* The entity storage object.
diff --git a/web/modules/contrib/entityqueue/src/EntityQueueInterface.php b/web/modules/contrib/entityqueue/src/EntityQueueInterface.php
index d861287bb..630e5e2fb 100644
--- a/web/modules/contrib/entityqueue/src/EntityQueueInterface.php
+++ b/web/modules/contrib/entityqueue/src/EntityQueueInterface.php
@@ -10,21 +10,29 @@ use Drupal\Core\Config\Entity\ConfigEntityInterface;
interface EntityQueueInterface extends ConfigEntityInterface {
/**
- * Gets the EntityQueueHandler plugin id.
+ * Gets the EntityQueueHandler plugin ID.
*
* @return string
*/
public function getHandler();
+ /**
+ * Gets the handler plugin configuration for this queue.
+ *
+ * @return mixed[]
+ * The handler plugin configuration.
+ */
+ public function getHandlerConfiguration();
+
/**
* Sets the EntityQueueHandler.
*
- * @param string $handler
+ * @param string $handler_id
* The handler name.
*
* @return $this
*/
- public function setHandler($handler);
+ public function setHandler($handler_id);
/**
* Gets the EntityQueueHandler plugin object.
@@ -33,6 +41,16 @@ interface EntityQueueInterface extends ConfigEntityInterface {
*/
public function getHandlerPlugin();
+ /**
+ * Sets the EntityQueueHandler plugin object.
+ *
+ * @param \Drupal\entityqueue\EntityQueueHandlerInterface $handler
+ * A queue handler plugin.
+ *
+ * @return $this
+ */
+ public function setHandlerPlugin($handler);
+
/**
* Gets the ID of the target entity type.
*
diff --git a/web/modules/contrib/entityqueue/src/EntityQueueListBuilder.php b/web/modules/contrib/entityqueue/src/EntityQueueListBuilder.php
index 76a13df3f..77fa85da0 100644
--- a/web/modules/contrib/entityqueue/src/EntityQueueListBuilder.php
+++ b/web/modules/contrib/entityqueue/src/EntityQueueListBuilder.php
@@ -2,10 +2,12 @@
namespace Drupal\entityqueue;
+use Drupal\Core\Cache\Cache;
use Drupal\Core\Config\Entity\ConfigEntityListBuilder;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Session\AccountInterface;
use Drupal\entityqueue\Entity\EntitySubqueue;
use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -21,6 +23,11 @@ class EntityQueueListBuilder extends ConfigEntityListBuilder {
*/
protected $entityTypeManager;
+ /**
+ * {@inheritdoc}
+ */
+ protected $limit = FALSE;
+
/**
* Constructs a new class instance.
*
@@ -49,11 +56,16 @@ class EntityQueueListBuilder extends ConfigEntityListBuilder {
* {@inheritdoc}
*/
public function load() {
- $entities = array(
- 'enabled' => array(),
- 'disabled' => array(),
- );
+ $entities = [
+ 'enabled' => [],
+ 'disabled' => [],
+ ];
+ /** @var \Drupal\entityqueue\EntityQueueInterface $entity */
foreach (parent::load() as $entity) {
+ // Don't display queues which can not be edited by the user.
+ if (!$entity->access('update')) {
+ continue;
+ }
if ($entity->status()) {
$entities['enabled'][] = $entity;
}
@@ -87,7 +99,7 @@ class EntityQueueListBuilder extends ConfigEntityListBuilder {
'handler' => $entity->getHandlerPlugin()->getPluginDefinition()['title'],
'items' => $this->getQueueItemsStatus($entity),
] + parent::buildRow($entity),
- 'title' => $this->t('Machine name: @name', array('@name' => $entity->id())),
+ 'title' => $this->t('Machine name: @name', ['@name' => $entity->id()]),
];
return $row;
@@ -102,25 +114,29 @@ class EntityQueueListBuilder extends ConfigEntityListBuilder {
$build['#type'] = 'container';
$build['#attributes']['id'] = 'entity-queue-list';
$build['#attached']['library'][] = 'core/drupal.ajax';
+ $build['#cache'] = [
+ 'contexts' => Cache::mergeContexts($this->entityType->getListCacheContexts(), ['user.permissions']),
+ 'tags' => $this->entityType->getListCacheTags(),
+ ];
- $build['enabled']['heading']['#markup'] = '
' . t('This module intends to deal with the EU Directive on Privacy and Electronic Communications that comes into effect on 26th May 2012.
- From that date, if you are not compliant or visibly working towards compliance,
- you run the risk of enforcement action, which can include a fine of up to
- half a million pounds for a serious breach.') . '
';
+ $output .= '
' . t('This module intends to deal with the EU Directive on Privacy and Electronic Communications that comes into effect on 26th May 2012. From that date, if you are not compliant or visibly working towards compliance, you run the risk of enforcement action, which can include a fine of up to half a million pounds for a serious breach.') . '
';
$output .= '
' . t('How it works') . '
';
- $output .= '
' . t('The module displays a banner at the bottom or the top of website to make users aware of the fact that cookies are being set. The user may then give
- his/her consent or move to a page that provides more details. Consent is given
- by user pressing the agree buttons or by continuing browsing the website. Once
- consent is given another banner appears with a âThank youâ message.') . '
';
+ $output .= '
' . t('The module displays a banner at the bottom or the top of website to make users aware of the fact that cookies are being set. The user may then give his/her consent or move to a page that provides more details. Consent is given by user pressing the agree buttons or by continuing browsing the website. Once consent is given another banner appears with a "Thank you" message.') . '
';
$output .= '
' . t('The module provides a settings page where the banner can be customized. There are also template files for the banners that can be overridden by your theme.') . '
';
$output .= '
' . t('Installation') . '
';
$output .= '
' . t('Unzip the files to the "sites/all/modules" OR "modules" directory and enable the module.') . '
';
@@ -67,7 +63,7 @@ function eu_cookie_compliance_page_attachments(&$attachments) {
if (!empty($config->get('domains_list'))) {
global $base_url;
- $domains_list = str_replace(array("\r\n", "\r"), "\n", $config->get('domains_list'));
+ $domains_list = str_replace(["\r\n", "\r"], "\n", $config->get('domains_list'));
$domains_list = explode("\n", $domains_list);
$domains_list = preg_replace('{/$}', '', $domains_list);
$domain_match = in_array($base_url, $domains_list);
@@ -85,8 +81,12 @@ function eu_cookie_compliance_page_attachments(&$attachments) {
$path_match = FALSE;
if (!empty($config->get('exclude_paths'))) {
+ // Check both the URL path and the URL alias against the list to exclude.
$path = Drupal::service('path.current')->getPath();
+ $url_alias_path = \Drupal::service('path.alias_manager')->getAliasByPath($path);
$path_match = Drupal::service('path.matcher')->matchPath($path, $config->get('exclude_paths'));
+ $path_match_url_alias = Drupal::service('path.matcher')->matchPath($url_alias_path, $config->get('exclude_paths'));
+ $path_match = $path_match || $path_match_url_alias;
$exclude_paths = $config->get('exclude_paths');
Drupal::moduleHandler()->alter('eu_cookie_compliance_path_match', $path_match, $path, $exclude_paths);
}
@@ -102,7 +102,7 @@ function eu_cookie_compliance_page_attachments(&$attachments) {
}
}
- $geoip_match = TRUE;
+ $geoip_match = ['in_eu' => TRUE];
if (!empty($config->get('eu_only')) && $config->get('eu_only')) {
$geoip_match = eu_cookie_compliance_user_in_eu();
}
@@ -119,39 +119,93 @@ function eu_cookie_compliance_page_attachments(&$attachments) {
$modules_allow_popup = TRUE;
Drupal::moduleHandler()->alter('eu_cookie_compliance_show_popup', $modules_allow_popup);
- if ($config->get('popup_enabled') && Drupal::currentUser()->hasPermission('display eu cookie compliance popup') && $geoip_match && $domain_allow && !$path_match && !$admin_theme_match && $uid1_match && $modules_allow_popup) {
+ if ($config->get('popup_enabled') && Drupal::currentUser()->hasPermission('display eu cookie compliance popup') && $geoip_match['in_eu'] && $domain_allow && !$path_match && !$admin_theme_match && $uid1_match && $modules_allow_popup) {
$language = Drupal::languageManager()->getCurrentLanguage();
$data['css'] = '';
// Color overrides.
if ($config->get('popup_bg_hex') !== '' && $config->get('popup_text_hex') !== '') {
- $data['css'] = 'div#sliding-popup {background:#' . Html::escape($config->get('popup_bg_hex')) . '} #sliding-popup h1, #sliding-popup h2, #sliding-popup h3, #sliding-popup p { color:#' . Html::escape($config->get('popup_text_hex')) . ';}';
+ $data['css'] = 'div#sliding-popup, div#sliding-popup .eu-cookie-withdraw-banner, .eu-cookie-withdraw-tab {background: #' . Html::escape($config->get('popup_bg_hex')) . '} div#sliding-popup.eu-cookie-withdraw-wrapper { background: transparent; } #sliding-popup h1, #sliding-popup h2, #sliding-popup h3, #sliding-popup p, .eu-cookie-compliance-more-button, .eu-cookie-compliance-secondary-button, .eu-cookie-withdraw-tab { color: #' . Html::escape($config->get('popup_text_hex')) . ';} .eu-cookie-withdraw-tab { border-color: #' . Html::escape($config->get('popup_text_hex')) . ';}';
}
if (!empty($config->get('popup_position')) && $config->get('popup_position') && !empty($config->get('fixed_top_position')) && $config->get('fixed_top_position')) {
$data['css'] .= '#sliding-popup.sliding-popup-top { position: fixed; }';
}
- $popup_text_info = str_replace(array("\r", "\n"), '', $config->get('popup_info.value'));
- $popup_text_agreed = str_replace(array("\r", "\n"), '', $config->get('popup_agreed.value'));
- $html_info = array(
+ $method = $config->get('method');
+
+ if ($method == 'auto') {
+ $dnt = isset($_SERVER['HTTP_DNT']) ? $_SERVER['HTTP_DNT'] : NULL;
+ if ((int) $dnt === 0 && $dnt !== NULL) {
+ $method = 'default';
+ }
+ else {
+ $method = 'opt_in';
+ }
+ }
+
+ switch ($method) {
+ case 'default':
+ $click_confirmation = $config->get('popup_clicking_confirmation');
+ $scroll_confirmation = $config->get('popup_scrolling_confirmation');
+ $primary_button_label = $config->get('popup_agree_button_message');
+ $primary_button_class = 'agree-button eu-cookie-compliance-default-button';
+ $secondary_button_label = '';
+ $secondary_button_class = '';
+ break;
+
+ case 'opt_in':
+ $click_confirmation = FALSE;
+ $scroll_confirmation = FALSE;
+ $primary_button_label = $config->get('popup_agree_button_message');
+ $primary_button_class = 'agree-button eu-cookie-compliance-secondary-button';
+ $secondary_button_label = $config->get('disagree_button_label');
+ $secondary_button_class = 'decline-button eu-cookie-compliance-default-button';
+ break;
+
+ case 'opt_out':
+ $click_confirmation = FALSE;
+ $scroll_confirmation = FALSE;
+ $primary_button_label = $config->get('disagree_button_label');
+ $primary_button_class = 'decline-button eu-cookie-compliance-secondary-button';
+ $secondary_button_label = $config->get('popup_agree_button_message');
+ $secondary_button_class = 'agree-button eu-cookie-compliance-default-button';
+ break;
+ }
+
+ $popup_text_info = str_replace(["\r", "\n"], '', $config->get('popup_info.value'));
+ $popup_text_agreed = str_replace(["\r", "\n"], '', $config->get('popup_agreed.value'));
+ $withdraw_markup = str_replace(["\r", "\n"], '', $config->get('withdraw_message.value'));
+ $html_info = [
'#theme' => 'eu_cookie_compliance_popup_info',
'#message' => check_markup($popup_text_info, $config->get('popup_info.format'), FALSE),
- '#agree_button' => $config->get('popup_agree_button_message'),
+ '#agree_button' => $primary_button_label,
'#disagree_button' => ($config->get('show_disagree_button') == TRUE) ? $config->get('popup_disagree_button_message') : FALSE,
- );
- $mobile_popup_text_info = str_replace(array("\r", "\n"), '', $config->get('mobile_popup_info.value'));
- $mobile_html_info = array(
+ '#secondary_button_label' => $secondary_button_label,
+ '#primary_button_class' => $primary_button_class,
+ '#secondary_button_class' => $secondary_button_class,
+ ];
+ $mobile_popup_text_info = str_replace(["\r", "\n"], '', $config->get('mobile_popup_info.value'));
+ $mobile_html_info = [
'#theme' => 'eu_cookie_compliance_popup_info',
'#message' => check_markup($mobile_popup_text_info, $config->get('popup_info.format'), FALSE),
- '#agree_button' => $config->get('popup_agree_button_message'),
+ '#agree_button' => $primary_button_label,
'#disagree_button' => ($config->get('show_disagree_button') == TRUE) ? $config->get('popup_disagree_button_message') : FALSE,
- );
- $html_agreed = array(
+ '#secondary_button_label' => $secondary_button_label,
+ '#primary_button_class' => $primary_button_class,
+ '#secondary_button_class' => $secondary_button_class,
+ ];
+ $html_agreed = [
'#theme' => 'eu_cookie_compliance_popup_agreed',
'#message' => check_markup($popup_text_agreed, $config->get('popup_agreed.format'), FALSE),
'#hide_button' => $config->get('popup_hide_button_message'),
'#find_more_button' => ($config->get('show_disagree_button') == TRUE) ? $config->get('popup_find_more_button_message') : FALSE,
- );
+ ];
+ $withdraw_markup = [
+ '#theme' => 'eu_cookie_compliance_withdraw',
+ '#message' => check_markup($withdraw_markup, $config->get('withdraw_message.format'), FALSE),
+ '#withdraw_tab_button_label' => $config->get('withdraw_tab_button_label'),
+ '#withdraw_action_button_label' => $config->get('withdraw_action_button_label'),
+ ];
$was_debugging = FALSE;
@@ -168,6 +222,7 @@ function eu_cookie_compliance_page_attachments(&$attachments) {
$html_info = trim(Drupal::service('renderer')->renderRoot($html_info)->__toString());
$mobile_html_info = trim(Drupal::service('renderer')->renderRoot($mobile_html_info)->__toString());
$html_agreed = trim(Drupal::service('renderer')->renderRoot($html_agreed)->__toString());
+ $withdraw_markup = trim(Drupal::service('renderer')->renderRoot($withdraw_markup)->__toString());
if ($was_debugging) {
$twig_service->enableDebug();
@@ -178,17 +233,21 @@ function eu_cookie_compliance_page_attachments(&$attachments) {
$popup_link = Url::fromUri($popup_link);
}
else {
+ // Guard against translations being entered without leading slash.
+ if (substr( $popup_link, 0, 1) != '/' && substr( $popup_link, 0, 1) != '?' && substr( $popup_link, 0, 1) != '#') {
+ $popup_link = '/' . $popup_link;
+ }
$popup_link = $popup_link === '' ? '/' : $popup_link;
$popup_link = Url::fromUserInput($popup_link);
}
$popup_link = $popup_link->toString();
- $data['variables'] = array(
+ $data['variables'] = [
'popup_enabled' => $config->get('popup_enabled'),
'popup_agreed_enabled' => $config->get('popup_agreed_enabled'),
'popup_hide_agreed' => $config->get('popup_hide_agreed'),
- 'popup_clicking_confirmation' => $config->get('popup_clicking_confirmation'),
- 'popup_scrolling_confirmation' => $config->get('popup_scrolling_confirmation'),
+ 'popup_clicking_confirmation' => $click_confirmation,
+ 'popup_scrolling_confirmation' => $scroll_confirmation,
'popup_html_info' => $config->get('popup_enabled') ? $html_info : FALSE,
'use_mobile_message' => !empty($config->get('use_mobile_message')) ? $config->get('use_mobile_message') : FALSE,
'mobile_popup_html_info' => $config->get('popup_enabled') ? $mobile_html_info : FALSE,
@@ -202,14 +261,20 @@ function eu_cookie_compliance_page_attachments(&$attachments) {
'popup_link_new_window' => $config->get('popup_link_new_window'),
'popup_position' => $config->get('popup_position'),
'popup_language' => $language->getId(),
+ 'store_consent' => $config->get('consent_storage_method') != 'do_not_store',
'better_support_for_screen_readers' => !empty($config->get('better_support_for_screen_readers')) ? $config->get('better_support_for_screen_readers') : FALSE,
- 'cookie_name' => !empty($config->get('cookie_name')) ? $config->get('cookie_name') : '',
- 'reload_page' => !empty($config->get('reload_page')) ? $config->get('reload_page') : FALSE,
+ 'cookie_name' => !empty($config->get('cookie_name')) ? $config->get('cookie_name') : '',
+ 'reload_page' => !empty($config->get('reload_page')) ? $config->get('reload_page') : FALSE,
'domain' => $config->get('domain'),
'popup_eu_only_js' => !empty($config->get('eu_only_js')) ? $config->get('eu_only_js') : FALSE,
'cookie_lifetime' => $config->get('cookie_lifetime'),
- 'disagree_do_not_show_popup' => !empty($config->get('disagree_do_not_show_popup')) ? $config->get('disagree_do_not_show_popup') : FALSE,
- );
+ 'cookie_session' => $config->get('cookie_session'),
+ 'disagree_do_not_show_popup' => !empty($config->get('disagree_do_not_show_popup')) ? $config->get('disagree_do_not_show_popup') : FALSE,
+ 'method' => $method,
+ 'whitelisted_cookies' => !empty($config->get('whitelisted_cookies')) ? $config->get('whitelisted_cookies') : '',
+ 'withdraw_markup' => $withdraw_markup,
+ 'withdraw_enabled' => $config->get('withdraw_enabled'),
+ ];
$attachments['#attached']['drupalSettings']['eu_cookie_compliance'] = $data['variables'];
if ($config->get('use_bare_css')) {
@@ -218,6 +283,31 @@ function eu_cookie_compliance_page_attachments(&$attachments) {
else {
$attachments['#attached']['library'][] = 'eu_cookie_compliance/eu_cookie_compliance';
}
+ // Add inline javascript.
+ $disabled_javascripts = $config->get('disabled_javascripts');
+ $load_disabled_scripts = '';
+ if ($disabled_javascripts != '') {
+ $load_disabled_scripts = '';
+ $disabled_javascripts = _eu_cookie_compliance_explode_multiple_lines($disabled_javascripts);
+ foreach ($disabled_javascripts as $script) {
+ if (substr($script, 0, 4) !== 'http' && substr($script, 0, 2) !== '//') {
+ $script = '/' . $script;
+ }
+ $load_disabled_scripts .= 'var scriptTag = document.createElement("script");';
+ $load_disabled_scripts .= 'scriptTag.src = ' . Json::encode($script) . ';';
+ $load_disabled_scripts .= 'document.body.appendChild(scriptTag);';
+ }
+ }
+
+ $attachments['#attached']['html_head'][] = [
+ [
+ '#type' => 'html_tag',
+ '#tag' => 'script',
+ '#value' => 'function euCookieComplianceLoadScripts() {' . $load_disabled_scripts . '}',
+ ],
+ 'eu-cookie-compliance-js',
+ ];
+
// Add inline css.
$attachments['#attached']['html_head'][] = [
[
@@ -228,6 +318,27 @@ function eu_cookie_compliance_page_attachments(&$attachments) {
];
$cache_tags = isset($attachments['#cache']['tags']) ? $attachments['#cache']['tags'] : [];
$attachments['#cache']['tags'] = Cache::mergeTags($cache_tags, $config->getCacheTags());
+
+ // Check if disabled scripts are in page html_head.
+ $disabled_javascripts = $config->get('disabled_javascripts');
+ $disabled_javascripts = _eu_cookie_compliance_explode_multiple_lines($disabled_javascripts);
+ $disabled_javascripts = array_filter($disabled_javascripts);
+
+ if (!empty($disabled_javascripts)) {
+ foreach ($attachments['#attached']['html_head'] as $index => $asset) {
+ $is_script = !empty($asset[0]['#type']) && $asset[0]['#type'] == 'html_tag' && $asset[0]['#tag'] == 'script';
+ $is_src = !empty($asset[0]['#attributes']['src']);
+ if (!$is_script || !$is_src) {
+ continue;
+ }
+ $src = $asset[0]['#attributes']['src'];
+ $src = preg_replace('/\.js\?[^"]+/', '.js', $src);
+ $src = preg_replace('/^\//', '', $src);
+ if (in_array($src, $disabled_javascripts)) {
+ $attachments['#attached']['html_head'][$index][0]['#access'] = FALSE;
+ }
+ }
+ }
}
}
@@ -235,24 +346,35 @@ function eu_cookie_compliance_page_attachments(&$attachments) {
* Implements hook_theme().
*/
function eu_cookie_compliance_theme($existing, $type, $theme, $path) {
- return array(
- 'eu_cookie_compliance_popup_info' => array(
+ return [
+ 'eu_cookie_compliance_popup_info' => [
'template' => 'eu_cookie_compliance_popup_info',
- 'variables' => array(
+ 'variables' => [
'message' => NULL,
'agree_button' => NULL,
'disagree_button' => NULL,
- ),
- ),
- 'eu_cookie_compliance_popup_agreed' => array(
+ 'secondary_button_label' => NULL,
+ 'primary_button_class' => NULL,
+ 'secondary_button_class' => NULL,
+ ],
+ ],
+ 'eu_cookie_compliance_popup_agreed' => [
'template' => 'eu_cookie_compliance_popup_agreed',
- 'variables' => array(
+ 'variables' => [
'message' => NULL,
'hide_button' => NULL,
'find_more_button' => NULL,
- ),
- ),
- );
+ ],
+ ],
+ 'eu_cookie_compliance_withdraw' => [
+ 'template' => 'eu_cookie_compliance_withdraw',
+ 'variables' => [
+ 'withdraw_tab_button_label' => NULL,
+ 'message' => NULL,
+ 'withdraw_action_button_label' => NULL,
+ ],
+ ],
+ ];
}
/**
@@ -263,9 +385,9 @@ function eu_cookie_compliance_theme($existing, $type, $theme, $path) {
* @param \Drupal\Core\Form\FormStateInterface $form_state
* Form State Interface.
*/
-function eu_cookie_compliance_validate_hex($element, FormStateInterface &$form_state) {
+function eu_cookie_compliance_validate_hex(array $element, FormStateInterface &$form_state) {
if (!empty($element['#value']) && !preg_match('/^[0-9a-fA-F]{3,6}$/', $element['#value'])) {
- $form_state->setError($element, t('%name must be a HEX value (without leading #) or empty.', array('%name' => $element['#title'])));
+ $form_state->setError($element, t('%name must be a HEX value (without leading #) or empty.', ['%name' => $element['#title']]));
}
}
@@ -274,11 +396,11 @@ function eu_cookie_compliance_validate_hex($element, FormStateInterface &$form_s
*/
function eu_cookie_compliance_user_in_eu() {
$geoip_match = FALSE;
- $eu_countries_default = array(
+ $eu_countries_default = [
NULL, 'BE', 'BG', 'CZ', 'DK', 'DE', 'EE', 'IE', 'EL', 'ES', 'FR', 'HR',
'IT', 'CY', 'LV', 'LT', 'LU', 'HU', 'MT', 'NL', 'AT', 'PL', 'PT', 'RO',
'SI', 'SK', 'FI', 'SE', 'UK', 'GB', 'NO',
- );
+ ];
// Allow custom array of countries to be loaded from settings.php, defaulting
// to the array above.
$config = Drupal::config('eu_cookie_compliance.settings');
@@ -295,10 +417,43 @@ function eu_cookie_compliance_user_in_eu() {
$geoip_match = TRUE;
}
- return array(
+ return [
'country' => $country_code,
'in_eu' => $geoip_match,
- );
+ ];
+}
+
+/**
+ * Implements hook_js_alter().
+ */
+function eu_cookie_compliance_js_alter(&$javascript, AttachedAssetsInterface $assets) {
+ $config = Drupal::config('eu_cookie_compliance.settings');
+ $disabled_javascripts = $config->get('disabled_javascripts');
+ $disabled_javascripts = _eu_cookie_compliance_explode_multiple_lines($disabled_javascripts);
+
+ foreach ($disabled_javascripts as $script) {
+ unset($javascript[$script]);
+ }
+}
+
+/**
+ * Splits a return delimited text string into an array.
+ *
+ * @param string $text
+ * Text to split.
+ *
+ * @return array
+ * Text split into an array.
+ */
+function _eu_cookie_compliance_explode_multiple_lines($text) {
+ $text = explode("\r\n", $text);
+ if (count($text) == 1) {
+ $text = explode("\r", $text[0]);
+ }
+ if (count($text) == 1) {
+ $text = explode("\n", $text[0]);
+ }
+ return $text;
}
/**
@@ -308,6 +463,10 @@ function eu_cookie_compliance_user_in_eu() {
* URL to the node if found, otherwise FALSE.
*/
function _eu_cookie_compliance_find_privacy_policy() {
+ if (!\Drupal::entityTypeManager()->hasDefinition('node')) {
+ return FALSE;
+ }
+
$pattern = 'privacy|privacy +policy|cookie +policy|terms +of +use|terms +of +service|terms +and +conditions';
$connection = Database::getConnection();
@@ -334,3 +493,22 @@ function _eu_cookie_compliance_find_privacy_policy() {
}
return FALSE;
}
+
+/**
+ * Helper function to set module weight.
+ */
+function eu_cookie_compliance_module_set_weight() {
+ $weight = 1;
+ $exclude_modules = [
+ 'eu_cookie_compliance',
+ ];
+
+ $extension_config = \Drupal::configFactory()->get('core.extension');
+ // Loop through all installed modules to find the highest weight.
+ foreach ($extension_config->get('module') as $module_name => $module_weight) {
+ if ($module_weight > $weight && !in_array($module_name, $exclude_modules)) {
+ $weight = $module_weight + 1;
+ }
+ }
+ module_set_weight('eu_cookie_compliance', $weight);
+}
diff --git a/web/modules/contrib/eu_cookie_compliance/eu_cookie_compliance.routing.yml b/web/modules/contrib/eu_cookie_compliance/eu_cookie_compliance.routing.yml
index d6e1007b2..b80c65299 100644
--- a/web/modules/contrib/eu_cookie_compliance/eu_cookie_compliance.routing.yml
+++ b/web/modules/contrib/eu_cookie_compliance/eu_cookie_compliance.routing.yml
@@ -5,5 +5,12 @@ eu_cookie_compliance.settings:
_title: 'EU Cookie Compliance'
requirements:
_permission: 'administer eu cookie compliance popup'
+eu_cookie_compliance.store_consent:
+ path: '/eu-cookie-compliance/store_consent/{target}'
+ defaults:
+ _controller: \Drupal\eu_cookie_compliance\Controller\StoreConsent::store
+ _title: 'EU Cookie Compliance store consent'
+ requirements:
+ _access: 'TRUE'
route_callbacks:
- '\Drupal\eu_cookie_compliance\Routing\CheckIfEuCountryJs::routes'
diff --git a/web/modules/contrib/eu_cookie_compliance/eu_cookie_compliance.services.yml b/web/modules/contrib/eu_cookie_compliance/eu_cookie_compliance.services.yml
new file mode 100644
index 000000000..db0c0a044
--- /dev/null
+++ b/web/modules/contrib/eu_cookie_compliance/eu_cookie_compliance.services.yml
@@ -0,0 +1,4 @@
+services:
+ plugin.manager.eu_cookie_compliance.consent_storage:
+ class: Drupal\eu_cookie_compliance\Plugin\ConsentStorageManager
+ parent: default_plugin_manager
diff --git a/web/modules/contrib/eu_cookie_compliance/js/eu_cookie_compliance.js b/web/modules/contrib/eu_cookie_compliance/js/eu_cookie_compliance.js
index 8b6201f3f..bcb574ffb 100644
--- a/web/modules/contrib/eu_cookie_compliance/js/eu_cookie_compliance.js
+++ b/web/modules/contrib/eu_cookie_compliance/js/eu_cookie_compliance.js
@@ -14,7 +14,7 @@
// If configured, check JSON callback to determine if in EU.
if (drupalSettings.eu_cookie_compliance.popup_eu_only_js) {
if (Drupal.eu_cookie_compliance.showBanner()) {
- var url = drupalSettings.path.baseUrl + 'eu-cookie-compliance-check';
+ var url = drupalSettings.path.baseUrl + drupalSettings.path.pathPrefix + 'eu-cookie-compliance-check';
var data = {};
$.getJSON(url, data, function (data) {
// If in the EU, show the compliance banner.
@@ -51,7 +51,7 @@
}
var status = Drupal.eu_cookie_compliance.getCurrentStatus();
- if (status === 0 || status === null) {
+ if ((status === 0 && drupalSettings.eu_cookie_compliance.method === 'default') || status === null) {
if (!drupalSettings.eu_cookie_compliance.disagree_do_not_show_popup || status === null) {
// Detect mobile here and use mobile_popup_html_info, if we have a mobile device.
if (window.matchMedia('(max-width: ' + drupalSettings.eu_cookie_compliance.mobile_breakpoint + 'px)').matches && drupalSettings.eu_cookie_compliance.use_mobile_message) {
@@ -65,12 +65,89 @@
} else if (status === 1 && drupalSettings.eu_cookie_compliance.popup_agreed_enabled) {
Drupal.eu_cookie_compliance.createPopup(drupalSettings.eu_cookie_compliance.popup_html_agreed);
Drupal.eu_cookie_compliance.attachHideEvents();
+ } else if (status === 2 && drupalSettings.eu_cookie_compliance.withdraw_enabled) {
+ Drupal.eu_cookie_compliance.createWithdrawBanner(drupalSettings.eu_cookie_compliance.withdraw_markup);
+ Drupal.eu_cookie_compliance.attachWithdrawEvents();
}
}
catch (e) {
}
};
+ Drupal.eu_cookie_compliance.createWithdrawBanner = function (html) {
+ var $html = $('').html(html);
+ var $banner = $('.eu-cookie-withdraw-banner', $html);
+ $html.attr('id', 'sliding-popup');
+ $html.addClass('eu-cookie-withdraw-wrapper');
+
+ if (!drupalSettings.eu_cookie_compliance.popup_use_bare_css) {
+ $banner.height(drupalSettings.eu_cookie_compliance.popup_height)
+ .width(drupalSettings.eu_cookie_compliance.popup_width);
+ }
+ $html.hide();
+ var height = 0;
+ if (drupalSettings.eu_cookie_compliance.popup_position) {
+ $html.prependTo('body');
+ height = $html.outerHeight();
+
+ $html.show()
+ .addClass('sliding-popup-top')
+ .addClass('clearfix')
+ .css({ top: -1 * height });
+ // For some reason, the tab outerHeight is -10 if we don't use a timeout
+ // function to reveal the tab.
+ setTimeout(function () {
+ var height = $html.outerHeight();
+
+ $html.animate({ top: -1 * (height) }, drupalSettings.eu_cookie_compliance.popup_delay, null, function () {
+ $html.trigger('eu_cookie_compliance_popup_open');
+ });
+ }.bind($html), 0);
+ } else {
+ if (drupalSettings.eu_cookie_compliance.better_support_for_screen_readers) {
+ $html.prependTo('body');
+ } else {
+ $html.appendTo('body');
+ }
+ height = $html.outerHeight();
+ $html.show()
+ .addClass('sliding-popup-bottom')
+ .css({ bottom: -1 * height });
+ // For some reason, the tab outerHeight is -10 if we don't use a timeout
+ // function to reveal the tab.
+ setTimeout(function () {
+ var height = $html.outerHeight();
+
+ $html.animate({ bottom: -1 * (height) }, drupalSettings.eu_cookie_compliance.popup_delay, null, function () {
+ $html.trigger('eu_cookie_compliance_popup_open');
+ });
+ }.bind($html), 0);
+ }
+ };
+
+ Drupal.eu_cookie_compliance.toggleWithdrawBanner = function () {
+ var $wrapper = $('#sliding-popup');
+ var $tab = $('.eu-cookie-withdraw-tab');
+ var $bannerIsShowing = drupalSettings.eu_cookie_compliance.popup_position ? parseInt($wrapper.css('top')) === 0 : parseInt($wrapper.css('bottom')) === 0;
+ var height = $wrapper.outerHeight();
+ if (drupalSettings.eu_cookie_compliance.popup_position) {
+ if ($bannerIsShowing) {
+ $wrapper.animate({'top' : -1 * (height)}, drupalSettings.eu_cookie_compliance.popup_delay);
+ }
+ else {
+ $wrapper.animate({'top' : 0}, drupalSettings.eu_cookie_compliance.popup_delay);
+ }
+ }
+ else {
+ if ($bannerIsShowing) {
+ $wrapper.animate({'bottom' : -1 * (height)}, drupalSettings.eu_cookie_compliance.popup_delay);
+ }
+ else {
+ $wrapper.animate({'bottom' : 0}, drupalSettings.eu_cookie_compliance.popup_delay);
+ }
+ }
+ };
+
Drupal.eu_cookie_compliance.createPopup = function (html) {
// This fixes a problem with jQuery 1.9.
var popup = $('').html(html);
@@ -113,6 +190,7 @@
var scrollConfirms = drupalSettings.eu_cookie_compliance.popup_scrolling_confirmation;
$('.agree-button').click(Drupal.eu_cookie_compliance.acceptAction);
+ $('.decline-button').click(Drupal.eu_cookie_compliance.declineAction);
if (clickingConfirms) {
$('a, input[type=submit], button[type=submit]').bind('click.euCookieCompliance', Drupal.eu_cookie_compliance.acceptAction);
@@ -155,6 +233,11 @@
$('.find-more-button').not('.find-more-button-processed').addClass('find-more-button-processed').click(Drupal.eu_cookie_compliance.moreInfoAction);
};
+ Drupal.eu_cookie_compliance.attachWithdrawEvents = function () {
+ $('.eu-cookie-withdraw-button').click(Drupal.eu_cookie_compliance.withdrawAction);
+ $('.eu-cookie-withdraw-tab').click(Drupal.eu_cookie_compliance.toggleWithdrawBanner);
+ };
+
Drupal.eu_cookie_compliance.acceptAction = function () {
var agreedEnabled = drupalSettings.eu_cookie_compliance.popup_agreed_enabled;
var nextStatus = 1;
@@ -163,13 +246,37 @@
nextStatus = 2;
}
+ if (!euCookieComplianceHasLoadedScripts) {
+ euCookieComplianceLoadScripts();
+ }
+
+ if (typeof euCookieComplianceBlockCookies !== 'undefined') {
+ clearInterval(euCookieComplianceBlockCookies);
+ }
+
Drupal.eu_cookie_compliance.changeStatus(nextStatus);
};
+ Drupal.eu_cookie_compliance.declineAction = function () {
+ Drupal.eu_cookie_compliance.setStatus(0);
+ let popup = $('#sliding-popup');
+ if (popup.hasClass('sliding-popup-top')) {
+ popup.animate({ top: popup.outerHeight() * -1 }).trigger('eu_cookie_compliance_popup_close');
+ }
+ else {
+ popup.animate({ bottom: popup.outerHeight() * -1 }).trigger('eu_cookie_compliance_popup_close');
+ }
+ };
+
+ Drupal.eu_cookie_compliance.withdrawAction = function () {
+ Drupal.eu_cookie_compliance.setStatus(null);
+ location.reload();
+ };
+
Drupal.eu_cookie_compliance.moreInfoAction = function () {
if (drupalSettings.eu_cookie_compliance.disagree_do_not_show_popup) {
Drupal.eu_cookie_compliance.setStatus(0);
- $('#sliding-popup').remove().trigger('eu_cookie_compliance_popup_close');
+ $('#sliding-popup').trigger('eu_cookie_compliance_popup_close').remove();
} else {
if (drupalSettings.eu_cookie_compliance.popup_link_new_window) {
window.open(drupalSettings.eu_cookie_compliance.popup_link);
@@ -203,7 +310,7 @@
$('#sliding-popup').html(drupalSettings.eu_cookie_compliance.popup_html_agreed).animate({ top: 0 }, drupalSettings.eu_cookie_compliance.popup_delay);
Drupal.eu_cookie_compliance.attachHideEvents();
} else if (status === 1) {
- $('#sliding-popup').remove().trigger('eu_cookie_compliance_popup_close');
+ $('#sliding-popup').trigger('eu_cookie_compliance_popup_close').remove();
}
});
} else {
@@ -212,7 +319,7 @@
$('#sliding-popup').html(drupalSettings.eu_cookie_compliance.popup_html_agreed).animate({ bottom: 0 }, drupalSettings.eu_cookie_compliance.popup_delay);
Drupal.eu_cookie_compliance.attachHideEvents();
} else if (status === 1) {
- $('#sliding-popup').remove().trigger('eu_cookie_compliance_popup_close');
+ $('#sliding-popup').trigger('eu_cookie_compliance_popup_close').remove();
}
});
}
@@ -221,6 +328,11 @@
location.reload();
}
+ if (value === 2 && drupalSettings.eu_cookie_compliance.withdraw_enabled) {
+ Drupal.eu_cookie_compliance.createWithdrawBanner(drupalSettings.eu_cookie_compliance.withdraw_markup);
+ Drupal.eu_cookie_compliance.attachWithdrawEvents();
+ }
+
Drupal.eu_cookie_compliance.setStatus(value);
};
@@ -236,9 +348,21 @@
}
}
- date.setDate(date.getDate() + parseInt(drupalSettings.eu_cookie_compliance.cookie_lifetime));
- $.cookie(cookieName, status, { expires: date, path: path, domain: domain });
+ var cookie_session = parseInt(drupalSettings.eu_cookie_compliance.cookie_session);
+ if (cookie_session) {
+ $.cookie(cookieName, status, { path: path, domain: domain });
+ } else {
+ var lifetime = parseInt(drupalSettings.eu_cookie_compliance.cookie_lifetime);
+ date.setDate(date.getDate() + lifetime);
+ $.cookie(cookieName, status, { expires: date, path: path, domain: domain });
+ }
$(document).trigger('eu_cookie_compliance.changeStatus', [status]);
+
+ // Store consent if applicable.
+ if (drupalSettings.eu_cookie_compliance.store_consent && ((status === 1 && drupalSettings.eu_cookie_compliance.popup_agreed_enabled) || (status === 2 && !drupalSettings.eu_cookie_compliance.popup_agreed_enabled))) {
+ var url = drupalSettings.path.baseUrl + drupalSettings.path.pathPrefix + 'eu-cookie-compliance/store_consent/banner';
+ $.post(url, {}, function (data) { });
+ }
};
Drupal.eu_cookie_compliance.hasAgreed = function () {
@@ -249,7 +373,7 @@
Drupal.eu_cookie_compliance.showBanner = function () {
var showBanner = false;
var status = Drupal.eu_cookie_compliance.getCurrentStatus();
- if (status === 0 || status === null) {
+ if ((status === 0 && drupalSettings.eu_cookie_compliance.method === 'default') || status === null) {
if (!drupalSettings.eu_cookie_compliance.disagree_do_not_show_popup || status === null) {
showBanner = true;
}
@@ -270,8 +394,66 @@
return (cookieEnabled);
};
- Drupal.eu_cookie_compliance.reloadPage = function () {
+ // Load blocked scripts if the user has agreed to being tracked.
+ var euCookieComplianceHasLoadedScripts = false;
+ $(function () {
+ if (Drupal.eu_cookie_compliance.hasAgreed()
+ || (Drupal.eu_cookie_compliance.getCurrentStatus() === null && drupalSettings.eu_cookie_compliance.method !== 'opt_in')
+ ) {
+ euCookieComplianceLoadScripts();
+ euCookieComplianceHasLoadedScripts = true;
+ }
+ });
+
+ // Block cookies when the user hasn't agreed.
+ if ((drupalSettings.eu_cookie_compliance.method === 'opt_in' && (Drupal.eu_cookie_compliance.getCurrentStatus() === null || !Drupal.eu_cookie_compliance.hasAgreed()))
+ || (drupalSettings.eu_cookie_compliance.method === 'opt_out' && !Drupal.eu_cookie_compliance.hasAgreed() && Drupal.eu_cookie_compliance.getCurrentStatus() !== null)
+ ) {
+ // Split the white-listed cookies.
+ var euCookieComplianceWhitelist = drupalSettings.eu_cookie_compliance.whitelisted_cookies.split(/\r\n|\n|\r/g);
+
+ // Add the EU Cookie Compliance cookie.
+ euCookieComplianceWhitelist.push((drupalSettings.eu_cookie_compliance.cookie_name === '') ? 'cookie-agreed' : drupalSettings.eu_cookie_compliance.cookie_name);
+ var euCookieComplianceBlockCookies = setInterval(function () {
+ // Load all cookies from jQuery.
+ var cookies = $.cookie();
+
+ // Check each cookie and try to remove it if it's not white-listed.
+ for (var i in cookies) {
+ var remove = true;
+ var hostname = window.location.hostname;
+ var cookieRemoved = false;
+ var index = 0;
+
+ // Skip the PHP session cookie.
+ if (i.indexOf('SESS') === 0 || i.indexOf('SSESS') === 0) {
+ remove = false;
+ }
- };
+ // Check if the cookie is white-listed.
+ for (var item in euCookieComplianceWhitelist) {
+ if (i === euCookieComplianceWhitelist[item]) {
+ remove = false;
+ }
+ }
+
+ // Remove the cookie if it's not white-listed.
+ if (remove) {
+ while (!cookieRemoved && hostname !== '') {
+ // Attempt to remove.
+ cookieRemoved = $.removeCookie(i, { domain: '.' + hostname, path: '/' });
+ if (!cookieRemoved) {
+ cookieRemoved = $.removeCookie(i, { domain: hostname, path: '/' });
+ }
+
+ index = hostname.indexOf('.');
+
+ // We can be on a sub-domain, so keep checking the main domain as well.
+ hostname = (index === -1) ? '' : hostname.substring(index + 1);
+ }
+ }
+ }
+ }, 5000);
+ }
})(jQuery, Drupal, drupalSettings);
diff --git a/web/modules/contrib/eu_cookie_compliance/src/Annotation/ConsentStorage.php b/web/modules/contrib/eu_cookie_compliance/src/Annotation/ConsentStorage.php
new file mode 100644
index 000000000..a64437723
--- /dev/null
+++ b/web/modules/contrib/eu_cookie_compliance/src/Annotation/ConsentStorage.php
@@ -0,0 +1,52 @@
+alter('eu_cookie_compliance_geoip_match', $data);
+
return new JsonResponse($data, 200, ['Cache-Control' => 'private']);
}
diff --git a/web/modules/contrib/eu_cookie_compliance/src/Controller/StoreConsent.php b/web/modules/contrib/eu_cookie_compliance/src/Controller/StoreConsent.php
new file mode 100644
index 000000000..8d5ca4428
--- /dev/null
+++ b/web/modules/contrib/eu_cookie_compliance/src/Controller/StoreConsent.php
@@ -0,0 +1,37 @@
+get('eu_cookie_compliance.settings')
+ ->get('consent_storage_method');
+ // If we're not going to log consent, return NULL.
+ if (!$consent_storage_method || $consent_storage_method == 'do_not_store') {
+ return new JsonResponse(NULL);
+ }
+
+ // Get plugin.
+ /* @var \Drupal\eu_cookie_compliance\Plugin\ConsentStorageInterface $consent_storage */
+ $consent_storage = $consent_storages->createInstance($consent_storage_method);
+ // Register consent.
+ $result = $consent_storage->registerConsent($target);
+ // Return value.
+ return new JsonResponse($result);
+ }
+
+}
diff --git a/web/modules/contrib/eu_cookie_compliance/src/Form/EuCookieComplianceConfigForm.php b/web/modules/contrib/eu_cookie_compliance/src/Form/EuCookieComplianceConfigForm.php
index 728f358d2..d6f7a899d 100644
--- a/web/modules/contrib/eu_cookie_compliance/src/Form/EuCookieComplianceConfigForm.php
+++ b/web/modules/contrib/eu_cookie_compliance/src/Form/EuCookieComplianceConfigForm.php
@@ -12,6 +12,8 @@ use Drupal\Core\Routing\RequestContext;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\user\RoleStorageInterface;
+use Drupal\filter\Entity\FilterFormat;
+use Drupal\Core\Cache\Cache;
/**
* Provides settings for eu_cookie_compliance module.
@@ -116,15 +118,27 @@ class EuCookieComplianceConfigForm extends ConfigFormBase {
$config = $this->config('eu_cookie_compliance.settings');
$default_filter_format = filter_default_format();
- if ($default_filter_format == 'restricted_html') {
+ $full_html_format = FilterFormat::load('full_html');
+ if ($default_filter_format == 'restricted_html' && !empty($full_html_format) && $full_html_format->get('status')) {
$default_filter_format = 'full_html';
}
- $form['popup_enabled'] = array(
+ $consent_storages = \Drupal::service('plugin.manager.eu_cookie_compliance.consent_storage');
+ $plugin_definitions = $consent_storages->getDefinitions();
+
+ $consent_storage_options = [];
+ $consent_storage_options['do_not_store'] = $this->t('Do not store');
+ foreach ($plugin_definitions as $plugin_name => $plugin_definition) {
+ /* @var \Drupal\Core\StringTranslation\TranslatableMarkup $plugin_definition_name */
+ $plugin_definition_name = $plugin_definition['name'];
+ $consent_storage_options[$plugin_name] = $plugin_definition_name->render();
+ }
+
+ $form['popup_enabled'] = [
'#type' => 'checkbox',
'#title' => $this->t('Enable banner'),
'#default_value' => $config->get('popup_enabled'),
- );
+ ];
// List of checkbox values.
$role_names = [];
@@ -137,6 +151,7 @@ class EuCookieComplianceConfigForm extends ConfigFormBase {
foreach ($this->getRoles() as $role_name => $role) {
// Exclude Admin roles.
+ /* @var \Drupal\user\Entity\Role $role */
if (!$role->isAdmin()) {
$role_names[$role_name] = $role->label();
// Fetch permissions for the roles.
@@ -161,169 +176,356 @@ class EuCookieComplianceConfigForm extends ConfigFormBase {
'#default_value' => $role_values,
];
- $form['popup_message'] = array(
+ $form['consent_option'] = [
+ '#type' => 'details',
+ '#title' => $this->t('Consent for processing of personal information'),
+ '#open' => TRUE,
+ ];
+
+ $form['consent_option']['info'] = [
+ '#type' => 'markup',
+ '#markup' => $this->t("The EU General Data Protection Regulation (GDPR) (see https://www.eugdpr.org/) comes into enforcement from 25 May 2018 and introduces new requirements for web sites which handle information that can be used to identify individuals. The regulation underlines that consent must be unambiguous and involve a clear affirmative action. When evaluating how to best handle the requirements in the GDPR, remember that if you have a basic web site where the visitors don't log in, you always have the option to not process data that identifies individuals, in which case you may not need this module. Also note that GDPR applies to any electronic processing or storage of personal data that your organization may do, and simply installing a module may not be enough to become fully GDPR compliant."),
+ ];
+
+ $form['consent_option']['method'] = [
+ '#type' => 'radios',
+ '#title' => $this->t('Consent method'),
+ '#options' => [
+ 'default' => $this->t("Consent by default. Don't provide any option to opt out."),
+ 'opt_in' => $this->t("Opt-in. Don't track visitors unless they specifically give consent. (GDPR compliant)"),
+ 'opt_out' => $this->t('Opt-out. Track visitors by default, unless they choose to opt out.'),
+ 'auto' => $this->t('Automatic. Respect the DNT (Do not track) setting in the browser, if present. Uses opt-in when DNT is 1 or not set, and consent by default when DNT is 0.'),
+ ],
+ '#default_value' => $config->get('method'),
+ ];
+
+ $form['javascripts'] = [
+ '#type' => 'details',
+ '#title' => $this->t("Disable the following JavaScripts when consent isn't given"),
+ '#open' => TRUE,
+ '#states' => [
+ 'visible' => [
+ "input[name='method']" => ['!value' => 'default'],
+ ],
+ ],
+ ];
+
+ $form['javascripts']['disabled_javascripts'] = [
+ '#type' => 'textarea',
+ '#title' => $this->t('Disable JavaScripts'),
+ '#default_value' => $config->get('disabled_javascripts'),
+ '#description' => $this->t("Include the full path of JavaScripts, each on a separate line. When using the opt-in or opt-out consent options, you can block certain JavaScript files from being loaded when consent isn't given. The on-site JavaScripts should be written as root relative paths without the leading slash, and off-site JavaScripts should be written as complete URLs with the leading http(s)://. Note that after the user gives consent, the scripts will be executed in the order you enter here."),
+ ];
+
+ $form['cookies'] = [
+ '#type' => 'details',
+ '#title' => $this->t('Cookie handling'),
+ '#open' => TRUE,
+ '#states' => [
+ 'visible' => [
+ "input[name='method']" => ['!value' => 'default'],
+ ],
+ ],
+ ];
+
+ $form['cookies']['whitelisted_cookies'] = [
+ '#type' => 'textarea',
+ '#title' => $this->t('Whitelisted cookies'),
+ '#default_value' => $config->get('whitelisted_cookies'),
+ '#description' => $this->t("Include the name of cookies, each on a separate line. When using the opt-in or opt-out consent options, this module will prevent cookies that are not on the whitelist from being stored in the browser when consent isn't given. PHP session cookies and the cookie for this module are always whitelisted."),
+ ];
+
+ $form['consent_storage'] = [
+ '#type' => 'details',
+ '#title' => $this->t('Store record of consent'),
+ '#open' => TRUE,
+ '#states' => [
+ 'visible' => [
+ "input[name='method']" => ['!value' => 'default'],
+ ],
+ ],
+ ];
+
+ $form['consent_storage']['info'] = [
+ '#type' => 'markup',
+ '#markup' => $this->t('Depending on your implementation of GDPR, you may have to store a record when the user consents. This module comes with a basic consent storage plugin that writes a record to the database. Note that if your site has significant traffic, the basic consent storage may become a bottleneck, as every consent action will require a write to the database. You can easily create your own module with a ConsentStorage Plugin that extends ConsentStorageBase, using BasicConsentStorage from this module as a template. If you create a highly performant consent storage plugin, please consider contributing it back to the Drupal community as a contrib module.'),
+ ];
+
+ $form['consent_storage']['consent_storage_method'] = [
+ '#type' => 'radios',
+ '#title' => $this->t('Consent storage method'),
+ '#default_value' => $config->get('consent_storage_method'),
+ '#options' => $consent_storage_options,
+ ];
+
+ $form['popup_message'] = [
'#type' => 'details',
'#title' => $this->t('Cookie information banner'),
'#open' => TRUE,
- );
+ ];
- $form['popup_message']['popup_clicking_confirmation'] = array(
+ $form['popup_message']['popup_clicking_confirmation'] = [
'#type' => 'checkbox',
'#title' => $this->t('Consent by clicking'),
'#default_value' => $config->get('popup_clicking_confirmation'),
'#description' => $this->t('By default by clicking any link or button on the website the visitor accepts the cookie policy. Uncheck this box if you donât require this functionality. You may want to edit the banner message below accordingly.'),
- );
+ '#states' => [
+ 'visible' => [
+ 'input[name="method"]' => ['value' => 'default'],
+ ],
+ ],
+ ];
- $form['popup_message']['popup_info'] = array(
+ $config_format = $config->get('popup_info.format');
+ if (!empty($config_format)) {
+ $filter_format = FilterFormat::load($config_format);
+ if (empty($filter_format) || !$filter_format->get('status')) {
+ $config_format = $default_filter_format;
+ }
+ }
+
+ $form['popup_message']['popup_info'] = [
'#type' => 'text_format',
'#title' => $this->t('Cookie information banner message'),
'#default_value' => $config->get('popup_info.value'),
'#required' => TRUE,
- '#format' => !empty($config->get('popup_info.format')) ? $config->get('popup_info.format') : $default_filter_format,
- );
+ '#format' => $config_format,
+ ];
- $form['popup_message']['use_mobile_message'] = array(
+ $form['popup_message']['use_mobile_message'] = [
'#type' => 'checkbox',
- '#title' => $this->t('Use a different message for mobile phones'),
+ '#title' => $this->t('Use a different message for mobile phones.'),
'#default_value' => !empty($config->get('use_mobile_message')) ? $config->get('use_mobile_message') : FALSE,
- );
+ ];
- $form['popup_message']['container'] = array(
+ $form['popup_message']['container'] = [
'#type' => 'container',
- '#states' => array('visible' => array('input[name="use_mobile_message"]' => array('checked' => TRUE))),
- );
+ '#states' => ['visible' => ['input[name="use_mobile_message"]' => ['checked' => TRUE]]],
+ ];
+
+ $config_format = $config->get('mobile_popup_info.format');
+ if (!empty($config_format)) {
+ $filter_format = FilterFormat::load($config_format);
+ if (empty($filter_format) || !$filter_format->get('status')) {
+ $config_format = $default_filter_format;
+ }
+ }
- $form['popup_message']['container']['mobile_popup_info'] = array(
+ $form['popup_message']['container']['mobile_popup_info'] = [
'#type' => 'text_format',
'#title' => $this->t('Cookie information banner message - mobile'),
'#default_value' => $config->get('mobile_popup_info.value'),
'#required' => FALSE,
- '#format' => !empty($config->get('mobile_popup_info.format')) ? $config->get('mobile_popup_info.format') : $default_filter_format,
- );
+ '#format' => $config_format,
+ ];
- $form['popup_message']['mobile_breakpoint'] = array(
+ $form['popup_message']['mobile_breakpoint'] = [
'#type' => 'number',
'#title' => $this->t('Mobile breakpoint'),
'#default_value' => !empty($config->get('mobile_breakpoint')) ? $config->get('mobile_breakpoint') : '768',
- '#field_suffix' => ' ' . $this->t('pixels'),
+ '#field_suffix' => $this->t('px'),
'#size' => 4,
'#maxlength' => 4,
'#required' => FALSE,
'#description' => $this->t('The mobile message will be used when the window width is below or equal to the given value.'),
- '#states' => array(
- 'visible' => array(
- "input[name='use_mobile_message']" => array('checked' => TRUE),
- ),
- ),
- );
+ '#states' => [
+ 'visible' => [
+ "input[name='use_mobile_message']" => ['checked' => TRUE],
+ ],
+ ],
+ ];
- $form['popup_message']['popup_agree_button_message'] = array(
+ $form['popup_message']['popup_agree_button_message'] = [
'#type' => 'textfield',
'#title' => $this->t('Agree button label'),
'#default_value' => $config->get('popup_agree_button_message'),
'#size' => 30,
'#required' => TRUE,
- );
+ ];
$form['popup_message']['disagree_button'] = [
'#type' => 'checkbox',
- '#title' => $this->t('Show âCookie Policyâ and âMore infoâ buttons'),
- '#description' => $this->t('If this option is checked, the cookie policy button will be shown on the site. Disabling this option will hide both the âCookie Policyâ button on the information banner and the âMore infoâ button on the âThank youâ banner.'),
+ '#title' => $this->t('Show "Cookie Policy" and "More info" buttons'),
+ '#description' => $this->t('If this option is checked, the cookie policy button will be shown on the site. Disabling this option will hide both the "Cookie Policy" button on the information banner and the "More info" button on the "Thank you" banner.'),
'#default_value' => $config->get('show_disagree_button'),
+ '#states' => [
+ 'visible' => [
+ "input[name='method']" => ['value' => 'default'],
+ ],
+ ],
];
- $form['popup_message']['popup_disagree_button_message'] = array(
+ $form['popup_message']['popup_disagree_button_message'] = [
'#type' => 'textfield',
'#title' => $this->t('Cookie policy button label'),
'#default_value' => $config->get('popup_disagree_button_message'),
'#size' => 30,
'#states' => [
'visible' => [
- 'input[name="disagree_button"]' => ['checked' => TRUE],
+ ['input[name="disagree_button"]' => ['checked' => TRUE]],
+ ['input[name="method"]' => ['!value' => 'default']],
],
'required' => [
- 'input[name="disagree_button"]' => ['checked' => TRUE],
+ ['input[name="disagree_button"]' => ['checked' => TRUE]],
+ ['input[name="method"]' => ['!value' => 'default']],
],
],
- );
+ ];
+
+ $form['popup_message']['disagree_button_label'] = [
+ '#type' => 'textfield',
+ '#title' => $this->t('Disagree button label'),
+ '#default_value' => $config->get('disagree_button_label'),
+ '#size' => 30,
+ '#states' => [
+ 'visible' => [
+ 'input[name="method"]' => ['!value' => 'default'],
+ ],
+ 'required' => [
+ 'input[name="method"]' => ['!value' => 'default'],
+ ],
+ ],
+ ];
+
+ $form['withdraw_consent'] = [
+ '#type' => 'details',
+ '#title' => $this->t('Withdraw consent'),
+ '#open' => TRUE,
+ '#states' => [
+ 'visible' => [
+ "input[name='method']" => ['!value' => 'default'],
+ ],
+ ],
+ ];
+
+ $form['withdraw_consent']['info'] = [
+ '#type' => 'markup',
+ '#markup' => t('GDPR requires that withdrawing consent for handling personal information should be as easy as giving consent. This module offers a tab button that when clicked brings up a message and a button that can be used to withdraw consent.'),
+ ];
+
+ $form['withdraw_consent']['withdraw_enabled'] = [
+ '#type' => 'checkbox',
+ '#title' => t('Enable floating privacy settings tab and withdraw consent banner'),
+ '#default_value' => $config->get('withdraw_enabled'),
+ ];
+
+ $config_format = $config->get('popup_info.format');
+ if (!empty($config_format)) {
+ $filter_format = FilterFormat::load($config_format);
+ if (empty($filter_format) || !$filter_format->get('status')) {
+ $config_format = $default_filter_format;
+ }
+ }
+
+ $form['withdraw_consent']['withdraw_message'] = [
+ '#type' => 'text_format',
+ '#title' => t('Withdraw consent banner message'),
+ '#default_value' => isset($config->get('withdraw_message')['value']) ? $config->get('withdraw_message')['value'] : '',
+ '#description' => t('Text that will be displayed in the banner that appears when the privacy settings tab is clicked.'),
+ '#format' => $config_format,
+ ];
- $form['thank_you'] = array(
+ $form['withdraw_consent']['withdraw_tab_button_label'] = [
+ '#type' => 'textfield',
+ '#title' => t('Privacy settings tab label'),
+ '#default_value' => $config->get('withdraw_tab_button_label'),
+ '#description' => t('Tab button that reveals/hides the withdraw message and action button when clicked.'),
+ ];
+
+ $form['withdraw_consent']['withdraw_action_button_label'] = [
+ '#type' => 'textfield',
+ '#title' => t('Withdraw consent action button label'),
+ '#default_value' => $config->get('withdraw_action_button_label'),
+ '#description' => t('This button will withdraw consent when clicked.'),
+ ];
+
+ $form['thank_you'] = [
'#type' => 'details',
'#open' => TRUE,
'#title' => $this->t('Thank you banner'),
- );
+ ];
- $form['thank_you']['popup_agreed_enabled'] = array(
+ $form['thank_you']['popup_agreed_enabled'] = [
'#type' => 'checkbox',
- '#title' => $this->t('Enable âThank youâ banner'),
+ '#title' => $this->t('Enable "Thank you" banner'),
'#default_value' => $config->get('popup_agreed_enabled'),
- );
+ ];
- $form['thank_you']['popup_hide_agreed'] = array(
+ $form['thank_you']['popup_hide_agreed'] = [
'#type' => 'checkbox',
- '#title' => $this->t('Clicking hides âThank youâ banner'),
+ '#title' => $this->t('Clicking hides "Thank you" banner.'),
'#default_value' => $config->get('popup_hide_agreed'),
- '#description' => $this->t('Clicking a link or button hides the âThank youâ message automatically.'),
- );
+ '#description' => $this->t('Clicking a link or button hides the "Thank you" message automatically.'),
+ ];
+
+ $config_format = $config->get('popup_info.format');
+ if (!empty($config_format)) {
+ $filter_format = FilterFormat::load($config_format);
+ if (empty($filter_format) || !$filter_format->get('status')) {
+ $config_format = $default_filter_format;
+ }
+ }
- $form['thank_you']['popup_agreed'] = array(
+ $form['thank_you']['popup_agreed'] = [
'#type' => 'text_format',
- '#title' => $this->t('âThank youâ banner message'),
+ '#title' => $this->t('"Thank you" banner message'),
'#default_value' => !empty($config->get('popup_agreed')['value']) ? $config->get('popup_agreed')['value'] : '',
'#required' => TRUE,
- '#format' => !empty($config->get('popup_agreed')['format']) ? $config->get('popup_agreed')['format'] : $default_filter_format,
- );
+ '#format' => $config_format,
+ ];
- $form['thank_you']['popup_find_more_button_message'] = array(
+ $form['thank_you']['popup_find_more_button_message'] = [
'#type' => 'textfield',
'#title' => $this->t('More info button label'),
'#default_value' => $config->get('popup_find_more_button_message'),
'#size' => 30,
'#states' => [
'visible' => [
- 'input[name="disagree_button"]' => ['checked' => TRUE],
+ ['input[name="disagree_button"]' => ['checked' => TRUE]],
+ ['input[name="method"]' => ['!value' => 'default']],
],
'required' => [
- 'input[name="disagree_button"]' => ['checked' => TRUE],
+ ['input[name="disagree_button"]' => ['checked' => TRUE]],
+ ['input[name="method"]' => ['!value' => 'default']],
],
],
- );
+ ];
- $form['thank_you']['popup_hide_button_message'] = array(
+ $form['thank_you']['popup_hide_button_message'] = [
'#type' => 'textfield',
'#title' => $this->t('Hide button label'),
'#default_value' => $config->get('popup_hide_button_message'),
'#size' => 30,
'#required' => TRUE,
- );
+ ];
- $form['privacy'] = array(
+ $form['privacy'] = [
'#type' => 'details',
'#open' => TRUE,
- '#title' => $this->t('Privacy Policy'),
- );
+ '#title' => $this->t('Privacy policy'),
+ ];
- $form['privacy']['popup_link'] = array(
+ $form['privacy']['popup_link'] = [
'#type' => 'textfield',
'#title' => $this->t('Privacy policy link'),
'#default_value' => $config->get('popup_link'),
'#maxlength' => 1024,
'#required' => TRUE,
'#description' => $this->t('Enter link to your privacy policy or other page that will explain cookies to your users, external links should start with http:// or https://.'),
- '#element_validate' => array(array($this, 'validatePopupLink')),
- );
+ '#element_validate' => [[$this, 'validatePopupLink']],
+ ];
- $form['privacy']['popup_link_new_window'] = array(
+ $form['privacy']['popup_link_new_window'] = [
'#type' => 'checkbox',
- '#title' => $this->t('Open privacy policy link in a new window'),
+ '#title' => $this->t('Open privacy policy link in a new window.'),
'#default_value' => $config->get('popup_link_new_window'),
- );
+ ];
- $form['appearance'] = array(
+ $form['appearance'] = [
'#type' => 'details',
'#open' => TRUE,
'#title' => $this->t('Appearance'),
- );
+ ];
$form_color_picker_type = 'textfield';
@@ -338,224 +540,254 @@ class EuCookieComplianceConfigForm extends ConfigFormBase {
$popup_position_value = ($config->get('popup_position') === TRUE ? 'top' : ($config->get('popup_position') === FALSE ? 'bottom' : $config->get('popup_position')));
- $form['appearance']['popup_position'] = array(
+ $form['appearance']['popup_position'] = [
'#type' => 'radios',
'#title' => $this->t('Position'),
'#default_value' => $popup_position_value,
'#options' => $popup_position_options,
- );
+ ];
- $form['appearance']['use_bare_css'] = array(
+ $form['appearance']['use_bare_css'] = [
'#type' => 'checkbox',
'#title' => $this->t('Include minimal CSS, I want to style the banner in the theme CSS.'),
'#default_value' => !empty($config->get('use_bare_css')) ? $config->get('use_bare_css') : 0,
'#description' => $this->t('This may be useful if you want the banner to share the button style of your theme. Note that you will have to configure values like the banner width, text color and background color in your CSS file.'),
- );
+ ];
- $form['appearance']['popup_text_hex'] = array(
+ $form['appearance']['popup_text_hex'] = [
'#type' => $form_color_picker_type,
'#title' => $this->t('Text color'),
'#default_value' => $config->get('popup_text_hex'),
'#description' => $this->t('Change the text color of the banner. Provide HEX value without the #.'),
- '#element_validate' => array('eu_cookie_compliance_validate_hex'),
- '#states' => array(
- 'visible' => array(
- "input[name='use_bare_css']" => array('checked' => FALSE),
- ),
- ),
- );
+ '#element_validate' => ['eu_cookie_compliance_validate_hex'],
+ '#states' => [
+ 'visible' => [
+ "input[name='use_bare_css']" => ['checked' => FALSE],
+ ],
+ ],
+ ];
- $form['appearance']['popup_bg_hex'] = array(
+ $form['appearance']['popup_bg_hex'] = [
'#type' => $form_color_picker_type,
'#title' => $this->t('Background color'),
'#default_value' => $config->get('popup_bg_hex'),
'#description' => $this->t('Change the background color of the banner. Provide HEX value without the #.'),
- '#element_validate' => array('eu_cookie_compliance_validate_hex'),
- '#states' => array(
- 'visible' => array(
- "input[name='use_bare_css']" => array('checked' => FALSE),
- ),
- ),
- );
+ '#element_validate' => ['eu_cookie_compliance_validate_hex'],
+ '#states' => [
+ 'visible' => [
+ "input[name='use_bare_css']" => ['checked' => FALSE],
+ ],
+ ],
+ ];
- $form['appearance']['popup_height'] = array(
+ $form['appearance']['popup_height'] = [
'#type' => 'number',
- '#title' => $this->t('Banner height in pixels'),
+ '#title' => $this->t('Banner height'),
'#default_value' => !empty($config->get('popup_height')) ? $config->get('popup_height') : '',
- '#field_suffix' => ' ' . $this->t('pixels'),
+ '#field_suffix' => $this->t('px'),
'#size' => 5,
'#maxlength' => 5,
'#required' => FALSE,
'#description' => $this->t('Enter an integer value for a desired height in pixels or leave empty for automatically adjusted height.'),
- '#states' => array(
- 'visible' => array(
- "input[name='use_bare_css']" => array('checked' => FALSE),
- ),
- ),
- );
+ '#states' => [
+ 'visible' => [
+ "input[name='use_bare_css']" => ['checked' => FALSE],
+ ],
+ ],
+ ];
- $form['appearance']['popup_width'] = array(
+ $form['appearance']['popup_width'] = [
'#type' => 'textfield',
'#title' => $this->t('Banner width in pixels or a percentage value'),
'#default_value' => $config->get('popup_width'),
- '#field_suffix' => ' ' . $this->t('px or %'),
+ '#field_suffix' => $this->t('px or %'),
'#size' => 5,
'#maxlength' => 5,
'#description' => $this->t('Set the width of the banner. This can be either an integer value or percentage of the screen width. For example: 200 or 50%.'),
- '#states' => array(
- 'visible' => array("input[name='use_bare_css']" => array('checked' => FALSE)),
- 'required' => array("input[name='use_bare_css']" => array('checked' => FALSE)),
- ),
- );
+ '#states' => [
+ 'visible' => ["input[name='use_bare_css']" => ['checked' => FALSE]],
+ 'required' => ["input[name='use_bare_css']" => ['checked' => FALSE]],
+ ],
+ ];
- $form['eu_only'] = array(
+ $form['eu_only'] = [
'#type' => 'details',
'#open' => TRUE,
'#title' => t('EU countries'),
- );
+ ];
if ($this->moduleHandler->moduleExists('smart_ip') || extension_loaded('geoip')) {
- $form['eu_only']['eu_only'] = array(
+ $form['eu_only']['eu_only'] = [
'#type' => 'checkbox',
- '#title' => $this->t('Only display banner in EU countries'),
+ '#title' => $this->t('Only display banner in EU countries.'),
'#default_value' => !empty($config->get('eu_only')) ? $config->get('eu_only') : 0,
'#description' => $this->t('You can limit the number of countries for which the banner is displayed by checking this option. If you want to provide a list of countries other than current EU states, you may place an array in $config[\'eu_cookie_compliance.settings\'][\'eu_countries\'] in your settings.php file. Using the smart_ip module or the geoip_country_code_by_name() PHP function.'),
- );
- $form['eu_only']['eu_only_js'] = array(
+ ];
+ $form['eu_only']['eu_only_js'] = [
'#type' => 'checkbox',
- '#title' => $this->t('JavaScript-based (for Varnish): Only display banner in EU countries'),
+ '#title' => $this->t('JavaScript-based (for Varnish): Only display banner in EU countries.'),
'#default_value' => !empty($config->get('eu_only_js')) ? $config->get('eu_only_js') : 0,
'#description' => $this->t('This option also works for visitors that bypass Varnish. You can limit the number of countries for which the banner is displayed by checking this option. If you want to provide a list of countries other than current EU states, you may place an array in $config[\'eu_cookie_compliance.settings\'][\'eu_countries\'] in your settings.php file. Using the smart_ip module or the geoip_country_code_by_name() PHP function.'),
- );
+ ];
}
else {
- $form['eu_only']['info'] = array(
+ $form['eu_only']['info'] = [
'#markup' => t('You can choose to show the banner only to visitors from EU countries. In order to achieve this, you need to install the smart_ip module or enable the geoip_country_code_by_name() PHP function.'),
- );
+ ];
}
- $form['advanced'] = array(
+ $form['advanced'] = [
'#type' => 'details',
'#open' => FALSE,
'#title' => $this->t('Advanced'),
- );
+ ];
- $form['advanced']['fixed_top_position'] = array(
+ $form['advanced']['fixed_top_position'] = [
'#type' => 'checkbox',
- '#title' => $this->t('If the banner is at the top, donât scroll the banner with the page'),
+ '#title' => $this->t("If the banner is at the top, don't scroll the banner with the page."),
'#default_value' => $config->get('fixed_top_position'),
'#description' => $this->t('Use position:fixed for the banner when displayed at the top.'),
- );
+ ];
- $form['advanced']['popup_delay'] = array(
+ $form['advanced']['popup_delay'] = [
'#type' => 'number',
- '#title' => $this->t('Banner sliding animation time in milliseconds'),
+ '#title' => $this->t('Banner sliding animation time'),
'#default_value' => $config->get('popup_delay'),
- '#field_suffix' => ' ' . $this->t('milliseconds'),
+ '#field_suffix' => $this->t('ms'),
'#size' => 5,
'#maxlength' => 5,
'#required' => TRUE,
- );
+ ];
- $form['advanced']['disagree_do_not_show_popup'] = array(
+ $form['advanced']['disagree_do_not_show_popup'] = [
'#type' => 'checkbox',
- '#title' => $this->t('Donât show cookie policy when the user clicks the âCookie Policyâ button.'),
+ '#title' => $this->t('Do not show cookie policy when the user clicks the "Cookie Policy" button.'),
'#default_value' => !empty($config->get('disagree_do_not_show_popup')) ? $config->get('disagree_do_not_show_popup') : 0,
'#description' => $this->t('Enabling this will make it possible to record the fact that the user disagrees without the user having to see the privacy policy.'),
- );
+ ];
- $form['advanced']['reload_page'] = array(
+ $form['advanced']['reload_page'] = [
'#type' => 'checkbox',
- '#title' => $this->t('Reload page after user clicks the âAgreeâ button.'),
+ '#title' => $this->t('Reload page after user clicks the "Agree" button.'),
'#default_value' => !empty($config->get('reload_page')) ? $config->get('reload_page') : 0,
- );
+ ];
- $form['advanced']['popup_scrolling_confirmation'] = array(
+ $form['advanced']['popup_scrolling_confirmation'] = [
'#type' => 'checkbox',
'#title' => $this->t('Consent by scrolling'),
'#default_value' => $config->get('popup_scrolling_confirmation'),
'#description' => $this->t('Scrolling makes the visitors to accept the cookie policy. In some countries, like Italy, it is permitted.'),
- );
+ '#states' => [
+ 'visible' => [
+ ['input[name="method"]' => ['value' => 'default']],
+ ],
+ ],
+ ];
- $form['advanced']['cookie_name'] = array(
+ $form['advanced']['cookie_name'] = [
'#type' => 'textfield',
'#title' => $this->t('Cookie name'),
'#default_value' => !empty($config->get('cookie_name')) ? $config->get('cookie_name') : '',
- '#description' => $this->t('Sets the cookie name that is used to check whether the user has agreed or not. This option is useful when policies change and the user needs to agree again.'),
- );
+ '#description' => $this->t('Sets the cookie name that is used to check whether the user has agreed or not. This option is useful when policies change and the user needs to agree again.'),
+ ];
// Adding option to add/remove banner on specified domains.
- $exclude_domains_option_active = array(
+ $exclude_domains_option_active = [
0 => $this->t('Add'),
1 => $this->t('Remove'),
- );
+ ];
- $form['advanced']['domains_option'] = array(
+ $form['advanced']['domains_option'] = [
'#type' => 'radios',
'#title' => $this->t('Add/remove banner on specified domains'),
'#default_value' => $config->get('domains_option'),
'#options' => $exclude_domains_option_active,
'#description' => $this->t('Specify if you want to add or remove banner on the listed below domains.'),
- );
+ ];
- $form['advanced']['domains_list'] = array(
+ $form['advanced']['domains_list'] = [
'#type' => 'textarea',
'#title' => $this->t('Domains list'),
'#default_value' => $config->get('domains_list'),
'#description' => $this->t('Specify domains with protocol (e.g., http or https). Enter one domain per line.'),
- );
+ ];
- $form['advanced']['exclude_paths'] = array(
+ $form['advanced']['exclude_paths'] = [
'#type' => 'textarea',
'#title' => $this->t('Exclude paths'),
'#default_value' => !empty($config->get('exclude_paths')) ? $config->get('exclude_paths') : '',
- '#description' => $this->t("Specify pages by using their paths. Enter one path per line. The '*' character is a wildcard. Example paths are %blog for the blog page and %blog-wildcard for every personal blog. %front is the front page.", array(
+ '#description' => $this->t("Specify pages by using their paths. Enter one path per line. The '*' character is a wildcard. Example paths are %blog for the blog page and %blog-wildcard for every personal blog. %front is the front page.", [
'%blog' => '/blog',
'%blog-wildcard' => '/blog/*',
'%front' => '',
- )),
- );
+ ]),
+ ];
- $form['advanced']['exclude_admin_theme'] = array(
+ $form['advanced']['exclude_admin_theme'] = [
'#type' => 'checkbox',
- '#title' => $this->t('Exclude admin pages'),
+ '#title' => $this->t('Exclude admin pages.'),
'#default_value' => $config->get('exclude_admin_theme'),
- );
+ ];
- $form['advanced']['exclude_uid_1'] = array(
+ $form['advanced']['exclude_uid_1'] = [
'#type' => 'checkbox',
- '#title' => $this->t('Donât show the banner for UID 1.'),
+ '#title' => $this->t("Don't show the banner for UID 1."),
'#default_value' => !empty($config->get('exclude_uid_1')) ? $config->get('exclude_uid_1') : 0,
- );
+ ];
- $form['advanced']['better_support_for_screen_readers'] = array(
+ $form['advanced']['better_support_for_screen_readers'] = [
'#type' => 'checkbox',
'#title' => $this->t('Let screen readers see the banner before other links on the page.'),
'#default_value' => !empty($config->get('better_support_for_screen_readers')) ? $config->get('better_support_for_screen_readers') : 0,
'#description' => $this->t('Enable this if you want to place the banner as the first HTML element on the page. This will make it possible for screen readers to close the banner without tabbing through all links on the page.'),
- );
+ ];
- $form['advanced']['domain'] = array(
+ $form['advanced']['domain'] = [
'#type' => 'textfield',
'#title' => $this->t('Domain'),
'#default_value' => $config->get('domain'),
'#description' => $this->t('Sets the domain of the cookie to a specific url. Used when you need consistency across domains. This is language independent. Note: Make sure you actually enter a domain that the browser can make use of. For example if your site is accessible at both www.domain.com and domain.com, you will not be able to hide the banner at domain.com if your value for this field is www.domain.com.'),
- );
+ ];
+
+ $form['advanced']['cookie_session'] = [
+ '#type' => 'checkbox',
+ '#title' => $this->t('Prompt for consent (from the same user) at every new browser session.'),
+ '#description' => $this->t("This sets cookie lifetime to 0, invalidating the cookie at the end of the browser session. To set a cookie lifetime greater than 0, uncheck this option. Note that some users will find this behavior highly annoying, and it's recommended to double-check with the legal advisor whether you really need this option enabled."),
+ '#default_value' => $config->get('cookie_session'),
+ ];
- $form['advanced']['cookie_lifetime'] = array(
+ $form['advanced']['cookie_lifetime'] = [
'#type' => 'number',
'#title' => $this->t('Cookie lifetime'),
- '#description' => $this->t("How long does the system remember the user's choice, in days."),
+ '#description' => $this->t("How many days the system remember the user's choice."),
'#default_value' => $config->get('cookie_lifetime'),
- '#field_suffix' => ' ' . $this->t('days'),
+ '#field_suffix' => $this->t('days'),
'#size' => 5,
'#maxlength' => 5,
'#required' => TRUE,
- );
+ '#states' => [
+ 'enabled' => [
+ "input[name='cookie_session']" => ['checked' => FALSE],
+ ],
+ ],
+ ];
return parent::buildForm($form, $form_state);
}
+ /**
+ * {@inheritdoc}
+ */
+ public function validateForm(array &$form, FormStateInterface $form_state) {
+ parent::validateForm($form, $form_state);
+
+ // Validate cookie name against valid characters.
+ if (preg_match('/[&\'\x00-\x20\x22\x28-\x29\x2c\x2f\x3a-\x40\x5b-\x5d\x7b\x7d\x7f]/', $form_state->getValue('cookie_name'))) {
+ $form_state->setErrorByName('cookie_name', $this->t('Invalid cookie name, please remove any special characters and try again.'));
+ }
+
+ }
+
/**
* {@inheritdoc}
*/
@@ -581,6 +813,7 @@ class EuCookieComplianceConfigForm extends ConfigFormBase {
$permission_name = 'display eu cookie compliance popup';
foreach ($this->getRoles() as $role_name => $role) {
+ /* @var \Drupal\user\Entity\Role $role */
if (!$role->isAdmin()) {
if (array_key_exists($role_name, $form_state->getValue('see_the_banner')) && $form_state->getValue('see_the_banner')[$role_name]) {
user_role_grant_permissions($role_name, [$permission_name]);
@@ -599,6 +832,24 @@ class EuCookieComplianceConfigForm extends ConfigFormBase {
$form_state->setValue('popup_position', FALSE);
}
+ $method = $form_state->getValue('method');
+
+ if ($method != 'default') {
+ $form_state->setValue('disagree_button', TRUE);
+ $form_state->setValue('popup_clicking_confirmation', FALSE);
+ $form_state->setValue('popup_scrolling_confirmation', FALSE);
+
+ }
+ else {
+ $form_state->setValue('whitelisted_cookies', '');
+ $form_state->setValue('disabled_javascripts', '');
+ }
+
+ // Clear cached javascript.
+ Cache::invalidateTags(['library_info']);
+
+ eu_cookie_compliance_module_set_weight();
+
// Save settings.
$this->config('eu_cookie_compliance.settings')
->set('domain', $form_state->getValue('domain'))
@@ -611,7 +862,7 @@ class EuCookieComplianceConfigForm extends ConfigFormBase {
->set('popup_disagree_button_message', $form_state->getValue('popup_disagree_button_message'))
->set('popup_info', $form_state->getValue('popup_info'))
->set('use_mobile_message', $form_state->getValue('use_mobile_message'))
- ->set('mobile_popup_info', $form_state->getValue('use_mobile_message') ? $form_state->getValue('mobile_popup_info') : array('value' => '', 'format' => filter_default_format()))
+ ->set('mobile_popup_info', $form_state->getValue('use_mobile_message') ? $form_state->getValue('mobile_popup_info') : ['value' => '', 'format' => filter_default_format()])
->set('mobile_breakpoint', $form_state->getValue('mobile_breakpoint'))
->set('popup_agreed_enabled', $form_state->getValue('popup_agreed_enabled'))
->set('popup_hide_agreed', $form_state->getValue('popup_hide_agreed'))
@@ -630,6 +881,7 @@ class EuCookieComplianceConfigForm extends ConfigFormBase {
->set('exclude_paths', $form_state->getValue('exclude_paths'))
->set('exclude_admin_theme', $form_state->getValue('exclude_admin_theme'))
->set('cookie_lifetime', $form_state->getValue('cookie_lifetime'))
+ ->set('cookie_session', $form_state->getValue('cookie_session'))
->set('eu_only', $form_state->getValue('eu_only'))
->set('eu_only_js', $form_state->getValue('eu_only_js'))
->set('use_bare_css', $form_state->getValue('use_bare_css'))
@@ -639,6 +891,15 @@ class EuCookieComplianceConfigForm extends ConfigFormBase {
->set('exclude_uid_1', $form_state->getValue('exclude_uid_1'))
->set('better_support_for_screen_readers', $form_state->getValue('better_support_for_screen_readers'))
->set('fixed_top_position', $form_state->getValue('fixed_top_position'))
+ ->set('method', $form_state->getValue('method'))
+ ->set('disagree_button_label', $form_state->getValue('disagree_button_label'))
+ ->set('whitelisted_cookies', $form_state->getValue('whitelisted_cookies'))
+ ->set('disabled_javascripts', $form_state->getValue('disabled_javascripts'))
+ ->set('consent_storage_method', $form_state->getValue('consent_storage_method'))
+ ->set('withdraw_message', $form_state->getValue('withdraw_message'))
+ ->set('withdraw_action_button_label', $form_state->getValue('withdraw_action_button_label'))
+ ->set('withdraw_tab_button_label', $form_state->getValue('withdraw_tab_button_label'))
+ ->set('withdraw_enabled', $form_state->getValue('withdraw_enabled'))
->save();
parent::submitForm($form, $form_state);
@@ -652,7 +913,7 @@ class EuCookieComplianceConfigForm extends ConfigFormBase {
* @param \Drupal\Core\Form\FormStateInterface $form_state
* Form state.
*/
- public function validatePopupLink($element, FormStateInterface &$form_state) {
+ public function validatePopupLink(array $element, FormStateInterface &$form_state) {
if (empty($element['#value'])) {
return;
}
@@ -661,17 +922,17 @@ class EuCookieComplianceConfigForm extends ConfigFormBase {
if (UrlHelper::isExternal($input)) {
$allowed_protocols = ['http', 'https'];
if (!in_array(parse_url($input, PHP_URL_SCHEME), $allowed_protocols)) {
- $form_state->setError($element, $this->t('Invalid protocol specified for the %name (valid protocols: %protocols).', array(
+ $form_state->setError($element, $this->t('Invalid protocol specified for the %name (valid protocols: %protocols).', [
'%name' => $element['#title'],
'%protocols' => implode(', ', $allowed_protocols),
- )));
+ ]));
}
else {
try {
Url::fromUri($input);
}
catch (\Exception $exc) {
- $form_state->setError($element, $this->t('Invalid %name (:message).', array('%name' => $element['#title'], ':message' => $exc->getMessage())));
+ $form_state->setError($element, $this->t('Invalid %name (:message).', ['%name' => $element['#title'], ':message' => $exc->getMessage()]));
}
}
}
@@ -684,7 +945,7 @@ class EuCookieComplianceConfigForm extends ConfigFormBase {
Url::fromUserInput($input);
}
catch (\Exception $exc) {
- $form_state->setError($element, $this->t('Invalid URL in %name field (:message).', array('%name' => $element['#title'], ':message' => $exc->getMessage())));
+ $form_state->setError($element, $this->t('Invalid URL in %name field (:message).', ['%name' => $element['#title'], ':message' => $exc->getMessage()]));
}
}
}
diff --git a/web/modules/contrib/eu_cookie_compliance/src/Plugin/ConsentStorage/BasicConsentStorage.php b/web/modules/contrib/eu_cookie_compliance/src/Plugin/ConsentStorage/BasicConsentStorage.php
new file mode 100644
index 000000000..ce1368ad2
--- /dev/null
+++ b/web/modules/contrib/eu_cookie_compliance/src/Plugin/ConsentStorage/BasicConsentStorage.php
@@ -0,0 +1,47 @@
+getCurrentPolicyNodeRevision();
+ $timestamp = time();
+ $ip_address = \Drupal::request()->getClientIp();
+ $uid = \Drupal::currentUser()->id();
+
+ \Drupal::database()->insert('eu_cookie_compliance_basic_consent')->fields(
+ [
+ 'uid' => $uid,
+ 'ip_address' => $ip_address,
+ 'timestamp' => $timestamp,
+ 'revision_id' => $revision_id ? $revision_id : 0 ,
+ 'consent_type' => $consent_type,
+ ]
+ )->execute();
+ return TRUE;
+ }
+
+}
diff --git a/web/modules/contrib/eu_cookie_compliance/src/Plugin/ConsentStorageBase.php b/web/modules/contrib/eu_cookie_compliance/src/Plugin/ConsentStorageBase.php
new file mode 100644
index 000000000..9871422bc
--- /dev/null
+++ b/web/modules/contrib/eu_cookie_compliance/src/Plugin/ConsentStorageBase.php
@@ -0,0 +1,122 @@
+configFactory = $config_factory;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+ return new static(
+ $configuration,
+ $plugin_id,
+ $plugin_definition,
+ $container->get('config.factory')
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function label() {
+ return $this->pluginDefinition['label'];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function description() {
+ return $this->pluginDefinition['description'];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getStatus() {
+ return TRUE;
+ }
+
+ /**
+ * Get the current revision of the privacy policy node.
+ *
+ * @return bool|int
+ * Returns the latest revision ID of the curreny privacy policy node, or
+ * FALSE if no priacy policy exists.
+ *
+ * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
+ */
+ public function getCurrentPolicyNodeRevision() {
+ $config = $this->configFactory->get('eu_cookie_compliance.settings');
+ $cookie_policy_link = $config->get('popup_link');
+ $cookie_policy_drupal_path = \Drupal::service('path.alias_manager')->getPathByAlias($cookie_policy_link, \Drupal::languageManager()->getCurrentLanguage()->getId());
+ if (substr($cookie_policy_drupal_path, 0, 6) == '/node/') {
+ $node_id = explode('/', $cookie_policy_drupal_path)[2];
+ /* @var \Drupal\node\Entity\Node $node */
+ $node = \Drupal::entityTypeManager()->getStorage('node')->load($node_id);
+ return $node->getRevisionId();
+ }
+ else {
+ return FALSE;
+ }
+ }
+
+ /**
+ * Register consent.
+ *
+ * In addition to the parameters passed to the function, consider storing the
+ * uid, ip address, timestamp and the current revision of the cookie policy.
+ *
+ * @param string $consent_type
+ * "banner" if the consent is given to the cookie banner or the form ID when
+ * consent is given on a form.
+ *
+ * @return bool
+ * Returns TRUE when the consent has been stored successfully, FALSE on
+ * error.
+ */
+ abstract protected function registerConsent($consent_type);
+
+}
diff --git a/web/modules/contrib/eu_cookie_compliance/src/Plugin/ConsentStorageInterface.php b/web/modules/contrib/eu_cookie_compliance/src/Plugin/ConsentStorageInterface.php
new file mode 100644
index 000000000..bf7d24a90
--- /dev/null
+++ b/web/modules/contrib/eu_cookie_compliance/src/Plugin/ConsentStorageInterface.php
@@ -0,0 +1,34 @@
+alterInfo('consent_storage_info');
+ $this->setCacheBackend($cache_backend, 'consent_storage_info_plugins');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFallbackPluginId($plugin_id, array $configuration = []) {
+ return 'basic';
+ }
+
+}
diff --git a/web/modules/contrib/eu_cookie_compliance/src/Plugin/ConsentStorageManagerInterface.php b/web/modules/contrib/eu_cookie_compliance/src/Plugin/ConsentStorageManagerInterface.php
new file mode 100644
index 000000000..c32845a61
--- /dev/null
+++ b/web/modules/contrib/eu_cookie_compliance/src/Plugin/ConsentStorageManagerInterface.php
@@ -0,0 +1,31 @@
+moduleExists('smart_ip')) {
+ $routes = [];
+ if (\Drupal::config('eu_cookie_compliance.settings')->get('eu_only_js')) {
$routes['eu_cookie_compliance.check_if_eu_country_js'] = new Route(
'/eu-cookie-compliance-check',
[
diff --git a/web/modules/contrib/eu_cookie_compliance/templates/eu_cookie_compliance_popup_agreed.html.twig b/web/modules/contrib/eu_cookie_compliance/templates/eu_cookie_compliance_popup_agreed.html.twig
index 608988525..abd78b175 100644
--- a/web/modules/contrib/eu_cookie_compliance/templates/eu_cookie_compliance_popup_agreed.html.twig
+++ b/web/modules/contrib/eu_cookie_compliance/templates/eu_cookie_compliance_popup_agreed.html.twig
@@ -11,7 +11,7 @@
* find-more-button - link to an information page
*
* Variables available:
- * - $message: Contains the text that will be display whithin the banner
+ * - $message: Contains the text that will be display within the banner
* - $hide_button: Label for the hide button
* - $find_more_button: Label for the find out more button
*/
@@ -25,7 +25,7 @@
{% if find_more_button %}
-
+
{% endif %}
diff --git a/web/modules/contrib/eu_cookie_compliance/templates/eu_cookie_compliance_popup_info.html.twig b/web/modules/contrib/eu_cookie_compliance/templates/eu_cookie_compliance_popup_info.html.twig
index 4317b1635..f9f1a4dec 100644
--- a/web/modules/contrib/eu_cookie_compliance/templates/eu_cookie_compliance_popup_info.html.twig
+++ b/web/modules/contrib/eu_cookie_compliance/templates/eu_cookie_compliance_popup_info.html.twig
@@ -12,8 +12,17 @@
*
* Variables available:
* - message: Contains the text that will be display whithin the banner
- * - agree_button: Label for the agree button
- * - disagree_button: Label for the disagree button
+ * - agree_button: Label for the primary/agree button. Note that this is the
+ * primary button. For backwards compatibility, the name remains agree_button.
+ * - disagree_button: Contains Cookie policy button title. (Note: for historical
+ * reasons, this label is called "disagree" even though it just displays the
+ * privacy policy.)
+ * - secondary_button_label: Contains the secondary button label. The current
+ * action depends on whether you're running the module in Opt-out or Opt-in
+ * mode.
+ * - primary_button_class: Contains class names for the primary button.
+ * - secondary_button_class: Contains class names for the secondary button
+ * (if visible).
*/
#}
@@ -21,12 +30,15 @@
diff --git a/web/modules/contrib/eu_cookie_compliance/templates/eu_cookie_compliance_withdraw.html.twig b/web/modules/contrib/eu_cookie_compliance/templates/eu_cookie_compliance_withdraw.html.twig
new file mode 100755
index 000000000..1b63b23df
--- /dev/null
+++ b/web/modules/contrib/eu_cookie_compliance/templates/eu_cookie_compliance_withdraw.html.twig
@@ -0,0 +1,28 @@
+{#
+/**
+ * @file
+ * This is a template file for the cookie consent withdraw button.
+ *
+ * When overriding this template it is important to note that jQuery will use
+ * the following classes to assign actions to the button:
+ *
+ * eu-cookie-withdraw-button - withdraw button
+ * eu-cookie-withdraw-tab - tab that reveals the withdraw interface
+ *
+ * Variables available:
+ * - message: Contains the text that will be displayed within the banner.
+ * - withdraw_tab_button_label: Label for the tab that sits at the window edge.
+ * - withdraw_action_button_label: Label for the withdraw button.
+ */
+#}
+
+
+
+
+ {{ message }}
+
+
+
+
+
+
diff --git a/web/modules/contrib/entity/LICENSE.txt b/web/modules/contrib/file_mdm/LICENSE.txt
similarity index 100%
rename from web/modules/contrib/entity/LICENSE.txt
rename to web/modules/contrib/file_mdm/LICENSE.txt
diff --git a/web/modules/contrib/file_mdm/README.md b/web/modules/contrib/file_mdm/README.md
new file mode 100644
index 000000000..aa26f1054
--- /dev/null
+++ b/web/modules/contrib/file_mdm/README.md
@@ -0,0 +1,115 @@
+# File metadata manager
+
+A Drupal 8 module providing a file metadata manager service and API. Allows to
+get, via an unified API, information stored in files like EXIF photo
+information, TrueType font information, etc.
+
+Metadata protocols are pluggable. Developers can implement a plugin and use the
+service framework to get the metadata required.
+
+The following plugins are provided by the module:
+
+Plugin | Read | Write | Description |
+--------------|:----:|:-----:|--------------------------------------------------------------|
+exif | X | X | Uses the [PHP Exif Library](https://github.com/lsolesen/pel) to read/write EXIF information to image files, bypassing the limitations of the standard PHP Exif extensions which only provides read capabilities. Enable the _file_mdm_exif_ submodule to enable this plugin. |
+font | X | | Uses the [PHP Font Lib](https://github.com/PhenX/php-font-lib) to read font information from TTF/OTF/WOFF font files. Enable the _file_mdm_exif_ submodule to enable this plugin. |
+getimagesize | X | | Caches calls to the PHP ```getimagesize()``` function. |
+
+The module is inspired by discussions at [#2630242 Provide methods to retrieve EXIF image information via the Image object](https://www.drupal.org/node/2630242).
+
+
+## Features:
+
+1. Load from, and save to, file embedded metadata directly from the files.
+2. Metadata for a file is statically cached during a request's lifetime. This
+ avoids different modules all repeat I/O on the same file.
+3. Metadata can be cached in a Drupal cache bin to avoid repeating I/O on the
+ files in successive requests.
+4. Metadata standards (EXIF, TTF, etc.) are implemented as plugins. The service
+ loads the metadata plugin needed based on the calling code request.
+5. Manages copying to/from local temporary storage files stored in remote file
+ systems, to allow PHP functions that do not support remote stream wrappers
+ access the file locally.
+
+
+## Installing:
+
+The module requires [using Composer to manage Drupal site dependencies](https://www.drupal.org/node/2718229).
+Once you have setup building your code base using composer, require the module
+via
+
+```$ composer require drupal/file_mdm```
+
+then enable the module as usual. Also enable the EXIF or font submodules if
+needed.
+
+
+## Configuration:
+
+- Go to _Manage > Configuration > System > File Metadata Manager_ and specify
+ the cache retention requirements, in general and/or per each metadata plugin.
+
+
+## Usage examples:
+
+Metadata are retrieved by specifying the protocol plugin required, and the
+specific _metadata key_ needed.
+
+For the 'getimagesize' protocol, the metadata keys supported correspond to the
+array keys returned by the PHP ```getimagesize()``` function:
+
+Key | Description |
+---------|--------------------------------------------------------------|
+0 | Width of the image |
+1 | Height of the image |
+2 | The _IMAGETYPE_*_ constant indicating the type of the image |
+3 | Text string with the correct _height="yyy" width="xxx"_ string that can be used directly in an IMG tag |
+mime | The MIME type of the image |
+channels | 3 for RGB pictures and 4 for CMYK pictures |
+bits | The number of bits for each color |
+
+1. __Basic usage:__
+
+ a. Use the _file_metadata_manager_ service to prepare collecting metadata for
+ the file located at a desired URI:
+ ```php
+ $fmdm = \Drupal::service('file_metadata_manager');
+ $my_file_metadata = $fmdm->uri('public::/my_directory/test-image.jpeg');
+ ```
+ b. Get the metadata for the specific protocol, identified by the _plugin_, and
+ the metadata _key_ required:
+ ```php
+ $mime = $my_file_metadata->getMetadata('getimagesize', 'mime');
+ ```
+ c. Summarizing, in the context of a controller returning a render array:
+ ```php
+ $fmdm = \Drupal::service('file_metadata_manager');
+ $my_file_metadata = $fmdm->uri('public::/my_directory/test-image.jpeg');
+ $mime = $my_file_metadata->getMetadata('getimagesize', 'mime');
+ return ['#markup' => 'MIME type: ' . $mime];
+ ```
+
+ will return something like
+ ```
+ MIME type: image/jpeg
+ ```
+
+2. __Use a known local temp copy of the remote file to avoid remote file access:__
+
+ ```php
+ $fmdm = \Drupal::service('file_metadata_manager');
+ $my_file_metadata = $fmdm->uri('remote_wrapper::/my_directory/test-image.jpeg');
+ $my_file_metadata->setLocalTempPath($temp_path);
+ $mime = $my_file_metadata->getMetadata('getimagesize', 'mime');
+ ...
+ ```
+
+3. __Make a local temp copy of the remote file to avoid remote file access:__
+
+ ```php
+ $fmdm = \Drupal::service('file_metadata_manager');
+ $my_file_metadata = $fmdm->uri('remote_wrapper::/my_directory/test-image.jpeg');
+ $my_file_metadata->copyUriToTemp();
+ $mime = $my_file_metadata->getMetadata('getimagesize', 'mime');
+ ...
+ ```
diff --git a/web/modules/contrib/file_mdm/composer.json b/web/modules/contrib/file_mdm/composer.json
new file mode 100644
index 000000000..3872c5ec7
--- /dev/null
+++ b/web/modules/contrib/file_mdm/composer.json
@@ -0,0 +1,10 @@
+{
+ "name": "drupal/file_mdm",
+ "type": "drupal-module",
+ "description": "Provides a service to manage file metadata.",
+ "require": {
+ "php": ">=5.6",
+ "phenx/php-font-lib": "0.5",
+ "lsolesen/pel": "0.9.6"
+ }
+}
diff --git a/web/modules/contrib/file_mdm/config/install/file_mdm.file_metadata_plugin.getimagesize.yml b/web/modules/contrib/file_mdm/config/install/file_mdm.file_metadata_plugin.getimagesize.yml
new file mode 100644
index 000000000..394780947
--- /dev/null
+++ b/web/modules/contrib/file_mdm/config/install/file_mdm.file_metadata_plugin.getimagesize.yml
@@ -0,0 +1,7 @@
+configuration:
+ cache:
+ override: FALSE
+ settings:
+ enabled: TRUE
+ expiration: 172800
+ disallowed_paths: { }
diff --git a/web/modules/contrib/file_mdm/config/install/file_mdm.settings.yml b/web/modules/contrib/file_mdm/config/install/file_mdm.settings.yml
new file mode 100644
index 000000000..3ac296f8e
--- /dev/null
+++ b/web/modules/contrib/file_mdm/config/install/file_mdm.settings.yml
@@ -0,0 +1,4 @@
+metadata_cache:
+ enabled: TRUE
+ expiration: 172800
+ disallowed_paths: { }
diff --git a/web/modules/contrib/file_mdm/config/schema/file_mdm.data_types.schema.yml b/web/modules/contrib/file_mdm/config/schema/file_mdm.data_types.schema.yml
new file mode 100644
index 000000000..37bf4e24a
--- /dev/null
+++ b/web/modules/contrib/file_mdm/config/schema/file_mdm.data_types.schema.yml
@@ -0,0 +1,32 @@
+# Basic data types for file_mdm module.
+
+file_mdm.cache_settings:
+ type: mapping
+ label: 'Cache settings'
+ mapping:
+ enabled:
+ type: boolean
+ label: 'Enable metadata caching'
+ expiration:
+ type: integer
+ label: 'Cache entry duration'
+ disallowed_paths:
+ type: sequence
+ label: 'Paths to be excluded from caching'
+ sequence:
+ type: string
+
+file_mdm.plugin.configuration:
+ type: mapping
+ label: 'FileMetadata plugin settings'
+ mapping:
+ cache:
+ type: mapping
+ label: 'Cache settings'
+ mapping:
+ override:
+ type: boolean
+ label: 'Override general settings'
+ settings:
+ type: file_mdm.cache_settings
+ label: 'Plugin overridden cache settings'
diff --git a/web/modules/contrib/file_mdm/config/schema/file_mdm.schema.yml b/web/modules/contrib/file_mdm/config/schema/file_mdm.schema.yml
new file mode 100644
index 000000000..91bed16c8
--- /dev/null
+++ b/web/modules/contrib/file_mdm/config/schema/file_mdm.schema.yml
@@ -0,0 +1,18 @@
+# file_mdm module schema
+
+# Schema for settings.
+file_mdm.settings:
+ type: config_object
+ label: 'file_mdm settings'
+ mapping:
+ metadata_cache:
+ type: file_mdm.cache_settings
+ label: 'Main metadata caching'
+
+file_mdm.file_metadata_plugin.getimagesize:
+ type: config_object
+ label: 'getimagesize file metadata plugin settings'
+ mapping:
+ configuration:
+ type: file_mdm.plugin.configuration
+ label: 'getimagesize plugin settings'
diff --git a/web/modules/contrib/file_mdm/file_mdm.info.yml b/web/modules/contrib/file_mdm/file_mdm.info.yml
new file mode 100644
index 000000000..da246ee07
--- /dev/null
+++ b/web/modules/contrib/file_mdm/file_mdm.info.yml
@@ -0,0 +1,15 @@
+type: module
+# core: 8.x
+name: 'File metadata manager'
+description: 'Provides a service to manage file metadata.'
+package: File metadata
+configure: file_mdm.settings
+php: 5.6
+test_dependencies:
+ - image_effects
+
+# Information added by Drupal.org packaging script on 2017-02-28
+version: '8.x-1.1'
+core: '8.x'
+project: 'file_mdm'
+datestamp: 1488273795
diff --git a/web/modules/contrib/file_mdm/file_mdm.links.menu.yml b/web/modules/contrib/file_mdm/file_mdm.links.menu.yml
new file mode 100644
index 000000000..471a909d6
--- /dev/null
+++ b/web/modules/contrib/file_mdm/file_mdm.links.menu.yml
@@ -0,0 +1,5 @@
+file_mdm.settings:
+ title: 'File metadata manager'
+ route_name: file_mdm.settings
+ description: 'Configure file metadata settings.'
+ parent: system.admin_config_system
diff --git a/web/modules/contrib/file_mdm/file_mdm.module b/web/modules/contrib/file_mdm/file_mdm.module
new file mode 100644
index 000000000..34e6a70d5
--- /dev/null
+++ b/web/modules/contrib/file_mdm/file_mdm.module
@@ -0,0 +1,26 @@
+deleteCachedMetadata($entity->getFileUri());
+ $fmdm->release($entity->getFileUri());
+}
diff --git a/web/modules/contrib/file_mdm/file_mdm.routing.yml b/web/modules/contrib/file_mdm/file_mdm.routing.yml
new file mode 100644
index 000000000..7f4a17a4c
--- /dev/null
+++ b/web/modules/contrib/file_mdm/file_mdm.routing.yml
@@ -0,0 +1,9 @@
+# file_mdm module routes
+
+file_mdm.settings:
+ path: '/admin/config/system/file_mdm'
+ defaults:
+ _form: '\Drupal\file_mdm\Form\SettingsForm'
+ _title: 'File metadata manager'
+ requirements:
+ _permission: 'administer site configuration'
diff --git a/web/modules/contrib/file_mdm/file_mdm.services.yml b/web/modules/contrib/file_mdm/file_mdm.services.yml
new file mode 100644
index 000000000..bd8829155
--- /dev/null
+++ b/web/modules/contrib/file_mdm/file_mdm.services.yml
@@ -0,0 +1,17 @@
+services:
+ cache.file_mdm:
+ class: Drupal\Core\Cache\CacheBackendInterface
+ tags:
+ - { name: cache.bin }
+ factory: cache_factory:get
+ arguments: ['file_mdm']
+ logger.channel.file_mdm:
+ parent: logger.channel_base
+ arguments: ['file_mdm']
+ file_metadata_manager:
+ class: Drupal\file_mdm\FileMetadataManager
+ arguments: ['@plugin.manager.file_metadata', '@logger.channel.file_mdm', '@config.factory', '@file_system', '@cache.file_mdm']
+ plugin.manager.file_metadata:
+ class: Drupal\file_mdm\Plugin\FileMetadataPluginManager
+ parent: default_plugin_manager
+ arguments: ['@config.factory']
diff --git a/web/modules/contrib/file_mdm/file_mdm_exif/README.md b/web/modules/contrib/file_mdm/file_mdm_exif/README.md
new file mode 100644
index 000000000..9f50240c4
--- /dev/null
+++ b/web/modules/contrib/file_mdm/file_mdm_exif/README.md
@@ -0,0 +1,134 @@
+# File metadata EXIF
+
+A Drupal 8 module providing a file metadata plugin for the EXIF protocol.
+
+
+## Features:
+
+Uses the [PHP Exif Library](https://github.com/lsolesen/pel) to read/write EXIF
+information to image files, so bypassing the limitations of the standard PHP
+Exif extensions which only provides read capabilities.
+
+
+## Usage examples:
+
+1. __Get EXIF information from a file:__
+
+ a. Prepare collecting metadata for the file located at a desired URI:
+
+ ```php
+ $fmdm = \Drupal::service('file_metadata_manager');
+ $my_file_metadata = $fmdm->uri('public::/my_directory/test-exif.jpeg');
+ ...
+ ```
+
+ b. Get the metadata for the metadata _$key_ required. The value returned is an
+ associative array with two keys:
+ - 'text': the string representation of the EXIF tag, suitable for
+ presentation;
+ - 'value': the EXIF tag value in PEL internal format.
+
+ ```php
+ ...
+ $val = $my_file_metadata->getMetadata('exif', $key);
+ ...
+ ```
+
+ c. EXIF metadata is organized in 'headers' (IFDs) and 'tags'. For this reason,
+ the metadata _$key_ can be specified in the ```getMetadata``` method:
+ - as a string: in this case, it is assumed that a TAG is specified, and the
+ default IFD for that TAG will be used to fetch the information:
+ - as an array: in this case, the first and the second array elements
+ specify respectively the IFD and the TAG requested. IFD and TAG can be
+ strings, or integers.
+ The following statements all are equivalent in returning the same
+ information about the 'ApertureValue' TAG in the 'Exif' IFD:
+
+ ```php
+ ...
+ $aperture = $my_file_metadata->getMetadata('exif', 'ApertureValue');
+ $aperture = $my_file_metadata->getMetadata('exif', ['Exif', 'ApertureValue']);
+ $aperture = $my_file_metadata->getMetadata('exif', [2, 'ApertureValue']);
+ $aperture = $my_file_metadata->getMetadata('exif', ['Exif', 0x9202]);
+ $aperture = $my_file_metadata->getMetadata('exif', [2, 0x9202]);
+ ...
+ ```
+
+ d. Get a list of IFDs:
+
+ ```php
+ ...
+ $my_file_metadata->getSupportedKeys('exif', ['ifds' => TRUE]);
+ ...
+ ```
+
+ e. Get a list of TAGs for a given IFD:
+
+ ```php
+ ...
+ $my_file_metadata->getSupportedKeys('exif', ['ifd' => 'GPS']);
+ ...
+ ```
+
+ f. Walk through all possible IFDs/TAGs and build a table with results:
+
+ ```php
+ ...
+ $header = [
+ ['data' => 'key'],
+ ['data' => 'text'],
+ ['data' => 'value'],
+ ];
+ $rows = [];
+ foreach ($my_file_metadata->getSupportedKeys('exif', ['ifds' => TRUE]) as $ifd) {
+ $rows[] = [['data' => $ifd[0], 'colspan' => 3]];
+ $keys = $my_file_metadata->getSupportedKeys('exif', ['ifd' => $ifd[0]]);
+ foreach ($keys as $key) {
+ $x = $my_file_metadata->getMetadata('exif', $key);
+ if ($x) {
+ $rows[] = ['data' => [$key[1], $x ? $x['text'] : NULL, $x ? var_export($x['value'], TRUE) : NULL]];
+ }
+ }
+ }
+ return [
+ '#theme' => 'table',
+ '#header' => $header,
+ '#rows' => $rows,
+ ];
+ ```
+
+2. __Change EXIF information and save to file:__
+
+Changing EXIF information and saving it back to the file requires some
+understanding of how the PEL library manages EXIF entries.
+
+a. If you are changing information that is _already_ existing in the source
+ file, then you can use the plugin ```setMetadata``` method, passing the value
+ that the PEL Exif entry expects:
+
+ ```php
+ ...
+ $my_file_metadata->setMetadata('exif', 'Orientation', 7);
+ ...
+ ```
+
+b. If you are _adding_ a TAG that was not existing before, you need to pass a
+ new PEL Exif entry, as expected for that entry. This can also be done as an
+ alternative to change an existing entry:
+
+ ```php
+ ...
+ $artist_tag = \Drupal::service('file_mdm_exif.tag_mapper')->resolveKeyToIfdAndTag('Artist');
+ $value = 'MEEeeee!';
+ $artist = new PelEntryAscii($artist_tag['tag'], $value);
+ $my_file_metadata->setMetadata('exif', 'Artist', $artist);
+ ...
+ ```
+
+c. Save changed metadata to file:
+
+ ```php
+ ...
+ $my_file_metadata->saveMetadataToFile('exif');
+ ...
+ ```
diff --git a/web/modules/contrib/file_mdm/file_mdm_exif/config/install/file_mdm_exif.file_metadata_plugin.exif.yml b/web/modules/contrib/file_mdm/file_mdm_exif/config/install/file_mdm_exif.file_metadata_plugin.exif.yml
new file mode 100644
index 000000000..9f1433b56
--- /dev/null
+++ b/web/modules/contrib/file_mdm/file_mdm_exif/config/install/file_mdm_exif.file_metadata_plugin.exif.yml
@@ -0,0 +1,33 @@
+ifd_map:
+ 0:
+ type: 0
+ aliases:
+ - '0'
+ - 'IFD0'
+ - 'Main'
+ 1:
+ type: 1
+ aliases:
+ - '1'
+ - 'IFD1'
+ - 'Thumbnail'
+ Exif:
+ type: 2
+ aliases:
+ - 'Exif'
+ GPS:
+ type: 3
+ aliases:
+ - 'GPS'
+ Interoperability:
+ type: 4
+ aliases:
+ - 'Interoperability'
+ - 'Interop'
+configuration:
+ cache:
+ override: FALSE
+ settings:
+ enabled: TRUE
+ expiration: 172800
+ disallowed_paths: { }
diff --git a/web/modules/contrib/file_mdm/file_mdm_exif/config/schema/file_mdm_exif.data_types.schema.yml b/web/modules/contrib/file_mdm/file_mdm_exif/config/schema/file_mdm_exif.data_types.schema.yml
new file mode 100644
index 000000000..a594ee4be
--- /dev/null
+++ b/web/modules/contrib/file_mdm/file_mdm_exif/config/schema/file_mdm_exif.data_types.schema.yml
@@ -0,0 +1,14 @@
+# Basic data types for file_mdf_exif module.
+
+file_mdm_exif.ifd:
+ type: mapping
+ label: 'EXIF IFD'
+ mapping:
+ type:
+ type: integer
+ label: 'IFD type'
+ aliases:
+ type: sequence
+ sequence:
+ type: string
+ label: 'Literal representation of IFD'
diff --git a/web/modules/contrib/file_mdm/file_mdm_exif/config/schema/file_mdm_exif.schema.yml b/web/modules/contrib/file_mdm/file_mdm_exif/config/schema/file_mdm_exif.schema.yml
new file mode 100644
index 000000000..6403814c8
--- /dev/null
+++ b/web/modules/contrib/file_mdm/file_mdm_exif/config/schema/file_mdm_exif.schema.yml
@@ -0,0 +1,13 @@
+# file_mdm_exif module schema
+
+file_mdm_exif.file_metadata_plugin.exif:
+ type: config_object
+ label: 'File metadata EXIF plugin settings'
+ mapping:
+ ifd_map:
+ type: sequence
+ sequence:
+ type: file_mdm_exif.ifd
+ configuration:
+ type: file_mdm.plugin.configuration
+ label: 'exif plugin settings'
diff --git a/web/modules/contrib/file_mdm/file_mdm_exif/file_mdm_exif.info.yml b/web/modules/contrib/file_mdm/file_mdm_exif/file_mdm_exif.info.yml
new file mode 100644
index 000000000..878b487d1
--- /dev/null
+++ b/web/modules/contrib/file_mdm/file_mdm_exif/file_mdm_exif.info.yml
@@ -0,0 +1,17 @@
+type: module
+# core: 8.x
+name: File metadata - EXIF
+description: 'Provides a file metadata plugin for EXIF image information.'
+package: File metadata
+configure: file_mdm.settings
+php: 5.6
+dependencies:
+ - file_mdm
+test_dependencies:
+ - image_effects
+
+# Information added by Drupal.org packaging script on 2017-02-28
+version: '8.x-1.1'
+core: '8.x'
+project: 'file_mdm'
+datestamp: 1488273795
diff --git a/web/modules/contrib/file_mdm/file_mdm_exif/file_mdm_exif.services.yml b/web/modules/contrib/file_mdm/file_mdm_exif/file_mdm_exif.services.yml
new file mode 100644
index 000000000..ecf2b24b4
--- /dev/null
+++ b/web/modules/contrib/file_mdm/file_mdm_exif/file_mdm_exif.services.yml
@@ -0,0 +1,4 @@
+services:
+ file_mdm_exif.tag_mapper:
+ class: Drupal\file_mdm_exif\ExifTagMapper
+ arguments: ['@logger.channel.file_mdm', '@config.factory', '@cache.file_mdm']
diff --git a/web/modules/contrib/file_mdm/file_mdm_exif/src/ExifTagMapper.php b/web/modules/contrib/file_mdm/file_mdm_exif/src/ExifTagMapper.php
new file mode 100644
index 000000000..c7b39cc14
--- /dev/null
+++ b/web/modules/contrib/file_mdm/file_mdm_exif/src/ExifTagMapper.php
@@ -0,0 +1,350 @@
+logger = $logger;
+ $this->configFactory = $config_factory;
+ $this->cache = $cache_service;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function resolveKeyToIfdAndTag($key) {
+ if ($key === NULL) {
+ throw new FileMetadataException('Missing $key argument', NULL, __METHOD__);
+ }
+ if (is_string($key)) {
+ $tag = $this->stringToTag($key);
+ return ['ifd' => $tag[0], 'tag' => $tag[1]];
+ }
+ if (is_array($key)) {
+ if (!isset($key[0]) || !isset($key[1])) {
+ throw new FileMetadataException('Invalid $key array specified, must have two values', NULL, __METHOD__);
+ }
+ // Deal with ifd.
+ if (is_int($key[0])) {
+ $ifd = $key[0];
+ }
+ elseif (is_string($key[0])) {
+ $ifd = $this->stringToIfd($key[0]);
+ }
+ else {
+ throw new FileMetadataException('Invalid EXIF IFD specified, must be a string or an integer', NULL, __METHOD__);
+ }
+ // Deal with tag.
+ if (is_string($key[1])) {
+ $tag = $this->stringToTag($key[1])[1];
+ }
+ elseif (is_int($key[1])) {
+ $tag = $key[1];
+ }
+ else {
+ throw new FileMetadataException('Invalid EXIF TAG specified, must be a string or an integer', NULL, __METHOD__);
+ }
+ return ['ifd' => $ifd, 'tag' => $tag];
+ }
+ throw new FileMetadataException('Invalid $key argument, must be a string or an array', NULL, __METHOD__);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getSupportedKeys(array $options = NULL) {
+ if (isset($options['ifds'])) {
+ return $this->getSupportedIfdsMap();
+ }
+ elseif (isset($options['ifd'])) {
+ return array_filter($this->getSupportedKeysMap(), function ($a) use ($options) {
+ return strtolower($options['ifd']) === strtolower($a[0]);
+ });
+ }
+ else {
+ return $this->getSupportedKeysMap();
+ }
+ }
+
+ /**
+ * Returns the list of supported IFDs.
+ *
+ * Builds and caches the list as needed.
+ *
+ * @return array
+ * A simple array of IFDs, expressed as literal/integer combinations.
+ */
+ protected function getSupportedIfdsMap() {
+ if (!$this->supportedIfdsMap) {
+ $cache_id = 'supportedIfds';
+ if ($cache = $this->getCache($cache_id)) {
+ $this->supportedIfdsMap = $cache->data;
+ }
+ else {
+ $this->supportedIfdsMap = [];
+ $ifd_types = [
+ PelIfd::IFD0,
+ PelIfd::IFD1,
+ PelIfd::EXIF,
+ PelIfd::GPS,
+ PelIfd::INTEROPERABILITY,
+ ];
+ foreach ($ifd_types as $type) {
+ $this->supportedIfdsMap[] = [PelIfd::getTypeName($type), $type];
+ }
+ $this->setCache($cache_id, $this->supportedIfdsMap);
+ }
+ }
+ return $this->supportedIfdsMap;
+ }
+
+ /**
+ * Returns the list of supported metadata 'keys'.
+ *
+ * Builds and caches the list as needed.
+ *
+ * @return array
+ * A simple array of IFD/TAG combinations, expressed as literals.
+ */
+ protected function getSupportedKeysMap() {
+ if (!$this->supportedKeysMap) {
+ $cache_id = 'supportedKeys';
+ if ($cache = $this->getCache($cache_id)) {
+ $this->supportedKeysMap = $cache->data;
+ }
+ else {
+ $this->supportedKeysMap = [];
+ foreach ($this->getSupportedIfdsMap() as $ifd) {
+ $ifd_obj = new PelIfd($ifd[1]);
+ $valid_tags = $ifd_obj->getValidTags();
+ foreach ($valid_tags as $tag) {
+ $this->supportedKeysMap[] = [
+ $ifd[0],
+ PelTag::getName($ifd[1], $tag),
+ ];
+ }
+ }
+ $this->setCache($cache_id, $this->supportedKeysMap);
+ }
+ }
+ return $this->supportedKeysMap;
+ }
+
+ /**
+ * Returns the IFD/TAG integers for a TAG literal.
+ *
+ * @param string $value
+ * A TAG literal.
+ *
+ * @return array
+ * A simple array of with IFD and TAG, expressed as integers.
+ *
+ * @throws \Drupal\file_mdm\FileMetadataException
+ * When the IFD/TAG combination could not be found.
+ */
+ protected function stringToTag($value) {
+ $v = strtolower($value);
+ $tag = isset($this->getStringToTagMap()[$v]) ? $this->getStringToTagMap()[$v] : NULL;
+ if ($tag) {
+ return $tag;
+ }
+ throw new FileMetadataException("No EXIF TAG found for key '{$value}'", "EXIF");
+ }
+
+ /**
+ * Returns the map of TAG strings to IFD/TAG integers.
+ *
+ * Builds and caches the list as needed.
+ *
+ * @return array
+ * An associative array where keys are TAG literals, and values a simple
+ * array of IFD/TAG integer identifiers.
+ */
+ protected function getStringToTagMap() {
+ if (!$this->stringToTagMap) {
+ $cache_id = 'stringToTag';
+ if ($cache = $this->getCache($cache_id)) {
+ $this->stringToTagMap = $cache->data;
+ }
+ else {
+ foreach ($this->getSupportedIfdsMap() as $ifd) {
+ $ifd_obj = new PelIfd($ifd[1]);
+ $valid_tags = $ifd_obj->getValidTags();
+ foreach ($valid_tags as $tag) {
+ $tag_name = strtolower(PelTag::getName($ifd[1], $tag));
+ if (!isset($this->stringToTagMap[$tag_name])) {
+ $this->stringToTagMap[$tag_name] = [$ifd[1], $tag];
+ }
+ }
+ }
+ $this->setCache($cache_id, $this->stringToTagMap);
+ }
+ }
+ return $this->stringToTagMap;
+ }
+
+ /**
+ * Returns the IFD integer for an IFD literal.
+ *
+ * @param string $value
+ * An IFD literal.
+ *
+ * @return int
+ * The IFD identifier.
+ *
+ * @throws \Drupal\file_mdm\FileMetadataException
+ * When the IFD could not be found.
+ */
+ protected function stringToIfd($value) {
+ $v = strtolower($value);
+ if (isset($this->getStringToIfdMap()[$v])) {
+ return $this->getStringToIfdMap()[$v];
+ }
+ throw new FileMetadataException("Invalid EXIF IFD '{$value}' specified", "EXIF");
+ }
+
+ /**
+ * Returns the map of IFD strings to IFD integers.
+ *
+ * Builds and caches the list as needed.
+ *
+ * @return array
+ * An associative array where keys are IFD literals, and values the IFD
+ * integer identifiers.
+ */
+ protected function getStringToIfdMap() {
+ if (!$this->stringToIfdMap) {
+ $cache_id = 'stringToIfd';
+ if ($cache = $this->getCache($cache_id)) {
+ $this->stringToIfdMap = $cache->data;
+ }
+ else {
+ $config_map = $this->configFactory->get('file_mdm_exif.file_metadata_plugin.exif')->get('ifd_map');
+ $this->stringToIfdMap = [];
+ foreach ($config_map as $value) {
+ foreach ($value['aliases'] as $alias) {
+ $k = strtolower($alias);
+ $this->stringToIfdMap[$k] = $value['type'];
+ }
+ }
+ $this->setCache($cache_id, $this->stringToIfdMap);
+ }
+ }
+ return $this->stringToIfdMap;
+ }
+
+ /**
+ * Gets a cache entry.
+ *
+ * @param string $id
+ * The cache id to get.
+ *
+ * @return object|null
+ * The cache item or NULL on failure.
+ */
+ protected function getCache($id) {
+ if ($cache = $this->cache->get("map:exif:{$id}")) {
+ return $cache;
+ }
+ else {
+ return NULL;
+ }
+ }
+
+ /**
+ * Sets a cache entry.
+ *
+ * @param string $id
+ * The cache id to set.
+ * @param mixed $value
+ * The value to cache.
+ *
+ * @return $this
+ */
+ protected function setCache($id, $value) {
+ $config = $this->configFactory->get('file_mdm_exif.file_metadata_plugin.exif');
+ $this->cache->set("map:exif:{$id}", $value, Cache::PERMANENT, $config->getCacheTags());
+ return $this;
+ }
+
+}
diff --git a/web/modules/contrib/file_mdm/file_mdm_exif/src/ExifTagMapperInterface.php b/web/modules/contrib/file_mdm/file_mdm_exif/src/ExifTagMapperInterface.php
new file mode 100644
index 000000000..9b7d645fa
--- /dev/null
+++ b/web/modules/contrib/file_mdm/file_mdm_exif/src/ExifTagMapperInterface.php
@@ -0,0 +1,54 @@
+ TRUE], the supported IFDs are returned.
+ * If $options contains ['ifd' => $value], the IFD/TAG combinations
+ * supported by the IFD specified by $value are returned.
+ *
+ * @return array
+ * A simple array.
+ * When returning a list of supported IFDs, each array element is a simple
+ * array with:
+ * 0 => the default string identifier of the IFD.
+ * 1 => the integer identifier of the IFD.
+ * When returning a list of supported IFD/TAGs, each array element is a
+ * simple array with:
+ * 0 => the string identifier of the IFD.
+ * 1 => the string identifier of the TAG.
+ */
+ public function getSupportedKeys(array $options = NULL);
+
+}
diff --git a/web/modules/contrib/file_mdm/file_mdm_exif/src/Plugin/FileMetadata/Exif.php b/web/modules/contrib/file_mdm/file_mdm_exif/src/Plugin/FileMetadata/Exif.php
new file mode 100644
index 000000000..ce5320454
--- /dev/null
+++ b/web/modules/contrib/file_mdm/file_mdm_exif/src/Plugin/FileMetadata/Exif.php
@@ -0,0 +1,399 @@
+mimeTypeGuesser = $mime_type_guesser;
+ $this->tagMapper = $tag_mapper;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+ return new static(
+ $configuration,
+ $plugin_id,
+ $plugin_definition,
+ $container->get('cache.file_mdm'),
+ $container->get('config.factory'),
+ $container->get('file.mime_type.guesser'),
+ $container->get('file_mdm_exif.tag_mapper')
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getSupportedKeys($options = NULL) {
+ return $this->tagMapper->getSupportedKeys($options);
+ }
+
+ /**
+ * Returns the PEL file object for the image file.
+ *
+ * @return \lsolesen\pel\PelJpeg|\lsolesen\pel\PelTiff
+ * A PEL file object.
+ */
+ protected function getFile() {
+ if ($this->pelFile !== NULL) {
+ return $this->pelFile;
+ }
+ else {
+ switch ($this->mimeTypeGuesser->guess($this->getUri())) {
+ case 'image/jpeg':
+ $this->pelFile = new PelJpeg($this->getLocalTempPath());
+ return $this->pelFile !== NULL ? $this->pelFile : FALSE;
+
+ case 'image/tiff':
+ $this->pelFile = new PelTiff($this->getLocalTempPath());
+ return $this->pelFile !== NULL ? $this->pelFile : FALSE;
+
+ default:
+ return FALSE;
+
+ }
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doGetMetadataFromFile() {
+ // Get the file as a PelJpeg or PelTiff object.
+ $file = $this->getFile();
+ if (!$file) {
+ return [];
+ }
+
+ // Get the TIFF section if existing, or return if not.
+ if ($file instanceof PelJpeg) {
+ $exif = $file->getExif();
+ if ($exif === NULL) {
+ return [];
+ }
+ $tiff = $exif->getTiff();
+ if ($tiff === NULL) {
+ return [];
+ }
+ }
+ elseif ($file instanceof PelTiff) {
+ $tiff = $file;
+ }
+
+ // Scans metadata for entries of supported tags.
+ $metadata = [];
+ $keys = $this->tagMapper->getSupportedKeys();
+ foreach ($keys as $key) {
+ $ifd_tag = $this->tagMapper->resolveKeyToIfdAndTag($key);
+ if ($entry = $this->getEntry($tiff, $ifd_tag['ifd'], $ifd_tag['tag'])) {
+ $metadata[$ifd_tag['ifd']][$ifd_tag['tag']] = $entry;
+ }
+ }
+ return $metadata;
+ }
+
+ /**
+ * Returns a PelEntry.
+ *
+ * @param \lsolesen\pel\PelTiff $tiff
+ * A PelTiff object.
+ * @param int $ifd_tag
+ * The IFD EXIF integer identifier.
+ * @param int $key_tag
+ * The TAG EXIF integer identifier.
+ *
+ * @return \lsolesen\pel\PelEntry
+ * The PelEntry for the specified IFD and TAG.
+ */
+ protected function getEntry(PelTiff $tiff, $ifd_tag, $key_tag) {
+ $ifd = $tiff->getIfd();
+ switch ($ifd_tag) {
+ case PelIfd::IFD0:
+ return $ifd->getEntry($key_tag);
+
+ case PelIfd::IFD1:
+ $ifd1 = $ifd->getNextIfd();
+ if (!$ifd1) {
+ return NULL;
+ }
+ return $ifd1->getEntry($key_tag);
+
+ case PelIfd::EXIF:
+ $exif = $ifd->getSubIfd(PelIfd::EXIF);
+ if (!$exif) {
+ return NULL;
+ }
+ return $exif->getEntry($key_tag);
+
+ case PelIfd::INTEROPERABILITY:
+ $exif = $ifd->getSubIfd(PelIfd::EXIF);
+ if (!$exif) {
+ return NULL;
+ }
+ $interop = $exif->getSubIfd(PelIfd::INTEROPERABILITY);
+ if (!$interop) {
+ return NULL;
+ }
+ return $interop->getEntry($key_tag);
+
+ case PelIfd::GPS:
+ $gps = $ifd->getSubIfd(PelIfd::GPS);
+ if (!$gps) {
+ return NULL;
+ }
+ return $gps->getEntry($key_tag);
+
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isSaveToFileSupported() {
+ return TRUE;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doSaveMetadataToFile() {
+ // Get the file as a PelJpeg or PelTiff object.
+ $file = $this->getFile();
+ if (!$file) {
+ return FALSE;
+ }
+
+ // Get the TIFF section if existing, or create one if not.
+ if ($file instanceof PelJpeg) {
+ $exif = $file->getExif();
+ if ($exif === NULL) {
+ // If EXIF section is missing we simply create a new APP1 section
+ // (a PelExif object) and add it to the PelJpeg object.
+ $exif = new PelExif();
+ $file->setExif($exif);
+ }
+ $tiff = $exif->getTiff();
+ if ($tiff === NULL) {
+ // Same for TIFF section.
+ $tiff = new PelTiff();
+ $exif->setTiff($tiff);
+ }
+ }
+ elseif ($file instanceof PelTiff) {
+ $tiff = $file;
+ }
+
+ // Get IFD0 if existing, or create it if not.
+ $ifd0 = $tiff->getIfd();
+ if ($ifd0 === NULL) {
+ // No IFD in the TIFF data, we just create and insert an empty PelIfd
+ // object.
+ $ifd0 = new PelIfd(PelIfd::IFD0);
+ $tiff->setIfd($ifd0);
+ }
+
+ // Loops through in-memory metadata and update tag entries accordingly.
+ foreach ($this->metadata as $ifd_id => $entries) {
+ switch ($ifd_id) {
+ case PelIfd::IFD0:
+ $this->setIfdEntries($ifd0, $entries);
+ break;
+
+ case PelIfd::IFD1:
+ $ifd1 = $ifd0->getNextIfd();
+ if ($ifd1 === NULL) {
+ $ifd1 = new PelIfd(PelIfd::IFD1);
+ $ifd0->setNextIfd($ifd1);
+ }
+ $this->setIfdEntries($ifd1, $entries);
+ break;
+
+ case PelIfd::EXIF:
+ $exif = $ifd0->getSubIfd(PelIfd::EXIF);
+ if ($exif === NULL) {
+ $exif = new PelIfd(PelIfd::EXIF);
+ $ifd0->addSubIfd($exif);
+ }
+ $this->setIfdEntries($exif, $entries);
+ break;
+
+ case PelIfd::INTEROPERABILITY:
+ $exif = $ifd0->getSubIfd(PelIfd::EXIF);
+ if ($exif === NULL) {
+ $exif = new PelIfd(PelIfd::EXIF);
+ $ifd0->addSubIfd($exif);
+ }
+ $interop = $exif->getSubIfd(PelIfd::INTEROPERABILITY);
+ if ($interop === NULL) {
+ $interop = new PelIfd(PelIfd::INTEROPERABILITY);
+ $exif->addSubIfd($interop);
+ }
+ $this->setIfdEntries($interop, $entries);
+ break;
+
+ case PelIfd::GPS:
+ $gps = $ifd0->getSubIfd(PelIfd::GPS);
+ if ($gps === NULL) {
+ $gps = new PelIfd(PelIfd::GPS);
+ $ifd0->addSubIfd($gps);
+ }
+ $this->setIfdEntries($gps, $entries);
+ break;
+
+ }
+ }
+
+ return $file->saveFile($this->getLocalTempPath()) === FALSE ? FALSE : TRUE;
+ }
+
+ /**
+ * Adds or changes entries for an IFD.
+ *
+ * @param lsolesen\pel\PelIfd $ifd
+ * A PelIfd object.
+ * @param lsolesen\pel\PelEntry[] $entries
+ * An array of PelEntry objects.
+ *
+ * @return bool
+ * TRUE if entries were added/changed successfully, FALSE otherwise.
+ */
+ protected function setIfdEntries(PelIfd $ifd, array $entries) {
+ foreach ($entries as $tag => $input_entry) {
+ if ($c = $ifd->getEntry($tag)) {
+ if ($input_entry === 'deleted') {
+ unset($ifd[$tag]);
+ }
+ else {
+ $c->setValue($input_entry->getValue());
+ }
+ }
+ else {
+ if ($input_entry !== 'deleted') {
+ $ifd->addEntry($input_entry);
+ }
+ }
+ }
+ return TRUE;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doGetMetadata($key = NULL) {
+ if (!$this->metadata) {
+ return NULL;
+ }
+ if (!$key) {
+ return $this->metadata;
+ }
+ else {
+ $ifd_tag = $this->tagMapper->resolveKeyToIfdAndTag($key);
+ if (!isset($this->metadata[$ifd_tag['ifd']][$ifd_tag['tag']]) || $this->metadata[$ifd_tag['ifd']][$ifd_tag['tag']] === 'deleted') {
+ return NULL;
+ }
+ $entry = $this->metadata[$ifd_tag['ifd']][$ifd_tag['tag']];
+ return [
+ 'value' => $entry->getValue(),
+ 'text' => $entry->getText(),
+ ];
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doSetMetadata($key, $value) {
+ $ifd_tag = $this->tagMapper->resolveKeyToIfdAndTag($key);
+ if ($value instanceof PelEntry) {
+ $this->metadata[$ifd_tag['ifd']][$ifd_tag['tag']] = $value;
+ return TRUE;
+ }
+ elseif (isset($this->metadata[$ifd_tag['ifd']][$ifd_tag['tag']])) {
+ $this->metadata[$ifd_tag['ifd']][$ifd_tag['tag']]->setValue($value);
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doRemoveMetadata($key) {
+ if (!$this->metadata || !$key) {
+ return FALSE;
+ }
+ else {
+ $ifd_tag = $this->tagMapper->resolveKeyToIfdAndTag($key);
+ if (isset($this->metadata[$ifd_tag['ifd']][$ifd_tag['tag']])) {
+ $this->metadata[$ifd_tag['ifd']][$ifd_tag['tag']] = 'deleted';
+ return TRUE;
+ }
+ return FALSE;
+ }
+ }
+
+}
diff --git a/web/modules/contrib/file_mdm/file_mdm_exif/tests/src/Kernel/FileMetadataExifTest.php b/web/modules/contrib/file_mdm/file_mdm_exif/tests/src/Kernel/FileMetadataExifTest.php
new file mode 100644
index 000000000..ce9a81883
--- /dev/null
+++ b/web/modules/contrib/file_mdm/file_mdm_exif/tests/src/Kernel/FileMetadataExifTest.php
@@ -0,0 +1,350 @@
+installConfig(['file_mdm_exif']);
+ }
+
+ /**
+ * Test EXIF plugin.
+ */
+ public function testExifPlugin() {
+ // Prepare a copy of test files.
+ file_unmanaged_copy(drupal_get_path('module', 'simpletest') . '/files/image-test.jpg', 'public://', FILE_EXISTS_REPLACE);
+ file_unmanaged_copy(drupal_get_path('module', 'simpletest') . '/files/image-test.png', 'public://', FILE_EXISTS_REPLACE);
+ file_unmanaged_copy(drupal_get_path('module', 'file_mdm') . '/tests/files/test-exif.jpeg', 'public://', FILE_EXISTS_REPLACE);
+ file_unmanaged_copy(drupal_get_path('module', 'file_mdm') . '/tests/files/test-exif.jpeg', 'temporary://', FILE_EXISTS_REPLACE);
+ // The image files that will be tested.
+ $image_files = [
+ [
+ // Pass a path instead of the URI.
+ 'uri' => drupal_get_path('module', 'file_mdm') . '/tests/files/test-exif.jpeg',
+ 'count_keys' => 48,
+ 'test_keys' => [
+ ['Orientation', 8],
+ ['orientation', 8],
+ ['OrIeNtAtIoN', 8],
+ ['ShutterSpeedValue', [106, 32]],
+ ['ApertureValue', [128, 32]],
+ [['exif', 'aperturevalue'], [128, 32]],
+ [[2, 'aperturevalue'], [128, 32]],
+ [['exif', 0x9202], [128, 32]],
+ [[2, 0x9202], [128, 32]],
+ ],
+ ],
+ [
+ // Pass a URI.
+ 'uri' => 'public://test-exif.jpeg',
+ 'count_keys' => 48,
+ 'test_keys' => [
+ ['Orientation', 8],
+ ['ShutterSpeedValue', [106, 32]],
+ ],
+ ],
+ [
+ // Remote storage file. Let the file be copied to a local temp copy.
+ 'uri' => 'dummy-remote://test-exif.jpeg',
+ 'copy_to_temp' => TRUE,
+ 'count_keys' => 48,
+ 'test_keys' => [
+ ['Orientation', 8],
+ ['ShutterSpeedValue', [106, 32]],
+ ],
+ ],
+ [
+ // JPEG Image with GPS data.
+ 'uri' => drupal_get_path('module', 'file_mdm') . '/tests/files/1024-2006_1011_093752.jpg',
+ 'count_keys' => 59,
+ 'test_keys' => [
+ ['Orientation', 1],
+ ['FocalLength', [8513, 256]],
+ ['GPSLatitudeRef', 'S'],
+ ['GPSLatitude', [[33, 1], [51, 1], [2191, 100]]],
+ ['GPSLongitudeRef', 'E'],
+ ['GPSLongitude', [[151, 1], [13, 1], [1173, 100]]],
+ ],
+ ],
+ [
+ // JPEG Image with no EXIF data.
+ 'uri' => 'public://image-test.jpg',
+ 'count_keys' => 0,
+ 'test_keys' => [],
+ ],
+ [
+ // TIFF image.
+ 'uri' => drupal_get_path('module', 'file_mdm') . '/tests/files/sample-1.tiff',
+ 'count_keys' => 11,
+ 'test_keys' => [
+ ['Orientation', 1],
+ ['BitsPerSample', [8, 8, 8, 8]],
+ ],
+ ],
+ [
+ // PNG should not have any data.
+ 'uri' => 'public://image-test.png',
+ 'count_keys' => 0,
+ 'test_keys' => [],
+ ],
+ ];
+
+ $fmdm = $this->container->get('file_metadata_manager');
+
+ // Walk through test files.
+ foreach ($image_files as $image_file) {
+ $file_metadata = $fmdm->uri($image_file['uri']);
+ if (!$file_metadata) {
+ $this->fail("File not found: {$image_file['uri']}");
+ continue;
+ }
+ if (isset($image_file['copy_to_temp'])) {
+ $file_metadata->copyUriToTemp();
+ }
+ $this->assertEqual($image_file['count_keys'], $this->countMetadataKeys($file_metadata, 'exif'));
+ foreach ($image_file['test_keys'] as $test) {
+ $entry = $file_metadata->getMetadata('exif', $test[0]);
+ $this->assertEqual($test[1], $entry ? $entry['value'] : NULL);
+ }
+ }
+
+ // Test loading metadata from an in-memory object.
+ $file_metadata_from = $fmdm->uri($image_files[0]['uri']);
+ $metadata = $file_metadata_from->getMetadata('exif');
+ $new_file_metadata = $fmdm->uri('public://test-output.jpeg');
+ $new_file_metadata->loadMetadata('exif', $metadata);
+ $this->assertEqual($image_files[0]['count_keys'], $this->countMetadataKeys($new_file_metadata, 'exif'));
+ foreach ($image_files[0]['test_keys'] as $test) {
+ $entry = $file_metadata->getMetadata('exif', $test[0]);
+ $this->assertEqual($test[1], $new_file_metadata->getMetadata('exif', $test[0])['value']);
+ }
+
+ // Test removing metadata.
+ $fmdm->release($image_files[0]['uri']);
+ $this->assertFalse($fmdm->has($image_files[0]['uri']));
+ $file_metadata = $fmdm->uri($image_files[0]['uri']);
+ $this->assertEqual($image_files[0]['count_keys'], $this->countMetadataKeys($file_metadata, 'exif'));
+ $this->assertTrue($file_metadata->removeMetadata('exif', 'shutterspeedValue'));
+ $this->assertTrue($file_metadata->removeMetadata('exif', 'apertureValue'));
+ $this->assertFalse($file_metadata->removeMetadata('exif', 'bar'));
+ $this->assertEqual($image_files[0]['count_keys'] - 2, $this->countMetadataKeys($file_metadata, 'exif'));
+ $this->assertNull($file_metadata->getMetadata('exif', 'shutterspeedValue'));
+ $this->assertNull($file_metadata->getMetadata('exif', 'apertureValue'));
+ $this->assertNotNull($file_metadata->getMetadata('exif', 'orientation'));
+ }
+
+ /**
+ * Test writing metadata to JPEG file.
+ */
+ public function testJpegExifSaveToFile() {
+ $fmdm = $this->container->get('file_metadata_manager');
+
+ // Copy test file to public://.
+ file_unmanaged_copy(drupal_get_path('module', 'image_effects') . '/tests/images/portrait-painting.jpg', 'public://', FILE_EXISTS_REPLACE);
+ $file_uri = 'public://portrait-painting.jpg';
+ $file_metadata = $fmdm->uri($file_uri);
+
+ // Check values via exif_read_data before operations.
+ $data = @exif_read_data($file_uri);
+ $this->assertEqual(8, $data['Orientation']);
+ $this->assertFalse(isset($data['Artist']));
+ $this->assertEqual('Canon', $data['Make']);
+ $this->assertEqual(800, $data['ISOSpeedRatings']);
+
+ // Change the Orientation tag from IFD0.
+ $this->assertEqual(8, $file_metadata->getMetadata('exif', 'orientation')['value']);
+ $this->assertTrue($file_metadata->setMetadata('exif', 'orientation', 4));
+ $this->assertEqual(4, $file_metadata->getMetadata('exif', 'orientation')['value']);
+ // Add the Artist tag to IFD0.
+ $this->assertEqual(48, $this->countMetadataKeys($file_metadata, 'exif'));
+ $this->assertNull($file_metadata->getMetadata('exif', 'artist'));
+ $artist_tag = $this->container->get('file_mdm_exif.tag_mapper')->resolveKeyToIfdAndTag('artist');
+ $artist = new PelEntryAscii($artist_tag['tag'], 'shot by foo!');
+ $file_metadata->setMetadata('exif', 'artist', $artist);
+ $this->assertEqual('shot by foo!', $file_metadata->getMetadata('exif', 'artist')['value']);
+ $this->assertEqual(49, $this->countMetadataKeys($file_metadata, 'exif'));
+ // Setting an unknown tag leads to failure.
+ $this->assertFalse($file_metadata->setMetadata('exif', 'bar', 'qux'));
+ // Remove the Make tag from IFD0.
+ $this->assertEqual('Canon', $file_metadata->getMetadata('exif', 'make')['value']);
+ $this->assertTrue($file_metadata->removeMetadata('exif', 'make'));
+ $this->assertNull($file_metadata->getMetadata('exif', 'make'));
+ $this->assertEqual(48, $this->countMetadataKeys($file_metadata, 'exif'));
+
+ // Add the ImageDescription tag to IFD1.
+ $this->assertNull($file_metadata->getMetadata('exif', [1, 'imagedescription']));
+ $desc_tag = $this->container->get('file_mdm_exif.tag_mapper')->resolveKeyToIfdAndTag([1, 'imagedescription']);
+ $desc = new PelEntryAscii($desc_tag['tag'], 'awesome!');
+ $file_metadata->setMetadata('exif', [1, 'imagedescription'], $desc);
+ $this->assertEqual('awesome!', $file_metadata->getMetadata('exif', [1, 'imagedescription'])['value']);
+ $this->assertEqual(49, $this->countMetadataKeys($file_metadata, 'exif'));
+ // Remove the Compression tag from IFD1.
+ $this->assertEqual(6, $file_metadata->getMetadata('exif', [1, 'compression'])['value']);
+ $this->assertTrue($file_metadata->removeMetadata('exif', [1, 'compression']));
+ $this->assertNull($file_metadata->getMetadata('exif', [1, 'compression']));
+ $this->assertEqual(48, $this->countMetadataKeys($file_metadata, 'exif'));
+
+ // Add the BrightnessValue tag to EXIF.
+ $this->assertNull($file_metadata->getMetadata('exif', ['exif', 'brightnessvalue']));
+ $brightness_tag = $this->container->get('file_mdm_exif.tag_mapper')->resolveKeyToIfdAndTag(['exif', 'brightnessvalue']);
+ $brightness = new PelEntrySRational($brightness_tag['tag'], [12, 4]);
+ $file_metadata->setMetadata('exif', ['exif', 'brightnessvalue'], $brightness);
+ $this->assertEqual('12/4', $file_metadata->getMetadata('exif', ['exif', 'brightnessvalue'])['text']);
+ $this->assertEqual(49, $this->countMetadataKeys($file_metadata, 'exif'));
+ // Remove the ISOSpeedRatings tag from EXIF.
+ $this->assertEqual(800, $file_metadata->getMetadata('exif', ['exif', 'isospeedratings'])['value']);
+ $this->assertTrue($file_metadata->removeMetadata('exif', ['exif', 'isospeedratings']));
+ $this->assertNull($file_metadata->getMetadata('exif', ['exif', 'isospeedratings']));
+ $this->assertEqual(48, $this->countMetadataKeys($file_metadata, 'exif'));
+
+ // Add the RelatedImageFileFormat tag to INTEROP.
+ $this->assertNull($file_metadata->getMetadata('exif', ['interop', 'RelatedImageFileFormat']));
+ $ff_tag = $this->container->get('file_mdm_exif.tag_mapper')->resolveKeyToIfdAndTag(['interop', 'RelatedImageFileFormat']);
+ $ff = new PelEntryAscii($ff_tag['tag'], 'qux');
+ $file_metadata->setMetadata('exif', ['interop', 'RelatedImageFileFormat'], $ff);
+ $this->assertEqual('qux', $file_metadata->getMetadata('exif', ['interop', 'RelatedImageFileFormat'])['text']);
+ $this->assertEqual(49, $this->countMetadataKeys($file_metadata, 'exif'));
+ // Remove the InteroperabilityIndex tag from INTEROP.
+ $this->assertEqual('R98', $file_metadata->getMetadata('exif', ['interop', 'InteroperabilityIndex'])['value']);
+ $this->assertTrue($file_metadata->removeMetadata('exif', ['interop', 'InteroperabilityIndex']));
+ $this->assertNull($file_metadata->getMetadata('exif', ['interop', 'InteroperabilityIndex']));
+ $this->assertEqual(48, $this->countMetadataKeys($file_metadata, 'exif'));
+
+ // Add Longitude/Latitude tags to GPS.
+ $this->assertNull($file_metadata->getMetadata('exif', 'GPSLatitudeRef'));
+ $this->assertNull($file_metadata->getMetadata('exif', 'GPSLatitude'));
+ $this->assertNull($file_metadata->getMetadata('exif', 'GPSLongitudeRef'));
+ $this->assertNull($file_metadata->getMetadata('exif', 'GPSLongitude'));
+ $atr_tag = $this->container->get('file_mdm_exif.tag_mapper')->resolveKeyToIfdAndTag('GPSLatitudeRef');
+ $at_tag = $this->container->get('file_mdm_exif.tag_mapper')->resolveKeyToIfdAndTag('GPSLatitude');
+ $otr_tag = $this->container->get('file_mdm_exif.tag_mapper')->resolveKeyToIfdAndTag('GPSLongitudeRef');
+ $ot_tag = $this->container->get('file_mdm_exif.tag_mapper')->resolveKeyToIfdAndTag('GPSLongitude');
+ $atr = new PelEntryAscii($atr_tag['tag'], 'N');
+ $at = new PelEntryRational($at_tag['tag'], [46, 1], [37, 1], [59448, 10000]);
+ $otr = new PelEntryAscii($otr_tag['tag'], 'E');
+ $ot = new PelEntryRational($ot_tag['tag'], [12, 1], [17, 1], [488112, 10000]);
+ $file_metadata->setMetadata('exif', 'GPSLatitudeRef', $atr);
+ $file_metadata->setMetadata('exif', 'GPSLatitude', $at);
+ $file_metadata->setMetadata('exif', 'GPSLongitudeRef', $otr);
+ $file_metadata->setMetadata('exif', 'GPSLongitude', $ot);
+ $this->assertEqual('N', $file_metadata->getMetadata('exif', 'GPSLatitudeRef')['text']);
+ $this->assertNotNull($file_metadata->getMetadata('exif', 'GPSLatitude')['text']);
+ $this->assertEqual('E', $file_metadata->getMetadata('exif', 'GPSLongitudeRef')['text']);
+ $this->assertNotNull($file_metadata->getMetadata('exif', 'GPSLongitude')['text']);
+ $this->assertEqual(52, $this->countMetadataKeys($file_metadata, 'exif'));
+
+ // Save metadata to file.
+ $this->assertTrue($file_metadata->saveMetadataToFile('exif'));
+
+ // Check results via exif_read_data.
+ $data = @exif_read_data($file_uri);
+ $this->assertEqual(4, $data['Orientation']);
+ $this->assertEqual('shot by foo!', $data['Artist']);
+ $this->assertFalse(isset($data['Make']));
+ $this->assertEqual('12/4', $data['BrightnessValue']);
+ $this->assertFalse(isset($data['ISOSpeedRatings']));
+ $this->assertEqual('qux', $data['RelatedFileFormat']);
+ $this->assertFalse(isset($data['InterOperabilityIndex']));
+ $this->assertEqual('N', $data['GPSLatitudeRef']);
+ $this->assertEqual(['46/1', '37/1', '59448/10000'], $data['GPSLatitude']);
+ $this->assertEqual('E', $data['GPSLongitudeRef']);
+ $this->assertEqual(['12/1', '17/1', '488112/10000'], $data['GPSLongitude']);
+
+ // Test writing metadata to a file that has no EXIF info.
+ file_unmanaged_copy(drupal_get_path('module', 'simpletest') . '/files/image-2.jpg', 'public://', FILE_EXISTS_REPLACE);
+ $test_2 = $fmdm->uri('public://image-2.jpg');
+ $this->assertEqual(0, $this->countMetadataKeys($test_2, 'exif'));
+ // Load EXIF metadata from previous file processed.
+ $test_2->loadMetadata('exif', $file_metadata->getMetadata('exif'));
+ // Save metadata to file.
+ $this->assertTrue($test_2->saveMetadataToFile('exif'));
+ $this->assertEqual(52, $this->countMetadataKeys($test_2, 'exif'));
+ // Check results via exif_read_data.
+ $data = @exif_read_data('public://image-2.jpg');
+ $this->assertEqual(4, $data['Orientation']);
+ $this->assertEqual('shot by foo!', $data['Artist']);
+ $this->assertEqual('12/4', $data['BrightnessValue']);
+ $this->assertEqual('qux', $data['RelatedFileFormat']);
+ $this->assertEqual('N', $data['GPSLatitudeRef']);
+ $this->assertEqual(['46/1', '37/1', '59448/10000'], $data['GPSLatitude']);
+ $this->assertEqual('E', $data['GPSLongitudeRef']);
+ $this->assertEqual(['12/1', '17/1', '488112/10000'], $data['GPSLongitude']);
+
+ // Check that after save, file metadata is retrieved from file first time,
+ // then from cache in further requests.
+ $file_metadata = NULL;
+ $this->assertTrue($fmdm->release($file_uri));
+ $file_metadata = $fmdm->uri($file_uri);
+ $this->assertEqual(52, $this->countMetadataKeys($file_metadata, 'exif'));
+ $this->assertIdentical(FileMetadataInterface::LOADED_FROM_FILE, $file_metadata->isMetadataLoaded('exif'));
+ $file_metadata = NULL;
+ $this->assertTrue($fmdm->release($file_uri));
+ $file_metadata = $fmdm->uri($file_uri);
+ $this->assertEqual(52, $this->countMetadataKeys($file_metadata, 'exif'));
+ $this->assertIdentical(FileMetadataInterface::LOADED_FROM_CACHE, $file_metadata->isMetadataLoaded('exif'));
+ }
+
+ /**
+ * Test writing metadata to TIFF file.
+ */
+ public function testTiffExifSaveToFile() {
+ $fmdm = $this->container->get('file_metadata_manager');
+
+ // Copy test file to public://.
+ file_unmanaged_copy(drupal_get_path('module', 'file_mdm') . '/tests/files/sample-1.tiff', 'public://', FILE_EXISTS_REPLACE);
+ $file_uri = 'public://sample-1.tiff';
+ $file_metadata = $fmdm->uri($file_uri);
+
+ // Check values via exif_read_data before operations.
+ $data = @exif_read_data($file_uri);
+ $this->assertEqual(1, $data['Orientation']);
+ $this->assertEqual(2, $data['PhotometricInterpretation']);
+
+ // Change tags from IFD0.
+ $this->assertEqual(1, $file_metadata->getMetadata('exif', 'orientation')['value']);
+ $this->assertTrue($file_metadata->setMetadata('exif', 'orientation', 4));
+ $this->assertEqual(4, $file_metadata->getMetadata('exif', 'orientation')['value']);
+ $this->assertEqual(2, $file_metadata->getMetadata('exif', 'PhotometricInterpretation')['value']);
+ $this->assertTrue($file_metadata->setMetadata('exif', 'PhotometricInterpretation', 4));
+ $this->assertEqual(4, $file_metadata->getMetadata('exif', 'PhotometricInterpretation')['value']);
+
+ // Save metadata to file.
+ $this->assertTrue($file_metadata->saveMetadataToFile('exif'));
+
+ // Check results via exif_read_data.
+ $data = @exif_read_data($file_uri);
+ $this->assertEqual(4, $data['Orientation']);
+ $this->assertEqual(4, $data['PhotometricInterpretation']);
+ }
+
+}
diff --git a/web/modules/contrib/file_mdm/file_mdm_font/README.md b/web/modules/contrib/file_mdm/file_mdm_font/README.md
new file mode 100644
index 000000000..05036276c
--- /dev/null
+++ b/web/modules/contrib/file_mdm/file_mdm_font/README.md
@@ -0,0 +1,68 @@
+# File metadata Font
+
+A Drupal 8 module providing a file metadata plugin to retrieve information from
+font files.
+
+
+## Features:
+
+Uses the [PHP Font Lib](https://github.com/PhenX/php-font-lib) to read font
+information from TTF/OTF/WOFF font files.
+
+
+## Usage examples:
+
+1. Use the _file_metadata_manager_ service to prepare collecting metadata for
+ the font located at a desired URI:
+
+ ```php
+ $fmdm = \Drupal::service('file_metadata_manager');
+ $my_font_metadata = $fmdm->uri('public::/my_font_directory/arial.ttf');
+ ...
+ ```
+
+2. Get the value of a key:
+
+ ```php
+ ...
+ $font_name = $my_font_metadata->getMetadata('font', 'FontName');
+ ...
+ ```
+
+3. Get an array with all the metadata values:
+
+ ```php
+ ...
+ $my_font_info = [];
+ foreach ($my_font_metadata->getSupportedKeys('font') as $key) {
+ $my_font_info[$key] = $my_font_metadata->getMetadata('font', $key);
+ }
+ ...
+ ```
+
+
+## Available metadata keys:
+
+Key |
+--------------------|
+FontType |
+FontWeight |
+Copyright |
+FontName |
+FontSubfamily |
+UniqueID |
+FullName |
+Version |
+PostScriptName |
+Trademark |
+Manufacturer |
+Designer |
+Description |
+FontVendorURL |
+FontDesignerURL |
+LicenseDescription |
+LicenseURL |
+PreferredFamily |
+PreferredSubfamily |
+CompatibleFullName |
+SampleText |
diff --git a/web/modules/contrib/file_mdm/file_mdm_font/config/install/file_mdm_font.file_metadata_plugin.font.yml b/web/modules/contrib/file_mdm/file_mdm_font/config/install/file_mdm_font.file_metadata_plugin.font.yml
new file mode 100644
index 000000000..394780947
--- /dev/null
+++ b/web/modules/contrib/file_mdm/file_mdm_font/config/install/file_mdm_font.file_metadata_plugin.font.yml
@@ -0,0 +1,7 @@
+configuration:
+ cache:
+ override: FALSE
+ settings:
+ enabled: TRUE
+ expiration: 172800
+ disallowed_paths: { }
diff --git a/web/modules/contrib/file_mdm/file_mdm_font/config/schema/file_mdm_font.schema.yml b/web/modules/contrib/file_mdm/file_mdm_font/config/schema/file_mdm_font.schema.yml
new file mode 100644
index 000000000..b9ac21334
--- /dev/null
+++ b/web/modules/contrib/file_mdm/file_mdm_font/config/schema/file_mdm_font.schema.yml
@@ -0,0 +1,9 @@
+# file_mdm_font module schema
+
+file_mdm_font.file_metadata_plugin.font:
+ type: config_object
+ label: 'font file metadata plugin settings'
+ mapping:
+ configuration:
+ type: file_mdm.plugin.configuration
+ label: 'font plugin settings'
diff --git a/web/modules/contrib/file_mdm/file_mdm_font/file_mdm_font.info.yml b/web/modules/contrib/file_mdm/file_mdm_font/file_mdm_font.info.yml
new file mode 100644
index 000000000..45171ea53
--- /dev/null
+++ b/web/modules/contrib/file_mdm/file_mdm_font/file_mdm_font.info.yml
@@ -0,0 +1,17 @@
+type: module
+# core: 8.x
+name: File metadata - Font
+description: 'Provides a file metadata plugin for TTF/OTF/WOFF font information.'
+package: File metadata
+configure: file_mdm.settings
+php: 5.6
+dependencies:
+ - file_mdm
+test_dependencies:
+ - image_effects
+
+# Information added by Drupal.org packaging script on 2017-02-28
+version: '8.x-1.1'
+core: '8.x'
+project: 'file_mdm'
+datestamp: 1488273795
diff --git a/web/modules/contrib/file_mdm/file_mdm_font/src/Plugin/FileMetadata/Font.php b/web/modules/contrib/file_mdm/file_mdm_font/src/Plugin/FileMetadata/Font.php
new file mode 100644
index 000000000..93f9ca564
--- /dev/null
+++ b/web/modules/contrib/file_mdm/file_mdm_font/src/Plugin/FileMetadata/Font.php
@@ -0,0 +1,113 @@
+getLocalTempPath());
+ // @todo ::parse raises 'Undefined offset' notices in phenx/php-font-lib
+ // 0.5, suppress errors while upstream is fixed.
+ @$font->parse();
+ $keys = $this->getSupportedKeys();
+ $metadata = [];
+ foreach ($keys as $key) {
+ $l_key = strtolower($key);
+ switch ($l_key) {
+ case 'fonttype':
+ $metadata[$l_key] = $font->getFontType();
+ break;
+
+ case 'fontweight':
+ $metadata[$l_key] = $font->getFontWeight();
+ break;
+
+ default:
+ $code = array_search($l_key, array_map('strtolower', name::$nameIdCodes), TRUE);
+ if ($value = $font->getNameTableString($code)) {
+ $metadata[$l_key] = $value;
+ }
+ break;
+
+ }
+ }
+ return $metadata;
+ }
+
+ /**
+ * Validates a file metadata key.
+ *
+ * @return bool
+ * TRUE if the key is valid.
+ *
+ * @throws \Drupal\file_mdm\FileMetadataException
+ * In case the key is invalid.
+ */
+ protected function validateKey($key, $method) {
+ if (!is_string($key)) {
+ throw new FileMetadataException("Invalid metadata key specified", $this->getPluginId(), $method);
+ }
+ if (!in_array(strtolower($key), array_map('strtolower', $this->getSupportedKeys()), TRUE)) {
+ throw new FileMetadataException("Invalid metadata key '{$key}' specified", $this->getPluginId(), $method);
+ }
+ return TRUE;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doGetMetadata($key = NULL) {
+ if ($key === NULL) {
+ return $this->metadata;
+ }
+ else {
+ $this->validateKey($key, __FUNCTION__);
+ $l_key = strtolower($key);
+ if (in_array($l_key, array_map('strtolower', $this->getSupportedKeys()), TRUE)) {
+ return isset($this->metadata[$l_key]) ? $this->metadata[$l_key] : NULL;
+ }
+ return NULL;
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doSetMetadata($key, $value) {
+ throw new FileMetadataException('Changing font metadata is not supported', $this->getPluginId());
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doRemoveMetadata($key) {
+ throw new FileMetadataException('Deleting font metadata is not supported', $this->getPluginId());
+ }
+
+}
diff --git a/web/modules/contrib/file_mdm/file_mdm_font/tests/src/Kernel/FileMetadataFontTest.php b/web/modules/contrib/file_mdm/file_mdm_font/tests/src/Kernel/FileMetadataFontTest.php
new file mode 100644
index 000000000..1cb24647e
--- /dev/null
+++ b/web/modules/contrib/file_mdm/file_mdm_font/tests/src/Kernel/FileMetadataFontTest.php
@@ -0,0 +1,114 @@
+installConfig(['file_mdm_font']);
+ }
+
+ /**
+ * Test 'font' plugin.
+ */
+ public function testFontPlugin() {
+ // The font files that will be tested.
+ $font_files = [
+ [
+ 'uri' => drupal_get_path('module', 'image_effects') . '/tests/fonts/LinLibertineTTF_5.3.0_2012_07_02/LinLibertine_Rah.ttf',
+ 'count_keys' => 15,
+ 'test_keys' => [
+ ['Version', 'Version 5.3.0 ; ttfautohint (v0.9)'],
+ ['version', 'Version 5.3.0 ; ttfautohint (v0.9)'],
+ ['VeRsIoN', 'Version 5.3.0 ; ttfautohint (v0.9)'],
+ ['FontWeight', 400],
+ ],
+ ],
+ [
+ 'uri' => drupal_get_path('module', 'image_effects') . '/tests/fonts/LinLibertineTTF_5.3.0_2012_07_02/LinBiolinum_Kah.ttf',
+ 'count_keys' => 15,
+ 'test_keys' => [
+ ['FullName', 'Linux Biolinum Keyboard'],
+ ['fullname', 'Linux Biolinum Keyboard'],
+ ['fUlLnAmE', 'Linux Biolinum Keyboard'],
+ ],
+ ],
+ ];
+
+ $fmdm = $this->container->get('file_metadata_manager');
+
+ // Walk through test files.
+ foreach ($font_files as $font_file) {
+ $file_metadata = $fmdm->uri($font_file['uri']);
+ if (!$file_metadata) {
+ $this->fail("File not found: {$font_file['uri']}");
+ continue;
+ }
+ $this->assertEqual($font_file['count_keys'], $this->countMetadataKeys($file_metadata, 'font'));
+ $this->assertIdentical(FileMetadataInterface::LOADED_FROM_FILE, $file_metadata->isMetadataLoaded('font'));
+ foreach ($font_file['test_keys'] as $test) {
+ $this->assertEqual($test[1], $file_metadata->getMetadata('font', $test[0]));
+ }
+ }
+ }
+
+ /**
+ * Test 'font' plugin supported keys.
+ */
+ public function testSupportedKeys() {
+ $expected_keys = [
+ 'FontType',
+ 'FontWeight',
+ 'Copyright',
+ 'FontName',
+ 'FontSubfamily',
+ 'UniqueID',
+ 'FullName',
+ 'Version',
+ 'PostScriptName',
+ 'Trademark',
+ 'Manufacturer',
+ 'Designer',
+ 'Description',
+ 'FontVendorURL',
+ 'FontDesignerURL',
+ 'LicenseDescription',
+ 'LicenseURL',
+ 'PreferredFamily',
+ 'PreferredSubfamily',
+ 'CompatibleFullName',
+ 'SampleText',
+ ];
+
+ $fmdm = $this->container->get('file_metadata_manager');
+ $file_md = $fmdm->uri(drupal_get_path('module', 'image_effects') . '/tests/fonts/LinLibertineTTF_5.3.0_2012_07_02/LinLibertine_Rah.ttf');
+ $this->assertEqual($expected_keys, $file_md->getSupportedKeys('font'));
+ }
+
+}
diff --git a/web/modules/contrib/file_mdm/phpcs.xml.dist b/web/modules/contrib/file_mdm/phpcs.xml.dist
new file mode 100644
index 000000000..20e1cb4cd
--- /dev/null
+++ b/web/modules/contrib/file_mdm/phpcs.xml.dist
@@ -0,0 +1,13 @@
+
+
+ PHP CodeSniffer configuration for file_mdm module.
+ .
+
+
+
+ ./README.md
+
+
+
+
+
diff --git a/web/modules/contrib/file_mdm/src/Element/FileMetadataCaching.php b/web/modules/contrib/file_mdm/src/Element/FileMetadataCaching.php
new file mode 100644
index 000000000..12fb974df
--- /dev/null
+++ b/web/modules/contrib/file_mdm/src/Element/FileMetadataCaching.php
@@ -0,0 +1,112 @@
+ TRUE,
+ '#process' => [[$class, 'processCaching']],
+ '#element_validate' => [[$class, 'validateCaching']],
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function valueCallback(&$element, $input, FormStateInterface $form_state) {
+ if ($input !== FALSE && $input !== NULL) {
+ $disallowed_paths = $input['disallowed_paths'];
+ if (!empty($disallowed_paths)) {
+ $disallowed_paths = preg_replace('/\r/', '', $disallowed_paths);
+ $disallowed_paths = explode("\n", $disallowed_paths);
+ while (empty($disallowed_paths[count($disallowed_paths) - 1])) {
+ array_pop($disallowed_paths);
+ }
+ $input['disallowed_paths'] = $disallowed_paths ?: [];
+ }
+ else {
+ $input['disallowed_paths'] = [];
+ }
+ return $input;
+ }
+ return NULL;
+ }
+
+ /**
+ * Processes a 'file_mdm_caching' form element.
+ *
+ * @param array $element
+ * The form element to process.
+ * @param \Drupal\Core\Form\FormStateInterface $form_state
+ * The current state of the form.
+ * @param array $complete_form
+ * The complete form structure.
+ *
+ * @return array
+ * The processed element.
+ */
+ public static function processCaching(array &$element, FormStateInterface $form_state, array &$complete_form) {
+ $element['enabled'] = [
+ '#type' => 'checkbox',
+ '#title' => t('Cache metadata'),
+ '#default_value' => $element['#default_value']['enabled'],
+ '#description' => t("If selected, metadata retrieved from files will be cached for further access."),
+ ];
+ $options = [86400, 172800, 604800, 1209600, 3024000, 7862400];
+ $options = array_map([\Drupal::service('date.formatter'), 'formatInterval'], array_combine($options, $options));
+ $options = [-1 => t('Never')] + $options;
+ $element['expiration'] = [
+ '#type' => 'select',
+ '#title' => t('Cache expires'),
+ '#default_value' => $element['#default_value']['expiration'],
+ '#options' => $options,
+ '#description' => t("Specify the required lifetime of cached entries. Longer times may lead to increased cache sizes."),
+ '#states' => [
+ 'visible' => [
+ ':input[name="' . $element['#name'] . '[enabled]"]' => array('checked' => TRUE),
+ ],
+ ],
+ ];
+ $element['disallowed_paths'] = [
+ '#type' => 'textarea',
+ '#title' => t('Excluded paths'),
+ '#rows' => 3,
+ '#default_value' => implode("\n", $element['#default_value']['disallowed_paths']),
+ '#description' => t("Only files prefixed by a valid URI scheme will be cached, like for example public://. Files in the temporary:// scheme will never be cached. Specify here if there are any paths to be additionally excluded from caching, one per line. Use wildcard patterns when entering the path. For example, public://styles/*."),
+ '#states' => [
+ 'visible' => [
+ ':input[name="' . $element['#name'] . '[enabled]"]' => array('checked' => TRUE),
+ ],
+ ],
+ ];
+
+ return $element;
+ }
+
+ /**
+ * Form element validation handler.
+ */
+ public static function validateCaching(&$element, FormStateInterface $form_state, &$complete_form) {
+ // Validate cache exclusion paths.
+ foreach ($element['#value']['disallowed_paths'] as $path) {
+ if (!file_valid_uri($path)) {
+ $form_state->setError($element['disallowed_paths'], t("'@path' is an invalid URI path", ['@path' => $path]));
+ }
+ }
+ }
+
+}
diff --git a/web/modules/contrib/file_mdm/src/FileMetadata.php b/web/modules/contrib/file_mdm/src/FileMetadata.php
new file mode 100644
index 000000000..4f2444f51
--- /dev/null
+++ b/web/modules/contrib/file_mdm/src/FileMetadata.php
@@ -0,0 +1,276 @@
+pluginManager = $plugin_manager;
+ $this->logger = $logger;
+ $this->fileSystem = $file_system;
+ $this->uri = $uri;
+ $this->hash = $hash;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getUri() {
+ return $this->uri;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getLocalTempPath() {
+ return $this->localTempPath;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setLocalTempPath($temp_uri) {
+ $this->localTempPath = $temp_uri;
+ foreach ($this->plugins as $plugin) {
+ $plugin->setLocalTempPath($this->localTempPath);
+ }
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function copyUriToTemp($temp_uri = NULL) {
+ if ($temp_uri === NULL) {
+ $temp_uri = $this->fileSystem->tempnam('temporary://', 'file_mdm_');
+ $this->fileSystem->unlink($temp_uri);
+ $temp_uri .= '.' . pathinfo($this->getUri(), PATHINFO_EXTENSION);
+ }
+ if ($temp_path = file_unmanaged_copy($this->getUri(), $this->fileSystem->realpath($temp_uri), FILE_EXISTS_REPLACE)) {
+ $this->setLocalTempPath($temp_path);
+ }
+ return (bool) $temp_path;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function copyTempToUri() {
+ if (($temp_path = $this->getLocalTempPath()) === NULL) {
+ return FALSE;
+ }
+ return (bool) file_unmanaged_copy($temp_path, $this->getUri(), FILE_EXISTS_REPLACE);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFileMetadataPlugin($metadata_id) {
+ if (!isset($this->plugins[$metadata_id])) {
+ try {
+ $this->plugins[$metadata_id] = $this->pluginManager->createInstance($metadata_id);
+ $this->plugins[$metadata_id]->setUri($this->uri);
+ $this->plugins[$metadata_id]->setLocalTempPath($this->localTempPath ?: $this->uri);
+ $this->plugins[$metadata_id]->setHash($this->hash);
+ }
+ catch (PluginNotFoundException $e) {
+ return NULL;
+ }
+ }
+ return $this->plugins[$metadata_id];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getSupportedKeys($metadata_id, $options = NULL) {
+ try {
+ if ($plugin = $this->getFileMetadataPlugin($metadata_id)) {
+ $keys = $plugin->getSupportedKeys($options);
+ }
+ else {
+ $keys = NULL;
+ }
+ }
+ catch (\Exception $e) {
+ $this->logger->error($e->getMessage());
+ $keys = NULL;
+ }
+ return $keys;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMetadata($metadata_id, $key = NULL) {
+ try {
+ if ($plugin = $this->getFileMetadataPlugin($metadata_id)) {
+ $metadata = $plugin->getMetadata($key);
+ }
+ else {
+ $metadata = NULL;
+ }
+ }
+ catch (\Exception $e) {
+ $this->logger->error($e->getMessage());
+ $metadata = NULL;
+ }
+ return $metadata;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function removeMetadata($metadata_id, $key) {
+ try {
+ if ($plugin = $this->getFileMetadataPlugin($metadata_id)) {
+ return $plugin->removeMetadata($key);
+ }
+ }
+ catch (\Exception $e) {
+ $this->logger->error($e->getMessage());
+ }
+ return FALSE;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setMetadata($metadata_id, $key, $value) {
+ try {
+ if ($plugin = $this->getFileMetadataPlugin($metadata_id)) {
+ return $plugin->setMetadata($key, $value);
+ }
+ }
+ catch (\Exception $e) {
+ $this->logger->error($e->getMessage());
+ }
+ return FALSE;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isMetadataLoaded($metadata_id) {
+ if ($plugin = $this->getFileMetadataPlugin($metadata_id)) {
+ return $plugin->isMetadataLoaded();
+ }
+ return FALSE;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function loadMetadata($metadata_id, $metadata) {
+ if ($plugin = $this->getFileMetadataPlugin($metadata_id)) {
+ return $plugin->loadMetadata($metadata);
+ }
+ return FALSE;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function loadMetadataFromCache($metadata_id) {
+ if ($plugin = $this->getFileMetadataPlugin($metadata_id)) {
+ return $plugin->loadMetadataFromCache();
+ }
+ return FALSE;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function saveMetadataToCache($metadata_id, array $tags = []) {
+ if ($plugin = $this->getFileMetadataPlugin($metadata_id)) {
+ return $plugin->saveMetadataToCache($tags);
+ }
+ return FALSE;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function saveMetadataToFile($metadata_id) {
+ if ($plugin = $this->getFileMetadataPlugin($metadata_id)) {
+ return $plugin->saveMetadataToFile();
+ }
+ return FALSE;
+ }
+
+}
diff --git a/web/modules/contrib/file_mdm/src/FileMetadataException.php b/web/modules/contrib/file_mdm/src/FileMetadataException.php
new file mode 100644
index 000000000..ac3c2b16c
--- /dev/null
+++ b/web/modules/contrib/file_mdm/src/FileMetadataException.php
@@ -0,0 +1,20 @@
+pluginManager = $plugin_manager;
+ $this->logger = $logger;
+ $this->configFactory = $config_factory;
+ $this->fileSystem = $file_system;
+ $this->cache = $cache_service;
+ }
+
+ /**
+ * Returns an hash for the URI, used internally by the manager.
+ *
+ * @param string $uri
+ * The URI to a file.
+ *
+ * @return string
+ * An hash string.
+ */
+ protected function calculateHash($uri) {
+ // Sanitize URI removing duplicate slashes, if any.
+ // @see http://stackoverflow.com/questions/12494515/remove-unnecessary-slashes-from-path
+ $uri = preg_replace('/([^:])(\/{2,})/', '$1/', $uri);
+ // If URI is invalid and no local file path exists, return NULL.
+ if (!file_valid_uri($uri) && !$this->fileSystem->realpath($uri)) {
+ return NULL;
+ }
+ // Return a hash of the URI.
+ return hash('sha256', $uri);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function has($uri) {
+ $hash = $this->calculateHash($uri);
+ return $hash ? isset($this->files[$hash]) : NULL;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function uri($uri) {
+ if (!$hash = $this->calculateHash($uri)) {
+ return NULL;
+ }
+ if (!isset($this->files[$hash])) {
+ $this->files[$hash] = new FileMetadata($this->pluginManager, $this->logger, $this->fileSystem, $uri, $hash);
+ }
+ return $this->files[$hash];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function deleteCachedMetadata($uri) {
+ if (!$hash = $this->calculateHash($uri)) {
+ return FALSE;
+ }
+ foreach (array_keys($this->pluginManager->getDefinitions()) as $plugin_id) {
+ $this->cache->delete("hash:{$plugin_id}:{$hash}");
+ }
+ return TRUE;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function release($uri) {
+ if (!$hash = $this->calculateHash($uri)) {
+ return FALSE;
+ }
+ if (isset($this->files[$hash])) {
+ unset($this->files[$hash]);
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function count() {
+ return count($this->files);
+ }
+
+}
diff --git a/web/modules/contrib/file_mdm/src/FileMetadataManagerInterface.php b/web/modules/contrib/file_mdm/src/FileMetadataManagerInterface.php
new file mode 100644
index 000000000..62a0b51b2
--- /dev/null
+++ b/web/modules/contrib/file_mdm/src/FileMetadataManagerInterface.php
@@ -0,0 +1,63 @@
+getDefinitions() as $id => $definition) {
+ $this->metadataPlugins[$id] = $manager->createInstance($id);
+ }
+ uasort($this->metadataPlugins, function ($a, $b) {
+ return Unicode::strcasecmp((string) $a->getPluginDefinition()['title'], (string) $b->getPluginDefinition()['title']);
+ });
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(ContainerInterface $container) {
+ return new static(
+ $container->get('config.factory'),
+ $container->get('plugin.manager.file_metadata')
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFormId() {
+ return 'file_mdm_settings';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getEditableConfigNames() {
+ return ['file_mdm.settings'];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildForm(array $form, FormStateInterface $form_state) {
+ // Cache metadata.
+ $form['metadata_cache'] = [
+ '#type' => 'details',
+ '#open' => TRUE,
+ '#collapsible' => FALSE,
+ '#title' => $this->t('Metadata caching'),
+ '#tree' => TRUE,
+ ];
+ $form['metadata_cache']['settings'] = [
+ '#type' => 'file_mdm_caching',
+ '#default_value' => $this->config('file_mdm.settings')->get('metadata_cache'),
+ ];
+
+ // Settings tabs.
+ $form['plugins'] = array(
+ '#type' => 'vertical_tabs',
+ '#tree' => FALSE,
+ );
+
+ // Load subforms from each plugin.
+ foreach ($this->metadataPlugins as $id => $plugin) {
+ $definition = $plugin->getPluginDefinition();
+ $form['file_mdm_plugin_settings'][$id] = array(
+ '#type' => 'details',
+ '#title' => $definition['title'],
+ '#description' => $definition['help'],
+ '#open' => FALSE,
+ '#tree' => TRUE,
+ '#group' => 'plugins',
+ );
+ $form['file_mdm_plugin_settings'][$id] += $plugin->buildConfigurationForm(array(), $form_state);
+ }
+
+ return parent::buildForm($form, $form_state);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validateForm(array &$form, FormStateInterface $form_state) {
+ parent::validateForm($form, $form_state);
+ // Call the form validation handler for each of the plugins.
+ foreach ($this->metadataPlugins as $plugin) {
+ $plugin->validateConfigurationForm($form, $form_state);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function submitForm(array &$form, FormStateInterface $form_state) {
+ // Call the form submit handler for each of the plugins.
+ foreach ($this->metadataPlugins as $plugin) {
+ $plugin->submitConfigurationForm($form, $form_state);
+ }
+
+ $this->config('file_mdm.settings')->set('metadata_cache', $form_state->getValue(['metadata_cache', 'settings']));
+
+ // Only save settings if they have changed to prevent unnecessary cache
+ // invalidations.
+ if ($this->config('file_mdm.settings')->getOriginal() != $this->config('file_mdm.settings')->get()) {
+ $this->config('file_mdm.settings')->save();
+ }
+ parent::submitForm($form, $form_state);
+ }
+
+}
diff --git a/web/modules/contrib/file_mdm/src/Plugin/Annotation/FileMetadata.php b/web/modules/contrib/file_mdm/src/Plugin/Annotation/FileMetadata.php
new file mode 100644
index 000000000..7632ce004
--- /dev/null
+++ b/web/modules/contrib/file_mdm/src/Plugin/Annotation/FileMetadata.php
@@ -0,0 +1,43 @@
+cache = $cache_service;
+ $this->configFactory = $config_factory;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+ return new static(
+ $configuration,
+ $plugin_id,
+ $plugin_definition,
+ $container->get('cache.file_mdm'),
+ $container->get('config.factory')
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function defaultConfiguration() {
+ return [
+ 'cache' => [
+ 'override' => FALSE,
+ 'settings' => [
+ 'enabled' => TRUE,
+ 'expiration' => 172800,
+ 'disallowed_paths' => [],
+ ],
+ ],
+ ];
+ }
+
+ /**
+ * Gets the configuration object for this plugin.
+ *
+ * @param bool $editable
+ * If TRUE returns the editable configuration object.
+ *
+ * @return \Drupal\Core\Config\ImmutableConfig|\Drupal\Core\Config\Config
+ * The ImmutableConfig of the Config object for this plugin.
+ */
+ protected function getConfigObject($editable = FALSE) {
+ $plugin_definition = $this->getPluginDefinition();
+ $config_name = $plugin_definition['provider'] . '.file_metadata_plugin.' . $plugin_definition['id'];
+ return $editable ? $this->configFactory->getEditable($config_name) : $this->configFactory->get($config_name);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
+ $form['override'] = [
+ '#type' => 'checkbox',
+ '#title' => $this->t('Override main caching settings'),
+ '#default_value' => $this->configuration['cache']['override'],
+ ];
+ $form['cache_details'] = [
+ '#type' => 'details',
+ '#open' => TRUE,
+ '#collapsible' => FALSE,
+ '#title' => $this->t('Metadata caching'),
+ '#tree' => TRUE,
+ '#states' => [
+ 'visible' => [
+ ':input[name="' . $this->getPluginId() . '[override]"]' => ['checked' => TRUE],
+ ],
+ ],
+ ];
+ $form['cache_details']['settings'] = [
+ '#type' => 'file_mdm_caching',
+ '#default_value' => $this->configuration['cache']['settings'],
+ ];
+
+ return $form;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
+ // @codingStandardsIgnoreStart
+ $this->configuration['cache']['override'] = (bool) $form_state->getValue([$this->getPluginId(), 'override']);
+ $this->configuration['cache']['settings'] = $form_state->getValue([$this->getPluginId(), 'cache_details', 'settings']);
+ // @codingStandardsIgnoreEnd
+
+ $config = $this->getConfigObject(TRUE);
+ $config->set('configuration', $this->configuration);
+ if ($config->getOriginal('configuration') != $config->get('configuration')) {
+ $config->save();
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setUri($uri) {
+ if (!$uri) {
+ throw new FileMetadataException('Missing $uri argument', $this->getPluginId(), __FUNCTION__);
+ }
+ $this->uri = $uri;
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getUri() {
+ return $this->uri;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setLocalTempPath($temp_path) {
+ $this->localTempPath = $temp_path;
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getLocalTempPath() {
+ return $this->localTempPath;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setHash($hash) {
+ if (!$hash) {
+ throw new FileMetadataException('Missing $hash argument', $this->getPluginId(), __FUNCTION__);
+ }
+ $this->hash = $hash;
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isMetadataLoaded() {
+ return $this->isMetadataLoaded;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function loadMetadata($metadata) {
+ $this->metadata = $metadata;
+ $this->hasMetadataChangedFromFileVersion = TRUE;
+ $this->hasMetadataChangedFromCacheVersion = TRUE;
+ $this->deleteCachedMetadata();
+ if ($this->metadata === NULL) {
+ $this->isMetadataLoaded = FileMetadataInterface::NOT_LOADED;
+ }
+ else {
+ $this->isMetadataLoaded = FileMetadataInterface::LOADED_BY_CODE;
+ $this->saveMetadataToCache();
+ }
+ return (bool) $this->metadata;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function loadMetadataFromFile() {
+ if (!file_exists($this->getLocalTempPath())) {
+ // File does not exists.
+ throw new FileMetadataException("File at '{$this->getLocalTempPath()}' does not exist", $this->getPluginId(), __FUNCTION__);
+ }
+ $this->hasMetadataChangedFromFileVersion = FALSE;
+ if (($this->metadata = $this->doGetMetadataFromFile()) === NULL) {
+ $this->isMetadataLoaded = FileMetadataInterface::NOT_LOADED;
+ $this->deleteCachedMetadata();
+ }
+ else {
+ $this->isMetadataLoaded = FileMetadataInterface::LOADED_FROM_FILE;
+ $this->saveMetadataToCache();
+ }
+ return (bool) $this->metadata;
+ }
+
+ /**
+ * Gets file metadata from the file at URI/local path.
+ *
+ * @return mixed
+ * The metadata retrieved from the file.
+ *
+ * @throws \Drupal\file_mdm\FileMetadataException
+ * In case there were significant errors reading from file.
+ */
+ abstract protected function doGetMetadataFromFile();
+
+ /**
+ * {@inheritdoc}
+ */
+ public function loadMetadataFromCache() {
+ $plugin_id = $this->getPluginId();
+ $this->hasMetadataChangedFromFileVersion = FALSE;
+ $this->hasMetadataChangedFromCacheVersion = FALSE;
+ if ($this->isUriFileMetadataCacheable() !== FALSE && ($cache = $this->cache->get("hash:{$plugin_id}:{$this->hash}"))) {
+ $this->metadata = $cache->data;
+ $this->isMetadataLoaded = FileMetadataInterface::LOADED_FROM_CACHE;
+ }
+ else {
+ $this->metadata = NULL;
+ $this->isMetadataLoaded = FileMetadataInterface::NOT_LOADED;
+ }
+ return (bool) $this->metadata;
+ }
+
+ /**
+ * Checks if file metadata should be cached.
+ *
+ * @return array|bool
+ * The caching settings array retrieved from configuration if file metadata
+ * is cacheable, FALSE otherwise.
+ */
+ protected function isUriFileMetadataCacheable() {
+ // Check plugin settings first, if they override general settings.
+ if ($this->configuration['cache']['override']) {
+ $settings = $this->configuration['cache']['settings'];
+ if (!$settings['enabled']) {
+ return FALSE;
+ }
+ }
+
+ // Use general settings if they are not overridden by plugin.
+ if (!isset($settings)) {
+ $settings = $this->configFactory->get('file_mdm.settings')->get('metadata_cache');
+ if (!$settings['enabled']) {
+ return FALSE;
+ }
+ }
+
+ // URIs without valid scheme, and temporary:// URIs are not cached.
+ if (!file_valid_uri($this->getUri()) || file_uri_scheme($this->getUri()) === 'temporary') {
+ return FALSE;
+ }
+
+ // URIs falling into disallowed paths are not cached.
+ foreach ($settings['disallowed_paths'] as $pattern) {
+ $p = "#^" . strtr(preg_quote($pattern, '#'), ['\*' => '.*', '\?' => '.']) . "$#i";
+ if (preg_match($p, $this->getUri())) {
+ return FALSE;
+ }
+ }
+
+ return $settings;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMetadata($key = NULL) {
+ if (!$this->getUri()) {
+ throw new FileMetadataException("No URI specified", $this->getPluginId(), __FUNCTION__);
+ }
+ if (!$this->hash) {
+ throw new FileMetadataException("No hash specified", $this->getPluginId(), __FUNCTION__);
+ }
+ if ($this->metadata === NULL) {
+ // Metadata has not been loaded yet. Try loading it from cache first.
+ $this->loadMetadataFromCache();
+ }
+ if ($this->metadata === NULL && $this->isMetadataLoaded !== FileMetadataInterface::LOADED_FROM_FILE) {
+ // Metadata has not been loaded yet. Try loading it from file if URI is
+ // defined and a read attempt was not made yet.
+ $this->loadMetadataFromFile();
+ }
+ return $this->doGetMetadata($key);
+ }
+
+ /**
+ * Gets a metadata element.
+ *
+ * @param mixed|null $key
+ * A key to determine the metadata element to be returned. If NULL, the
+ * entire metadata will be returned.
+ *
+ * @return mixed|null
+ * The value of the element specified by $key. If $key is NULL, the entire
+ * metadata. If no metadata is available, return NULL.
+ */
+ abstract protected function doGetMetadata($key = NULL);
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setMetadata($key, $value) {
+ if ($key === NULL) {
+ throw new FileMetadataException("No metadata key specified for file at '{$this->getUri()}'", $this->getPluginId(), __FUNCTION__);
+ }
+ if (!$this->metadata && !$this->getMetadata()) {
+ throw new FileMetadataException("No metadata loaded for file at '{$this->getUri()}'", $this->getPluginId(), __FUNCTION__);
+ }
+ if ($this->doSetMetadata($key, $value)) {
+ $this->hasMetadataChangedFromFileVersion = TRUE;
+ if ($this->isMetadataLoaded === FileMetadataInterface::LOADED_FROM_CACHE) {
+ $this->hasMetadataChangedFromCacheVersion = TRUE;
+ }
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ /**
+ * Sets a metadata element.
+ *
+ * @param mixed $key
+ * A key to determine the metadata element to be changed.
+ * @param mixed $value
+ * The value to change the metadata element to.
+ *
+ * @return bool
+ * TRUE if metadata was changed successfully, FALSE otherwise.
+ */
+ abstract protected function doSetMetadata($key, $value);
+
+ /**
+ * {@inheritdoc}
+ */
+ public function removeMetadata($key) {
+ if ($key === NULL) {
+ throw new FileMetadataException("No metadata key specified for file at '{$this->getUri()}'", $this->getPluginId(), __FUNCTION__);
+ }
+ if (!$this->metadata && !$this->getMetadata()) {
+ throw new FileMetadataException("No metadata loaded for file at '{$this->getUri()}'", $this->getPluginId(), __FUNCTION__);
+ }
+ if ($this->doRemoveMetadata($key)) {
+ $this->hasMetadataChangedFromFileVersion = TRUE;
+ if ($this->isMetadataLoaded === FileMetadataInterface::LOADED_FROM_CACHE) {
+ $this->hasMetadataChangedFromCacheVersion = TRUE;
+ }
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ /**
+ * Removes a metadata element.
+ *
+ * @param mixed $key
+ * A key to determine the metadata element to be removed.
+ *
+ * @return bool
+ * TRUE if metadata was removed successfully, FALSE otherwise.
+ */
+ abstract protected function doRemoveMetadata($key);
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isSaveToFileSupported() {
+ return FALSE;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function saveMetadataToFile() {
+ if (!$this->isSaveToFileSupported()) {
+ throw new FileMetadataException('Write metadata to file is not supported', $this->getPluginId(), __FUNCTION__);
+ }
+ if ($this->metadata === NULL) {
+ return FALSE;
+ }
+ if ($this->hasMetadataChangedFromFileVersion) {
+ // Clears cache so that next time metadata will be fetched from file.
+ $this->deleteCachedMetadata();
+ return $this->doSaveMetadataToFile();
+ }
+ return FALSE;
+ }
+
+ /**
+ * Saves metadata to file at URI.
+ *
+ * @return bool
+ * TRUE if metadata was saved successfully, FALSE otherwise.
+ */
+ protected function doSaveMetadataToFile() {
+ return FALSE;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function saveMetadataToCache(array $tags = []) {
+ if ($this->metadata === NULL) {
+ return FALSE;
+ }
+ if (($cache_settings = $this->isUriFileMetadataCacheable()) === FALSE) {
+ return FALSE;
+ }
+ if ($this->isMetadataLoaded !== FileMetadataInterface::LOADED_FROM_CACHE || ($this->isMetadataLoaded === FileMetadataInterface::LOADED_FROM_CACHE && $this->hasMetadataChangedFromCacheVersion)) {
+ $tags = Cache::mergeTags($tags, $this->getConfigObject()->getCacheTags());
+ $tags = Cache::mergeTags($tags, $this->configFactory->get('file_mdm.settings')->getCacheTags());
+ $expire = $cache_settings['expiration'] === -1 ? Cache::PERMANENT : time() + $cache_settings['expiration'];
+ $this->cache->set("hash:{$this->getPluginId()}:{$this->hash}", $this->getMetadataToCache(), $expire, $tags);
+ $this->hasMetadataChangedFromCacheVersion = FALSE;
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ /**
+ * Gets metadata to save to cache.
+ *
+ * @return mixed
+ * The metadata to be cached.
+ */
+ protected function getMetadataToCache() {
+ return $this->metadata;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function deleteCachedMetadata() {
+ if ($this->isUriFileMetadataCacheable() === FALSE) {
+ return FALSE;
+ }
+ $plugin_id = $this->getPluginId();
+ $this->cache->delete("hash:{$plugin_id}:{$this->hash}");
+ $this->hasMetadataChangedFromCacheVersion = FALSE;
+ return TRUE;
+ }
+
+}
diff --git a/web/modules/contrib/file_mdm/src/Plugin/FileMetadata/GetImageSize.php b/web/modules/contrib/file_mdm/src/Plugin/FileMetadata/GetImageSize.php
new file mode 100644
index 000000000..4922edf09
--- /dev/null
+++ b/web/modules/contrib/file_mdm/src/Plugin/FileMetadata/GetImageSize.php
@@ -0,0 +1,89 @@
+getLocalTempPath())) {
+ return $data;
+ }
+ else {
+ return NULL;
+ }
+ }
+
+ /**
+ * Validates a file metadata key.
+ *
+ * @return bool
+ * TRUE if the key is valid.
+ *
+ * @throws \Drupal\file_mdm\FileMetadataException
+ * In case the key is invalid.
+ */
+ protected function validateKey($key, $method) {
+ if (!is_int($key) && !is_string($key)) {
+ throw new FileMetadataException("Invalid metadata key specified", $this->getPluginId(), $method);
+ }
+ if (!in_array($key, $this->getSupportedKeys(), TRUE)) {
+ throw new FileMetadataException("Invalid metadata key '{$key}' specified", $this->getPluginId(), $method);
+ }
+ return TRUE;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doGetMetadata($key = NULL) {
+ if ($key === NULL) {
+ return $this->metadata;
+ }
+ else {
+ $this->validateKey($key, __FUNCTION__);
+ return isset($this->metadata[$key]) ? $this->metadata[$key] : NULL;
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doSetMetadata($key, $value) {
+ $this->validateKey($key, __FUNCTION__);
+ $this->metadata[$key] = $value;
+ return TRUE;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doRemoveMetadata($key) {
+ $this->validateKey($key, __FUNCTION__);
+ if (isset($this->metadata[$key])) {
+ unset($this->metadata[$key]);
+ }
+ return TRUE;
+ }
+
+}
diff --git a/web/modules/contrib/file_mdm/src/Plugin/FileMetadataPluginInterface.php b/web/modules/contrib/file_mdm/src/Plugin/FileMetadataPluginInterface.php
new file mode 100644
index 000000000..b44a9522d
--- /dev/null
+++ b/web/modules/contrib/file_mdm/src/Plugin/FileMetadataPluginInterface.php
@@ -0,0 +1,211 @@
+alterInfo('file_metadata_plugin_info');
+ $this->setCacheBackend($cache_backend, 'file_metadata_plugins');
+ $this->configFactory = $config_factory;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function createInstance($plugin_id, array $configuration = array()) {
+ $plugin_definition = $this->getDefinition($plugin_id);
+ $default_config = call_user_func($plugin_definition['class'] . '::defaultConfiguration');
+ $configuration = $this->configFactory->get($plugin_definition['provider'] . '.file_metadata_plugin.' . $plugin_id)->get('configuration') ?: [];
+ return parent::createInstance($plugin_id, NestedArray::mergeDeep($default_config, $configuration));
+ }
+
+}
diff --git a/web/modules/contrib/file_mdm/tests/files/1024-2006_1011_093752.jpg b/web/modules/contrib/file_mdm/tests/files/1024-2006_1011_093752.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..925ed043fe6873b4883f3c6e0a6acaa4f7b0a6a8
GIT binary patch
literal 209855
zcmbTdcUTkO+BP~NG(!^zy%!}xiYP+pp+lk&LXj>_DM~Lw04YilrAkp03?%|8O{z$j
zCJI78R6trlx^x9ZIK%$A&))C3-apRwtz46J&zjZCv!3T(Ge=*JrhtgkAPA!N<2w-ZgZ>nFodhuq^bf#`4FUxqpnrVv
zLTLWw(}FjAe=#$N5r5-QfpO%(v}Zw|6AV8GVmOHPK&%4dI-Cu-;zo&W^&D+`YVS1UL$7J9=LAbCeP`^m3K~blfj#>gx(?o;&W6f0gxbUnkgD
z*w`n)-PvCl=jSbK8sO;V;^^lhEH86bMot)U+0f|xIi&Dqxl5PNndx0V51c!DRzX?r
ztg@V(@L470^NPwB&H*AocJx0zv;sCY=P%v{v1t51Ee0C{Nc_bvAO=$C0I)&8*>mUQ
zpeg_K)&Urw`Y%2SCV-^=69)qJ8Z-^|uUd