# Question
Title: Persist query string arguments across all links in a particular menu?
I have a menu "Display Style Switcher" which has two links: Map, and List. You click Map, you get the Map display of search results, and if you click List you get the list display of search results. The List and Map displays are two different displays of the same view.

Both variations of the display results leverage a views exposed form and facets which all share the same query string identifiers.

My requirement is all links in the "Display Style Switcher" menu should inherit the current query string parameters of the request (at least, I think this is the way to go). So, while in the List display and you have activated a few filters (which sets query string arguments), if you switch to the Map display your current result set should be maintained (the same query string arguments are preserved and passed to the List display of the view).

What would be the right approach to implementing this?

# Answer
I ended up solving this by building the tree and menu render array and injecting it into the view template in a preprocess function (this is fired for both displays on the view).

The key point was collecting the query string arguments from the current request and using that to set the query string option for each menu link element in the tree.

```
/**
 * Implements hook_preprocess_HOOK().
 */
function mc_location_explorer_preprocess_views_view__program_location_search_api(&$variables) {
  // Generate the Map/List display menu and inject into the listing and map view
  // templates.
  $menu_name = 'program-search-displays';
  /** @var \Drupal\Core\Menu\MenuLinkTreeInterface $menu_tree */
  $menu_tree = \Drupal::service('menu.link_tree');
  $params = $menu_tree->getCurrentRouteMenuTreeParameters($menu_name);
  $manipulators = [
    ['callable' => 'menu.default_tree_manipulators:checkAccess'],
    ['callable' => 'menu.default_tree_manipulators:generateIndexAndSort'],
  ];
  $tree = $menu_tree->load($menu_name, $params);

  // Attach current requests query string parameters to each display link, in
  // order to preserve the current filters and facets in a user's search.
  $query_params = \Drupal::request()->query->all();
  foreach ($tree as $item) {
    $item->options['query'] = $query_params;
  }
  $tree = $menu_tree->transform($tree, $manipulators);
  $build = $menu_tree->build($tree);
  // Because we attached query string parameters for the current page to each
  // link in the menu, we need to vary the menu's cacheability by query string.
  $build['#cache']['contexts'][] = 'url.query_args';
  $variables['search_display_switcher'] = $build;
}

```
> 1 votes

---
Tags: views, navigation
---


# Question
Title: What does scaffolding files for drupal/core do when I do a composer require <module>?
I noticed that default.settings.php files gets copied to scaffold folder:

Copy \[web-root\]/sites/default/default.settings.php from assets/scaffold/files/default.settings.php

Why is it copying this file to scaffold and what is it the purpose of this?

# Answer
> 3 votes
> The purpose of scaffolding files is to allow Drupal sites to be fully managed by Composer, and still allow individual asset files to be placed in arbitrary locations.

From: https://github.com/drupal/core-composer-scaffold

The reason that `default.settings.php` is copied across is that this file is not part of the Drupal core (the contents of `/web/core`), nor is it part of a module, theme, or distribution. But it's part of a base Drupal installation, so Composer copies it to the correct location upon install.

---
Tags: 9, composer
---


# Question
Title: Dependency injection for FormElement #process callback
Is there any way to inject container services into FormElement callbacks like '#process'? Or do I need to call \Drupal::container()-\>get(..)?

I noticed https://www.drupal.org/docs/8/api/services-and-dependency-injection/dependency-injection-for-a-form, but this is for forms, not for form element types.

# Answer
Dependency injection for any method of a class is done for the whole class. So if you have a dependency for the method you're adding for any method in the class, you will set that as a dependency for the whole class, not just a single function. However, #process callbacks are static functions, and static functions cannot use dependency injection. They should use the `\Drupal::service()` method, which is for static functions and procedural code.
> 3 votes

# Answer
Technically it's possible with the help of ContainerFactoryPluginInterface. The `#process` is just an array of callables, and it's initialized in getInfo() which is non-static. So, you have access to FormElement's `$this` when creating the array of `#process` callbacks. Documentation doesn't seem to put any restrictions on `#process` array, except requiring it to be an array of callables (nothing is said about them to be static). Also, it's not enforced by any interface nor class inherited by FormElement. So, generally, the following is possible:

```
<?php

namespace Drupal\my_module\Element;

use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Render\Element\FormElement;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * @FormElement("my_element")
 */
class MyElement extends FormElement implements ContainerFactoryPluginInterface {
    /**
     * @var MyDependency
     */
    protected $myDependency;

    public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): static {
        return new static(
            $configuration,
            $plugin_id,
            $plugin_definition,
            $container->get('my_dependency')
        );
    }

    public function __construct(array $configuration, $plugin_id, $plugin_definition, MyDependency $my_dependency) {
        parent::__construct($configuration, $plugin_id, $plugin_definition);
        $this->myDependency = $my_dependency;
    }

    public function getInfo() {
        return [
            '#process' => [[$this, 'processMyElement']],
        ];
    }

    public function processMyElement(&$element, FormStateInterface $form_state, &$form) {
        // $this->myDependency available here...
        return $element;
    }
}

```

Unfortunately I haven't found any instance of non-static `#process` method in Drupal's core, so maybe there is a convention, or silent agreement, to not use instance methods as callbacks.
> 1 votes

---
Tags: 8, forms
---


# Question
Title: Is it a bad idea to have more than a custom entity defined in a module?
**Fact #1**

Drush module exposes two commands `drush generate module-content-entity` and `drush generate module-configuration-entity`, both generating new custom modules with entity classes defined. There is no separate command to generate custom entity code for existing module.

**Fact #2**

I could not find the module in Drupal's core, where a single module defines more than one custom entity (Maybe there are some and I have not seen all). There are modules that register content and configuration entities, but not multiple contents or multiple configuration entity (or block or any other).

---

I have a feeling that, even though it's not forbidden, it's not a good idea to have multiple entities in a single module. Maybe it's an architectural pattern.

Can anyone elaborate on this or share some content (docs, articles) where this is discussed?

# Answer
## About Fact #1

You can generate multiple entities for a single module directly with the Chi-teck's Drupal Code Generator.

Require the package:

```
composer require chi-teck/drupal-code-generator --dev

```

If you have the latest Drush version this package is already installed.

Run the command `./vendor/bin/dcg` to display the main navigation:

```
./vendor/bin/dcg
 Select generator
  [ 0] ..
  [ 1] Console
  [ 2] Entity
  [ 3] Form
  [ 4] Miscellaneous
  [ 5] Plugin
  [ 6] Service
  [ 7] Test
  [ 8] Yaml
  [ 9] composer.json
  [10] Controller
  [11] Field
  [12] Hook
  [13] Install file
  [14] Javascript
  [15] Layout
  [16] Module
  [17] Module file
  [18] PhpStorm metadata
  [19] Plugin manager
  [20] Render element
  [21] Service provider
  [22] Template
  [23] Theme
  [24] Theme file
  [25] Theme settings

```

Choose \[16\] to start a new module and then run \[ 2\] twice.

**Edit:**

The current Drush version 11 supports also generating entities separately:

```
drush generate entity:content

```
> 5 votes

# Answer
While Drupal core modules normally implement a single content entity, that isn't a Drupal limit; it is rather the modules that focus on implementing a single functionality and a single entity.

The Aggregator module implements two content entities: the Aggregator feed entity and the Aggregator feed item entity, for example.

```
/**
 * @ContentEntityType(
 *   id = "aggregator_feed",
 *   label = @Translation("Aggregator feed"),
 *   label_collection = @Translation("Aggregator feeds"),
 *   label_singular = @Translation("aggregator feed"),
 *   label_plural = @Translation("aggregator feeds"),
 *   label_count = @PluralTranslation(
 *     singular = "@count aggregator feed",
 *     plural = "@count aggregator feeds",
 *   ),
 *   handlers = {
 *     "storage" = "Drupal\aggregator\FeedStorage",
 *     "storage_schema" = "Drupal\aggregator\FeedStorageSchema",
 *     "view_builder" = "Drupal\aggregator\FeedViewBuilder",
 *     "access" = "Drupal\aggregator\FeedAccessControlHandler",
 *     "views_data" = "Drupal\aggregator\AggregatorFeedViewsData",
 *     "form" = {
 *       "default" = "Drupal\aggregator\FeedForm",
 *       "delete" = "Drupal\aggregator\Form\FeedDeleteForm",
 *       "delete_items" = "Drupal\aggregator\Form\FeedItemsDeleteForm",
 *     },
 *     "route_provider" = {
 *       "html" = "Drupal\aggregator\FeedHtmlRouteProvider",
 *     },
 *   },
 *   links = {
 *     "canonical" = "/aggregator/sources/{aggregator_feed}",
 *     "edit-form" = "/aggregator/sources/{aggregator_feed}/configure",
 *     "delete-form" = "/aggregator/sources/{aggregator_feed}/delete",
 *   },
 *   field_ui_base_route = "aggregator.admin_overview",
 *   base_table = "aggregator_feed",
 *   render_cache = FALSE,
 *   entity_keys = {
 *     "id" = "fid",
 *     "label" = "title",
 *     "langcode" = "langcode",
 *     "uuid" = "uuid",
 *   }
 * )
 */

```

```
/**
 * @ContentEntityType(
 *   id = "aggregator_item",
 *   label = @Translation("Aggregator feed item"),
 *   label_collection = @Translation("Aggregator feed items"),
 *   label_singular = @Translation("aggregator feed item"),
 *   label_plural = @Translation("aggregator feed items"),
 *   label_count = @PluralTranslation(
 *     singular = "@count aggregator feed item",
 *     plural = "@count aggregator feed items",
 *   ),
 *   handlers = {
 *     "storage" = "Drupal\aggregator\ItemStorage",
 *     "storage_schema" = "Drupal\aggregator\ItemStorageSchema",
 *     "view_builder" = "Drupal\aggregator\ItemViewBuilder",
 *     "access" = "Drupal\aggregator\FeedAccessControlHandler",
 *     "views_data" = "Drupal\aggregator\AggregatorItemViewsData"
 *   },
 *   uri_callback = "Drupal\aggregator\Entity\Item::buildUri",
 *   base_table = "aggregator_item",
 *   render_cache = FALSE,
 *   list_cache_tags = { "aggregator_feed_list" },
 *   entity_keys = {
 *     "id" = "iid",
 *     "label" = "title",
 *     "langcode" = "langcode",
 *   }
 * )
 */

```

It's not a bad idea, implementing more than a content entity in a module. I would only avoid implementing content entities that aren't necessary.

As for why Drush creates a new module for each content/configuration entity, as other users said, that is probably to keep the Drush code simple and because usually that's what is done.
> 4 votes

---
Tags: entities
---


# Question
Title: Load css and js assets as absolute paths during twig render
By default, Drupal 8 loads css and js libraries using relative paths.

ie: /core/modules/contextual/css/contextual.module.css

However, because I want to generate static pages to be used by another consumer, how can I have all my libraries as absolute paths instead?

I thought of using the css\_alter hook and my code is below:

