Skip to content
Snippets Groups Projects
Verified Commit af4109a7 authored by Andreas De Rijcke's avatar Andreas De Rijcke
Browse files

Initial commit.

parents
No related branches found
No related tags found
No related merge requests found
Pipeline #354517 passed
Showing
with 649 additions and 0 deletions
################
# DrupalCI GitLabCI template
#
# Gitlab-ci.yml to replicate DrupalCI testing for Contrib
#
# With thanks to:
# * The GitLab Acceleration Initiative participants
# * DrupalSpoons
################
################
# Guidelines
#
# This template is designed to give any Contrib maintainer everything they need to test, without requiring modification. It is also designed to keep up to date with Core Development automatically through the use of include files that can be centrally maintained.
#
# However, you can modify this template if you have additional needs for your project.
################
################
# Includes
#
# Additional configuration can be provided through includes.
# One advantage of include files is that if they are updated upstream, the changes affect all pipelines using that include.
#
# Includes can be overridden by re-declaring anything provided in an include, here in gitlab-ci.yml
# https://docs.gitlab.com/ee/ci/yaml/includes.html#override-included-configuration-values
################
include:
################
# DrupalCI includes:
# As long as you include this, any future includes added by the Drupal Association will be accessible to your pipelines automatically.
# View these include files at https://git.drupalcode.org/project/gitlab_templates/
################
- project: $_GITLAB_TEMPLATES_REPO
ref: $_GITLAB_TEMPLATES_REF
file:
- '/includes/include.drupalci.main.yml'
# EXPERIMENTAL: For Drupal 7, remove the above line and uncomment the below.
# - '/includes/include.drupalci.main-d7.yml'
- '/includes/include.drupalci.variables.yml'
- '/includes/include.drupalci.workflows.yml'
################
# Pipeline configuration variables
#
# These are the variables provided to the Run Pipeline form that a user may want to override.
#
# Docs at https://git.drupalcode.org/project/gitlab_templates/-/blob/1.0.x/includes/include.drupalci.variables.yml
################
# variables:
# SKIP_ESLINT: '1'
###################################################################################
#
# *
# /(
# ((((,
# /(((((((
# ((((((((((*
# ,(((((((((((((((
# ,(((((((((((((((((((
# ((((((((((((((((((((((((*
# *(((((((((((((((((((((((((((((
# ((((((((((((((((((((((((((((((((((*
# *(((((((((((((((((( .((((((((((((((((((
# ((((((((((((((((((. /(((((((((((((((((*
# /((((((((((((((((( .(((((((((((((((((,
# ,(((((((((((((((((( ((((((((((((((((((
# .(((((((((((((((((((( .(((((((((((((((((
# ((((((((((((((((((((((( ((((((((((((((((/
# (((((((((((((((((((((((((((/ ,(((((((((((((((*
# .((((((((((((((/ /(((((((((((((. ,(((((((((((((((
# *(((((((((((((( ,(((((((((((((/ *((((((((((((((.
# ((((((((((((((, /(((((((((((((. ((((((((((((((,
# (((((((((((((/ ,(((((((((((((* ,(((((((((((((,
# *((((((((((((( .((((((((((((((( ,(((((((((((((
# ((((((((((((/ /((((((((((((((((((. ,((((((((((((/
# ((((((((((((( *(((((((((((((((((((((((* *((((((((((((
# ((((((((((((( ,(((((((((((((..((((((((((((( *((((((((((((
# ((((((((((((, /((((((((((((* /((((((((((((/ ((((((((((((
# ((((((((((((( /((((((((((((/ (((((((((((((* ((((((((((((
# (((((((((((((/ /(((((((((((( ,((((((((((((, *((((((((((((
# (((((((((((((( *(((((((((((/ *((((((((((((. ((((((((((((/
# *((((((((((((((((((((((((((, /(((((((((((((((((((((((((
# ((((((((((((((((((((((((( ((((((((((((((((((((((((,
# .(((((((((((((((((((((((/ ,(((((((((((((((((((((((
# ((((((((((((((((((((((/ ,(((((((((((((((((((((/
# *((((((((((((((((((((( (((((((((((((((((((((,
# ,(((((((((((((((((((((, ((((((((((((((((((((/
# ,(((((((((((((((((((((* /((((((((((((((((((((
# ((((((((((((((((((((((, ,/((((((((((((((((((((,
# ,(((((((((((((((((((((((((((((((((((((((((((((((((((
# .(((((((((((((((((((((((((((((((((((((((((((((
# .((((((((((((((((((((((((((((((((((((,.
# .,(((((((((((((((((((((((((.
#
###################################################################################
@TODO Create proper README file.
INSTALLATION
------------
* Install as you would normally install a contributed Drupal module. Visit
[Installing Modules](https://www.drupal.org/node/1897420) for further
information.
* Apply the Search API using Composer, so the Rendered Item processor will
receive the flag we need to know if Layout Builder is rendering for indexing.
\ No newline at end of file
{
"name": "drupal/search_api_exclude_lb",
"description": "Allow Layout Builder components to be excluded from being indexed.",
"type": "drupal-module",
"keywords": ["Developer Tools","Import and Export","Integrations","Web services"],
"homepage": "https://www.drupal.org/project/sync_clients",
"license": "GPL-2.0-or-later",
"authors": [
{
"name": "Andreas De Rijcke (andreasderijcke)",
"homepage": "https://www.drupal.org/u/andreasderijcke",
"role": "Maintainer"
},
{
"name": "Kris Booghmans",
"homepage": "https://www.drupal.org/u/kriboogh",
"role": "Maintainer"
},
{
"name": "Michael Schuddings (mschudders)",
"homepage": "https://www.drupal.org/u/mschudders",
"role": "Maintainer"
}
],
"support": {
"issues": "https://www.drupal.org/project/issues/search_api_exclude_lb",
"source": "https://git.drupalcode.org/project/search_api_exclude_lb"
},
"require": {
"drupal/search_api": "^1.34"
}
}
\ No newline at end of file
langcode: en
status: false
dependencies:
module:
- media
- system
id: search_api_indexer
label: 'Search API Indexer'
weight: 0
is_admin: false
permissions:
- 'access content'
- 'view media'
diff --git a/src/Plugin/search_api/processor/RenderedItem.php b/src/Plugin/search_api/processor/RenderedItem.php
index efdf8fa0..a8daaef6 100644
--- a/src/Plugin/search_api/processor/RenderedItem.php
+++ b/src/Plugin/search_api/processor/RenderedItem.php
@@ -192,7 +192,7 @@ class RenderedItem extends ProcessorPluginBase {
// Change the current user to our dummy implementation to ensure we are
// using the configured roles.
$this->getAccountSwitcher()
- ->switchTo(new UserSession(['roles' => array_values($roles)]));
+ ->switchTo(new UserSession(['roles' => array_values($roles), 'search_api_processor' => 'rendered_item']));
$datasource_id = $item->getDatasourceId();
$datasource = $item->getDatasource();
parameters:
ignoreErrors:
-
message: "#^Function search_api_exclude_lb_block_alter\\(\\) has parameter \\$definitions with no value type specified in iterable type array\\.$#"
count: 1
path: search_api_exclude_lb.module
-
message: "#^Method Drupal\\\\search_api_exclude_lb\\\\Form\\\\SettingsForm\\:\\:buildForm\\(\\) has parameter \\$form with no value type specified in iterable type array\\.$#"
count: 1
path: src/Form/SettingsForm.php
-
message: "#^Method Drupal\\\\search_api_exclude_lb\\\\Form\\\\SettingsForm\\:\\:buildForm\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
path: src/Form/SettingsForm.php
-
message: "#^Method Drupal\\\\search_api_exclude_lb\\\\Form\\\\SettingsForm\\:\\:getEditableConfigNames\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
path: src/Form/SettingsForm.php
-
message: "#^Method Drupal\\\\search_api_exclude_lb\\\\Form\\\\SettingsForm\\:\\:submitForm\\(\\) has parameter \\$form with no value type specified in iterable type array\\.$#"
count: 1
path: src/Form/SettingsForm.php
# Configuration file for PHPStan static code checking, see https://phpstan.org.
includes:
- phpstan-baseline.neon
- phar://phpstan.phar/conf/bleedingEdge.neon
parameters:
level: 7
treatPhpDocTypesAsCertain: false
ignoreErrors:
name: Search API Exclude - Layout Builder
description: Allow Layout Builder components to be excluded from being indexed.
type: module
core_version_requirement: ^10 || ^11
package: Search
dependencies:
- drupal:layout_builder
- search_api:search_api
search_api_exclude_lb:
title: Search API Exclude LB
route_name: search_api_exclude_lb.settings
parent: system.admin_config_search
<?php
/**
* @file
* Module hooks.
*/
declare(strict_types=1);
use Drupal\search_api_exclude_lb\SearchApiExcludeLb;
/**
* Implements hook_block_alter().
*/
function search_api_exclude_lb_block_alter(array &$definitions): void {
// @todo Fetch from module config.
$plugin_ids = [];
SearchApiExcludeLb::excludeByPluginId($plugin_ids, $definitions);
// @todo Fetch from module config.
$plugin_ids = [];
SearchApiExcludeLb::excludeByRegex($plugin_ids, $definitions);
}
administer search_api_exclude_lb:
title: Administer module configuration
use debug mode:
title: Use debug mode
search_api_exclude_lb.settings:
path: '/admin/config/search/search-api-exclude-lb'
defaults:
_form: '\Drupal\search_api_exclude_lb\Form\SettingsForm'
_title: 'Search API Exclude LB'
requirements:
_permission: 'administer search_api_exclude_lb+use debug mode'
\ No newline at end of file
services:
search_api_exclude_lb.helper:
class: Drupal\search_api_exclude_lb\SearchApiExcludeLb
arguments:
- '@state'
search_api_exclude_lb.render_block_component_subscriber:
class: Drupal\search_api_exclude_lb\EventSubscriber\BlockComponentExclude
arguments:
- '@current_user'
- '@search_api_exclude_lb.helper'
tags:
- { name: event_subscriber }
<?php
declare(strict_types=1);
namespace Drupal\search_api_exclude_lb\EventSubscriber;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\layout_builder\Event\SectionComponentBuildRenderArrayEvent;
use Drupal\layout_builder\LayoutBuilderEvents;
use Drupal\search_api_exclude_lb\SearchApiExcludeLbInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Removes render array during indexing if applicable.
*/
final class BlockComponentExclude implements EventSubscriberInterface {
/**
* Whether debug mode is enabled.
*
* @var bool
*/
protected bool $debug;
/**
* Constructor.
*
* @param \Drupal\Core\Session\AccountProxyInterface $currentUser
* The current user.
* @param \Drupal\search_api_exclude_lb\SearchApiExcludeLbInterface $helper
* Our helper service.
*/
public function __construct(
protected AccountProxyInterface $currentUser,
protected SearchApiExcludeLbInterface $helper,
) {
$this->debug = $helper->getDebugMode();
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents(): array {
// We want to run first, so we can prevent unnecessary processing too.
$events[LayoutBuilderEvents::SECTION_COMPONENT_BUILD_RENDER_ARRAY] = [
'onBuildRender',
110,
];
return $events;
}
/**
* When it is a view block during indexing, return empty build.
*
* @param \Drupal\layout_builder\Event\SectionComponentBuildRenderArrayEvent $event
* The section component render event.
*/
public function onBuildRender(SectionComponentBuildRenderArrayEvent $event): void {
$definition = $event->getPlugin()->getPluginDefinition();
$is_flagged = (
// @todo Do we need to support
// \Drupal\Component\Plugin\Definition\PluginDefinitionInterface as well?
// It seems we always get arrays here.
is_array($definition)
&& array_key_exists('search_api_exclude_lb', $definition)
&& $definition['search_api_exclude_lb'] === TRUE);
if ($is_flagged === FALSE) {
return;
}
$cacheableMetadata = new CacheableMetadata();
$cacheableMetadata->addCacheTags($this->helper::getCacheTags());
// Allow our processing only for indexing, or when debug mode is enabled and
// the user has the permission to use/view it.
$account = $this->currentUser->getAccount();
if (property_exists($account, 'search_api_processor')) {
if ($account->search_api_processor === 'rendered_item') {
// Don't cache our manipulations for indexing.
$cacheableMetadata->setCacheMaxAge(0);
$event->addCacheableDependency($cacheableMetadata);
$event->setBuild([]);
// Abort any other processing in the render array we altered.
$event->stopPropagation();
return;
}
}
if ($this->currentUser->hasPermission('use debug mode')) {
$cacheableMetadata->addCacheContexts(['user.permissions']);
$event->addCacheableDependency($cacheableMetadata);
if ($this->debug === TRUE) {
$label = $event->getPlugin()->getPluginId();
if (is_array($definition) && array_key_exists('admin_label', $definition)) {
$label = $definition['admin_label'];
}
$replacement = [
'#type' => 'inline_template',
'#template' => '<div style="padding: 1rem 2rem; background-color: beige">{{ "Skipped for indexing:"|t }} {{ label }}</div>',
'#context' => [
'label' => $label,
],
];
$event->setBuild($replacement);
}
}
}
}
<?php
declare(strict_types=1);
namespace Drupal\search_api_exclude_lb\Form;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\State\StateInterface;
use Drupal\search_api_exclude_lb\SearchApiExcludeLb;
use Drupal\search_api_exclude_lb\SearchApiExcludeLbInterface;
/**
* Defines the form to toggle debug mode.
*/
final class SettingsForm extends ConfigFormBase {
/**
* The State service.
*
* @var \Drupal\Core\State\StateInterface
*/
protected StateInterface $state;
/**
* {@inheritdoc}
*/
public function getFormId(): string {
return 'search_api_exclude_lb_settings_form';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state): array {
$this->setState();
$enabled = $this->state->get(SearchApiExcludeLbInterface::STATE_KEY, FALSE);
$form['state'] = [
'#type' => 'details',
'#title' => $this->t('Debug mode'),
'#description' => $this->t('Replaces all Layout Builder components skipped for indexing with debug info, for all users having permissions to use the debug mode'),
'#open' => $enabled,
];
if ($enabled === FALSE) {
$form['state']['enable'] = [
'#type' => 'submit',
'#button_type' => 'secondary',
'#value' => $this->t('Enable'),
'#submit' => [[$this, 'enableDebugMode']],
'#attributes' => [
'class' => [
'form-item',
],
],
];
}
else {
$form['state']['disable'] = [
'#type' => 'submit',
'#button_type' => 'secondary',
'#value' => $this->t('Disable'),
'#submit' => [[$this, 'disableDebugMode']],
'#attributes' => [
'class' => [
'form-item',
],
],
];
}
return $form;
}
/**
* Disable debug mode.
*/
public function disableDebugMode(): void {
$this->setState();
$this->state->set(SearchApiExcludeLbInterface::STATE_KEY, FALSE);
$this->messenger()->addMessage($this->t('Debug mode disabled.'));
$this->invalidateCacheTags();
}
/**
* Enable debug mode.
*/
public function enableDebugMode(): void {
$this->setState();
$this->state->set(SearchApiExcludeLbInterface::STATE_KEY, TRUE);
$this->messenger()->addMessage($this->t('Debug mode enabled.'));
$this->invalidateCacheTags();
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state): void {}
/**
* {@inheritdoc}
*/
protected function getEditableConfigNames(): array {
return ['search_api_exclude_lb.settings'];
}
/**
* Invalidated render arrays that affect.
*/
protected function invalidateCacheTags(): void {
Cache::invalidateTags(SearchApiExcludeLb::getCacheTags());
}
/**
* Set the State service.
*/
protected function setState(): void {
if (!isset($this->state)) {
// @todo Use DI when we only have to support D11 and we don't have to deal
// with the changed constructor parameters.
// @phpstan-ignore-next-line
$this->state = \Drupal::state();
}
}
}
<?php
declare(strict_types=1);
namespace Drupal\search_api_exclude_lb;
use Drupal\Core\State\StateInterface;
/**
* Default implementation of the helper.
*/
final class SearchApiExcludeLb implements SearchApiExcludeLbInterface {
/**
* Constructor.
*
* @param \Drupal\Core\State\StateInterface $state
* The State service.
*/
public function __construct(protected StateInterface $state) {}
/**
* {@inheritdoc}
*/
public function getDebugMode(): bool {
return $this->state->get(self::STATE_KEY, FALSE);
}
/**
* {@inheritdoc}
*/
public function setDebugMode(bool $debug_mode = FALSE): void {
$this->state->set(self::STATE_KEY, $debug_mode);
}
/**
* {@inheritdoc}
*/
public static function getCacheTags(): array {
return [self::STATE_KEY];
}
/**
* {@inheritdoc}
*/
public static function excludeByPluginId(array $plugin_ids, array &$plugin_definitions): void {
foreach ($plugin_definitions as $id => &$definition) {
if (in_array($id, $plugin_ids, TRUE)) {
$definition['search_api_exclude_lb'] = TRUE;
}
}
}
/**
* {@inheritdoc}
*/
public static function excludeByRegex(array $regex, array &$plugin_definitions): void {
foreach ($plugin_definitions as $id => &$definition) {
foreach ($regex as $expression) {
if (preg_match($expression, $id)) {
$definition['search_api_exclude_lb'] = TRUE;
break;
}
}
}
}
}
<?php
declare(strict_types=1);
namespace Drupal\search_api_exclude_lb;
/**
* Defines our helper class.
*/
interface SearchApiExcludeLbInterface {
/**
* Our state key.
*
* @var string
*/
public const STATE_KEY = 'search_api_exclude_lb';
/**
* Get debug mode state value.
*
* @return bool
* TRUE if debug mode is enabled.
*/
public function getDebugMode(): bool;
/**
* Update the debug mode state.
*
* @param bool $debug_mode
* The new value. Defaults to FALSE.
*/
public function setDebugMode(bool $debug_mode = FALSE): void;
/**
* Get cache tag(s) associated with the renders we want to affect.
*
* @return string[]
* The cache tag(s).
*/
public static function getCacheTags(): array;
/**
* Flag given (Block) plugin IDs to be excluded from search indexing.
*
* @param string[] $plugin_ids
* The (Block) plugin IDs.
* @param array<string, mixed> $plugin_definitions
* All (Block) plugin definitions.
*/
public static function excludeByPluginId(array $plugin_ids, array &$plugin_definitions): void;
/**
* Flag (Block) plugin IDs matching regex to be excluded from search indexing.
*
* @param string[] $regex
* The regular expression.
* @param array<string, mixed> $plugin_definitions
* All (Block) plugin definitions.
*/
public static function excludeByRegex(array $regex, array &$plugin_definitions): void;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment