diff --git a/composer.json b/composer.json index aabb08e27f9d9f6b236d25ceee1f9c3347a59129..8e3a9bce102b445406a28dc8fdfa5966cf3c0516 100644 --- a/composer.json +++ b/composer.json @@ -95,8 +95,8 @@ "drupal/better_exposed_filters": "3.0-alpha6", "drupal/bigmenu": "1.0.0-alpha1", "drupal/block_field": "1.0.0-rc1", - "drupal/block_permissions": "1.0", - "drupal/block_region_permissions": "1.2", + "drupal/block_permissions": "1.1", + "drupal/block_region_permissions": "1.3", "drupal/bootstrap": "3.16", "drupal/ckeditor_indentblock": "1.0.0-beta2", "drupal/config_direct_save": "1.0", @@ -120,7 +120,7 @@ "drupal/entity_reference_revisions": "1.8", "drupal/externalauth": "1.1", "drupal/features": "3.8", - "drupal/field_group": "3.0", + "drupal/field_group": "3.1", "drupal/field_permissions": "1.0", "drupal/file_browser": "1.1", "drupal/focal_point": "1.4", @@ -176,7 +176,7 @@ "drupal/view_unpublished": "1.0-rc1", "drupal/views_accordion": "1.1", "drupal/views_ajax_history": "1.2", - "drupal/views_autocomplete_filters": "1.2", + "drupal/views_autocomplete_filters": "1.3", "drupal/views_bootstrap": "3.1", "drupal/views_bulk_operations": "3.4", "drupal/views_fieldsets": "3.3", @@ -279,9 +279,6 @@ "drupal/better_exposed_filters": { "2961022": "https://www.drupal.org/files/issues/2018-09-27/better_exposed_filters-autosubmit-fix-2961022-4.patch" }, - "drupal/block_permissions": { - "2962965": "https://www.drupal.org/files/issues/2018-09-01/block-permissions-2962965-4.patch" - }, "drupal/entity_clone": { "3060223": "https://www.drupal.org/files/issues/2019-10-17/%20entity_clone-corrupted-paragraph-cloning-3060223-5.patch" }, diff --git a/composer.lock b/composer.lock index cd907bc32a4bb92cbebe1f47f5fedb9224a235a6..b3eee3a9857336263eb2f6b499b80aedc5b5626c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "7d3787aaafd1ba3db8d0785fee363f8b", + "content-hash": "97a7b4312e4113ee81b8d863f237ad12", "packages": [ { "name": "alchemy/zippy", @@ -2516,43 +2516,41 @@ }, { "name": "drupal/block_permissions", - "version": "1.0.0", + "version": "1.1.0", "source": { "type": "git", "url": "https://git.drupalcode.org/project/block_permissions.git", - "reference": "8.x-1.0" + "reference": "8.x-1.1" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/block_permissions-8.x-1.0.zip", - "reference": "8.x-1.0", - "shasum": "3f1cb219379fc88a80445d494f66dd4fb2a5befa" + "url": "https://ftp.drupal.org/files/projects/block_permissions-8.x-1.1.zip", + "reference": "8.x-1.1", + "shasum": "734c00f78dfb674294b2d35bc87fcaed7ecf2042" }, "require": { - "drupal/core": "~8.0" + "drupal/core": "^8 || ^9" }, "type": "drupal-module", "extra": { - "branch-alias": { - "dev-1.x": "1.x-dev" - }, "drupal": { - "version": "8.x-1.0", - "datestamp": "1478790983", + "version": "8.x-1.1", + "datestamp": "1592480089", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" } - }, - "patches_applied": { - "2962965": "https://www.drupal.org/files/issues/2018-09-01/block-permissions-2962965-4.patch" } }, "notification-url": "https://packages.drupal.org/8/downloads", "license": [ - "GPL-2.0-or-later" + "GPL-2.0+" ], "authors": [ + { + "name": "Steven Buteneers", + "homepage": "https://www.drupal.org/user/3301055" + }, { "name": "jefuri", "homepage": "https://www.drupal.org/user/2733365" @@ -2565,37 +2563,35 @@ "description": "Adds specific permissions for administering blocks.", "homepage": "https://www.drupal.org/project/block_permissions", "support": { - "source": "http://cgit.drupalcode.org/block_permissions" + "source": "http://cgit.drupalcode.org/block_permissions", + "issues": "https://www.drupal.org/project/issues/block_permissions?version=8.x" } }, { "name": "drupal/block_region_permissions", - "version": "1.2.0", + "version": "1.3.0", "source": { "type": "git", "url": "https://git.drupalcode.org/project/block_region_permissions.git", - "reference": "8.x-1.2" + "reference": "8.x-1.3" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/block_region_permissions-8.x-1.2.zip", - "reference": "8.x-1.2", - "shasum": "9776b2be5af7b9ebe7777f17487ef31e48f76c78" + "url": "https://ftp.drupal.org/files/projects/block_region_permissions-8.x-1.3.zip", + "reference": "8.x-1.3", + "shasum": "ae52eaf8e4186aa68f8cc151770030addc4b8742" }, "require": { - "drupal/core": "~8.0" + "drupal/core": "^8 || ^9" }, "type": "drupal-module", "extra": { - "branch-alias": { - "dev-1.x": "1.x-dev" - }, "drupal": { - "version": "8.x-1.2", - "datestamp": "1507771445", + "version": "8.x-1.3", + "datestamp": "1592351316", "security-coverage": { - "status": "not-covered", - "message": "Project has not opted into security advisory coverage!" + "status": "covered", + "message": "Covered by Drupal's security advisory policy" } } }, @@ -2612,7 +2608,7 @@ "description": "Adds specific permissions for administering blocks for each theme's regions.", "homepage": "https://www.drupal.org/project/block_region_permissions", "support": { - "source": "http://cgit.drupalcode.org/block_region_permissions" + "source": "https://git.drupalcode.org/project/block_region_permissions" } }, { @@ -4813,29 +4809,29 @@ }, { "name": "drupal/field_group", - "version": "3.0.0", + "version": "3.1.0", "source": { "type": "git", "url": "https://git.drupalcode.org/project/field_group.git", - "reference": "8.x-3.0" + "reference": "8.x-3.1" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/field_group-8.x-3.0.zip", - "reference": "8.x-3.0", - "shasum": "8d87cdc4abc417aa4d411bffcaeb0a3ef1afa497" + "url": "https://ftp.drupal.org/files/projects/field_group-8.x-3.1.zip", + "reference": "8.x-3.1", + "shasum": "8a719eaea594f0ba874172831cb28da93c66b77a" }, "require": { - "drupal/core": "^8 || ^9" + "drupal/core": "^8.8 || ^9" + }, + "require-dev": { + "drupal/jquery_ui_accordion": "^1.0" }, "type": "drupal-module", "extra": { - "branch-alias": { - "dev-3.x": "3.x-dev" - }, "drupal": { - "version": "8.x-3.0", - "datestamp": "1580250787", + "version": "8.x-3.1", + "datestamp": "1591772567", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -4844,7 +4840,7 @@ }, "notification-url": "https://packages.drupal.org/8/downloads", "license": [ - "GPL-2.0+" + "GPL-2.0-or-later" ], "authors": [ { @@ -4871,7 +4867,8 @@ "description": "Provides the field_group module.", "homepage": "https://www.drupal.org/project/field_group", "support": { - "source": "https://git.drupalcode.org/project/field_group" + "source": "https://git.drupalcode.org/project/field_group", + "issues": "https://www.drupal.org/project/issues/field_group" } }, { @@ -8100,29 +8097,26 @@ }, { "name": "drupal/views_autocomplete_filters", - "version": "1.2.0", + "version": "1.3.0", "source": { "type": "git", "url": "https://git.drupalcode.org/project/views_autocomplete_filters.git", - "reference": "8.x-1.2" + "reference": "8.x-1.3" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/views_autocomplete_filters-8.x-1.2.zip", - "reference": "8.x-1.2", - "shasum": "bab27febe29aa69eff5c6b3ce3125e49685a6346" + "url": "https://ftp.drupal.org/files/projects/views_autocomplete_filters-8.x-1.3.zip", + "reference": "8.x-1.3", + "shasum": "55762182e55c70f117d5edb8692049e0881ec4ce" }, "require": { - "drupal/core": "*" + "drupal/core": "^8 || ^9" }, "type": "drupal-module", "extra": { - "branch-alias": { - "dev-1.x": "1.x-dev" - }, "drupal": { - "version": "8.x-1.2", - "datestamp": "1500109743", + "version": "8.x-1.3", + "datestamp": "1587146330", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -8138,15 +8132,24 @@ "name": "RobLoach", "homepage": "https://www.drupal.org/user/61114" }, + { + "name": "colan", + "homepage": "https://www.drupal.org/user/58704" + }, { "name": "vasike", "homepage": "https://www.drupal.org/user/156237" } ], - "description": "Use Autocomplete for string field filters.", + "description": "Add autocomplete functionality to the views filter text fields.", "homepage": "https://www.drupal.org/project/views_autocomplete_filters", + "keywords": [ + "Drupal", + "views_autocomplete_filters" + ], "support": { - "source": "https://git.drupalcode.org/project/views_autocomplete_filters" + "source": "https://git.drupalcode.org/project/views_autocomplete_filters", + "issues": "https://www.drupal.org/project/issues/views_autocomplete_filters" } }, { diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 9d55d91d2dfba5113562356562d6dbe081fbdd73..d01d34d36b8815e914af6479d8c1cf02ed2b6d93 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -2595,45 +2595,43 @@ }, { "name": "drupal/block_permissions", - "version": "1.0.0", - "version_normalized": "1.0.0.0", + "version": "1.1.0", + "version_normalized": "1.1.0.0", "source": { "type": "git", "url": "https://git.drupalcode.org/project/block_permissions.git", - "reference": "8.x-1.0" + "reference": "8.x-1.1" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/block_permissions-8.x-1.0.zip", - "reference": "8.x-1.0", - "shasum": "3f1cb219379fc88a80445d494f66dd4fb2a5befa" + "url": "https://ftp.drupal.org/files/projects/block_permissions-8.x-1.1.zip", + "reference": "8.x-1.1", + "shasum": "734c00f78dfb674294b2d35bc87fcaed7ecf2042" }, "require": { - "drupal/core": "~8.0" + "drupal/core": "^8 || ^9" }, "type": "drupal-module", "extra": { - "branch-alias": { - "dev-1.x": "1.x-dev" - }, "drupal": { - "version": "8.x-1.0", - "datestamp": "1478790983", + "version": "8.x-1.1", + "datestamp": "1592480089", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" } - }, - "patches_applied": { - "2962965": "https://www.drupal.org/files/issues/2018-09-01/block-permissions-2962965-4.patch" } }, "installation-source": "dist", "notification-url": "https://packages.drupal.org/8/downloads", "license": [ - "GPL-2.0-or-later" + "GPL-2.0+" ], "authors": [ + { + "name": "Steven Buteneers", + "homepage": "https://www.drupal.org/user/3301055" + }, { "name": "jefuri", "homepage": "https://www.drupal.org/user/2733365" @@ -2646,38 +2644,36 @@ "description": "Adds specific permissions for administering blocks.", "homepage": "https://www.drupal.org/project/block_permissions", "support": { - "source": "http://cgit.drupalcode.org/block_permissions" + "source": "http://cgit.drupalcode.org/block_permissions", + "issues": "https://www.drupal.org/project/issues/block_permissions?version=8.x" } }, { "name": "drupal/block_region_permissions", - "version": "1.2.0", - "version_normalized": "1.2.0.0", + "version": "1.3.0", + "version_normalized": "1.3.0.0", "source": { "type": "git", "url": "https://git.drupalcode.org/project/block_region_permissions.git", - "reference": "8.x-1.2" + "reference": "8.x-1.3" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/block_region_permissions-8.x-1.2.zip", - "reference": "8.x-1.2", - "shasum": "9776b2be5af7b9ebe7777f17487ef31e48f76c78" + "url": "https://ftp.drupal.org/files/projects/block_region_permissions-8.x-1.3.zip", + "reference": "8.x-1.3", + "shasum": "ae52eaf8e4186aa68f8cc151770030addc4b8742" }, "require": { - "drupal/core": "~8.0" + "drupal/core": "^8 || ^9" }, "type": "drupal-module", "extra": { - "branch-alias": { - "dev-1.x": "1.x-dev" - }, "drupal": { - "version": "8.x-1.2", - "datestamp": "1507771445", + "version": "8.x-1.3", + "datestamp": "1592351316", "security-coverage": { - "status": "not-covered", - "message": "Project has not opted into security advisory coverage!" + "status": "covered", + "message": "Covered by Drupal's security advisory policy" } } }, @@ -2695,7 +2691,7 @@ "description": "Adds specific permissions for administering blocks for each theme's regions.", "homepage": "https://www.drupal.org/project/block_region_permissions", "support": { - "source": "http://cgit.drupalcode.org/block_region_permissions" + "source": "https://git.drupalcode.org/project/block_region_permissions" } }, { @@ -4955,30 +4951,30 @@ }, { "name": "drupal/field_group", - "version": "3.0.0", - "version_normalized": "3.0.0.0", + "version": "3.1.0", + "version_normalized": "3.1.0.0", "source": { "type": "git", "url": "https://git.drupalcode.org/project/field_group.git", - "reference": "8.x-3.0" + "reference": "8.x-3.1" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/field_group-8.x-3.0.zip", - "reference": "8.x-3.0", - "shasum": "8d87cdc4abc417aa4d411bffcaeb0a3ef1afa497" + "url": "https://ftp.drupal.org/files/projects/field_group-8.x-3.1.zip", + "reference": "8.x-3.1", + "shasum": "8a719eaea594f0ba874172831cb28da93c66b77a" }, "require": { - "drupal/core": "^8 || ^9" + "drupal/core": "^8.8 || ^9" + }, + "require-dev": { + "drupal/jquery_ui_accordion": "^1.0" }, "type": "drupal-module", "extra": { - "branch-alias": { - "dev-3.x": "3.x-dev" - }, "drupal": { - "version": "8.x-3.0", - "datestamp": "1580250787", + "version": "8.x-3.1", + "datestamp": "1591772567", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -4988,7 +4984,7 @@ "installation-source": "dist", "notification-url": "https://packages.drupal.org/8/downloads", "license": [ - "GPL-2.0+" + "GPL-2.0-or-later" ], "authors": [ { @@ -5015,7 +5011,8 @@ "description": "Provides the field_group module.", "homepage": "https://www.drupal.org/project/field_group", "support": { - "source": "https://git.drupalcode.org/project/field_group" + "source": "https://git.drupalcode.org/project/field_group", + "issues": "https://www.drupal.org/project/issues/field_group" } }, { @@ -8352,30 +8349,27 @@ }, { "name": "drupal/views_autocomplete_filters", - "version": "1.2.0", - "version_normalized": "1.2.0.0", + "version": "1.3.0", + "version_normalized": "1.3.0.0", "source": { "type": "git", "url": "https://git.drupalcode.org/project/views_autocomplete_filters.git", - "reference": "8.x-1.2" + "reference": "8.x-1.3" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/views_autocomplete_filters-8.x-1.2.zip", - "reference": "8.x-1.2", - "shasum": "bab27febe29aa69eff5c6b3ce3125e49685a6346" + "url": "https://ftp.drupal.org/files/projects/views_autocomplete_filters-8.x-1.3.zip", + "reference": "8.x-1.3", + "shasum": "55762182e55c70f117d5edb8692049e0881ec4ce" }, "require": { - "drupal/core": "*" + "drupal/core": "^8 || ^9" }, "type": "drupal-module", "extra": { - "branch-alias": { - "dev-1.x": "1.x-dev" - }, "drupal": { - "version": "8.x-1.2", - "datestamp": "1500109743", + "version": "8.x-1.3", + "datestamp": "1587146330", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -8392,15 +8386,24 @@ "name": "RobLoach", "homepage": "https://www.drupal.org/user/61114" }, + { + "name": "colan", + "homepage": "https://www.drupal.org/user/58704" + }, { "name": "vasike", "homepage": "https://www.drupal.org/user/156237" } ], - "description": "Use Autocomplete for string field filters.", + "description": "Add autocomplete functionality to the views filter text fields.", "homepage": "https://www.drupal.org/project/views_autocomplete_filters", + "keywords": [ + "Drupal", + "views_autocomplete_filters" + ], "support": { - "source": "https://git.drupalcode.org/project/views_autocomplete_filters" + "source": "https://git.drupalcode.org/project/views_autocomplete_filters", + "issues": "https://www.drupal.org/project/issues/views_autocomplete_filters" } }, { diff --git a/web/modules/block_permissions/block_permissions.info.yml b/web/modules/block_permissions/block_permissions.info.yml index a713c7e4c4d953994fd49a719792b46fe03fe3ad..30fd7150de5888ee543c841502550676ed0f7a27 100644 --- a/web/modules/block_permissions/block_permissions.info.yml +++ b/web/modules/block_permissions/block_permissions.info.yml @@ -2,10 +2,10 @@ name: 'Block permissions' type: module description: 'Adds specific permissions for administering blocks.' package: Block -# core: '8.x' - -# Information added by Drupal.org packaging script on 2016-11-10 -version: '8.x-1.0' core: '8.x' +core_version_requirement: ^8 || ^9 + +# Information added by Drupal.org packaging script on 2020-06-18 +version: '8.x-1.1' project: 'block_permissions' -datestamp: 1478790984 +datestamp: 1592480090 diff --git a/web/modules/block_permissions/composer.json b/web/modules/block_permissions/composer.json new file mode 100644 index 0000000000000000000000000000000000000000..033fa6952ba2b376b1870dfcecfdda19aa1d22d5 --- /dev/null +++ b/web/modules/block_permissions/composer.json @@ -0,0 +1,11 @@ +{ + "name": "drupal/block_permissions", + "type": "drupal-module", + "description": "Adds specific permissions for administering blocks.", + "homepage": "https://www.drupal.org/project/block_permissions", + "support": { + "issues": "https://www.drupal.org/project/issues/block_permissions?version=8.x", + "source": "http://cgit.drupalcode.org/block_permissions" + }, + "license": "GPL-2.0+" +} diff --git a/web/modules/block_permissions/src/BlockPermissionsPermissions.php b/web/modules/block_permissions/src/BlockPermissionsPermissions.php index 00a3534877126b40b7ad93044a6b818214f316ff..9a158982dbd8fa173949f336423b5c79b8546f15 100644 --- a/web/modules/block_permissions/src/BlockPermissionsPermissions.php +++ b/web/modules/block_permissions/src/BlockPermissionsPermissions.php @@ -63,10 +63,10 @@ public function permissions() { // administration per theme. $themes = $this->themeHandler->listInfo(); foreach ($themes as $key => $theme) { - if (isset($theme->info['hidden']) && $theme->status == 1 && $theme->info['hidden'] != 1) { + if ($theme->status == 1 && (!isset($theme->info['hidden']) || $theme->info['hidden'] != 1)) { $permissions['administer block settings for theme ' . $key] = [ 'title' => $this->t('Administer block settings for the theme @label', ['@label' => ucfirst($theme->getName())]), - 'description' => $this->t('This permission s the administer blocks permission.'), + 'description' => $this->t('This permission refines the administer blocks permission.'), ]; } } diff --git a/web/modules/block_region_permissions/block_region_permissions.info.yml b/web/modules/block_region_permissions/block_region_permissions.info.yml index 65fe8c5eb611c826420c06e4181832296dccb8ad..53eccc024a0dfe311b29c1290e969abe948bf1c8 100644 --- a/web/modules/block_region_permissions/block_region_permissions.info.yml +++ b/web/modules/block_region_permissions/block_region_permissions.info.yml @@ -2,10 +2,10 @@ name: Block Region Permissions description: "Adds specific permissions for administering blocks for each theme's regions." package: Block type: module -# core: 8.x +core: 8.x +core_version_requirement: ^8 || ^9 -# Information added by Drupal.org packaging script on 2017-10-12 -version: '8.x-1.2' -core: '8.x' +# Information added by Drupal.org packaging script on 2020-06-16 +version: '8.x-1.3' project: 'block_region_permissions' -datestamp: 1507771447 +datestamp: 1592351318 diff --git a/web/modules/field_group/composer.json b/web/modules/field_group/composer.json index ac893ea5173ee11b7d19b7dd874e7586e91c28a4..47b16e766fe2d25cdf334515fddd00a5122c8c53 100644 --- a/web/modules/field_group/composer.json +++ b/web/modules/field_group/composer.json @@ -2,9 +2,16 @@ "name": "drupal/field_group", "description": "Provides the field_group module.", "type": "drupal-module", - "license": "GPL-2.0+", + "license": "GPL-2.0-or-later", "minimum-stability": "dev", "require": { - "drupal/core": "^8 || ^9" + "drupal/core": "^8.8 || ^9" + }, + "require-dev": { + "drupal/jquery_ui_accordion": "^1.0" + }, + "support": { + "issues": "https://www.drupal.org/project/issues/field_group", + "source": "https://git.drupalcode.org/project/field_group" } } diff --git a/web/modules/field_group/contrib/field_group_migrate/field_group_migrate.info.yml b/web/modules/field_group/contrib/field_group_migrate/field_group_migrate.info.yml index f1a0fb93f4ff1b767d0d88cdc77bff84b6154ebd..de95c532dd18968edc4e350e165d611b1f47b66d 100644 --- a/web/modules/field_group/contrib/field_group_migrate/field_group_migrate.info.yml +++ b/web/modules/field_group/contrib/field_group_migrate/field_group_migrate.info.yml @@ -2,11 +2,11 @@ name: 'Field Group Migrate' type: module description: 'Provides the ability to migrate field groups from D6/D7 to D8.' package: Migration -core: 8.x +core_version_requirement: ^8.8 || ^9 dependencies: - field_group:field_group -# Information added by Drupal.org packaging script on 2020-01-28 -version: '8.x-3.0' +# Information added by Drupal.org packaging script on 2020-06-10 +version: '8.x-3.1' project: 'field_group' -datestamp: 1580250789 +datestamp: 1591772570 diff --git a/web/modules/field_group/contrib/field_group_migrate/src/Plugin/migrate/destination/d7/FieldGroup.php b/web/modules/field_group/contrib/field_group_migrate/src/Plugin/migrate/destination/d7/FieldGroup.php index 828715ffd8bbebc1cf8168520738d46953b29e4e..64b6c4cd1799c53b1feb509c601f4d946035ef0f 100644 --- a/web/modules/field_group/contrib/field_group_migrate/src/Plugin/migrate/destination/d7/FieldGroup.php +++ b/web/modules/field_group/contrib/field_group_migrate/src/Plugin/migrate/destination/d7/FieldGroup.php @@ -88,8 +88,8 @@ public function fields(MigrationInterface $migration = NULL) { * The entity display object. */ protected function getEntity($entity_type, $bundle, $mode, $type) { - $function = $type == 'entity_form_display' ? 'entity_get_form_display' : 'entity_get_display'; - return $function($entity_type, $bundle, $mode); + $function = $type == 'entity_form_display' ? 'getFormDisplay' : 'getViewDisplay'; + return \Drupal::service('entity_display.repository')->$function($entity_type, $bundle, $mode); } } diff --git a/web/modules/field_group/field_group.info.yml b/web/modules/field_group/field_group.info.yml index 42618f0d09d7c212d84d5c194f31d42ce77d7220..0e4b01a222153fc250a9dbd94fa9ca44429257f2 100644 --- a/web/modules/field_group/field_group.info.yml +++ b/web/modules/field_group/field_group.info.yml @@ -2,12 +2,11 @@ name: 'Field Group' type: module description: 'Provides the ability to group your fields on both form and display.' package : Fields -core: 8.x -core_version_requirement: ^8 || ^9 +core_version_requirement: ^8.8 || ^9 dependencies: - drupal:field -# Information added by Drupal.org packaging script on 2020-01-28 -version: '8.x-3.0' +# Information added by Drupal.org packaging script on 2020-06-10 +version: '8.x-3.1' project: 'field_group' -datestamp: 1580250789 +datestamp: 1591772570 diff --git a/web/modules/field_group/field_group.install b/web/modules/field_group/field_group.install index 659cf67a2fb029c6fbd4cf7270e1d34bc62a7422..b247a47a056ec9becc69842cbe456065cfd34a91 100644 --- a/web/modules/field_group/field_group.install +++ b/web/modules/field_group/field_group.install @@ -5,9 +5,59 @@ * Update hooks for the Field Group module. */ +/** + * Implements hook_requirements(). + */ +function field_group_requirements($phase) { + $requirements = []; + + if ($phase == 'runtime') { + // Check jQuery UI Accordion module for D9. + if (version_compare(\Drupal::VERSION, 9) > 0) { + if (!\Drupal::moduleHandler()->moduleExists('jquery_ui_accordion')) { + $requirements['field_group_jquery_ui_accordion'] = [ + 'title' => t('Field Group'), + 'value' => t('jQuery UI Accordion not enabled'), + 'description' => t('If you want to use the Field Group accordion formatter, you will need to install the <a href=":link" target="_blank">jQuery UI Accordion</a> module.', [':link' => 'https://www.drupal.org/project/jquery_ui_accordion']), + 'severity' => REQUIREMENT_WARNING, + ]; + } + else { + $requirements['field_group_jquery_ui_accordion'] = [ + 'title' => t('Field Group'), + 'description' => t('The jQuery UI Accordion module is installed'), + 'severity' => REQUIREMENT_INFO, + ]; + } + } + } + + return $requirements; +} + /** * Removed in favor of hook_post_update script. */ function field_group_update_8301() { // @see field_group_post_update_0001(). } + +/** + * Install the 'jquery_ui_accordion' module if it exists. + */ +function field_group_update_8302() { + try { + // Enables the jQuery UI accordion module if it exists. + if (\Drupal::service('extension.list.module') + ->getName('jquery_ui_accordion')) { + \Drupal::service('module_installer') + ->install(['jquery_ui_accordion'], FALSE); + return t('The "jquery_ui_accordion" module has been installed.'); + } + } + catch (\Exception $e) { + return + t('If you want to use the Field Group accordion formatter, you will need to install the <a href=":link" target="_blank">jQuery UI Accordion</a> module.', + [':link' => 'https://www.drupal.org/project/jquery_ui_accordion']); + } +} diff --git a/web/modules/field_group/field_group.module b/web/modules/field_group/field_group.module index 2e794568cfddea2dd4300c361f6528587964c412..006ae6f6e3f89d9695de0b1600d4d091db7c97ec 100644 --- a/web/modules/field_group/field_group.module +++ b/web/modules/field_group/field_group.module @@ -16,6 +16,7 @@ use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Render\Element; use Drupal\field_group\Element\VerticalTabs; +use Drupal\field_group\FormatterHelper; /** * Implements hook_help(). @@ -32,6 +33,24 @@ function field_group_help($route_name, RouteMatchInterface $route_match) { } } +/** + * Implements hook_library_info_alter(). + */ +function field_group_library_info_alter(&$libraries, $extension) { + // Swap jQuery.ui library if available. + // See https://www.drupal.org/project/field_group/issues/3109552 for more + // background on the logic. + if (version_compare(\Drupal::VERSION, 9) > 0 && $extension == 'field_group') { + if (\Drupal::moduleHandler()->moduleExists('jquery_ui_accordion')) { + $libraries['formatter.accordion']['dependencies'] = ['jquery_ui_accordion/accordion']; + } + else { + $libraries['formatter.accordion']['js'] = []; + $libraries['formatter.accordion']['dependencies'] = []; + } + } +} + /** * Implements hook_theme_registry_alter(). */ @@ -235,7 +254,7 @@ function field_group_form_alter(array &$form, FormStateInterface $form_state) { ]; field_group_attach_groups($form, $context); - $form['#process'][] = 'field_group_form_process'; + $form['#process'][] = [FormatterHelper::class, 'formProcess']; } } @@ -256,7 +275,7 @@ function field_group_inline_entity_form_entity_form_alter(&$entity_form, FormSta ]; field_group_attach_groups($entity_form, $context); - field_group_form_process($entity_form); + FormatterHelper::formProcess($entity_form, $form_state); } /** @@ -277,7 +296,7 @@ function field_group_form_layout_builder_update_block_alter(&$form, FormStateInt ]; field_group_attach_groups($form['settings']['block_form'], $context); - $form['settings']['block_form']['#process'][] = 'field_group_form_process'; + $form['settings']['block_form']['#process'][] = [FormatterHelper::class, 'formProcess']; } /** @@ -317,7 +336,7 @@ function field_group_entity_view_alter(&$build, EntityInterface $entity, EntityD // If DS is enabled, no pre render is needed (DS adds fieldgroup preprocessing). if (!$ds_enabled) { - $build['#pre_render'][] = 'field_group_entity_view_pre_render'; + $build['#pre_render'][] = [FormatterHelper::class, 'entityViewPrender']; } } } @@ -349,72 +368,7 @@ function field_group_form_pre_render(array $element) { * @return array */ function field_group_form_process(array &$element, FormStateInterface $form_state = NULL, array &$form = []) { - if (empty($element['#field_group_form_process'])) { - $element['#field_group_form_process'] = TRUE; - if (empty($element['#fieldgroups'])) { - return $element; - } - - // Create all groups and keep a flat list of references to these groups. - $group_references = []; - foreach ($element['#fieldgroups'] as $group_name => $group) { - if (!isset($element[$group_name])) { - $element[$group_name] = []; - } - - $group_parents = $element['#array_parents']; - $group_parents[] = empty($group->parent_name) ? $group->region : $group->parent_name; - $group_references[$group_name] = &$element[$group_name]; - $element[$group_name]['#group'] = implode('][', $group_parents); - - // Use array parents to set the group name. This will cover multilevel forms (eg paragraphs). - $parents = $element['#array_parents']; - $parents[] = $group_name; - $element[$group_name]['#parents'] = $parents; - $group_children_parent_group = implode('][', $parents); - foreach ($group->children as $child) { - if (!empty($element[$child]['#field_group_ignore'])) { - continue; - } - $element[$child]['#group'] = $group_children_parent_group; - } - } - - foreach ($element['#fieldgroups'] as $group_name => $group) { - $field_group_element = &$element[$group_name]; - - // Let modules define their wrapping element. - // Note that the group element has no properties, only elements. - foreach (Drupal::moduleHandler()->getImplementations('field_group_form_process') as $module) { - // The intention here is to have the opportunity to alter the - // elements, as defined in hook_field_group_formatter_info. - // Note, implement $element by reference! - $function = $module . '_field_group_form_process'; - $function($field_group_element, $group, $element); - } - - // Allow others to alter the pre_render. - Drupal::moduleHandler()->alter('field_group_form_process', $field_group_element, $group, $element); - } - - // Allow others to alter the complete processed build. - Drupal::moduleHandler()->alter('field_group_form_process_build', $element, $form_state, $form); - } - - return $element; -} - -/** - * Pre render callback for rendering groups on entities without theme hook. - * - * @param array $element - * Entity being rendered. - * - * @return array - */ -function field_group_entity_view_pre_render(array $element) { - field_group_build_entity_groups($element, 'view'); - return $element; + return FormatterHelper::formProcess($element, $form_state, $form); } /** diff --git a/web/modules/field_group/formatters/tabs/horizontal-tabs.css b/web/modules/field_group/formatters/tabs/horizontal-tabs.css index b28d5c9dea7c430a2eb625815e2ec95ddbfdf4c7..5aa784f928ecebbf95dff5396f54e46767bf871e 100644 --- a/web/modules/field_group/formatters/tabs/horizontal-tabs.css +++ b/web/modules/field_group/formatters/tabs/horizontal-tabs.css @@ -31,6 +31,7 @@ padding: 0 1em; border: 0; background-color: unset; + box-shadow: unset; } .horizontal-tabs-pane > summary { diff --git a/web/modules/field_group/formatters/tabs/horizontal-tabs.js b/web/modules/field_group/formatters/tabs/horizontal-tabs.js index ca0dc04ca51d0cf062ddf1c2b156cd8c4cc8eb4b..865da553291c5040ccccc9027f33117df88a1160 100644 --- a/web/modules/field_group/formatters/tabs/horizontal-tabs.js +++ b/web/modules/field_group/formatters/tabs/horizontal-tabs.js @@ -1,4 +1,4 @@ -(function ($) { +(function ($, Drupal) { 'use strict'; @@ -56,9 +56,9 @@ summaryElement = $this.find('> summary'); } - var summary = summaryElement.clone().children().remove().end().text(); + var summaryText = summaryElement.clone().children().remove().end().text().trim() || summaryElement.find('> span:first-child').text().trim(); var horizontal_tab = new Drupal.horizontalTab({ - title: $.trim(summary), + title: summaryText, details: $this }); horizontal_tab.item.addClass('horizontal-tab-button-' + i); @@ -178,7 +178,6 @@ // Display the tab. this.item.removeClass('horizontal-tab-hidden'); this.item.show(); - alert('show'); // Update .first marker for items. We need recurse from parent to retain the // actual DOM element order as jQuery implements sortOrder, but not as public @@ -201,7 +200,6 @@ // Hide this tab. this.item.addClass('horizontal-tab-hidden'); this.item.hide(); - alert('hide'); // Update .first marker for items. We need recurse from parent to retain the // actual DOM element order as jQuery implements sortOrder, but not as public @@ -253,4 +251,4 @@ return tab; }; -})(jQuery, Modernizr); +})(jQuery, Drupal); diff --git a/web/modules/field_group/includes/field_ui.inc b/web/modules/field_group/includes/field_ui.inc index 0a14e6b7719b3d3f693c0d512ff6fc16cd4015c4..5c53ff1a74dfddfb2a4998b37ba251b32f0d38e4 100644 --- a/web/modules/field_group/includes/field_ui.inc +++ b/web/modules/field_group/includes/field_ui.inc @@ -167,7 +167,6 @@ function field_group_field_ui_display_form_alter(&$form, FormStateInterface $for $settings = field_group_format_settings_form($group, $form, $form_state); $id = strtr($name, '_', '-'); - $js_rows_data[$id] = ['type' => 'group', 'name' => $name]; // A group cannot be selected as its own parent. $parent_options = $table['#parent_options']; $region = isset($group->region) && in_array($group->region, $params->available_regions) ? $group->region : $params->default_region; diff --git a/web/modules/field_group/src/Element/VerticalTabs.php b/web/modules/field_group/src/Element/VerticalTabs.php index 598e24cf472082fb8f7dca43f7bc8fb412bc6a2f..c8a212d209fe22fc551be21ec8ca2a984d8707e3 100644 --- a/web/modules/field_group/src/Element/VerticalTabs.php +++ b/web/modules/field_group/src/Element/VerticalTabs.php @@ -4,11 +4,12 @@ use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Render\Element; +use Drupal\Core\Render\Element\RenderCallbackInterface; /** * Provides extra processing and pre rendering on the vertical tabs. */ -class VerticalTabs { +class VerticalTabs implements RenderCallbackInterface { /** * Pre render the group to support #group parameter. diff --git a/web/modules/field_group/src/FieldGroupFormatterBase.php b/web/modules/field_group/src/FieldGroupFormatterBase.php index 0230b9ac3b08069f92287b7554a28717dccb98aa..b3297a637a7ec0fb655da92798ae99498d8859b3 100644 --- a/web/modules/field_group/src/FieldGroupFormatterBase.php +++ b/web/modules/field_group/src/FieldGroupFormatterBase.php @@ -90,13 +90,13 @@ public function settingsForm() { $form = []; $form['label'] = [ '#type' => 'textfield', - '#title' => t('Field group label'), + '#title' => $this->t('Field group label'), '#default_value' => $this->label, '#weight' => -5, ]; $form['id'] = [ - '#title' => t('ID'), + '#title' => $this->t('ID'), '#type' => 'textfield', '#default_value' => $this->getSetting('id'), '#weight' => 10, @@ -104,7 +104,7 @@ public function settingsForm() { ]; $form['classes'] = [ - '#title' => t('Extra CSS classes'), + '#title' => $this->t('Extra CSS classes'), '#type' => 'textfield', '#default_value' => $this->getSetting('classes'), '#weight' => 11, diff --git a/web/modules/field_group/src/Form/FieldGroupAddForm.php b/web/modules/field_group/src/Form/FieldGroupAddForm.php index a69b5904bec24edc63288fa5b1063daa569f007e..7b89fb3abac06857a8452ffa1b52b1cb0d4ac8e2 100644 --- a/web/modules/field_group/src/Form/FieldGroupAddForm.php +++ b/web/modules/field_group/src/Form/FieldGroupAddForm.php @@ -212,7 +212,7 @@ public function buildConfigurationForm(array &$form, FormStateInterface $form_st $group->bundle = $this->bundle; $group->mode = $this->mode; - $manager = \Drupal::service('plugin.manager.field_group.formatters'); + $manager = $this->fieldGroupFormatterPluginManager; $plugin = $manager->getInstance([ 'format_type' => $form_state->getValue('group_formatter'), 'configuration' => [ @@ -285,7 +285,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { // Store new group information for any additional submit handlers. $groups_added = $form_state->get('groups_added'); $groups_added['_add_new_group'] = $new_group->group_name; - $this->messenger->addMessage(t('New group %label successfully created.', ['%label' => $new_group->label])); + $this->messenger->addMessage($this->t('New group %label successfully created.', ['%label' => $new_group->label])); $form_state->setRedirectUrl(FieldgroupUi::getFieldUiRoute($new_group)); \Drupal::cache()->invalidate('field_groups'); diff --git a/web/modules/field_group/src/Form/FieldGroupDeleteForm.php b/web/modules/field_group/src/Form/FieldGroupDeleteForm.php index fafb76f1f1eb76757fd7c875d1072849dd7c4836..6814525f967a85effffdab992b57db3c39de8252 100644 --- a/web/modules/field_group/src/Form/FieldGroupDeleteForm.php +++ b/web/modules/field_group/src/Form/FieldGroupDeleteForm.php @@ -82,7 +82,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { field_group_delete_field_group($this->fieldGroup); - $this->messenger->addMessage(t('The group %group has been deleted from the %type content type.', ['%group' => t($this->fieldGroup->label), '%type' => $bundle_label])); + $this->messenger->addMessage($this->t('The group %group has been deleted from the %type content type.', ['%group' => $this->fieldGroup->label, '%type' => $bundle_label])); // Redirect. $form_state->setRedirectUrl($this->getCancelUrl()); @@ -93,7 +93,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { * {@inheritdoc} */ public function getQuestion() { - return $this->t('Are you sure you want to delete the group %group?', ['%group' => t($this->fieldGroup->label)]); + return $this->t('Are you sure you want to delete the group %group?', ['%group' => $this->fieldGroup->label]); } /** diff --git a/web/modules/field_group/src/FormatterHelper.php b/web/modules/field_group/src/FormatterHelper.php index 436d7d71cac25597bb4919dc69395f7aaf52a28a..4b840721582a7ea003725c0eb3a9fe97743f5d7b 100644 --- a/web/modules/field_group/src/FormatterHelper.php +++ b/web/modules/field_group/src/FormatterHelper.php @@ -3,11 +3,13 @@ namespace Drupal\field_group; use Drupal; +use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Security\TrustedCallbackInterface; /** * Static methods for fieldgroup formatters. */ -class FormatterHelper { +class FormatterHelper implements TrustedCallbackInterface { /** * Return an array of field_group_formatter options. @@ -18,7 +20,7 @@ public static function formatterOptions($type) { if (!isset($options)) { $options = []; - $manager = Drupal::service('plugin.manager.field_group.formatters'); + $manager = \Drupal::service('plugin.manager.field_group.formatters'); $formatters = $manager->getDefinitions(); foreach ($formatters as $formatter) { @@ -31,4 +33,94 @@ public static function formatterOptions($type) { return $options; } + /** + * Pre render callback for rendering groups on entities without theme hook. + * + * @param array $element + * Entity being rendered. + * + * @return array + */ + public static function entityViewPrender(array $element) { + field_group_build_entity_groups($element, 'view'); + return $element; + } + + /** + * Process callback for field groups. + * + * @param array $element + * Form that is being processed. + * @param \Drupal\Core\Form\FormStateInterface $form_state + * The current state of the form. + * @param array $form + * The complete form structure. + * + * @return array + */ + public static function formProcess(array &$element, FormStateInterface $form_state = NULL, array &$form = []) { + if (empty($element['#field_group_form_process'])) { + $element['#field_group_form_process'] = TRUE; + if (empty($element['#fieldgroups'])) { + return $element; + } + + // Create all groups and keep a flat list of references to these groups. + $group_references = []; + foreach ($element['#fieldgroups'] as $group_name => $group) { + if (!isset($element[$group_name])) { + $element[$group_name] = []; + } + + $group_parents = $element['#array_parents']; + $group_parents[] = empty($group->parent_name) ? $group->region : $group->parent_name; + $group_references[$group_name] = &$element[$group_name]; + $element[$group_name]['#group'] = implode('][', $group_parents); + + // Use array parents to set the group name. This will cover multilevel forms (eg paragraphs). + $parents = $element['#array_parents']; + $parents[] = $group_name; + $element[$group_name]['#parents'] = $parents; + $group_children_parent_group = implode('][', $parents); + foreach ($group->children as $child) { + if (!empty($element[$child]['#field_group_ignore'])) { + continue; + } + $element[$child]['#group'] = $group_children_parent_group; + } + } + + foreach ($element['#fieldgroups'] as $group_name => $group) { + $field_group_element = &$element[$group_name]; + + // Let modules define their wrapping element. + // Note that the group element has no properties, only elements. + foreach (Drupal::moduleHandler()->getImplementations('field_group_form_process') as $module) { + // The intention here is to have the opportunity to alter the + // elements, as defined in hook_field_group_formatter_info. + // Note, implement $element by reference! + $function = $module . '_field_group_form_process'; + $function($field_group_element, $group, $element); + } + + // Allow others to alter the pre_render. + Drupal::moduleHandler()->alter('field_group_form_process', $field_group_element, $group, $element); + } + + // Allow others to alter the complete processed build. + Drupal::moduleHandler()->alter('field_group_form_process_build', $element, $form_state, $form); + } + + return $element; + } + + + /** + * {@inheritdoc} + */ + public static function trustedCallbacks() { + return ['entityViewPrender', 'formProcess']; + } + + } diff --git a/web/modules/field_group/tests/modules/field_group_test/field_group_test.info.yml b/web/modules/field_group/tests/modules/field_group_test/field_group_test.info.yml index 279040ed8eb78698f92f3f484c8bbe884cc6705f..b5e79b5971e7fb140944f39ad4e1f67804f0b097 100644 --- a/web/modules/field_group/tests/modules/field_group_test/field_group_test.info.yml +++ b/web/modules/field_group/tests/modules/field_group_test/field_group_test.info.yml @@ -1,11 +1,11 @@ name: 'Field Group Test' description: 'Test module for Field Group' -core: 8.x +core_version_requirement: ^8.8 || ^9 package: 'Fields' type: module hidden: TRUE -# Information added by Drupal.org packaging script on 2020-01-28 -version: '8.x-3.0' +# Information added by Drupal.org packaging script on 2020-06-10 +version: '8.x-3.1' project: 'field_group' -datestamp: 1580250789 +datestamp: 1591772570 diff --git a/web/modules/field_group/tests/src/Functional/EntityDisplayTest.php b/web/modules/field_group/tests/src/Functional/EntityDisplayTest.php index 7eda8fa638a89e03d466e6ecf767db2378141c5e..5f0060ab37e11a6d6ba92d1371586b935a035429 100644 --- a/web/modules/field_group/tests/src/Functional/EntityDisplayTest.php +++ b/web/modules/field_group/tests/src/Functional/EntityDisplayTest.php @@ -23,7 +23,7 @@ class EntityDisplayTest extends BrowserTestBase { 'field_test', 'field_ui', 'field_group', - 'field_group_test', + 'field_group_test' ]; /** @@ -157,8 +157,8 @@ public function testHtmlElement() { $this->drupalGet('node/' . $this->node->id()); // Test group ids and classes. - $this->assertTrue($this->xpath("//div[contains(@id, 'wrapper-id')]"), 'Wrapper id set on wrapper div'); - $this->assertTrue($this->xpath("//div[contains(@class, 'test-class')]"), 'Test class set on wrapper div, class="' . $group->group_name . ' test-class'); + $this->assertCount(1, $this->xpath("//div[contains(@id, 'wrapper-id')]"), 'Wrapper id set on wrapper div'); + $this->assertCount(1, $this->xpath("//div[contains(@class, 'test-class')]"), 'Test class set on wrapper div, class="' . $group->group_name . ' test-class'); // Test group label. $this->assertSession()->responseNotContains('<h3><span>' . $data['label'] . '</span></h3>'); @@ -178,8 +178,8 @@ public function testHtmlElement() { field_group_group_save($group); $this->drupalGet('node/' . $this->node->id()); - $this->assertTrue($this->xpath("//div[contains(@class, 'speed-fast')]"), 'Speed class is set'); - $this->assertTrue($this->xpath("//div[contains(@class, 'effect-blink')]"), 'Effect class is set'); + $this->assertCount(1, $this->xpath("//div[contains(@class, 'speed-fast')]"), 'Speed class is set'); + $this->assertCount(1, $this->xpath("//div[contains(@class, 'effect-blink')]"), 'Effect class is set'); } /** @@ -205,8 +205,8 @@ public function testFieldset() { $this->drupalGet('node/' . $this->node->id()); // Test group ids and classes. - $this->assertTrue($this->xpath("//fieldset[contains(@id, 'fieldset-id')]"), 'Correct id set on the fieldset'); - $this->assertTrue($this->xpath("//fieldset[contains(@class, 'test-class')]"), 'Test class set on the fieldset'); + $this->assertCount(1, $this->xpath("//fieldset[contains(@id, 'fieldset-id')]"), 'Correct id set on the fieldset'); + $this->assertCount(1, $this->xpath("//fieldset[contains(@class, 'test-class')]"), 'Test class set on the fieldset'); } /** @@ -264,16 +264,16 @@ public function testTabs() { $this->drupalGet('node/' . $this->node->id()); // Test properties. - $this->assertTrue($this->xpath("//div[contains(@class, 'test-class-wrapper')]"), 'Test class set on tabs wrapper'); - $this->assertTrue($this->xpath("//details[contains(@class, 'test-class-2')]"), 'Test class set on second tab'); + $this->assertCount(1, $this->xpath("//div[contains(@class, 'test-class-wrapper')]"), 'Test class set on tabs wrapper'); + $this->assertCount(1, $this->xpath("//details[contains(@class, 'test-class-2')]"), 'Test class set on second tab'); $this->assertSession()->responseContains('<div class="details-description">description of second tab</div>'); // Test if correctly nested. - $this->assertTrue($this->xpath("//div[contains(@class, 'test-class-wrapper')]//details[contains(@class, 'test-class')]"), 'First tab is displayed as child of the wrapper.'); - $this->assertTrue($this->xpath("//div[contains(@class, 'test-class-wrapper')]//details[contains(@class, 'test-class-2')]"), 'Second tab is displayed as child of the wrapper.'); + $this->assertCount(2, $this->xpath("//div[contains(@class, 'test-class-wrapper')]//details[contains(@class, 'test-class')]"), 'First tab is displayed as child of the wrapper.'); + $this->assertCount(1, $this->xpath("//div[contains(@class, 'test-class-wrapper')]//details[contains(@class, 'test-class-2')]"), 'Second tab is displayed as child of the wrapper.'); // Test if it's a vertical tab. - $this->assertTrue($this->xpath('//div[@data-vertical-tabs-panes=""]'), 'Tabs are shown vertical.'); + $this->assertCount(1, $this->xpath('//div[@data-vertical-tabs-panes=""]'), 'Tabs are shown vertical.'); // Switch to horizontal. $tabs_group->format_settings['direction'] = 'horizontal'; @@ -282,7 +282,7 @@ public function testTabs() { $this->drupalGet('node/' . $this->node->id()); // Test if it's a horizontal tab. - $this->assertTrue($this->xpath('//div[@data-horizontal-tabs-panes=""]'), 'Tabs are shown horizontal.'); + $this->assertCount(1, $this->xpath('//div[@data-horizontal-tabs-panes=""]'), 'Tabs are shown horizontal.'); } /** @@ -338,15 +338,15 @@ public function testAccordion() { $this->drupalGet('node/' . $this->node->id()); // Test properties. - $this->assertTrue($this->xpath("//div[contains(@class, 'test-class-wrapper')]"), 'Test class set on tabs wrapper'); - $this->assertTrue($this->xpath("//div[contains(@class, 'effect-bounceslide')]"), 'Correct effect is set on the accordion'); - $this->assertTrue($this->xpath("//div[contains(@class, 'test-class')]"), 'Accordion item with test-class is shown'); - $this->assertTrue($this->xpath("//div[contains(@class, 'test-class-2')]"), 'Accordion item with test-class-2 is shown'); - $this->assertTrue($this->xpath("//h3[contains(@class, 'field-group-accordion-active')]"), 'Accordion item 2 was set active'); + $this->assertCount(1, $this->xpath("//div[contains(@class, 'test-class-wrapper')]"), 'Test class set on tabs wrapper'); + $this->assertCount(1, $this->xpath("//div[contains(@class, 'effect-bounceslide')]"), 'Correct effect is set on the accordion'); + $this->assertCount(3, $this->xpath("//div[contains(@class, 'test-class')]"), 'Accordion item with test-class is shown'); + $this->assertCount(1, $this->xpath("//div[contains(@class, 'test-class-2')]"), 'Accordion item with test-class-2 is shown'); + $this->assertCount(1, $this->xpath("//h3[contains(@class, 'field-group-accordion-active')]"), 'Accordion item 2 was set active'); // Test if correctly nested. - $this->assertTrue($this->xpath("//div[contains(@class, 'test-class-wrapper')]//div[contains(@class, 'test-class')]"), 'First item is displayed as child of the wrapper.'); - $this->assertTrue($this->xpath("//div[contains(@class, 'test-class-wrapper')]//div[contains(@class, 'test-class-2')]"), 'Second item is displayed as child of the wrapper.'); + $this->assertCount(2, $this->xpath("//div[contains(@class, 'test-class-wrapper')]//div[contains(@class, 'test-class')]"), 'First item is displayed as child of the wrapper.'); + $this->assertCount(1, $this->xpath("//div[contains(@class, 'test-class-wrapper')]//div[contains(@class, 'test-class-2')]"), 'Second item is displayed as child of the wrapper.'); } } diff --git a/web/modules/field_group/tests/src/Functional/FieldGroupTestTrait.php b/web/modules/field_group/tests/src/Functional/FieldGroupTestTrait.php index 563ec92cd148c89925113e002f775cb169a95d18..a4c2d7776502bbd1503636b716ece2c9f9a7077f 100644 --- a/web/modules/field_group/tests/src/Functional/FieldGroupTestTrait.php +++ b/web/modules/field_group/tests/src/Functional/FieldGroupTestTrait.php @@ -23,7 +23,7 @@ trait FieldGroupTestTrait { * @param array $data * Data for the field group. * - * @return \stdClass + * @return object * An object that represents the field group. */ protected function createGroup($entity_type, $bundle, $context, $mode, array $data) { @@ -34,7 +34,11 @@ protected function createGroup($entity_type, $bundle, $context, $mode, array $da $data['format_settings'] += Drupal::service('plugin.manager.field_group.formatters')->getDefaultSettings($data['format_type'], $context); - $group_name = 'group_' . mb_strtolower($this->randomMachineName()); + $group_name_without_prefix = isset($data['group_name']) && is_string($data['group_name']) + ? preg_replace('/^group_/', '', $data['group_name']) + : mb_strtolower($this->randomMachineName()); + + $group_name = 'group_' . $group_name_without_prefix; $field_group = (object) [ 'group_name' => $group_name, diff --git a/web/modules/field_group/tests/src/FunctionalJavascript/HorizontalTabsLabelsTest.php b/web/modules/field_group/tests/src/FunctionalJavascript/HorizontalTabsLabelsTest.php new file mode 100644 index 0000000000000000000000000000000000000000..8c6701fc17332c7693adc0226078c529943f8636 --- /dev/null +++ b/web/modules/field_group/tests/src/FunctionalJavascript/HorizontalTabsLabelsTest.php @@ -0,0 +1,288 @@ +<?php + +namespace Drupal\Tests\field_group\FunctionalJavascript; + +use Drupal\Core\Extension\Exception\UnknownExtensionException; +use Drupal\Core\Extension\ThemeInstallerInterface; +use Drupal\Core\Url; +use Drupal\field\FieldStorageConfigInterface; +use Drupal\FunctionalJavascriptTests\WebDriverTestBase; +use Drupal\Tests\field_group\Functional\FieldGroupTestTrait; + +/** + * Tests horizontal tabs labels. + * + * @group field_group + */ +class HorizontalTabsLabelsTest extends WebDriverTestBase { + + use FieldGroupTestTrait; + + /** + * {@inheritdoc} + */ + protected $defaultTheme = 'stark'; + + /** + * Modules to enable. + * + * @var array + */ + public static $modules = [ + 'block', + 'field_group', + 'node', + 'user', + ]; + + /** + * The themes to test with. + * + * @var string[] + */ + protected $themeList = [ + 'bartik', + 'claro', + 'classy', + 'seven', + 'stable', + 'stable9', + 'stark', + ]; + + /** + * The themes that are shipped with block configurations. + * + * @var string[] + */ + protected $themesWithBlocks = [ + 'claro', + ]; + + /** + * The webassert session. + * + * @var \Drupal\Tests\WebAssert + */ + protected $assertSession; + + /** + * The page element. + * + * @var \Behat\Mink\Element\DocumentElement + */ + protected $page; + + /** + * The node type used for testing. + * + * @var \Drupal\node\NodeTypeInterface + */ + protected $testNodeType; + + /** + * {@inheritdoc} + */ + public function setUp() { + parent::setUp(); + + $this->assertSession = $this->assertSession(); + $this->page = $this->getSession()->getPage(); + $this->testNodeType = $this->drupalCreateContentType([ + 'type' => 'test_node_bundle', + 'name' => 'Test Node Type', + ]); + + // Add an extra field to the test content type. + $entity_type_manager = $this->container->get('entity_type.manager'); + $field_storage = $entity_type_manager + ->getStorage('field_storage_config') + ->create([ + 'type' => 'string', + 'field_name' => 'test_label', + 'entity_type' => 'node', + ]); + assert($field_storage instanceof FieldStorageConfigInterface); + $field_storage->save(); + + $entity_type_manager->getStorage('field_config') + ->create([ + 'label' => 'Test label', + 'field_storage' => $field_storage, + 'bundle' => $this->testNodeType->id(), + ]) + ->save(); + + $tab1 = [ + 'label' => 'Tab1', + 'group_name' => 'group_tab1', + 'weight' => '1', + 'children' => [ + 0 => 'test_label', + ], + 'format_type' => 'tab', + 'format_settings' => [ + 'label' => 'Tab1', + 'formatter' => 'open', + ], + ]; + $this->createGroup('node', $this->testNodeType->id(), 'form', 'default', $tab1); + $this->createGroup('node', $this->testNodeType->id(), 'view', 'default', $tab1); + + $tab2 = [ + 'label' => 'Tab2', + 'group_name' => 'group_tab2', + 'weight' => '2', + 'children' => [ + 0 => 'body', + ], + 'format_type' => 'tab', + 'format_settings' => [ + 'label' => 'Tab2', + 'formatter' => 'closed', + ], + ]; + $this->createGroup('node', $this->testNodeType->id(), 'form', 'default', $tab2); + $this->createGroup('node', $this->testNodeType->id(), 'view', 'default', $tab2); + + $horizontal_tabs = [ + 'label' => 'Horizontal tabs', + 'group_name' => 'group_horizontal_tabs', + 'weight' => '-5', + 'children' => [ + 'group_tab1', + 'group_tab2', + ], + 'format_type' => 'tabs', + 'format_settings' => [ + 'direction' => 'horizontal', + 'label' => 'Horizontal tabs', + ], + ]; + $this->createGroup('node', $this->testNodeType->id(), 'form', 'default', $horizontal_tabs); + $this->createGroup('node', $this->testNodeType->id(), 'view', 'default', $horizontal_tabs); + + $entity_type_manager->getStorage('entity_form_display') + ->load(implode('.', [ + 'node', + $this->testNodeType->id(), + 'default', + ])) + ->setComponent('test_label', ['weight' => '1']) + ->save(); + + $entity_type_manager->getStorage('entity_view_display') + ->load(implode('.', [ + 'node', + $this->testNodeType->id(), + 'default', + ])) + ->setComponent('test_label', ['weight' => '1']) + ->save(); + } + + /** + * Tests horizontal tabs labels. + * + * @dataProvider providerTestHorizontalTabsLabels + */ + public function testHorizontalTabsLabels(string $theme_name) { + if ($theme_name !== $this->defaultTheme) { + $theme_installer = \Drupal::service('theme_installer'); + assert($theme_installer instanceof ThemeInstallerInterface); + try { + $theme_installer->install([$theme_name], TRUE); + } + catch (UnknownExtensionException $ex) { + // Themes might be missing, e.g Drupal 8.x does not have stable9 theme. + $this->pass("The $theme_name theme does not exist in the current test environment."); + return; + } + \Drupal::configFactory() + ->getEditable('system.theme') + ->set('default', $theme_name) + ->set('admin', $theme_name) + ->save(); + } + + if (!in_array($theme_name, $this->themesWithBlocks, TRUE)) { + $this->drupalPlaceBlock('page_title_block', [ + 'region' => 'content', + ]); + $this->drupalPlaceBlock('local_tasks_block', [ + 'region' => 'content', + 'weight' => 1, + ]); + $this->drupalPlaceBlock('local_actions_block', [ + 'region' => 'content', + 'weight' => 2, + ]); + $this->drupalPlaceBlock('system_main_block', [ + 'region' => 'content', + 'weight' => 3, + ]); + } + + $this->drupalLogin($this->rootUser); + + // Actual test: check the node edit page. Tab1 and Tab2 should be present. + $this->drupalGet(Url::fromRoute('node.add', [ + 'node_type' => $this->testNodeType->id(), + ])); + $this->assertHorizontalTabsLabels(); + + // Create a node. + $this->page->fillField('title[0][value]', 'Field Group Horizontal Tabs Test Node'); + $this->page->fillField('Test label', 'Test label'); + $this->assertNotNull($tab2 = $this->page->find('css', '.js .field-group-tabs-wrapper a[href="#edit-group-tab2"]')); + $tab2->click(); + $this->assertSession->waitForElementVisible('css', '[name="body[0][value]"]'); + $this->page->fillField('body[0][value]', 'Donec laoreet imperdiet.'); + $this->page->findButton('edit-submit')->click(); + $this->assertSession->waitForElement('css', 'html.js [data-drupal-messages]'); + $status_message = $this->page->find('css', 'html.js [data-drupal-messages]'); + $this->assertStringContainsString("{$this->testNodeType->label()} Field Group Horizontal Tabs Test Node has been created.", $status_message->getText()); + + // Check the node. + $this->drupalGet(Url::fromRoute('entity.node.canonical', [ + 'node' => '1', + ])); + $this->assertHorizontalTabsLabels(); + + $this->drupalLogout(); + + // Retest the node with anonymous user. + $this->drupalGet(Url::fromRoute('entity.node.canonical', [ + 'node' => '1', + ])); + $this->assertHorizontalTabsLabels(); + } + + /** + * Asserts the horizontal tabs labels. + */ + protected function assertHorizontalTabsLabels() { + $this->assertSession->waitForElement('css', '.js .field-group-tabs-wrapper a[href="#edit-group-tab1"]'); + $this->assertSession->waitForElement('css', '.js .field-group-tabs-wrapper a[href="#edit-group-tab2"]'); + $this->assertNotNull($tab1 = $this->page->find('css', '.js .field-group-tabs-wrapper a[href="#edit-group-tab1"]')); + $this->assertStringContainsString('Tab1', $tab1->getText()); + $this->assertNotNull($tab2 = $this->page->find('css', '.js .field-group-tabs-wrapper a[href="#edit-group-tab2"]')); + $this->assertStringContainsString('Tab2', $tab2->getText()); + } + + /** + * Data provider for testHorizontalTabsLabels. + * + * @return string[][][] + * The test cases with the theme machine names. + */ + public function providerTestHorizontalTabsLabels() { + return array_reduce($this->themeList, function (array $carry, string $theme_name) { + $carry[$theme_name] = [ + 'theme_name' => $theme_name, + ]; + return $carry; + }, []); + } + +} diff --git a/web/modules/views_autocomplete_filters/composer.json b/web/modules/views_autocomplete_filters/composer.json new file mode 100644 index 0000000000000000000000000000000000000000..381cb35c1fbfffbe65c099369af8b2becba25bbe --- /dev/null +++ b/web/modules/views_autocomplete_filters/composer.json @@ -0,0 +1,13 @@ +{ + "name": "drupal/views_autocomplete_filters", + "description": "Add autocomplete functionality to the views filter text fields.", + "type": "drupal-module", + "keywords": ["Drupal", "views_autocomplete_filters"], + "homepage": "https://www.drupal.org/project/views_autocomplete_filters", + "support": { + "issues": "https://www.drupal.org/project/issues/views_autocomplete_filters" + }, + "require": { + "drupal/core": "^8 || ^9" + } +} diff --git a/web/modules/views_autocomplete_filters/js/views-autocomplete-filters-dependent.js b/web/modules/views_autocomplete_filters/js/views-autocomplete-filters-dependent.js index 9e81b71b4cbc4d0c551a766ddc732b75f70c315c..79fb745b48850730f39b319a3201e4dfe3d128e1 100644 --- a/web/modules/views_autocomplete_filters/js/views-autocomplete-filters-dependent.js +++ b/web/modules/views_autocomplete_filters/js/views-autocomplete-filters-dependent.js @@ -149,7 +149,13 @@ if (Drupal.isDependent(this.element)) { var a = Drupal.serializeOuterForm(this.element); $.each(a, function (key, value) { - data_string.data[value['name']] = value['value']; + // We should have an array of values for element with multi values. + if (value['name'].indexOf('[]') > -1) { + if (!data_string.data[value['name']]) data_string.data[value['name']] = [] + data_string.data[value['name']].push(value['value']); + } else { + data_string.data[value['name']] = value['value']; + } }); } var options = $.extend(data_string, autocomplete.ajax); diff --git a/web/modules/views_autocomplete_filters/src/Controller/ViewsAutocompleteFiltersController.php b/web/modules/views_autocomplete_filters/src/Controller/ViewsAutocompleteFiltersController.php index 5d7fc54da2f7ee25d9e5c7de1a2bbbf710dddb13..5458b6c7cddb427e70652fefcc095aaeec9cc154 100644 --- a/web/modules/views_autocomplete_filters/src/Controller/ViewsAutocompleteFiltersController.php +++ b/web/modules/views_autocomplete_filters/src/Controller/ViewsAutocompleteFiltersController.php @@ -4,8 +4,11 @@ use Drupal\Component\Utility\Html; use Drupal\Component\Utility\Unicode; +use Drupal\Component\Utility\Xss; use Drupal\Core\Access\AccessResult; use Drupal\Core\DependencyInjection\ContainerInjectionInterface; +use Drupal\views\Plugin\views\display\DisplayPluginBase; +use Drupal\views\ViewExecutable; use Drupal\views\Views; use Psr\Log\LoggerInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -165,15 +168,9 @@ public function autocomplete(Request $request, $view_name, $view_display, $filte return new JsonResponse($matches); } } + // Collect exposed filter values and set them to the view. - if (!empty($expose_options['autocomplete_dependent'])) { - $exposed_input = $view->getExposedInput() ; - } - else { - $exposed_input = []; - } - $exposed_input[$expose_options['identifier']] = $string; - $view->setExposedInput($exposed_input); + $view->setExposedInput($this->getExposedInput($view, $request, $expose_options)); // Disable cache for view, because caching autocomplete is a waste of time and memory. $display_handler->setOption('cache', ['type' => 'none']); @@ -207,11 +204,11 @@ public function autocomplete(Request $request, $view_name, $view_display, $filte $view->row_index = 0; foreach ($view->result as $index => $row) { $view->row_index = $index; - $rendered_field = $raw_field = ''; /** @var \Drupal\views\Plugin\views\style\StylePluginBase $style_plugin */ $style_plugin = $display_handler->getPlugin('style'); foreach ($field_names as $field_name) { + $rendered_field = $raw_field = ''; // Render field only if suggestion or dropdown item not in RAW format. if (!$use_raw_suggestion || !$use_raw_dropdown) { $rendered_field = $style_plugin->getField($index, $field_name); @@ -231,21 +228,28 @@ public function autocomplete(Request $request, $view_name, $view_display, $filte } } - if (empty($raw_field)) { + if (empty($raw_field) && !empty($rendered_field)) { $raw_field = [['value' => $rendered_field]]; } - foreach ($raw_field as $delta => $item) { - if (isset($item['value']) && strstr(Unicode::strtolower($item['value']), Unicode::strtolower($string))) { - $dropdown = $use_raw_dropdown ? Html::escape($item['value']) : $rendered_field; - if ($dropdown != '') { - $suggestion = $use_raw_suggestion ? Html::escape($item['value']) : $rendered_field; - $suggestion = Html::decodeEntities($suggestion); + if (is_array($raw_field)) { + foreach ($raw_field as $delta => $item) { + if (isset($item['value']) && strstr(mb_strtolower($item['value']), mb_strtolower($string))) { + $dropdown = $use_raw_dropdown ? Html::escape($item['value']) : $rendered_field; + if ($dropdown != '') { + if ($use_raw_suggestion) { + $suggestion = Unicode::truncate(Html::escape($item['value']), 128); + } + else { + $suggestion = Unicode::truncate(Xss::filter($rendered_field, []), 128); + } + $suggestion = Html::decodeEntities($suggestion); - // Add a class wrapper for a few required CSS overrides. - $matches[] = [ - 'value' => $suggestion, - 'label' => $dropdown, - ]; + // Add a class wrapper for a few required CSS overrides. + $matches[] = [ + 'value' => $suggestion, + 'label' => $dropdown, + ]; + } } } } @@ -264,4 +268,41 @@ public function autocomplete(Request $request, $view_name, $view_display, $filte return new JsonResponse($matches); } + /** + * Collect exposed filter values for setting them to the view. + * + * @param \Drupal\views\ViewExecutable $view + * The view. + * @param \Symfony\Component\HttpFoundation\Request $request + * The request. + * @param array $expose_options + * The options for the exposed filter. + * + * @return array|string[] + * The exposed input. + */ + protected function getExposedInput(ViewExecutable $view, Request $request, array $expose_options) { + $display_handler = $view->display_handler; + $filters = $display_handler->getOption('filters'); + + if (!empty($expose_options['autocomplete_dependent'])) { + $exposed_input = $view->getExposedInput(); + } + else { + $exposed_input = []; + // Need to reset the default values for exposed filters. + foreach ($display_handler->getOption('filters') as $name => $filter) { + if (!empty($filters[$name]['exposed'])) { + if (!empty($filter['is_grouped'])) { + $filters[$name]['group_info']['default_group'] = 'All'; + } + $filters[$name]['value'] = []; + } + } + $display_handler->setOption('filters', $filters); + } + $exposed_input[$expose_options['identifier']] = $request->query->get('q'); + return $exposed_input; + } + } diff --git a/web/modules/views_autocomplete_filters/src/Plugin/views/filter/ViewsAutocompleteFiltersTrait.php b/web/modules/views_autocomplete_filters/src/Plugin/views/filter/ViewsAutocompleteFiltersTrait.php index f737d3e3e73825e878c9dd2c3f41f0bc5fea8d28..8888157c10ce52532cad02b08183b1944563e1c7 100644 --- a/web/modules/views_autocomplete_filters/src/Plugin/views/filter/ViewsAutocompleteFiltersTrait.php +++ b/web/modules/views_autocomplete_filters/src/Plugin/views/filter/ViewsAutocompleteFiltersTrait.php @@ -36,83 +36,105 @@ public function defineOptions() { public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - if ($this->canExpose() && !empty($form['expose'])) { - $field_options_all = $this->view->display_handler->getFieldLabels(); - // Limit options to fields with the same name. - /** @var \Drupal\views\Plugin\views\field\FieldHandlerInterface $handler */ - foreach ($this->view->display_handler->getHandlers('field') as $id => $handler) { - if ($handler->field == $this->realField) { - $field_options[$id] = $field_options_all[$id]; - } - } - if (empty($field_options)) { - $field_options[''] = $this->t('Add some fields to view'); - } - elseif (empty($this->options['expose']['autocomplete_field']) && !empty($field_options[$this->options['id']])) { - $this->options['expose']['autocomplete_field'] = $this->options['id']; - } + if (!$this->canExpose() || empty($form['expose'])) { + return; + } + + $field_options = $this->getFieldOptions(); + if (empty($this->options['expose']['autocomplete_field']) && !empty($field_options[$this->options['id']])) { + $this->options['expose']['autocomplete_field'] = $this->options['id']; + } + + // Build form elements for the right side of the exposed filter form. + $states = [ + 'visible' => [' + :input[name="options[expose][autocomplete_filter]"]' => ['checked' => TRUE], + ], + ]; + $form['expose'] += [ + 'autocomplete_filter' => [ + '#type' => 'checkbox', + '#title' => $this->t('Use Autocomplete'), + '#default_value' => $this->options['expose']['autocomplete_filter'], + '#description' => $this->t('Use Autocomplete for this filter.'), + ], + 'autocomplete_items' => [ + '#type' => 'number', + '#title' => $this->t('Maximum number of items in Autocomplete'), + '#default_value' => $this->options['expose']['autocomplete_items'], + '#description' => $this->t('Enter 0 for no limit.'), + '#min' => 0, + '#states' => $states, + ], + 'autocomplete_min_chars' => [ + '#type' => 'number', + '#title' => $this->t('Minimum number of characters to start filter'), + '#default_value' => $this->options['expose']['autocomplete_min_chars'], + '#min' => 0, + '#states' => $states, + ], + 'autocomplete_dependent' => [ + '#type' => 'checkbox', + '#title' => $this->t('Suggestions depend on other filter fields'), + '#default_value' => $this->options['expose']['autocomplete_dependent'], + '#description' => $this->t('Autocomplete suggestions will be filtered by other filter fields'), + '#states' => $states, + ], + 'autocomplete_field' => [ + '#type' => 'select', + '#title' => $this->t('Field with autocomplete results'), + '#default_value' => $this->options['expose']['autocomplete_field'], + '#options' => $field_options, + '#description' => $this->t('Selected field will be used for dropdown results of autocomplete. In most cases it should be the same field you use for filter.'), + '#states' => $states, + ], + 'autocomplete_raw_dropdown' => [ + '#type' => 'checkbox', + '#title' => $this->t('Unformatted dropdown'), + '#default_value' => $this->options['expose']['autocomplete_raw_dropdown'], + '#description' => $this->t('Use unformatted data from database for dropdown list instead of field formatter result. Value will be printed as plain text.'), + '#states' => $states, + ], + 'autocomplete_raw_suggestion' => [ + '#type' => 'checkbox', + '#title' => $this->t('Unformatted suggestion'), + '#default_value' => $this->options['expose']['autocomplete_raw_suggestion'], + '#description' => $this->t('The same as above, but for suggestion (text appearing inside textfield when item is selected).'), + '#states' => $states, + ], + ]; + if (!$this->hasAutocompleteFieldSelector()) { + unset($form['expose']['autocomplete_field']); + } + } - // Build form elements for the right side of the exposed filter form. - $states = [ - 'visible' => [' - :input[name="options[expose][autocomplete_filter]"]' => ['checked' => TRUE], - ], - ]; - $form['expose'] += [ - 'autocomplete_filter' => [ - '#type' => 'checkbox', - '#title' => $this->t('Use Autocomplete'), - '#default_value' => $this->options['expose']['autocomplete_filter'], - '#description' => $this->t('Use Autocomplete for this filter.'), - ], - 'autocomplete_items' => [ - '#type' => 'textfield', - '#title' => $this->t('Maximum number of items in Autocomplete'), - '#default_value' => $this->options['expose']['autocomplete_items'], - '#description' => $this->t('Enter 0 for no limit.'), - '#states' => $states, - ], - 'autocomplete_min_chars' => [ - '#type' => 'textfield', - '#title' => t('Minimum number of characters to start filter'), - '#default_value' => $this->options['expose']['autocomplete_min_chars'], - '#element_validate' => ['element_validate_integer'], - '#states' => $states, - ], - 'autocomplete_dependent' => [ - '#type' => 'checkbox', - '#title' => $this->t('Suggestions depend on other filter fields'), - '#default_value' => $this->options['expose']['autocomplete_dependent'], - '#description' => $this->t('Autocomplete suggestions will be filtered by other filter fields'), - '#states' => $states, - ], - 'autocomplete_field' => [ - '#type' => 'select', - '#title' => $this->t('Field with autocomplete results'), - '#default_value' => $this->options['expose']['autocomplete_field'], - '#options' => $field_options, - '#description' => $this->t('Selected field will be used for dropdown results of autocomplete. In most cases it should be the same field you use for filter.'), - '#states' => $states, - ], - 'autocomplete_raw_dropdown' => [ - '#type' => 'checkbox', - '#title' => $this->t('Unformatted dropdown'), - '#default_value' => $this->options['expose']['autocomplete_raw_dropdown'], - '#description' => $this->t('Use unformatted data from database for dropdown list instead of field formatter result. Value will be printed as plain text.'), - '#states' => $states, - ], - 'autocomplete_raw_suggestion' => [ - '#type' => 'checkbox', - '#title' => $this->t('Unformatted suggestion'), - '#default_value' => $this->options['expose']['autocomplete_raw_suggestion'], - '#description' => $this->t('The same as above, but for suggestion (text appearing inside textfield when item is selected).'), - '#states' => $states, - ], - ]; - if (!$this->hasAutocompleteFieldSelector()) { - unset($form['expose']['autocomplete_field']); + /** + * Fetches the autocomplete field options. + * + * @return array + * The list of options. + */ + protected function getFieldOptions() { + $field_options = []; + + // Limit options to fields with the same name. + /** @var \Drupal\views\Plugin\views\field\FieldHandlerInterface $handler */ + foreach ($this->view->display_handler->getHandlers('field') as $id => $handler) { + if (in_array($this->realField, [ + $handler->field, + $handler->field . '_value', + $handler->realField . '_value', + ])) { + $field_options_all = $this->view->display_handler->getFieldLabels(); + $field_options[$id] = $field_options_all[$id]; } } + + if (empty($field_options)) { + $field_options[''] = $this->t('Add some fields to view'); + } + + return $field_options; } public function valueForm(&$form, FormStateInterface $form_state) { diff --git a/web/modules/views_autocomplete_filters/views_autocomplete_filters.info.yml b/web/modules/views_autocomplete_filters/views_autocomplete_filters.info.yml index 0b096a291a2fb35b2fee950853cdff7df8a7503b..1442c29c7847a00960e9965cb2f18aa25562bb49 100644 --- a/web/modules/views_autocomplete_filters/views_autocomplete_filters.info.yml +++ b/web/modules/views_autocomplete_filters/views_autocomplete_filters.info.yml @@ -2,15 +2,15 @@ name: Views Autocomplete Filters type: module description: 'Use Autocomplete for string field filters.' package: Views -# core: 8.x +core: 8.x +core_version_requirement: ^8 || ^9 dependencies: - - views + - drupal:views tags: - views - utility -# Information added by Drupal.org packaging script on 2017-07-15 -version: '8.x-1.2' -core: '8.x' +# Information added by Drupal.org packaging script on 2020-04-17 +version: '8.x-1.3' project: 'views_autocomplete_filters' -datestamp: 1500109745 +datestamp: 1587146332