```
function rint_css_alter(&$css, \Drupal\Core\Asset\AttachedAssetsInterface $assets) {

    foreach ($css as $key => $value) {
        $assetOriginalPath = $css[$key]["data"];
        $css[$key]["data"] =  "https://coaching.ddev.site/$assetOriginalPath";
    }
    print_r($css);

}

```

When I view the print\_r result, it seems successful.

Result:

However, when I remove the print\_r to view the page, I still see the relative paths for the css assets.

Note: When I used the print\_r, I also saw the following error:

```
The website encountered an unexpected error. Please try again later.<br><em class="placeholder">RuntimeException</em>: Failed to start the session because headers have already been sent

```

Is there a way to make css and js assets load as absolute paths? as in

```
http://example.com/core/modules/contextual/css/contextual.module.css

```

# Answer
> 0 votes
The folwing hook implemention will change the URL's to absolute URL's

```
/**
 * Implements hook_js_alter().
 *
 * Pass the JavaScript array to the optimizer service.
 */
function HOOK_js_alter(&$js, $assets) {
  foreach ($js as $key => $file) {
    $file['data'] = 'http://example.com/' . $file['data'];
    $file['type'] = 'external';
    $js['http://example.com/' . $key] = $file;
    unset($js[$key]);
  }
}

/**
 * Implements hook_js_alter().
 *
 * Pass the JavaScript array to the optimizer service.
 */
function HOOK_css_alter(&$css, $assets) {
  foreach ($css as $key => $file) {
    $file['data'] = 'http://example.com/' . $file['data'];
    $file['type'] = 'external';
    $css['http://example.com/' . $key] = $file;
    unset($css[$key]);
  }
}

```

---
Tags: 8, hooks
---


# Question
Title: How do I print an exposed filter block in a template file?
I have a view with an exposed taxonomy filter. I configured it to be displayed as a separate block so that I can print it another twig template. I tried this.

```
/**
 * Implements hook_preprocess_block() for block.html.twig.
 */
 function themename_preprocess_block(array &$variables) {
   $variables['featured'] = views_embed_view('view_name', 'contextual_filter_block_machine_name');
 }

```

Then I used `{{ featured }}` in the block template, but it doesn't work.

Is there another way to do this?

# Answer
> 0 votes
I used another approach to solve the problem. I overrode the views template to print the exposed filter where I wanted. You can get it as

```
{{ exposed}}

```

in the twig template.

# Answer
> 0 votes
I almost always use the `twig_tweak` module, there is 3 ways to render a block. You can see the doc here Twig tweak Block render, you should probably use

```
drush ev "print_r(array_keys(\Drupal::service('plugin.manager.block')->getDefinitions()));"

```

find your block in the list and then use

```
{{ drupal_block('your_block_id') }}

```

---
Tags: 8, views, theming
---


title: Add paragraph value to referenced node

text:
# Question
Title: Add paragraph value to referenced node
I have a paragraph with two field:

* `Paragraph title` \[text field\]
* `Node` \[entity reference field\]

The node is displaying its title and an image. By default the `Node title` is a H2 heading. But I want it to change based on the existence of the `Paragraph title`.

When the `Paragraph title` is set. The `Paragraph title` should be a H2 and the `Node title` should be a H3. But when the `Paragraph title` field is empty the `Node title` should be surrounded by a H2.

How can this be done?

# Answer
> 0 votes
You probably can use the hook `function template_preprocess_paragraph(&$variables)`.

In the hook function you can test if you are on a the proper paragraph and if you are on a Node object like this :

```
$paragraph_type = $variables['paragraph']->getType();
$node = \Drupal::routeMatch()->getParameter('node');

```

And then from here you can test if your Node has the value you want (the title) and if the paragraph\_type is the correct type and return the good title in `$variables['my_new_title']`.

In twig template of the paragraph, you can then call `{{ my_new_title }}`.

---
Tags: nodes, 9, paragraphs
---


# Question
Title: Configuration import continues to list items as 'importable'
I am developing on a Drupal 9 site. I have found something a bit odd when running `drush cim`. There are a handful of configurations for which it DOES say there was a success, but when you run `drush cim` once again, it still says they are ready for import. Clearly there is something wrong.

I looked at the diff of one of them, and they all seem to be like this.

>

It tries to change the line order.

I tried to manually edit the config in the database `drush config:edit swiftmailer.message` so that active (which is the database) matched staged. However, I once again ran the import, found it was in the same state, and found that when I once again ran `drush config:edit swiftmailer.message`, it was back to the way it was!!

Can someone explain to me how to get out of this circle?

# Answer
This happens, unfortunately. It can happen by a module that was enabled in the past and it changes the configuration but wasn't refreshed by the developer. Most of the time this appears when you resave the config then it becomes visible this kind of problem. Also, one of the core versions changed or added order to the keys, which also caused this. Our team had this issue several times, mostly it can cause similar missing configs when you add an extra field, but if you don't resave all the displays then the extra field is missing from some of the configs and later on, when somebody saves it, it will appear.

In your case most likely that you did the core upgrade but did not save all the configs and exported them at that time so it remained hidden until now.

What I can suggest preventing this in the feature is to create a drush command which loads all the site configs and saves them (without any change) then export and commit. Then when you enable or do an upgrade you run that command and export the changes. This will "prevent" to have such problems later on in the 99% of the cases.

Like this (written by one of my collaguage), but there are some edge cases where this also does not save some of the configs:

```
<?php

declare(strict_types=1);

namespace Drush\Commands;

use Consolidation\AnnotatedCommand\CommandResult;
use Consolidation\SiteAlias\SiteAliasManagerAwareTrait;
use Drush\SiteAlias\SiteAliasManagerAwareInterface;

/**
 * Drush commands.
 *
 * @package Drush\Commands
 */
class Commands extends DrushCommands implements SiteAliasManagerAwareInterface {

  use SiteAliasManagerAwareTrait;

  /**
   * Checks if there is any noise/artifacts in config.
   *
   * Config artifacts is unwanted noise which is not detected by config:status
   * and can appear for some configuration entities after being re-saved
   * (e.g: when the site gets installed from config).
   * Some examples include computed fields or extra fields impacting view modes.
   *
   * @command config-artifacts
   * @aliases ca
   * @bootstrap full
   * @option resave
   *   Re-save all config before comparing.
   *
   * @usage drush config-artifacts
   *   Use this after install-clean.
   *   Detect artifacts without re-saving config (e.g: after clean-install).
   * @usage drush config-artifacts --resave
   *   Use this after install-clone or to resolve existing artifacts (then run
   *   config:export).
   */
  public function configArtifacts($options = ['resave' => FALSE]) {
    if ($options['resave']) {
      $this->resaveConfig();
    }

    $selfRecord = $this->siteAliasManager()->getSelf();

    /** @var \Consolidation\SiteProcess\SiteProcess $process */
    $process = $this->processManager()->drush($selfRecord, 'config-status');
    $process->mustRun();
    $output = $process->getOutput();

    if (!empty($output)) {
      $this->logger()->error(dt('Found config artifacts between DB and sync directory.'));
      return CommandResult::dataWithExitCode($output, self::EXIT_FAILURE);
    }
    else {
      $this->logger()->success(dt('No config artifacts found.'));
    }
  }

  /**
   * Re-Save all config entities.
   */
  protected function resaveConfig() {
    /** @var \Drupal\Core\Config\ConfigManagerInterface $config_manager */
    $config_manager = \Drupal::service('config.manager');
    $config_factory = $config_manager->getConfigFactory();
    $names = $config_manager->getConfigFactory()->listAll();

    foreach ($names as $name) {
      if ($entity_type = $config_manager->getEntityTypeIdByName($name)) {
        if ($config = $config_factory->getEditable($name)) {
          $entity_storage = $config_manager
            ->getEntityTypeManager()
            ->getStorage($entity_type);
          $entity_storage->importUpdate($name, $config, $config);
        }
      }
    }
  }

}

```
> 2 votes

---
Tags: 9, configuration, importing-exporting
---


# Question
Title: How do I fix the The service "sanitize.userfields.commands" has a dependency on a non-existent service "entity.manager" error?
I am running Drush the first time in a Drupal 9 site. I get the following error.

> In CheckExceptionOnInvalidReferenceBehaviorPass.php line 86: The service "sanitize.userfields.commands" has a dependency on a non-existent service "entity.manager".

How can I fix this error?

`drush --version` and `drush cr` work.

# Answer
> 10 votes
As folks (Hudri, leymannx) alluded to in the comments, `entity.manager` was deprecated in Drupal 8 which means it was **removed** in Drupal 9. The project that has the code that's calling `entity.manager` is not ready for Drupal 9 (or at least the version you have installed is not ready for Drupal 9). You may want to look for alternative modules if the one your using isn't ready for Drupal 9.

This one particular error is relatively simple to fix though, you may just need to replace any references to `entity.manager` with references to `entity_type.manager`. This issue on d.o gives a good example of what you may have to do.

As @Jaypan noted in the comments, `entity_type.manager` may not always be the correct replacement. From the *entity.manager* documentation:

> Use \Drupal::entityTypeManager() \[i.e. `entity_type.manager`\] instead in most cases. If the needed method is not on \Drupal\Core\Entity\EntityTypeManagerInterface, see the deprecated \Drupal\Core\Entity\EntityManager to find the correct interface or service.

Note: if this issue is being caused by a contributed package, e.g. a d.o module or theme or other package included by composer, you need to work within that project's issue queue to patch the project instead of updating the files directly in your codebase. At the very least, you'll want to create a local patch in your composer project and configure composer to apply the patch.

# Answer
> 8 votes
Seems like Drush which came with the setup was not fully compatible. I installed it again using the composer using

`composer require drush/drush`

It is working as expected.

Here is updated "require" section looks like in **composer.json**

```
   "require": {
        "composer/installers": "^1.9",
        "drupal/bootstrap_barrio": "^4.28",
        "drupal/bootstrap_sass": "^1.12",
        "drupal/core-composer-scaffold": "^9",
        "drupal/core-project-message": "^9",
        "drupal/core-recommended": "^9",
        "drush/drush": "^10.2"
    },

```

# Answer
> 0 votes
For me the below works, obviously nothing any better than a band-aid fix, but an immediate remedy to a blocker

* rm-rf vendor
* composer install

# Answer
> 0 votes
Error I was facing - The service "sanitize.userfields.commands" has a dependency on a non-existent service "entity.manager".

Drush old version 8

**Updating composer version resolved my issue.**

```
composer require drush/drush

```

After update Drupal version : 11.0.9 command to check drush version `drush version`

---
Tags: drush, 9
---


# Question
Title: How to use helper/private methods with a .module file?
Let's say I use a hook with a lot of code inside. To improve readability and reusability I'd like to use helper/private methods. However, a Drupal *.module* file is not a class.

The idea is to split big methods from this file into more readable and reusable smaller methods.

What is the correct way to call helper/private methods from a Drupal *.module* file?

# Answer
I tend to follow Symfony standards when it comes to helper functions. So I normally add a class under `src/Utils` for helper methods.

Then I create a service for it that I can inject other services to and that itself can be injected everywhere I need it. It can also be used in procedural code (hooks) in `*.module` or `*.theme` files easily.

**web/modules/custom/my\_module/src/Utils/MyHelperFunctions.php**

```
namespace Drupal\my_module\Utils;

/**
 * Class MyHelperFunctions.
 */
class MyHelperFunctions {

  /**
   * The Site path.
   *
   * @var string
   */
  protected $sitePath;

  /**
   * MyHelperFunctions constructor.
   *
   * @param string $site_path
   *   The site path.
   */
  public function __construct($site_path) {
    $this->sitePath = $site_path;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('site.path')
    );
  }

  /**
   * Get current multisite directory name.
   *
   * @return string
   *   The basename of the matching multisite directory.
   */
  public function getMultisiteAlias() {

    $site_path = $this->sitePath;
    $site = explode('/', $site_path);

    return $site[1];
  }

}

```

**web/modules/custom/my\_module/my\_module.services.yml**

```
services:
  my_module.helper_functions:
    class: Drupal\my_module\Utils\MyHelperFunctions
    arguments: ['@site.path']

```

**web/modules/themes/custom/my\_theme/my\_theme.theme**

```
/**
 * Implements template_preprocess_html().
 */
function my_theme_preprocess_html(&$variables) {

  // Add multisite body class.
  $site = \Drupal::service('my_module.helper_functions')->getMultisiteAlias();

  $variables['attributes']['class'][] = 'site-' . $site;
}

```

---

Read more: When should I create a service or a utility function?
> 12 votes

# Answer
For people who prefer to use OOP, instead of using the traditional Drupal hook system, we can use the event system using Hook Event Dispatcher module which dispatches events for several Drupal core hooks.

May be all hooks will be replaced in Drupal as discussed here and here.
> 2 votes

# Answer
In our project we create classes for hooks.

```
/**
 * Implementation of hook xyz.
 */
function my_module_some_hook($arguments) {
  MyHookClass::create(\Drupal::getContainer())->myMethod($arguments);
}

```

In your class you just need to implement `ContainerInjectionInterface`, and you are good to go. You can do anything in OO now, nevertheless you can also write unit tests for it if needed.
> 0 votes

# Answer
I would either put the code in a service, as leymannx said in his answer, or do like two Drupal core modules do: Put the code in a class that is retrieved and instantiated with `\Drupal::service('class_resolver')->getInstanceFromDefinition($class_name)`.

That is what the *Content Moderation* module do in some of its hooks.

```
function content_moderation_entity_base_field_info(EntityTypeInterface $entity_type) {
  return \Drupal::service('class_resolver')
    ->getInstanceFromDefinition(EntityTypeInfo::class)
    ->entityBaseFieldInfo($entity_type);
}

```

```
function content_moderation_entity_update(EntityInterface $entity) {
  return \Drupal::service('class_resolver')
    ->getInstanceFromDefinition(EntityOperations::class)
    ->entityUpdate($entity);
}

```

```
class EntityOperations implements ContainerInjectionInterface {

  // …

  /**
   * Constructs a new EntityOperations object.
   *
   * @param \Drupal\content_moderation\ModerationInformationInterface $moderation_info
   *   Moderation information service.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   Entity type manager service.
   * @param \Drupal\Core\Form\FormBuilderInterface $form_builder
   *   The form builder.
   * @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $bundle_info
   *   The entity bundle information service.
   * @param \Drupal\Core\Routing\RouteBuilderInterface $router_builder
   *   The router builder service.
   */
  public function __construct(ModerationInformationInterface $moderation_info, EntityTypeManagerInterface $entity_type_manager, FormBuilderInterface $form_builder, EntityTypeBundleInfoInterface $bundle_info, RouteBuilderInterface $router_builder) {
    $this->moderationInfo = $moderation_info;
    $this->entityTypeManager = $entity_type_manager;
    $this->formBuilder = $form_builder;
    $this->bundleInfo = $bundle_info;
    $this->routerBuilder = $router_builder;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static($container
      ->get('content_moderation.moderation_information'), $container
      ->get('entity_type.manager'), $container
      ->get('form_builder'), $container
      ->get('entity_type.bundle.info'), $container
      ->get('router.builder'));
  }

  // …

  /**
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The entity that was just saved.
   *
   * @see hook_entity_update()
   */
  public function entityUpdate(EntityInterface $entity) {
    if ($this->moderationInfo->isModeratedEntity($entity)) {
      $this->updateOrCreateFromEntity($entity);
    }
    elseif ($entity instanceof Workflow && $entity->getTypePlugin()->getPluginId() == 'content_moderation') {
      $this->routerBuilder->setRebuildNeeded();
    }
  }

  // …

}

```

The used class can implement `ContainerInjectionInterface` (and `ContainerAwareInterface`); it can use dependency injection like service classes, but it's "lighter" than services classes, since it doesn't need an entry in the .services.yml file to work.
> 0 votes

---
Tags: 8, hooks
---


# Question
Title: Get all parent term taxonomy id and name of vocabulary
I have a vocabulary (*Vehicle*) which contains the following taxonomy terms.

* Maruti
    + Alto
    + Swift
    + Baleno
    + Barazza
* Hundai
    + I10
    + I20
    + Creta
* Tata
    + Nexon
    + Safari
    + Nano

I want to get only the parent taxonomy terms: *Maruti*, *Hundai*, and *Tata*.

I tried the following code, but it doesn't return the expected values.

```
$parent = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadParents($termId);

```

Also the following code didn't work for me.

```
$parents = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadAllParents('termid');

```

# Answer
The methods you are mentioning accept as argument a term ID and return parents of this term.

You can use loadTree() providing the vocabulary name and for the second argument 0 to load the entire tree, but only for one level (third argument):

```
$terms = \Drupal::entityTypeManager()
  ->getStorage('taxonomy_term')->loadTree('vehicle', 0, 1, TRUE);

```
> 2 votes

---
Tags: 8, taxonomy-terms
---


title: Is there a way to use jQuery?

text:
# Question
Title: Is there a way to use jQuery?
I heard Drupal 10 will no longer support jQuery out-of-the-box.

Is there a way to use jQuery in Drupal 10?

My guess would be that adding jQuery to a module's composer.json file would allow jQuery code to continue to function. I know this is not best practice, but large sites might need additional time to transition away from jQuery.

# Answer
**jQuery is still included in Drupal 10.1core.**

If it would be removed in the future you would actually add a libraries file: https://www.drupal.org/docs/creating-custom-modules/adding-assets-css-js-to-a-drupal-module-via-librariesyml

I would fully expect a contributor would share such a module.
> 3 votes

---
Tags: javascript, 10
---


# Question
Title: How can I disable CSS styles from a core module using libraries-override?
I'm trying to disable the CSS styles from the layout discovery module in my theme.info.yml file. I've tried several options, but I can't seem to get it to work. This is what I have now.

```
libraries-override:
  core/layout_discovery:
    css:
      theme:
        core/modules/layout_discovery/layouts/twocol/twocol.css: false

```

The CSS styles can be removed using `stylesheets-remove` at the moment, but that property has been deprecated. It does seem work at the moment, though.

I would like to find the proper way to remove the CSS stules using libraries-override, if I can.

```
stylesheets-remove:
  - core/modules/layout_discovery/layouts/onecol/onecol.css

```

# Answer
Seems you are missing a starting `/` on the full path. And the name of the overriding library looks wrong as well. There's no library `core/layout_discovery`. It must be `layout_discovery/twocol` instead.

```
libraries-override:
  layout_discovery/twocol:
    css:
      theme:
        /core/modules/layout_discovery/layouts/twocol/twocol.css: false

```

Source: Overriding and extending libraries

---

Alternatively, unsetting libraries via `hook_page_attachments_alter()` does the trick as well. Here comes a working code snippet to be placed in your theme's `*.theme` file. Replacy `MYTHEME` with the machine name of your theme.

```
/**
 * Implements hook_page_attachments_alter().
 */
function MYTHEME_page_attachments_alter(array &$attachments) {

  foreach ($attachments['#attached']['library'] as $key => $library) {

    // Install the Devel submodule Kint for debugging.
    // Check all libs:
    // ksm($attachments['#attached']['library']);

    // Here I disable the core base library.
    // Looks pretty ugly afterwards.
    if ($library == 'system/base') {
      unset($attachments['#attached']['library'][$key]);
    }

    // So for you it must be like following.
    // Simply try to find the right name via ksm($library);
    // or the other ksm() command from above.
    if ($library == 'layout_discovery/twocol') {
      unset($attachments['#attached']['library'][$key]);
    }
  }
}

```
> 5 votes

# Answer
I wanted to reduce count of http-requests and unset all unnecessary Drupal core css-files. Finally, this configuration works:

```
libraries-override:
  layout_discovery/onecol: false

```

It should be added in file MY\_THEME\_NAME.info.yml
Do not forget "clear all caches" on 'admin/config/development/performance' page.
> 2 votes

# Answer
It was difficult to identify the correct library to exclude, using hook\_css\_alter made it easy for me to exclude a specific file.

```
function THEME_css_alter(&$css) {
  $cssfile= "core/themes/stable/css/core/vertical-tabs.css";
  if ($css[$cssfile]) {
    unset($css[$cssfile]);
  }
}

```
> 0 votes

---
Tags: 8, theming, .info
---


# Question
Title: Allow to update unpublished node of sub user
I have a site where I work with *main users* and *sub users* (users created by a main user). Using permissions I allow these users to edit other users nodes.

Using a script inside `hook_node_access` I make sure access is only allowed for users that are related to each other.

The stripped version of my code looks something like:

```
hook_node_access(NodeInterface $node, $op, $account){
  if ($op == 'update') {
    $uids = [1,2,3,4] //array of user ids related to each other

    // when node author is not in user id array...forbid access
    return AccessResult::forbiddenIf(!in_array($account->id(), $uids))->cachePerUser()->addCacheableDependency($node);
  }
}

```

This works but when a none author tries to edit a unpublished node I get an error. `The path 'node/x' is either invalid or you do not have access to it.`

What can I do to give a none author update access to a unpublished node?

# Answer
> 0 votes
I discovered that having problems with updating the node is caused by restrictions in viewing the node. Because users are not able to view unpublished nodes of other users it was not possible to update them for some reason.

I changed the view access for these users so they are able to view unpublished nodes of other users and now updating the nodes is possible.

---
Tags: 9
---


# Question
Title: Allow users to add extra products/services in the cart
The idea is to allow users to choose supplemental products right in cart (for example, insurance or assembly). Those are in no way related to main product type items.

I know there is the Commerce Product Add-on module, but there is no need to relate those extra products.

How can I achieve it in Commerce 2?

# Answer
> 1 votes
If the supplemental products have no relationship to the main products, you can create a block that shows the supplemental products and then set that block to be shown on the cart page.

---
Tags: commerce, 9
---


# Question
Title: Using List(text) how not have a default value?
The first entry in the List(text) field is the one that is chosen as the default.

How do we ensure that an item is selected?

The field is

```
Deal Type   field_bond_deal_type    List (text)

```

The widget is 'select list'

The values are:

```
abs|Abs
green|Green

```

There is no blank row at the start.

# Answer
The options are

* change to taxonomy. The taxonomy system allows for 'none' as an option and also requiring that 'none' not be selected
* change the widget to 'checkboxes/radio'

Changing the widget to radio was the option chosen as there are only 3 options and taxonomy is a high overhead for 3 options.
> 0 votes

---
Tags: forms
---


# Question
Title: How do I export numeric data with JSON:API?
All the data exported is formatted with a string. Enclosed with quotes.

I'd like *excluded\_id* to be numeric. The current state is the following.

```
[
 {
  "pending_id": "1234",
  "excluded_id": "111",
}]

```

I'd like the format to be the following.

```
[
 {
  "pending_id": 1234,
  "excluded_id": 111,
}]

```

The JSON service is implemented as a REST plugin. The normalizer is the following.

```
use Drupal\serialization\Normalizer\NormalizerBase;

class CBIBondTableDataNormalizer extends NormalizerBase {
  protected $supportedInterfaceOrClass = 'Drupal\cbi_dms_data\data\model\CBIBondTableResultData';

  public function normalize($object, $format = NULL, array $context = []) {
   return $object->normalize();
  }
}

```

With the normalizer.

```
class MyTableResultData implements MyTableResultType {

  public $row = [];

  public function __construct() {}

  public function addSqlResult($object) {
    $result = new CBIBondTableResult($object);
    $this->row[] = $result;
  }

  public function normalize() {
    $output = [];
    foreach ($this->row as $currentRow) {
      $output[] = (object) $currentRow;
    }
    return $output;
  }
}

```

I've tried setting the type in `MyTableResultData`.

```
public int $PendingID;

```

This doesn't work as PHP 7 doesn't allow something to be an integer or null.

# Answer
Converting the value to integer helps

```
$int_value = intval($value);
if (strval($int_value) == $value) {
  $value = $int_value;
}
$this->$key_camel = $value;

```

I wrote it this way as I was concerned with null. Doesn't seem to be a problem.
> 0 votes

---
Tags: 9
---


title: Twig adding extra spaces around output

text:
# Question
Title: Twig adding extra spaces around output
I am trying to output the label of a node in twig with Quotations around it like this: `<h2>"{{ label }}"</h2>`

The output for some unknown reason though is: `" My Node Title "` with spaces. What I need is: `"My Node Title"`, without spaces.

I have tried both `{{- label -}}` and wrapping it with `{{ spaceless }}` to no avail. I have also tried using `"` but that did not change the output either.

The HTML Structure is showing that the extra spaces are not coming from the label field but is somehow being introduced by twig in some way.

My questions are:

1. Why is this space being introduced?
2. How can I make it stop?

Thank you in advance!

**Edit:**

So in this case, the `label` is a render array and the whitespace is not in the label value anyways. The whitespace is being added *presumably by twig* between the `"` and the `{{`.

Doing `{{ label|trim }}` produces an error that "trim" expects a string although it is an array.

The whitespace is being added somewhere and using trim would simply be undoing something I didn't intend to do. Ideally, I would like to stop the whitespace from happening initially rather than find a way to remove it later.

**Temporary Workaround Edit:**

I discovered that, if in my preprocess function I create a new variable like this:

```
$node->get('title')->getString();
$variables['new_label'] = '"'.$title.'" '

```

and then render the new\_label in twig with: `{{ new_label }}`, then I do not get the spaces.

The question remains though how to do this in twig...

# Answer
These are probably not single space characters but other whitespace or HTML comment tags coming from the title field template. Try first to switch off any debug output, for example Twig debug. If this doesn't help then render the field value directly without the field template:

```
<h2>"{{ node.label }}"</h2>

```

See also How do I get the plain text value for the {{ label }} field in a twig node template?
> 2 votes

# Answer
The trim filter strips whitespace (or other characters) from the beginning and end of a string:

```
{{ '  I like Twig.  '|trim }}

```
> 0 votes

---
Tags: theming
---


# Question
Title: AnnotationException for no apparent reason
This site suddenly is making an AnnotionException. Nothing was changed on the server nor de site itself, just maybe Apache / PHP updates. I tried using different PHP versions, 7.4 / 8.0 / 8.1 but all give the same error.

When I run the site locally on 8.0 or 8.1 there is no error. Can anyone point me in the right direction as to where I should start looking?

Drupal 9.4.0

```
Doctrine\Common\Annotations\AnnotationException: [Semantical Error] The class "Drupal\language\Annotation\LanguageNegotiation" is not annotated with @Annotation. Are you sure this class can be used as annotation? If so, then you need to add @Annotation to the _class_ doc comment of "Drupal\language\Annotation\LanguageNegotiation". If it is indeed no annotation, then you need to add @IgnoreAnnotation("LanguageNegotiation") to the _class_ doc comment of class Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationBrowser. in Doctrine\Common\Annotations\AnnotationException::semanticalError() (line 39 of /home/avascosolar/test/app/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationException.php).

Drupal\Component\Annotation\Doctrine\DocParser->Annotation() (Line: 640)
Drupal\Component\Annotation\Doctrine\DocParser->Annotations() (Line: 338)
Drupal\Component\Annotation\Doctrine\DocParser->parse('/**
 * Class for identifying language from the browser Accept-language HTTP header.
 *
 * @LanguageNegotiation(
 *   id = \Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationBrowser::METHOD_ID,
 *   weight = -2,
 *   name = @Translation("Browser"),
 *   description = @Translation("Language from the browser's language settings."),
 *   config_route_name = "language.negotiation_browser"
 * )
 */', 'class Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationBrowser') (Line: 101)
Drupal\Component\Annotation\Doctrine\SimpleAnnotationReader->getClassAnnotations(Object) (Line: 125)
Drupal\Component\Annotation\Doctrine\SimpleAnnotationReader->getClassAnnotation(Object, 'Drupal\language\Annotation\LanguageNegotiation') (Line: 145)
Drupal\Component\Annotation\Plugin\Discovery\AnnotatedClassDiscovery->getDefinitions() (Line: 86)
Drupal\Component\Plugin\Discovery\DerivativeDiscoveryDecorator->getDefinitions() (Line: 285)
Drupal\Core\Plugin\DefaultPluginManager->findDefinitions() (Line: 175)
Drupal\Core\Plugin\DefaultPluginManager->getDefinitions() (Line: 22)
Drupal\Core\Plugin\DefaultPluginManager->getDefinition('language-url') (Line: 185)
Drupal\language\LanguageNegotiator->negotiateLanguage('language_interface', 'language-url') (Line: 133)
Drupal\language\LanguageNegotiator->initializeType('language_interface') (Line: 218)
Drupal\language\ConfigurableLanguageManager->getCurrentLanguage() (Line: 92)
Drupal\language\EventSubscriber\LanguageRequestSubscriber->setLanguageOverrides() (Line: 74)
Drupal\language\EventSubscriber\LanguageRequestSubscriber->onKernelRequestLanguage(Object, 'kernel.request', Object)
call_user_func(Array, Object, 'kernel.request', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.request') (Line: 134)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 80)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 709)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)

```

# Answer
> 1 votes
If `@Annotation` is missing from the documentation comment for the `Drupal\language\Annotation\LanguageNegotiation`, in the file containing that class, then it's a problem of corrupted files that need to be replaced.

If the documentation comment for that class contains `@Annotation`, then it's a problem with the OPcache settings. If `opcache.save_comments` is disabled, then all documentation comments will be discarded from the opcode cache. As the documentation says, this breaks applications and frameworks that rely on comment parsing for annotations.
In this case, PHP should not even find the `@LanguageNegotiation` annotation.

# Answer
> 1 votes
When I look at my Drupal 9.4.0 code the class "Drupal\language\Annotation\LanguageNegotiation" is annotated with @Annotation:

*web/core/modules/language/src/Annotation/LanguageNegotiation.php*

```
<?php

namespace Drupal\language\Annotation;

use Drupal\Component\Annotation\Plugin;

/**
 * Defines a language negotiation annotation object.
 *
 * Plugin Namespace: Plugin\LanguageNegotiation
 *
 * For a working example, see
 * \Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationBrowser.
 *
 * @see \Drupal\language\LanguageNegotiator
 * @see \Drupal\language\LanguageNegotiationMethodManager
 * @see \Drupal\language\LanguageNegotiationMethodInterface
 * @see hook_language_negotiation_info_alter()
 * @see plugin_api
 *
 * @Annotation
 */
class LanguageNegotiation extends Plugin {

```

So somehow the Drupal code on the server is corrupted and you should download it again or sync it with the local copy.

---
Tags: 9
---


# Question
Title: How can I add CSS variables to the HTML head?
For my site I want to be able to set custom css variables to the sites head. I don't want to add css files just inline css code. In the end I want users to be able to set colors using a color picker. These colors should be translated to the css variables added to the sites head.

For this I looked at the code in the css vars module this brought me a long way. But i'm not able to add css variables in the body of the page.

For this I use `hook_page_top`. But my code now is ending up in the top of the `<body>` and I want it to be in the `<head>`. Strange enough...when I look at the screencast (min 7:35) of the creator of the css vars module I see that his code does get in to the `<head>`.

I simplified the code in my theme\_color module to figure out how it works. So maybe that's the problem? How can I get my css variables in the head of the page?

I have a theme\_color.module:

```
<?php
/**
 * @file
 *   CSS Variables module.
 */

use Drupal\theme_color\Hooks;

/**
 * Implements hook_page_top().
 */
function theme_color_page_top(array &$page_top) {
  Hooks::hookPageTop($page_top);
}

```

I have a Hooks.php just like the example module:

```
<?php

namespace Drupal\theme_color;

class Hooks
{

  public static function hookPageTop(array &$pageTop)
  {
    if ($build = self::makeThemeColorBuild()) {
      $pageTop['theme_color'] = $build;
    }
  }

  private static function makeThemeColorBuild()
  {
    $build = [
      '#type' => 'html_tag',
      '#tag' => 'style',
      '#value' => "html:root {\n--test-var: yellow;\n}",
    ];
    return $build;
  }
}

```

**Update:**

I tried earlier, and again after get the suggestions in comments to use `hook_preprocess_html`

```
function theme_color_preprocess_html(&$variables)
{
  $build = [
    '#tag' => 'style',
    '#value' => "html:root {\n--test-var: pink;\n}",
  ];
  $variables['page']['#attached']['html_head'][] = [$build, '?tag?'];
}

```

This is working but what kind of tag do I need to put after the $build in the $variables line of code??

# Answer
> 2 votes
To do this from `hook_preprocess_html` like in accepted answer to the duplicate question it works like in the snippet below.

```
/**
 * Implements hook_preprocess_HOOK().
 */
function MYMODULE_preprocess_html(&$variables) {
  $style = [
    '#tag' => 'style',
    '#value' => ":root {\n  --test-var: pink;\n}",
  ];
  $variables['page']['#attached']['html_head'][] = [$style, 'foobar-my-id'];
}

```

# Answer
> 0 votes
There is a module for COLOR variables on Drupal. It uses the core color module and has a UI if you need it. https://www.drupal.org/project/css\_color\_variables

---
Tags: theming, 9
---


# Question
Title: How to point phpcbf to the folder standards?
After installing **PHP\_CodeSniffer** on *Kali* with *composer*, I added point phpcs to the folder with standards (Drupal & DrupalPractice) where they are located, to run **CodeSniffer globally by alias** **phpcs**:

> phpcs --config-set installed\_paths ~/.config/composer/vendor/drupal/coder/coder\_sniffer

***Check of standards***:

> phpcs -i

```
The installed coding standards are MySource, PEAR, PSR1, PSR2, PSR12, Squiz, Zend, Drupal, DrupalPractice, VariableAnalysis and SlevomatCodingStandard

```

**Steps:**

1. Try to do the same things for **phpcbf**, doesn't have ***--config-set*** property or something similar to that work.
2. Add alias to the **.zshrc** file, doesn't see the folder with standards.

> phpcbf -i

```
The installed coding standards are Zend, MySource, PSR12, Squiz, PEAR, PSR1 and PSR2

```

Is there another ways to add point to the standards but for **phpcbf**?

Thanks!

# Answer
> 0 votes
Instead of trying to run it globally in a shell, use a Composer script.

For example, this is from my `composer.json`:

```
"scripts": {
    "code-sniff": [
        "./vendor/bin/phpcs --standard=Drupal,DrupalPractice --extensions=php,module,inc,install,test,profile,theme,info,txt,md --ignore=node_modules,bower_components,vendor,*.min.* ./web/modules/custom ./web/themes/custom"
    ],

```

To run this, you can just do `composer code-sniff`. That way, all the paths will be local and all the automatic discovery stuff will work as expected.

If you want a bash alias to run that, you can do something like `alias checkmycode='cd /my/drupal/dir;composer code-sniff'`.

This technique should work for phpcbf as well.

---
Tags: coding-standards
---


# Question
Title: How to render a custom block with variables from another custom block twig template
I have a custom block with some values I can access in the template of that block, for example the `product_type` variable. In the same template file I'm adding another view block with `{{ drupal_block('views_block:my-view-block_1', {product_type: 'clothes'}) }}`.

For that block I implemented this hook.

```
function myModule_views_pre_view(&$view, &$display_id, &$args) {
// I want to access that product_type variable in this hook
// because I want to add a filter.
$view->display_handler->display['display_options']['filters']['field_product_type_target_id']['default_value'] = $product_type;
}

```

The hook is invoked, but I cannot get the value of `product_type`. I'm not sure that is the correct way to achieve it, but I really need to pass that value from first block to second block to filter out results. It's been 2 days I'm trying to figure this out. Any help would be highly appreciated.

# Answer
> 2 votes
Variables are passed from PHP/preprocess to Twig, but ***never*** vice versa.

Instead of preprocessesing the filter of the second block, replace the product type filter in the 2nd views block with a "contextual filter" , and pass `product_type` as contextual argument to the view. And finally - since you are already using Twig Tweak module - use `drupal_view` to render the 2nd views block:

`{{ drupal_view('MY_VIEW_ID', 'MY_VIEWDISPLAY_ID', product_type) }}`

---
Tags: views, blocks, hooks
---


# Question
Title: How to avoid "Access to an undefined property" with text field format in PHPStan?
I have a text field that I am setting inside an entity bundle.

```
  protected function doSomethingAwesome(string $value): void {
    $this->set('field_text', $value);
    $this->field_text->format = 'special_format';
    $this->renderField();
  }

```

PHPStan complained about this: `Access to an undefined property Drupal\Core\Field\FieldItemListInterface::$format.`

So I tried using webmozarts/assert because it's already included with Drupal to assert the property:

```
  protected function doSomethingAwesome(string $value): void {
    Assert::propertyExists($this->field_text, 'format');
    $this->set('field_text', $value);
    $this->field_text->format = 'special_format';
    $this->renderField();
  }

```

This fixes the PHPStan error (after installing phpstan-webmozarts-assert), but the assert fails in production.

I know I could disable this rule, but I already fixed all the errors except this one related to `format`.

How can I tell PHPStan that drupal text field has a `format` property?

**phpstan.neon**

```
parameters:
    checkGenericClassInNonGenericObjectType: false
    level: 8
    paths:
        - web/modules/custom
        - web/themes/custom
    ignoreErrors:
      - '#no value type specified in iterable type array#'
      - '#Thrown exceptions in a catch block must bundle the previous exception#'
includes:
    - vendor/mglaman/phpstan-drupal/extension.neon
    - vendor/thecodingmachine/phpstan-strict-rules/phpstan-strict-rules.neon
    - vendor/phpstan/phpstan-webmozart-assert/extension.neon
    - vendor/phpstan/phpstan-deprecation-rules/rules.neon

```

I realize this question might also be a fit for Stack Overflow, but since this is specifically about handling of Drupal fields and PHPStan is now being used with core, I think it is a better fit here.

# Answer
Actually, this was caused by having a bad type hint on `hook_form_alter()`.

I had accidentally added `FormStateInterface` twice like this:

`mymodule_form_alter(FormStateInterface &$form, FormStateInterface $form_state, string $form_id)`

and it should be:

`mymodule_form_alter(array &$form, FormStateInterface $form_state, string $form_id)`
> 1 votes

---
Tags: testing
---


# Question
Title: How can I fix the "undefined class constant 'insecure_extension_regex' in {closure}()" error?
I'm upgrading some Drupal 8.9 modules and it gave me this error.

> undefined class constant 'insecure\_extension\_regex' in {closure}()

>

>

>

Does anyone know how to fix it?

The only thing I found was to replace line 32 of file.post\_update.php, but it still gives me an error.

# Answer
> 1 votes
The code shown in the third screenshot is part of `file_post_update_add_txt_if_allows_insecure_extensions()`, a post-update hook introduced in Drupal 9.2.

```
// Determine if this field uses an item definition that extends FileItem.
if (is_subclass_of($field->getItemDefinition()->getClass(), FileItem::class)) {
  $allowed_extensions_string = trim($field->getSetting('file_extensions'));
  $allowed_extensions = array_filter(explode(' ', $allowed_extensions_string));
  if (in_array('txt', $allowed_extensions, TRUE)) {
    // Since .txt is specifically allowed, there's nothing to do.
    return FALSE;
  }
  foreach ($allowed_extensions as $extension) {
    // Allow .txt if an insecure extension is allowed.
    if (preg_match(FileSystemInterface::INSECURE_EXTENSION_REGEX, 'test.' . $extension)) {
      $allowed_extensions_string .= ' txt';
      $field->setSetting('file_extensions', $allowed_extensions_string);
      return TRUE;
    }
  }
  return FALSE;
}

```

The `FileSystemInterface::INSECURE_EXTENSION_REGEX` constant has been defined since Drupal 9.2.

I take the site doesn't have the *core/lib/Drupal/Core/File/FileSystemInterface.php* file that comes with Drupal 9, but it still has the file that comes with Drupal 8. It could also be that file is corrupted, and PHP doesn't find that constant.

---
Tags: upgrading
---


# Question
Title: How can I use "drush updb" to pass a value to the hook_update_N() implementation done from a module?
I am trying to `drush updb` with an argument that is passed to the `hook_update_N()` implementation done from a module I wrote, which would use it to execute some update tasks.

```
function my_module_update_9001(&$value) {
  switch ($value) {
    case "unique":
      _set_unique_identifier();
      break;

    case "get":
      _get_field_typ_map();
      break;

    default:
      echo "Something went wrong...";
  }
}

function _set_unique_identifier() {
  _get_database_shame_connector()->uniqueIdentifier();
}

function _get_field_typ_map() {
  _get_database_shame_connector()->getFieldTypeMap();
}

```

How do I tell `drush updb` to pass an argument to an `hook_update_N()` implementation?

# Answer
> 1 votes
It's not possible because `drush updb` doesn't accept a parameter that is passed to `hook_update_N()` implementations, which makes sense, since the only parameter accepted from `hook_update_N()` is an array that allows that hook to use batch operations to run its updates. Passing a different argument to `hook_update_N()` implementations would cause issues with those implementations that use the batch API to run updates.

Even in the case `drush updb` would accept an argument to pass to an update hook and the function name for a `hook_update_N()` implementation, that implementation should be able to understand whether it's called by Drush with a different argument or by Drupal core with the expected argument.

There is a simpler way to execute code that runs after `drush updb`: Implement a post-command hook, as described on How to invoke a post drush command? for example.

```
namespace Drush\Commands;

class PostUpdateCommands extends DrushCommands {

  /**
   * Executes commands right after `drush updatedb`.
   *
   * @hook post-command updatedb
   *
   */
  public function postUpdate() {
    // Your code
  }

}

```

---
Tags: hooks, drush, 9
---


# Question
Title: DrupalDateTime::createFromFormat() returns the wrong time value
I want to get the date of last monday at 00:00:00 in a specific timezone. When I try this:

```
DrupalDateTime::createFromFormat('U', strtotime('last week monday'))->setTime(0, 0, 0)->setTimezone(new \DateTimeZone('America/New_York'))->render()

```

The result is:

```
2022-06-12 20:00:00 America/New_York

```

Which is actually Sunday at 10 PM.

How can I get it to return `2022-06-13 00:00:00 America/New_York` instead?

This "corrects" what I was seeing, but feels wrong:

```
    date_default_timezone_set('America/New_York');
    $from = DrupalDateTime::createFromFormat('U', strtotime('last week monday'))->getTimestamp();
    $to = DrupalDateTime::createFromFormat('U', strtotime('last monday'))->getTimestamp();

```

This gives me:

```
June 13th, 2022 12:00 AM
June 20th, 2022 12:00 AM

```

Which is last week monday through last monday (this week). Is calling -\>format() setting the timezone offset twice, perhaps?

If I format this timestamp using:

```
DrupalDateTime::createFromFormat('U', $returned_value)->format('F j, Y H:i:s e')

```

I get this on the screen:

```
June 13, 2022 04:00:00 +00:00

```

The server is in UTC time. I simply want the timestamp of a date, without offsets applied (but correctly formatted to the user).

Edit:

The objective is to query for entities in Drupal created in the last week (starting on Monday), at midnight (00:00:00) through the following Monday at midnight, in this specific timezone.

# Answer
I can see nothing unexpected. Midnight in UTC is 8 PM the day before in New York, at least in the summer time.

Timestamps are always UTC. This is the reason why your second attempt

```
$from = DrupalDateTime::createFromFormat('U', strtotime('last week monday'))->getTimestamp();

```

can be reduced to

```
$from = strtotime('last week monday');

```

without changing the result.

**Original question**

*How can I get it to return `2022-06-13 00:00:00 America/New_York` instead?*

In this case don't convert to UTC timestamps. You can specify the timezone (the Drupal enhanced DrupalDateTime object accepts the timezone as string) when creating the object:

```
$from = (new DrupalDateTime('last week monday', 'America/New_York'))->render();

```

results in

```
"2022-06-13 00:00:00 America/New_York"

```

Which will internally use a different timestamp than before, but this is only relevant if you convert it to a different timezone, for example to store it in the database or use it in a query against stored values.

**Updated OP in the comments**

*The goal is to query for nodes created Monday to Monday, which only happens in this timezone in EDT.*

The Created field in nodes is a timestamp field, so in this case you need the UTC timestamp:

```
$from = (new DrupalDateTime('last week monday', 'America/New_York'))->getTimestamp();

```

As you have already noticed in the second attempt, using legacy PHP date\_default\_timezone\_set()/strtotime(), this will be indeed 4 hours ahead of New York time.
> 4 votes

# Answer
I tried different snippets, but they all output a time for June 12, not for June 13.

```
echo DrupalDateTime::createFromFormat('U', strtotime('last week monday'), new \DateTimeZone('America/New_York'))
  ->setTime(0, 0, 0)
  ->render(), "\n";
// 2022-06-12 00:00:00 +00:00

```

```
echo DrupalDateTime::createFromFormat('U', strtotime('last week monday'))
  ->setTimezone(new \DateTimeZone('America/New_York'))
  ->setTime(0, 0, 0)
  ->render(), "\n";
// 2022-06-12 00:00:00 America/New_York

```

```
echo DrupalDateTime::createFromTimestamp(strtotime('last week monday'), new \DateTimeZone('America/New_York'))
  ->setTime(0, 0, 0)
  ->render(), "\n";
// 2022-06-12 00:00:00 America/New_York

```

```
echo DrupalDateTime::createFromTimestamp(strtotime('last week monday'), new \DateTimeZone('America/New_York'))
  ->render(), "\n";
// 2022-06-12 18:00:00 America/New_York

```

The only way to get the expected result is to set the default timezone with `date_default_timezone_set()`. In that case, the following code outputs the expected result.

```
date_default_timezone_set('America/New_York');
echo DrupalDateTime::createFromTimestamp(strtotime('last week monday'))->render(), "\n";
// 2022-06-13 00:00:00 America/New_York

```

Notice that isn't necessary to call `setTime(0, 0, 0)`, since `strtotime('last week monday')` returns a timestamp for midnight of last week Monday. (It can be verified with `echo date("F j, Y, g:i a", strtotime("last week monday")), "\n";` which outputs *June 13, 2022, 12:00 am*.)
> 1 votes

# Answer
DrupalDateTime::createFromFormat() is basically a wrapper for PHP's createFromFormat.

A search of the PHP docs reveals this comment:

> createFromFormat('U') has a strange behaviour: it ignores the datetimezone and the resulting DateTime object will always have GMT+0000 timezone.

So, PHP bug or feature, you decide.

To create a DateTime object with a time based on a string, as a general approach:

1. Instantiate the DateTime object with the timezone you want.
2. Change the object's time.

Source: I spent the past two years working on some scheduling software implemented in Drupal that does a lot of date manipulation, and ran into tons of gotchas like this.

**EDIT**

> The objective is to query for entities in Drupal created in the last week (starting on Monday), at midnight (00:00:00) through the following Monday at midnight, in this specific timezone.

Drupal always stores dates in the database as UTC. So if you are doing an EntityQuery, here is one way to do it:

1. Create a DateTime object. Set the timezone to the desired timezone.
2. Set the DateTime to the desired date and time.
3. Change the DateTime's timezone to UTC: `$datetime->setTimeZone(timezone_open(DateTimeItemInterface::STORAGE_TIMEZONE));`
4. Get a proper string from the DateTime: `$datetime->format((DateTimeItemInterface::DATETIME_STORAGE_FORMAT)`.
5. Run the EntityQuery with that string.
> 1 votes

---
Tags: datetime, 9
---


# Question
Title: Image styles - How to resize uploaded images and force an aspect ratio
I'm looking for a solution to resize uploaded images while maintaining a desired aspect ratio instead of cropping them.

We can configure some preset *Image styles*, but it seems we can only :
***Resize :*** Will force an exact set of width/height dimensions which can cause images to be stretched or shrunk disproportionately and loose.
***Scale and crop :*** will maintain the original aspect-ratio of the uploaded image, which can be different from the desired aspect ratio.

So is there a way to force a certain aspect ratio to uploaded images, by adding a white background for instance ?

# Answer
If you want to resize the image while maintaining the desired aspect ratio, this is actually two steps.

1. Get the image in the appropriate aspect ratio.
2. Resize the image.

One way to do this is with the Image Widget Crop module. This module allows you to decide which aspect ratios to crop to.

You can use one or multiple aspect ratios, and you can set which aspect ratios are usable for which image fields.

This adds a "cropping" step when you upload an image to set each required crop. There is an Automated Crop module available that may be able to help do this automatically but I haven't used it.

**Potential dealbreaker**

I do not think it is possible to use Image Widget Crop to set a crop that is larger than the image (to add a white background, for example). Instead, you have to crop the image within the "frame" of the image itself.

**Other modules**

Another module of note in this area is Image Effects, which will give you more scaling and resizing options, as well as many other useful things like adding watermarks.
> 0 votes

---
Tags: 8, media
---


# Question
Title: What is the proper way on submit of a config form to save its fields if #tree = true?
With a config form, when saving the fields in the submit, rather than

```
->set('FIELD NAME', $form_state->getValue('FIELD NAME')

```

how would a form with #tree = true be handled?

For example: $field\[topic1\]\[subtopic\_a\] $field\[topic1\]\[suntopic\_b\]

# Answer
> 1 votes
You can store an array to configuration. So you can almost use the code you provided. You could do something like:

```
->set('FIELD NAME', $form_state->getValue(['field_name']);

```

Where `field_name` is the key of the element that has had `#tree` set to it, containing child elements.

---
Tags: forms
---


# Question
Title: How can I add Composer to an existing site?
I have a site running on Drupal 9.3.15 installed from the zip file.

I want to use composer and I followed \[Add Composer to an existing site, but I get this error message.

> Parse error: syntax error, unexpected '?' in ../vendor/drupal/core-vendor-hardening/Config.php on line 142

The code causing the error is the following one.

```
// Merge root config with defaults.
foreach (array_change_key_case(static::$defaultConfig, CASE_LOWER) as $package => $paths) {
  $this->configData[$package] = array_merge(
    $this->configData[$package] ?? [],
    $paths);
  }

```

I don't know where the error is.

The differences I find between a site installed with Composer and one installed from a zip file is that projects installed with Composer use the web folder.

Does anyone know how to fix this error?

# Answer
> 2 votes
The linked documentation says:

> **For sites created on Drupal 8.8.0 or later**
>
> Even if you installed Drupal 8.8.0 from the tarball, Composer was pre-installed. So you should be able to manage your site using Composer without taking any extra steps to convert the site.

So `composer` can be used right away.

The line accidentally removed in the screenshot contains the `??` operator, which was introduced in PHP 7. An older PHP version causes a syntax error.

Check `php -v`. If this is an older version you need to fix this. You can't just run the composer binary with a different PHP version, because composer runs scripts like Config.php in a separate environment which uses whatever is linked in `/usr/bin/php`.

In Debian/Ubuntu systems you can configure the linked php version:

```
update-alternatives --config php

```

---

Alternatively, if your Linux doesn't have this tool to manage symbolic links or you don't have permissions to do this globally, you can create the symbolic link for a local account:

```
mkdir ~/bin
ln -s /usr/bin/php7.4 ~/bin/php

nano ~/.bashrc

```

in `.bashrc` add the new directory at the beginning of the variable PATH (where Linux searches for executables):

```
export PATH="$HOME/bin:$PATH"

```

---
Tags: 9, composer
---


# Question
Title: cant get file uri using field preprocess
Im trying to use function theme\_preprocess\_field to get the file path of a file field.

I have tried different variations of below.

```
  function mytheme_preprocess_field(&$variables) {
    if ($variables['element']['#field_name'] == 'my_file_field') {
      $uri = \Drupal\file\Entity\File::load($variables['items'][0]['content']['#item']->getValue())->getFileUri();
      $variables['my_file_field_path'] = $uri;
    }
  }

```

In my instance it says value null, but it isn't.

How can I get the file path of my\_file\_field? Thanks

# Answer
In a template don't use a `content` variable to get references to objects. This is what the template is rendering. The structure depends on the field formatter and its configuration. Use it only if you want to change this rendered output.

For object references use `element(s)`, unless you find a dedicated variable in the Twig doc block.

```
function mytheme_preprocess_field(&$variables) {
  $element = $variables['element'];
  if ($element['#field_name'] == 'my_file_field') {
    $items = $element['#items'];
    if (!$items->isEmpty()) {
      $file = $items[0]->entity;
      if ($file instanceof \Drupal\file\Entity\File) {
        $uri = $file->getFileUri();
      }
    }
  }
}

```
> 0 votes

---
Tags: 8, theming, hooks
---


# Question
Title: use-ajax class doesn't trigger ajax event
This is part of my code in custom module in src/Plugin/Block/FavoriteBlock.php:

```
$build['ajax_link'] = [
  '#type' => 'link',
  '#title' => $this->npxFavoritesRepository->getTitle($node),
  '#attached' => ['library' => ['npx_favorites/npx_favorites-library']],
  '#attributes' => ['class' => $classes],
  '#url' => Url::fromRoute('npx_favorites.ajax_link_callback', ['node' => $node->id()]),
];

```

And it results with output, that is fine, but it doesn't trigger the AJAX event:

```
<a href="/pl/favorite/1045/toggle" data-once="ajax" class="use-ajax n-favourite favorite-1045 active">Usuń z ulubionych</a>

```

So when I click on that it brings me to page that looks like that:

I have also another 'use-ajax' class from VUE template on the same page and it triggers the AJAX event. How can I make sure it is triggered, when I render this link from block?

# Answer
> 0 votes
It turned out, that VUE had conflicts with Ajax script.

# Answer
> 2 votes
Try attaching the `drupal.ajax` library.

```
$build['#attached']['library'][] = 'core/drupal.ajax';

```

---
Tags: ajax
---


# Question
Title: How to change a custom entity field type - with revisions
I have a custom content entity for which I needed to change the type of one of its fields.

Following the example on Updating a base field type, I wrote code to update the base entity, which updated perfectly. However, all revisions have null values, including the current revision. Even though the data is stored in the *base\_entity* table, it's not stored in the *base\_entity\_revision* table.

How do I modify `hook_update_N()` to also update the revision tables?

# Answer
In addition to updating the main table, you also need to update the revision table, so the following changes should be made:

1. `$id_key = $entity_definition->getKey('id');` becomes `$id_key = $entity_definition->getKey('id');
$revision_id_key = $entity_definition->getKey('revision');`
2. `$table_name = $storage->getDataTable() ?: $storage->getBaseTable();` becomes `$table_name = $storage->getDataTable() ?: $storage->getBaseTable();
$revision_table_name = $storage->getRevisionDataTable() ?: $storage->getRevisionTable();`
3. `$status_values = $database->select($table_name)
 ->fields($table_name, [$id_key, 'status_field'])
 ->execute()
 ->fetchAllKeyed();` becomes `$status_values = $database->select($table_name)
 ->fields($table_name, [$id_key, 'status_field'])
 ->execute()
 ->fetchAllKeyed();
$status_revision_values = $database->select($revision_table_name)
 ->fields($revision_table_name, [$revision_id_key, 'status_field'])
 ->execute()
 ->fetchAllKeyed();`
4. `$database->update($table_name)
 ->fields(['status_field' => NULL])
 ->execute();` becomes `$database->update($table_name)
 ->fields(['status_field' => NULL])
 ->execute();
$database->update($revision_table_name)
 ->fields(['status_field' => NULL])
 ->execute();`
5. `foreach ($status_values as $id => $value) {
 $database->update($table_name)
 ->fields(['status_field' => $value])
 ->condition($id_key, $id)
 ->execute();
}` becomes `foreach ($status_values as $id => $value) {
 $database->update($table_name)
 ->fields(['status_field' => $value])
 ->condition($id_key, $id)
 ->execute();
}`

`foreach ($status_revision_values as $id => $value) {
$database->update($revision_table_name)
->fields(['status_field' => $value])
->condition($revision_id_key, $id)
->execute();
}`
> 1 votes

---
Tags: entities
---


# Question
Title: How do I remove a configuration object from the active configuration?
I'm writing a custom module for Drupal 8. It defines a field storage configuration object, in a file called modules/mymod/config/install/field.storage.bloom\_stem.bs\_twitter\_ac.yml.

The problem is that this is not removed when I uninstall the module; it is apparently left behind because, when I re-install the module, I get a crash.

```
drush -y pm-uninstall mymod
drush cr
drush -y en mymod

```

> exception 'Drupal\Core\Config\PreExistingConfigException' with message 'Configuration objects (field.storage.bloom\_stem.bs\_twitter\_ac) provided by mymod already exist in active configuration'

So it seems I need to some how manually remove this configuration object. Do I need to provide some more code that deletes it when the module is uninstalled?

# Answer
The easiest way to do this at the moment is to use `drush php` (or `core-cli`) to open an interactive session.

Then use:

```
Drupal::configFactory()->getEditable('system.menu.devel')->delete();

```

This functionality will be added into Drupal console as well.
> 58 votes

# Answer
Drush command to delete configuration object: `drush config-delete <config_name>`.
> 34 votes

# Answer
You can use the following methods. Use the following code in hook\_uninstall

```
Drupal::configFactory()->reset('field.storage.bloom_stem.bs_twitter_ac');

```

OR

in the yml file you can put the dependencies like

```

dependencies:
  module:
    - yourmodule
  enforced:
    module:
      - yourmodule

```

then drupal will automatically remove this configurations on uninstalling your module as described by Berdir here https://drupal.stackexchange.com/a/173879/10436
> 17 votes

# Answer
Using the drupal console:

```
$ drupal config:delete 'the_config_to_delete'

```
> 10 votes

# Answer
Drupal::configFactory()-\>reset() does not delete the config object. For this run `Drupal::configFactory()->getEditable('field.storage.node.your_field_name')->delete()`
> 8 votes

# Answer
# Uninstall Active Configuration from Custom Module

I ran into the same problem trying to uninstall config files from a custom module. I have a custom module used to pass custom configuration files for webform. Since I'm not perfect I want to be able to uninstall the module, edit code and reinstall. I found if I referenced my custom module (my\_module) in the dependencies/enforced section in the config/install yml file, when I uninstalled my module the configuration files would also uninstall.

```
   langcode: en
    status: true
    dependencies:
        enforced:
            module:
                - webform
                - my_module // reference your module here

```
> 4 votes

# Answer
I created a simple module that you can use to delete configuration items.

https://www.drupal.org/project/config\_delete
> 4 votes

# Answer
Use hook\_uninstall to remove the configuration, when the module is uninstalled.

Then delete the configuration:

```
function hook_uninstall() {
  \Drupal::configFactory()->getEditable('the_setting.you.want.to.delete')->delete();
}

```
> 4 votes

# Answer
You can remove all the configs you imported from config/install by implementing HOOK\_uninstall():

```
function my_module_uninstall() {

  $module_path = \Drupal::service('extension.list.module')->getPath('my_module') . '/config/install';

  $configs = [];
  $files = \Drupal::service('file_system')->scanDirectory($module_path, '/\.yml$/');

  if ($files) {
    foreach ($files as $file) {
        $configs[] = $file->name;
    }

    foreach ($configs as $config_name) {
        \Drupal::configFactory()->getEditable($config_name)->delete();
    }

    return TRUE;
  }
}

```
> 3 votes

# Answer
You can use Drupal console to delete the active configuration, with `drupal config:delete active config_to_delete`.
> 2 votes

# Answer
All these answers recommend deleting the underlying config object directly, but the correct way is to delete the entity through the entity storage system.

For example, if you have an image style with ID "large" and you want to delete it, you should do this:

```
\Drupal::entityTypeManager()->getStorage('image_style')->load('large')->delete();

```

Doing it this way, core will invoke "predelete" before the config is deleted and "delete" hooks after the config is deleted, which other modules may rely on to perform various clean up operations.
> 2 votes

# Answer
Search for all the configurations listed using **drush config-list** Then identify the configuration that you would like to delete. Use the below command to delete the configuration **drush config-delete**
> 1 votes

# Answer
I could delete the active configuration using the drush config:delete command as below `drush cdel "name of the config"` for example in my case it was `drush cdel dtn_apple_news.setting`

after running this the configuration got deleted and then running `drush en-y "module name"` got the module to be installed.
> 1 votes

# Answer
Use Easy Install module to avoid this configuration issues, this module will allow to delete configurations while uninstalling a module, it works even if a module's configs not contains **enforced** in yml or not added configs in **optional** folder.
> 0 votes

# Answer
I leave here a tiny (yet a bit over-engineered) Python script which removes the configuration leftovers. It relies on `drush config-delete`.

```
# 'batch_config_delete.py'
# 'drush' has to be available in the current directory

import os
import argparse
import subprocess

MODULES_ROOT = "/var/www/html/MYSITE/web/modules/custom"

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Batch config delete.")
    parser.add_argument("-m", "--module", required=True, help="Module name")
    args = parser.parse_args()
    install_path = os.path.join(MODULES_ROOT, args.module, 'config/install')

    for f in os.listdir(install_path):
        if f.endswith('.yml'):
            config_name = os.path.splitext(f)[0]
            print "Delete config:", config_name
            subprocess.call(['drush', 'config-delete', config_name])

```

Should be executed like this:

```
python ../scripts/batch_config_delete.py -m foobar

```
> -1 votes

---
Tags: 8, entities, configuration
---


# Question
Title: How do I sort the field value by null in Search API Solr?
I want to alter the search API Solr query in Drupal 8 to order by field null in `hook_search_api_solr_query_alter()`. How do I add my sort expression in the Solr search query? Do I need to add it in `hook_views_query_alter()`?

# Answer
> 1 votes
I also had this issue, I couldn't find an easy way to sort by null in a query alter (although Solr does have sortMissingLast, I just couldn't figure out how to inject it through Search API). Instead, I added a processor to check the field in question and add another field to identify whether it's there or not. Then you can sort by that.

```
<?php

namespace Drupal\my_module\Plugin\search_api\processor;

use Drupal\Core\Annotation\Translation;
use Drupal\search_api\Annotation\SearchApiProcessor;
use Drupal\search_api\Datasource\DatasourceInterface;
use Drupal\search_api\Item\ItemInterface;
use Drupal\search_api\Processor\ProcessorPluginBase;
use Drupal\search_api\Processor\ProcessorProperty;

/**
 * Checks for my field.
 *
 * @SearchApiProcessor(
 *   id = "my_field_null",
 *   label = @Translation("Has My Field"),
 *   description = @Translation("Adds a check for null field to index."),
 *   stages = {
 *     "add_properties" = 0,
 *   },
 *   locked = true,
 *   hidden = false,
 * )
 */
class MyFieldNull extends ProcessorPluginBase {

  /**
   * Machine name of the processor.
   * @var string
   */
  protected $processor_id = 'my_field_null';

  /**
   * {@inheritdoc}
   */
  public function getPropertyDefinitions(DatasourceInterface $datasource = NULL) {
    $properties = [];

    if (!$datasource) {
      $definition = [
        'label' => $this->t('Has My Field'),
        'description' => $this->t('Does this have my field?'),
        'type' => 'string',
        'processor_id' => $this->getPluginId(),
      ];
      $properties[$this->processor_id] = new ProcessorProperty($definition);
    }

    return $properties;
  }

  /**
   * {@inheritdoc}
   */
  public function addFieldValues(ItemInterface $item) {
    $entity = $item->getOriginalObject()->getValue();
    if (method_exists($entity, 'hasField') && $entity->hasField('field_my_field')) {
      $has_field = TRUE;
    }
    else {
      $has_field = FALSE;
    }

    $fields = $this->getFieldsHelper()
      ->filterForPropertyPath($item->getFields(), NULL, $this->processor_id);

    foreach ($fields as $field) {
      $field->addValue($has_field);
    }
  }

}

```

# Answer
> 0 votes
I found an answer that works without writing any Drupal hooks or altering any PHP code!

Thanks to @ognockocaten for pointing out the sortMissingLast option! Looking at https://solr.apache.org/guide/6\_6/field-type-definitions-and-properties.html pointed me to altering the schema.xml file for solr.

The doc is for solr 6.6, but it also works for Solr 7.

All you have to do is add the sortMissingLast=true to your fieldType and restart solr

I wanted my date field to have the nulls at the bottom, so I ended up changing the pdate fieldType.

```
<fieldType name="pdate" class="solr.DatePointField" docValues="true" sortMissingLast="true"/>

```

After restarting solr, your null results will be at the bottom! Woohoo!

---
Tags: search
---


title: Lando local dev site tabs link to live

text:
# Question
Title: Lando local dev site tabs link to live
Suddenly, my local dev site's tabs have started linking to the live site. For example, when I view https://mysite.lndo.site and click the edit tab, it points to https://mysite.com/node/166. If I type in https://mysite.lndo.site/node/166, it still redirects me to the live site. This is a recent phenomenon, but I can't work out what change has caused this to start happening. Is there a simple setting I'm missing somewhere?

Drupal 9.4.1 PHP 8.0.18

# Answer
@Clive's comment was on track. I'm using the Domain modules and under Domain Source Settings, it was not set to disable link rewrites for these routes. This site is 2 years old now and I don't recall ever setting these before though, so something must have changed that I haven't caught onto yet. Anyway, leaving this here with what I figured out for posterity's sake.
> 3 votes

---
Tags: 9
---


title: Fee amount is incorrect

text:
# Question
Title: Fee amount is incorrect
I have created a fee type. I set up a rule according to the steps on the module's front page. I have it set to add $5.50 to the order. However, it is only adding $0.06 to the order instead.

Here is my rule (it's disabled since it isn't currently working):

```
{ "rules_handling_fee" : {
"LABEL" : "Handling fee",
"PLUGIN" : "reaction rule",
"ACTIVE" : false,
"OWNER" : "rules",
"REQUIRES" : [ "commerce_physical", "commerce_fees" ],
"ON" : { "commerce_fees_order" : [] },
"IF" : [
  { "commerce_physical_rules_order_is_shippable" : { "commerce_order" : [ "commerce_order" ] } }
],
"DO" : [
  { "commerce_fees_apply" : {
      "entity" : [ "commerce-order" ],
      "fee" : "handling",
      "amount" : "5.50",
      "currency_code" : "USD",
      "include_tax" : "0"
    }
  }
]

```

} }

# Answer
> 1 votes
I'd guess that `5.50` is cents, and is rounded up to $0.06. You probably need to multiple your value by 100:

```
  "amount" : "550",

```

---
Tags: commerce, rules
---


# Question
Title: How do I override the template file of a view so that it no longer displays links in my view, but only the plain text?
How do I override the template file of a view so that it no longer displays links in my view, but only the plain text?

This is a body field where the titles of the refenced entities are displayed as links. I would like to disable this for this view. I would like to do this via the template file for the view.

# Answer
> 1 votes
As a workaround, you can use the striptags filter of twig to strip the anchor tags. https://twig.symfony.com/doc/3.x/filters/striptags.html

For example: `{{ some_html|striptags('<a>') }}`

---
Tags: views, theming, entities
---


# Question
Title: Mocking the response of XmlResponse::getResultCode not working
Following is the code that I'm using to mock the response of `XmlResponse::getResultCode` as `Ok`, but it isn't working, I'm not sure what exactly is going wrong here:

```
$response = $this->createPartialMock('\CommerceGuys\AuthNet\Response\XmlResponse', ['getResultCode']);
$response->expects($this->any())->method('getResultCode')->will($this->returnValue('Ok'));

$client = $this->createMock('\GuzzleHttp\Client');
$client->expects($this->any())->method('request')->withAnyParameters()->will($this->returnValue($response));
$this->container->set('http_client', $client);

$clientFactory = $this->createMock('\Drupal\Core\Http\ClientFactory');
$clientFactory->expects($this->any())->method('fromOptions')->will($this->returnValue($client));
$this->container->set('http_client_factory', $clientFactory);

```

I've even tried the `prophesize` way, but that's not working either:

```
$response = $this->prophesize('\CommerceGuys\AuthNet\Response\XmlResponse');
$response->getResultCode()->willReturn('Ok');

```

My goal is to mock the response of `XmlResponse::getResultCode` to return string `Ok`.

Trying the above approach for the D8 site with PHPUnit 7.5.20 using Kernal Testcase.

# Answer
> 0 votes
So this is how I resolved this a while ago:

Create a new fixture, let's say `tests/fixtures/payment-response.xml` that'll contain the following response:

```
<?xml version="1.0" encoding="utf-8"?>
<createTransactionResponse xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd">
    <refId>123456</refId>
    <messages>
        <resultCode>Ok</resultCode>
        <message>
            <code>I00001</code>
            <text>Successful.</text>
        </message>
    </messages>
    <transactionResponse>
        <responseCode>1</responseCode>
        <authCode>UGELQC</authCode>
        <avsResultCode>E</avsResultCode>
        <cavvResultCode/>
        <transId>2148061808</transId>
        <refTransID/>
        <transHash>0B428D8A928AAC61121AF2F6EAC5FF3F</transHash>
        <accountNumber>XXXX0015</accountNumber>
        <accountType>Mastercard</accountType>
        <message>
            <code>1</code>
            <description>This transaction has been approved.</description>
        </message>
        <userFields>
            <userField>
                <name>MerchantDefinedFieldName1</name>
                <value>MerchantDefinedFieldValue1</value>
            </userField>
            <userField>
                <name>favorite_color</name>
                <value>lavender</value>
            </userField>
        </userFields>
        <networkTransId>123456789NNNH</networkTransId>
    </transactionResponse>
</createTransactionResponse>

```

Rest, all I need to do is update my PHP logic to fetch the response as data provided by `payment-response.xml`

```
    $response = new Response(200, [], file_get_contents(__DIR__ . '/../../fixtures/payment-response.xml'));
    $client = $this->createPartialMock(Client::class, ['request']);
    $client->expects(self::once())->method('request')->withAnyParameters()->willReturn($response);
    $this->container->set('http_client', $client);

    $clientFactory = $this->createPartialMock(ClientFactory::class, ['fromOptions']);
    $clientFactory->expects(self::any())->method('fromOptions')->willReturn($client);
    $this->container->set('http_client_factory', $clientFactory);

```

---
Tags: 8, commerce, testing
---


# Question
Title: Anonymous users can edit all anonymous users content
Drupal has a *edit own content* permission for each content type.

I have given the *Article: edit own content* to anonymous users and discovered that Drupal doesn't differentiate between different anonymous users, which means that an anonymous user has the permission to edit all the *Article* nodes created by anonymous users.

It seems that a sessions isn't really created for users until they sign in. So there isn't a session to identify anonymous users. Even then, the code checks the user ID, which is 0 for all the anonymous users.

Is this a bug with the permission, or can it be resolved?

I have seen other modules attempt to differentiate between different anonymous users. I think there was a flag for anonymous users. Then there is a few session based modules, but I don't see how these can help.

# Answer
> 2 votes
**The anonymous user is a single user.** Other systems have a concept of "anonymous users", but in Drupal it is called the anonymous user because from the standpoint of the system, in most senses, there is only one.

In particular, with respect to managing content, Drupal assigns user IDs to check permissions.

The anonymous user has an ID of 0, so everything created by the anonymous user is linked by the 0 user ID.

As a result, there are probably not many use cases where you would want to give edit permissions to the anonymous user for content. (This is not a criticism of your use case; what I am saying is that because of the way Drupal treats the anonymous user the same no matter who is anonymous, you will probably want to find a different way to implement your use case.)

Some modules support saving a draft for anonymous users, such as Webform, but for managing content by different people, they need to have accounts.

If you try to hack on some kind of support for distinguishing between anonymous users, you are quite likely to run into problems with the caching layer and run the risk of exposing data from one anonymous user to another.

---
Tags: 8, nodes
---


title: REST cookie authentication, Post 403

text:
# Question
Title: REST cookie authentication, Post 403
I am logged in to my Drupal account and if I use the jQuery code from here then I can make a post request to my site and create a node. But if I try from another site, like my local host or a third party site, I get 403 error.

I tried with a Get request from here, using jQuery, I could perform get the request, on both the Drupal site and an external site.

But I am unable to post, patch or delete from an external site using jquery and cookie authentication.

I'm not sure but I have a feeling it has something to do with the cookie not being sent with the request?

I can use basic\_authentication but that requires the login credentials to be sent, which I do not want.

how can I get the cookie authentication to work with jQuery?

# Answer
> 1 votes
> how can I get the cookie authentication to work with jQuery?

This is not possible. See this SO answer; the browser only allows you to use JS to access the cookies for the current domain; you cannot use JS to access cookies from other domains.

This is a basic security feature of modern browsers.

Alternatives:

* Implement Simple OAuth on the server
* Implement JWT on the server
* Implement something like Capacitor HTTP plugin for giving the browser access to your domain's cookies in all of your clients

---
Tags: 8, cookies
---


# Question
Title: Multistep Ajax form with ManagedFile: current step array dissapears from $form upon file upload callback
I have a custom multi-step Ajax form. On the second step, I have defined a `managed_file` field where users can upload several attachments:

```
public function buildForm(array $form, FormStateInterface $form_state)
  {
    $form['#tree'] = TRUE;
    ...
    $step = !empty($form_state->getValue('step')) ? $form_state->getValue('step') : 1;
    $form['step'] = [
      '#type' => 'value',
      '#value' => $step,
    ];
     // Steps previous to current one
    $steps = [1, 2, 3];
    foreach ($steps as $prev_step) {
      if ($prev_step < $step && $formState->hasValue('step' . $prev_step)) {
        $form['step'. $prev_step] = [
          '#type' => 'value',
          '#value' => $formState->getValue('step'. $prev_step),
        ];
      }
    }
    // Current step
    switch ($step) {
      ...
      case 2:
        $form['step' . $step] = [
          '#type' => 'fieldset',
          '#title' => $this->t('Step @number: Compose Emails', [
            '@number' => $step
          ]),
        ];
        ...
        $form['step' . $step]['test_file'] = [
          '#type' => 'managed_file',
          '#upload_location' => 'public://attachments/',
          '#multiple' => TRUE,
          '#description' => 'This is a description',
          '#upload_validators' => [
            'file_validate_extensions' => [],
            'file_validate_size' => array(25600000)
          ],
          '#default_value' => $form_state->hasValue(["step$step", 'test_file']) ? $form_state->getValue(["step$step", 'test_file']) : []
        ];
        ...
    }
    ...
  }

```

However, upon uploading the file, the `uploadAjaxCallback` of `Drupal\file\Element\ManagedFile` is not able to find my nested `step2` array in `$form`:

```
# \Drupal\file\Element\ManagedFile::uploadAjaxCallback, line 190
// Before calling getValue, $form does not have key 'step2', only 'step1'
$form = NestedArray::getValue($form, $form_parents);
// $form is now NULL!

```

Consequently, nothing is displayed in my form, and the file upload fails.

Am I doing something wrong here?

# Answer
Try to store the step in $form\_state:

```
$step = $form_state->has('step') ? $form_state->get('step') : 1;
$form_state->set('step', $step);

```
> 0 votes

---
Tags: forms, ajax, files, 9
---


# Question
Title: How do I add a filter to a checkbox list in a content editing form
I have a taxonomy select field within a node form (7). I've chosen checkboxes and it is hard to scan them. I'd like to be able to add a filter so that the user can enter text to limit the number of choices in the list. How?

# Answer
> 1 votes
In Drupal 8 the best way to create an advanced ER field widget is with the help of the Entity Browser module.

You will have to create the Entity browsers for your Taxonomy terms, and use Views Widget plugin to create the final browser that has the exposed filter: Views | Widgets

You can also find tutorials about how to set up your own Entity Browser, usually they describe how to build a Media gallery, but you can follow a lot of the steps from those to create the taxonomy term case you need.

# Answer
> 0 votes
You can change the `Reference method` option in your Field settings to `Views: Filter by an entity reference view`.

You first have to build the Views listing taxonomy terms, Display of type Entity Reference. Add the exposed filter there for the term name. Save the View.

Then you'll be able to select that ER Views Display in your Field settings.

# Answer
> 0 votes
In d7 achieved this by laying out the options as checkboxes and filtering with javascript. With d8 the entity browser is great if slow.

```
(function ($, Drupal, window, document) {
  'use strict';

   Drupal.behaviors.filterwebinars = {
     attach: function (context, settings) {
     if ($("#edit-field-event-sponsors").length) {
     $("<label for=\"filter-event-sponsors\">Filter Sponsors</label><input type=\"text\" class=\"filter-event-sponsors\" name=\"filter-event-sponsors\" id=\"filter-field-event-sponsors\"\/>").prependTo('#edit-field-event-sponsors');
     $('#filter-field-event-sponsors').keyup(function(){
      let filterText = $('#filter-field-event-sponsors').val().toLowerCase();
      let filter = $("#edit-field-event-sponsors-und :checkbox").filter(function() {
        if (this.labels[0].innerHTML.toLowerCase().includes(filterText)){
            $(this).parent().show();
              return this.value;
            }
            $.(this).parent().hide();
            return false;
          });
        });
      }
    }
  };

})(jQuery, Drupal, this, this.document);

```

---
Tags: 7, entities
---