# Question
Title: How can I prevent renaming of files uploaded with JSON:API for a specific field/filename?
I created a **Profile photo** image field on the user entity. This is for a decoupled site where users upload files with JSON:API.

The file field is configured like this:

* **File directory**: profile-pics/\[current-user:uid\]

My app always uploads the file as `profile_photo.jpg`. But, each time the user uploads a file, it gets renamed: `profile_photo_0.jpg`, `profile_photo_1.jpg`, and so on.

If the user uploads a new photo, I always want to overwrite the old photo; I do not want to store extra data.

## What I tried

I only want to force overwrites for a specific file name (`profile_photo.jpg` at the path `profile-pics/[current-user:uid]` for a specific field (`field_profile_pic` on the user entity).

Is there a hook I can use or a method I can override to force overwriting of files in this case?

# Answer
> 3 votes
A possible solution I could imagine would be overriding getDestinationFilename() of the file system service.

Thus, you could create a custom module with a service provider class for altering the definition of the Core `file_system` service to use your adapted version.

In your adapted method, you could check the destination path of the target file and add your logic (e.g., renaming existing files, rather than the newly added file) before returning the destination file name.

A quick wrap-up:

* Create a custom module 'profile\_pic\_path'
* Create a `ProfilePicPathServiceProvider.php` class file in its `src` folder. If you use a different module name, this class name should be constructed using the camel case module name and added `ServiceProvider` suffix:

```
<?php

namespace Drupal\profile_pic_path;

use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\DependencyInjection\ServiceProviderBase;
use Drupal\Core\DependencyInjection\ServiceProviderInterface;

/**
 * {@inheritdoc}
 *
 * Used to alter the container `file_system`
 * service definition.
 */
class ProfilePicPathServiceProvider extends ServiceProviderBase implements ServiceProviderInterface {

  /**
   * {@inheritdoc}
   */
  public function alter(ContainerBuilder $container) {
    $service_def = $container->getDefinition('file_system');
    // Use our custom class `CustomFileSystem`.
    $service_def->setClass(CustomFileSystem::class);
  }

}

```
* Create your file system class override `CustomFileSystem.php` in the `src` folder:

```
<?php

namespace Drupal\profile_pic_path;

use Drupal\Core\File\FileSystem;
use Drupal\Core\File\FileSystemInterface;

/**
 * {@inheritdoc}
 *
 * Example override of the core `file_system`
 * method `getDestinationFilename()`.
 */
class CustomFileSystem extends FileSystem implements FileSystemInterface {

  /**
   * {@inheritdoc}
   *
   * Renames existing files to a new file name
   * rather than renaming new files while
   * keeping the old files.
   */
  public function getDestinationFilename($destination, $replace) {
    $target_destination = parent::getDestinationFilename($destination, $replace);

    // Add your logic to check, whether it's a profile picture
    // and possibly to remove existing files/file entities/alter
    // the destination path/or rename existing files to the
    // suggested new file name while returning the original file
    // destination here. An example:
    if (
      // Whether the target file exists.
      file_exists($destination)
      // Whether file renaming has been requested.
      && $replace === FileSystemInterface::EXISTS_RENAME
    ) {
      // Rename the existing file to the new
      // name returned by the core method.
      $this->move($destination, $target_destination);

      // Update any existing file entities using
      // the existing file with the new URI.
      /** @var \Drupal\file\FileInterface[] $files */
      $files = \Drupal::entityTypeManager()
        ->getStorage('file')
        ->loadByProperties(['uri' => $destination]);

      if ($files) {
        foreach ($files as $file) {
          $file->setFileUri($target_destination);
          $file->save();
        }
      }

      // Return the original destination.
      return $destination;
    }

    // Return the destination determined by the
    // core method.
    return $target_destination;
  }

}

```

---
Tags: files, 9
---


# Question
Title: How To Resolve Commerce Button Returning Error?
I'm using the latest stable version of Drupal Commerce (on Drupal 9), with every module up to date

Problem: When the add to cart button is clicked the site returns message "The website encountered an unexpected error. Please try again later." When I check the log messages it displays the error `"Exception: The given entity is not assigned to any store."`

## Commerce setup

* Drupal Commerce's architecture, settings, permissions, and configurations have been fully setup and every other feature is working.
* It only has one store configured which is setup as the default store (default option is checked- the very last setting on the store's configuration page).
* The add to cart form is setup, but when add to cart button is clicked the above behavior happens.
* I am currently using Commerce Stripe as the payment gateway, and it is working well and able to complete orders and purchases by going to `admin/commerce/orders` and then manually creating orders. Everything seems to be working fully (except for the add to cart button).

I am using Stripe's payment gateway in test mode currently, and don't believe this is the issue but is it possible this is the case? (Payment's are working via stripe's test mode where stripe basically just provide's you with a fake card for testing, which as stated did work to complete purchases by navigating to admin/commerce/orders)

The log messages consistently display `"Exception: The given entity is not assigned to any store."` (Entity being the product or the article- both function as content entities and the add to cart button functions as a field for both of these).

## What I tried to do

* I've read through commerce's documentation numerous times and tried to setup an add to cart button on an article entity type to see if I get the same result. I was able to configure articles to include an add to cart button, and setup a view to display the articles, but when add to cart is pressed it returned the exact same message as above and the log showed the exact same error as well.
* I did try playing around with the product entities as well as the article entity and adding reference fields specifically for the stores within each. (Add field- reference- other- store, as well as the other- configuration- store type field) I added both of these fields to both the product entities, and articles, with the theory that they'd "assign the entity to the store" and still this didn't work.
* Then I tried adding these two fields to just about everything within commerce, the product attributes, product variation types, the order types, the order item types, the add to cart form itself, and no matter what I still get the same error messages as above.

Does anyone know how this can be resolved?

# Answer
> 0 votes
Found the solution here:

https://www.drupal.org/project/commerce/issues/2865233

Specifically #2, and #7.

You must make sure that the **original** store field is enabled for the add to cart form, then update your products. Mine was disabled, I enabled it, edited the products and now the button works. (You may be able to add your own store fields, but I tried and failed, and they were enabled. For me it was critical that the original and provided store field was the one enabled)

---
Tags: forms, commerce, 9
---


# Question
Title: How can I sort results by contextual filter value?
I have a set of pages that use path information to - amongst other things - create view of relevent news articles.

eg:

```
mysite.com/city-service
mysite.com/country-service
etc

```

I have an existing view that uses a contextual filter to extract the relevant portion of the URL and then look up relevant news articles that are tagged with an organisation tag that maps to each service.

This works great, but I have been asked to change the view to the following behavior:

1. Show ALL recent news articles
2. Sort the news articles so the relevant (and recent) organisation tagged news is at the top

I am not allowed to radically redesign the page or workflow for staff - eg manually tag all news articles - so the only place I can get the taxonomy term name for the sort is the url.

How can I sort view results based on a taxonomy term name that takes a parameter from the page url?

# Answer
> 4 votes
To accomplish this, you need to alter the views query with `hook_views_query_alter` in your custom module. Read out the requested URL and get the related taxonomy term to it. Then you can adjust the query according to your needs. A similar answer can be found here: How to sort on different columns in the same view?

Here is an example:

```
use Drupal\views\Plugin\views\query\QueryPluginBase;
use Drupal\views\ViewExecutable;

function MYMODULE_views_query_alter(ViewExecutable $view, QueryPluginBase $query) {
  // Determine view by id and current display.
  if ($view->id() == 'content_recent' && $view->current_display == 'default') {
    // Get the requested path.
    $request = \Drupal::request();
    $path = $request->getPathInfo();

    // Use some logic to get the term for the current path.
    // @see https://drupal.stackexchange.com/a/266084/15055
    $tid = FALSE;
    if ($path == 'example') {
      $tid = 9;
    }

    // If the URL belongs to a term, we change the order.
    if ($tid) {
      // You may need to add a relationship to the taxonomy terms,
      // if your view is not already doing this or add it in the Views UI.

      $sql = "CASE
        WHEN taxonomy_term_field_data_node_field_data.tid = $tid THEN 0
        ELSE 1
      END";
      // Add the sql formula for sorting.
      $query->addField(NULL, $sql, 'related_taxonomy_term');
      // We first sort by the related term and than by the views settings,
      // which should for example be the changed date descending.
      $query->orderby = array_merge([[
        'field' => 'related_taxonomy_term',
        'direction' => 'ASC',
      ]], $query->orderby);
    }
  }
}

```

---
Tags: views, 9
---


# Question
Title: Get node's view mode within template_preprocess_page
We have to get the current node's `view_mode` from within the `mymodule_preprocess_page(&$variables)` hook. When we tried the following we could not get the `view_mode` after performing some validation to make sure we have a `node` object.

In the `Basic page`, we have a `Related Articles` section that is an entity reference to the `Article` content type. This returns multiple nodes depending upon the page and we want to ensure the `template_preprocess_node()` hook is ran only once.

**How can we get the current node's `view_mode` from within the `template_preprocess_page(&$variables)` hook?**

Here is what we tried to do

```
function mymodule_preprocess_page(&$variables) {
  $node = $variables['node'];
  if(isset($node) && is_object($node) {
    // Tried printing variables but cannot find `view_mode`
    ksm($node);
  }
}

```

# Answer
It's possible you are using the wrong hook. `hook_preprocess_page()` is not for the content type `page`. Use a preprocess hook for nodes and check the content type:

```
function mymodule_preprocess_node(&$variables) {
  if ($variables['node']->getType() === 'page') {
    $view_mode = $variables['view_mode'];
    // preprocess only nodes of the content type "Basic Page"
  }
}

```
> 5 votes

# Answer
I needed to put a class based on view mode onto my pages. I seem to remember that view mode is handled separately from the node data. My solution was actually based on using the Display Suite submodule Switch View Mode (was already using DS). This module creates a new base field in the entity and sets the view mode to it.

This let me use the following code to create the class:

```
$view_mode = $node->ds_switch->value;
if (!empty($view_mode)) {
   $variables['page_class'] .= " node-view-{$view_mode}";
}

```

This solution won't work with out the module. A bit of tracing on how this works shows that it is based on using hook\_entity\_view\_mode\_alter() to get the view mode and add it to the ds\_switch field on the node.

This field seems to be added by using the hook\_entity\_base\_field\_info(). See the ds\_switch\_view\_mode.module file in the Display Suite code for details on this.
> 4 votes

# Answer
You should set a custom node parameter by overriding template\_preprocess\_node in your .theme file. For example:

```
function mytheme_preprocess_node(array &$variables, $hook) {
  if(isset($variables['view_mode'])) {
    $node = $variables['node'];
    $node->current_view_mode = $variables['view_mode'];
  }
}

```

When this is added you can access the custom parameter in template\_preprocess page as $node-\>current\_view\_mode.

See also Sharing variables between node preprocess and page preprocess
> 2 votes

---
Tags: 8, nodes, hooks
---


# Question
Title: Node view mode in page template suggestions
I would like **page** template suggestions when a **node** is using a custom view mode.

I think this would happen in `hook_theme_suggestions_page_alter()`.

I have already been able to get page-level template suggestions based on the node's content type, so it seems like I should be able to snag the name of the custom view mode?

I'm not good at this part of Drupal at all, so any help would be appreciated.

# Answer
You can do this by first setting a custom node parameter by overriding template\_preprocess\_node in your .theme file. For example:

```
function mytheme_preprocess_node(array &$variables, $hook) {
  if(isset($variables['view_mode'])) {
    $node = $variables['node'];
    $node->current_view_mode = $variables['view_mode'];
  }
}

```

When this is added you can access the custom parameter in hook\_theme\_suggestions\_page\_alter() page as $node-\>current\_view\_mode.

For example:

```
function mytheme_theme_suggestions_page_alter(array &$suggestions, array $variables) {
  if ($node = \Drupal::routeMatch()->getParameter('node')) {
    $suggestions[] = 'page__' . $node->current_view_mode;
 }
}

```

You may have to add some extra validation to ensure $node-\>current\_view\_mode has a useful value.

See also Sharing variables between node preprocess and page preprocess & Get node's view mode within template\_preprocess\_page
> 2 votes

# Answer
The hook `hook_theme_suggestions_HOOK` is the one you should implement.

When you have a ***node* of type *page*** (labeled as *Basic Page* from the *default profile*), then the *HOOK* is *node* and the specific *hook* you would implement is **`hook_theme_suggestions_node(array $variables)`**

As @pinueve points out, there is already a specific *suggestion* that includes the custom display mode: `node--page--CUSTOM_VIEW_MODE.html.twig`.

Also, as @pinueve suggests, the easy way to find the template suggestions is by enabling the debugging mode. I tested this using a custom view mode called `customvm` that I created, so I can see these suggestions in the browser by inspecting the source code:

```
* node--17--customvm.html.twig
* node--17.html.twig
* node--page--customvm.html.twig
* node--page.html.twig
* node--customvm.html.twig
x node.html.twig

```

**Alter hook**

Note that there is also an *alter* version of the hook `[HOOK_theme_suggestions_node(array &$suggestions, array $variables)][3]`, you should use this if you are trying to alter the existing suggestions, maybe changing the priorities.

**Suggestions for a *page* from a custom *controller***

The *page* *HOOK* is meant to be used when the output comes from a custom *controller* and *route*, like the one in this example: https://www.drupal.org/docs/8/api/routing-system/introductory-drupal-8-routes-and-controllers-example

In this case the *HOOK* is *page* and you would implement these hooks:

* HOOK\_theme\_suggestions\_page(array $variables)
* HOOK\_theme\_suggestions\_page\_alter(array &$suggestions, array $variables)
> 1 votes

---
Tags: 8, theming
---


title: I can't load inline jQuery

text:
# Question
Title: I can't load inline jQuery
I have a Drupal 9 page, where I am trying to load some inline jQuery code, from CKEditor, but it isn't working and I am not getting any error on the console.

This worked perfectly in Drupal 8.

```
<script>
 window.onload = function() {
  jQuery('.className').fadeOut();
  console.log("HI");
 };
</script>

```

# Answer
> 0 votes
The right way of doing it, is to add a js file to the js folder, then declare it in the my-theme.libraries.yml file, either globally or not. Then the trick is to make a hook for the specific node (or node-type, even theme) in the my-theme.theme file.

---
Tags: javascript, 9
---


# Question
Title: how to get the absolute path for files based on fid
How can i get the absolute path for a file based on the fid? Sorry if this is a repeat, I did a search but was unable to find the answer.

# Answer
**Drupal 7**

This is a two part process, using `file_load()` and `file_create_url()`

First, you need to turn the $fid into a Drupal URI:

```
$file = file_load($fid);
$uri = $file->uri;

```

Now, you can turn this into a URL

```
$url = file_create_url($uri);

```

`file_create_url()` always creates an absolute URL, either using the global `$base_path` that you have defined, or using the one that Drupal guessed during bootstrap.
> 40 votes

# Answer
### Drupal 8

```
$file = \Drupal\file\Entity\File::load($file_id);
$uri = $file->getFileUri();
$url = \Drupal\Core\Url::fromUri(file_create_url($uri))->toString();

```
> 10 votes

# Answer
In Drupal 7 you can also use MYSQL query, if you don't want to load all the fields of the file

```
  $fid = 1; //your file ID
  $uri = db_select('file_managed', 'f')
    ->condition('f.fid', $fid, '=')
    ->fields('f', array('uri'))
    ->execute()->fetchField();
  echo file_create_url($uri);

```
> 3 votes

# Answer
**Drupal 9**

All previous answers are now deprecated using Drupal 9. There is a perfect list of the up-to-date alternatives : https://www.drupal.org/node/2940031

An example step by step :

```
$file = File::load(15);
$uri = $file->getFileUri();
$url = \Drupal::service('file_url_generator')->generate($uri);
// Your url as a string
$string = $url ->toString();

```
> 2 votes

# Answer
These are both working for me in Drupal 8:

```
// top of file
use Drupal\file\Entity\File;
use Drupal\Core\Url;

// load the file object from some file id
$file_object = File::load(123);

// way 1
$file_uri = $file_object->uri->value;
$file_url = file_create_url($file_uri);

// way 2
$file_uri = $file_object->getFileUri();
$file_url = Url::fromUri(file_create_url($file_uri))->toString();

```
> 0 votes

---
Tags: files, uri
---


# Question
Title: Creating dynamic controllers for the same route
I have a route defined as

```
my_node_action.go:
  path: '/node/{node}/go'
  defaults:
    _title_callback: '\Drupal\my_node_action\Form\Go::title'
    _form: '\Drupal\my_node_action\Form\Go'
  options:
    parameters:
      node:
        type: entity:node
  requirements:
    _user_is_logged_in: 'TRUE'

```

where `Go` is extending `FormBase`.

I want to add 2 different classes: `NodeType1Go` and `NodeType2Go` which extend `Go` So that when the `node->bundle()` is `type1` the form will be `NodeType1Go` and when its `type2` the form is `NodeType2Go`

What is the best way to do this and still keep one single `routeName`

Thank you for your help

# Answer
> 1 votes
As you already imply in your question, you'll want to use a custom controller action that returns the form depending on your node type.

First, alter the route to point to a controller method:

```
my_node_action.go:
  path: '/node/{node}/go'
  defaults:
    _title_callback: '\Drupal\my_node_action\Controller\GoController::goFormTitle'
    _controller: '\Drupal\my_node_action\Controller\GoController::goForm'
  options:
    parameters:
      node:
        type: entity:node
  requirements:
    _user_is_logged_in: 'TRUE'

```

Then you create the `GoController.php` file in your module's `src/Controller` folder:

```
<?php

namespace Drupal\my_node_action\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Form\FormBuilderInterface;
use Drupal\node\NodeInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

class GoController extends ControllerBase implements ContainerInjectionInterface {

  /**
   * Constructs a GoController instance.
   *
   * @param \Drupal\Core\Form\FormBuilderInterface $form_builder
   *   The form builder.
   */
  public function __construct(
    FormBuilderInterface $form_builder
  ) {
    $this->formBuilder = $form_builder;
  }

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

  /**
   * Return the go form.
   *
   * @param \Drupal\node\NodeInterface $node
   *   The node.
   *
   * @return array
   *   Form render array for the go form.
   */
  public function goForm(NodeInterface $node) {
    $form = [];

    switch ($node->getType()) {
      case 'type1':
        $form = $this->formBuilder()->getForm('Drupal\my_node_action\Form\NodeType1Go', $node);
        break;

      // Further types/forms and/or a default form here...
    }

    return $form;
  }

  /**
   * Return the go form title.
   *
   * @param \Drupal\node\NodeInterface $node
   *   The node.
   *
   * @return string
   *   Form title.
   */
  public function goFormTitle(NodeInterface $node) {
    // Whatever logic may apply here...
  }

}

```

---
Tags: routes
---


# Question
Title: Saving block translation with large amount of text causes PDOException: Data too long for column 'translation'
I have a Drupal 7 project where I am using a Panel to patch together some Drupal blocks. These blocks have to be translated and I just added some data to the current French translation and apparently there is a limit to how much translated content you can have in a block because after I add the extra french content to the block and try to save I get an error that says: "The website encountered an unexpected error. Please try again later."

and going to the reports log I see:

```
PDOException: SQLSTATE[22001]: String data, right truncated: 1406 Data too long for column 'translation' at row 1: UPDATE {locales_target} SET translation=:db_update_placeholder_0 WHERE ( (lid = :db_condition_placeholder_0) AND (language = :db_condition_placeholder_1) ); Array ( [:db_update_placeholder_0] =>

[LOTS OF HTML MARKUP/TRANSLATION DATA HERE THAT I LEFT OUT FOR BREVITY]

[:db_condition_placeholder_0] => 16474 [:db_condition_placeholder_1] => fr ) in i18n_string_textgroup_default->save_translation() (line 747 of /home/master/public_html/sites/all/modules/i18n/i18n_string/i18n_string.inc).

```

The block contains HTML mixed with text and its pretty large, 72080 characters. I need it to be large because its a lot of text and I have HTML markup in it that works with some custom javascript I created.

Any idea how to get over this limit for the maximum amount you can translate in a block?

Here is the table that is being referenced and it looks like the field "language" is already a blob:

# Answer
> 0 votes
I fixed this issue with the code below. This code is similar to what the user @apderno suggested but his function call was missing 1 signature and didn't work or I would have rated his suggestion as the best answer.

To fix this I created a new custom module with a .module and .install file in the module. For my .module page:

```
 function make_translations_longer_schema_alter(&$schema) {

 if (isset($schema['locales_target']['translation'])) {

    $schema['locales_target']['translation'] = array(
      'type' => 'blob',
      'size' => 'big',
      'not null' => TRUE,
      'description' => 'Translation string value in this language.',
    );
  }
}

```

For my .install page:

```
function make_translations_longer_install() {

  db_change_field('locales_target', 'translation', 'translation', array(
    'description' => "Translation string value in this language.",
    'type' => 'blob',
    'not null' => FALSE,
    'size' => 'big',
  ));
}

```

I was then able to create the longer French translation. Thanks to @apderno!!!

# Answer
> 2 votes
You could change that database column and let other modules know about those changes with `hook_schema_alter()`, but this could cause problems with existing modules. If you are going through this, be sure to test it on the development site, before doing the same changes on the live site. In particular, be sure the code you are using doesn't conflict with another module that alters the same column; in that eventuality, you need to accordingly change your code.

To make that field larger, it's sufficient to run the following code, for example when installing a custom module.

```
function mymodule_install() {
  if (db_field_exists('locales_target', 'translation')) {
    $field = array(
      'type' => 'text',
      'mysql_type' => 'blob',
      'size' => 'big',
      'not null' => TRUE,
      'description' => 'Translation string value in this language.',
    );

    db_change_field('locales_target', 'translation', $field);
  }
}

```

The following hook implementation would make the other modules aware of the column changes.

```
function mymodule_schema_alter(&$schema) {
  if (isset($schema['locales_target']['translation'])) {
    $schema['locales_target']['translation'] = array(
      'type' => 'text',
      'mysql_type' => 'blob',
      'size' => 'big',
      'not null' => TRUE,
      'description' => 'Translation string value in this language.',
    );
  }
}

```

It's necessary to use a module since, without implementing `hook_schema_alter()`, other modules won't know the database column has been changed.

---
Tags: 7, blocks, i18n-l10n, panels
---


title: upgrade 8.5.15 to 8.9.20 failing

text:
# Question
Title: upgrade 8.5.15 to 8.9.20 failing
After the upgrade (done via composer) I get the following stack trace:

```
InvalidArgumentException: Field reusable is unknown. in Drupal\Core\Entity\ContentEntityBase->getTranslatedField() (line 587 of core/lib/Drupal/Core/Entity/ContentEntityBase.php).

Drupal\Core\Entity\ContentEntityBase->get('reusable') (Line: 308)
Drupal\block_content\Entity\BlockContent->isReusable() (Line: 68)
Drupal\block_content\BlockContentAccessControlHandler->checkAccess(Object, 'view', Object) (Line: 105)
Drupal\Core\Entity\EntityAccessControlHandler->access(Object, 'view', Object, 1) (Line: 709)
Drupal\Core\Entity\ContentEntityBase->access('view', Object, 1) (Line: 177)
Drupal\block_content\Plugin\Block\BlockContentBlock->blockAccess(Object) (Line: 120)
Drupal\Core\Block\BlockBase->access(Object, 1) (Line: 124)
Drupal\block\BlockAccessControlHandler->checkAccess(Object, 'view', Object) (Line: 105)
Drupal\Core\Entity\EntityAccessControlHandler->access(Object, 'view', Object, 1) (Line: 370)
Drupal\Core\Entity\EntityBase->access('view', NULL, 1) (Line: 56)
Drupal\block\BlockRepository->getVisibleBlocksPerRegion(Array) (Line: 137)
Drupal\block\Plugin\DisplayVariant\BlockPageVariant->build() (Line: 259)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 117)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 111)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch('kernel.view', Object) (Line: 156)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 68)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 106)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 85)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 52)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 708)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)

```

Perhaps i need to update db? But I can't:

```
 php -d "disable_functions=" ./vendor/drush/drush/drush updatedb
 [error]  The Pathauto module is not compatible with the current version of Drupal core. Update the <a href="https://drupal.org/project/pathauto">Pathauto</a> module to 8.x-1.6 or later.

 Requirements check reports errors. Do you wish to continue? (yes/no) [yes]:
 > yes

 [success] No pending updates.

```

Not sure whether this pathauto is important or not...

Update: Okay, so let's assume pathauto is really a problem. I added "drupal/pathauto": "^1.6" do composer.json and run composer update. Something something happened, and now I think i have a pretty new pathauto installed:

```
composer show --all| grep pathauto
Info from https://repo.packagist.org: #StandWithUkraine
  drupal/pathauto                          1.10.0   Provides a mechanism for modules to automatically generate aliases for the content they manage.
  ahebrank/pathauto_subnav
  aron-novak/pathauto
  wieni/wmpathauto
  wkse/pathauto
  drupal/pathauto                          1.10.0   Provides a mechanism for modules to automatically generate aliases for the content they manage.

```

But still the same error: The Pathauto module is not compatible with the current version of Drupal core. Update the Pathauto module to 8.x-1.6 or later.

# Answer
Okay, I did a bunch of things but mostly what i think worked was:

```
mv modules/pathauto ~/bak
composer require drupal/pathauto:^1.6
cp -r modules/contrib/pathauto/  modules/

```

I am 100% clueless about Drupal so don't ask me why i had to move it out from contrib and whether this is correct. But seems to work.
> 0 votes

---
Tags: upgrading
---


# Question
Title: How to redirect form submit to an external URL and also open it in a new tab
In D9 we have a custom form that needs to redirect the user to an external URL and also have it open in a new window/tab.

We have the external redirect working using TrustedRedirectResponse but there doesn't seem to be a way to have it open in a new tab.

What is a working solution to redirect to an external URL and also have it open in a new tab?

```
public function submitForm(array &$form, FormStateInterface $form_state) {
  $url = "https://somewebsite.com";
  $response = new TrustedRedirectResponse(\Drupal\Core\Url::fromUri($url)
    ->toString());
  $metadata = $response->getCacheableMetadata();
  $metadata->setCacheMaxAge(0);
  $form_state->setResponse($response);
}

```

# Answer
> 1 votes
This answer indicates that you can add a formtarget attribute to the submit action in order to open it in a new tab: https://drupal.stackexchange.com/a/307453

That worked for me:

```
$form['actions']['submit'] = [
  '#type' => 'submit',
  '#value' => 'Search',
  '#attributes' => [
    'formtarget' => '_blank'
  ]
];

public function submitForm(array &$form, FormStateInterface $form_state) {
  $response = new TrustedRedirectResponse($url);
  $metadata = $response->getCacheableMetadata();
  $metadata->setCacheMaxAge(0);
  $form_state->setResponse($response);
}

```

---
Tags: forms
---


# Question
Title: issue in construct function for dependency injection
error I am getting : CreateApplicationService::\__construct(), 0 passed in C:\xampp\htdocs\drupalwebsite\core\lib\Drupal\Component\DependencyInjection\Container.php on line 262 and exactly 1 expected

I have this below code:

nots sure what is the issue in the construct function. I have done the same POC in another module where I called from form.php and it works. Not sure what I am missing here?

# Answer
it was only missing argument parameter in service.yml.

I only added arguments: \['@OAuthTokenManagement.oauthtokenService'\]
> 1 votes

---
Tags: 9
---


# Question
Title: How do I check a form is a node type form?
I am writing a custom module and I want to add some condition in `hook_form_alter()` to check the form is a node type form.

Is there any function to check whether a form is for a node?

# Answer
> 3 votes
In the case you are referring to the node edit form (the form that allows you to edit a node), instead of `hook_form_alter()`, you need to implement `hook_form_BASE_FORM_ID_alter()`, which is a specific implementation of `hook_form_alter()` used when you know the form ID of the base form. In your case, you need to implement `hook_form_node_form_alter()` exactly how the Book module does with `book_form_node_form_alter()`.

```
function book_form_node_form_alter(&$form, &$form_state, $form_id) {
  $node = $form['#node'];

  // Omissis.
}

```

`$form['#node']` is set by `node_form()`, which contains the following code. (Note the comment, which says that `$form['#node']` is going to be removed in Drupal 8, and that modules should instead use `$form_state['node']`.)

```
// @todo D8: Remove. Modules should access the node using $form_state['node'].
$form['#node'] = $node;

```

In the case you are referring to the form you find at admin/structure/types/manage and that allows you to edit the properties of a content type, you need to implement `hook_form_FORM_ID_alter()`, which a specific implementation of `hook_form_alter()` done for a specific form ID, which in this case is *node\_type*. This is what does the Comment module with `comment_form_node_type_form_alter()`. If you need to know the content type for which the form is shown, you can use `$form['#node_type']->type`.

# Answer
> 0 votes
You can use `hook_form_node_form_alter`.

Example:

```
function my_module_form_node_form_alter(&$form, &$form_state, $form_id) {
  $type = $form['#node']->type;
}

```

# Answer
> 0 votes
d8/d9

```
use Drupal\Core\Form\FormStateInterface;
use Drupal\node\NodeForm;

/**
 * Implements hook_form_alter().
 */
function <module_name>_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  $form_object = $form_state->getFormObject();
  $isNodeForm = $form_object instanceof NodeForm;
  if ($isNodeForm) {
    ...
  }
}

```

---
Tags: 7, hooks, forms
---


# Question
Title: Redirect user to a custom page after one time login
If my user click to "forgot password", and email with a one-time login is sended.

When the user clicks the given link, he's redirected to this page `/user/reset/$id` with the `user_pass_reset` form (basically containing a single button for the one-time login)

I'd like to redirect to a custom page after the user clicked on the one-time login button, but can't find out why this code doesn't works

```
/**
 * Implements hook_form_BASE_FORM_ID_alter().
 */
function module_form_user_pass_reset_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id)
{
  $form['actions']['submit']['#submit'][] = '_module_user_reset_pass_form_submit';
}

function _module_user_reset_pass_form_submit(&$form, FormStateInterface $form_state) {
  $form_state->setRedirect('module.custom_reset_password_page');
}

```

I'm using drupal 9

# Answer
> 2 votes
Look at the code of the Login Destination module. But maybe the Password Reset Landing Page module is actually what you are looking for.

Because you normally also need to take care of having the users reset their passwords after accessing a one-time login link.

> Users often forget to change their password after they use the one time login link in their password reset email. Forgetting to set their password will require them to request password reset link emails repeatedly, without fixing the underlying problem - namely that they haven't set their password to something they can remember.

> The Password Reset Landing Page "PRLP" module enhances the original password reset landing page by letting a user set their new password at the same time they "log in" using the one-time-login link. It can also show a username and email address field. The password entry field can be configured to be mandatory. Other entry fields can be hidden through configuration and the page the user is taken to after login can be configured.

Also look at the **Similar modules** section of PRLP.

---
Tags: forms, 9, redirection
---


# Question
Title: Provide theme suggestions for menu content items
For a mega menu, I'm trying to add theme suggestions to every parent menu item / menu link depending on the chosen view mode for that menu item.

I'm aware of the `MYTHEME_theme_suggestions_menu_link_content_alter()` function but it does not work for me.

Every menu item has a `view mode` field but since I can't use a hook to preprocess it, I cannot create any theme suggestion for menu items .When I try to use the `theme_suggestion` hook on the menu, I can only see items like this:

Am I missing something? Is it possible to add theme suggestions to menu items? If so,how can I do that?

# Answer
> 1 votes
View modes in menu items don't come from core. You are probably using the Menu Item Extras module.

You can look at the Menu Item Extras module's code which does what you are asking for in menu\_item\_extras.module#L158-184.

But to have the suggestions kick in, you maybe need to make your current `menu--MY-MENU.html.twig` print actual menu item `{{ content }}` first.

Alternatively for testing try to remove any prior `menu--MY-MENU.html.twig` to have the `menu--extras.html.twig` kick in and see how the suggestions by view mode appear. You even get one suggestion for the level.

```
<!-- FILE NAME SUGGESTIONS:
   * menu-link-content--main--1--MY-VIEW-MODE.html.twig
   * menu-link-content--main--1.html.twig
   * menu-link-content--main--menu-level-0--MY-VIEW-MODE.html.twig
   * menu-link-content--main--menu-level-0.html.twig
   * menu-link-content--menu-level-0.html.twig
   * menu-link-content--main--MY-VIEW-MODE.html.twig
   * menu-link-content--main.html.twig
   * menu-link-content--MY-VIEW-MODE.html.twig
   x menu-link-content.html.twig
-->

```

---
Tags: theming, hooks
---


# Question
Title: Is it possible to override a template from the module where the original is declared
I'd like, from within a single module, to have several 'api\_field' template depending of the 'field\_name' (including the default 'api-field.html.twig' )

Like api-field--country.html.twig, api-field--date.html.twig...

So i did this

```
/**
 * Implements hook_theme().
 */
function HOOK_block_table_theme($existing, $type, $theme, $path) {
  return [
    'api_field' => [
      'variables' => [
        'field_name' => '',
        'value' => NULL
      ],
    ]
  ];
}

/**
 * Implements hook_theme_suggestions_HOOK().
 */

function HOOK_theme_suggestions_alter(array &$suggestions, array $variables, $hook) {
  if ($hook === 'api_field') {
    $suggestions[] = 'api_field__' . $variables['field_name'];
  }
}

```

But my templates ovverides are loaded only if they are in the theme, if I put them in the module they seem to be ignored by Drupal (I do place them in the "templates" directory)...

(The default template is loaded normaly from within the module)

Is this normal and if yes can it be done ?

# Answer
Any template override you want to place in the module folder has to be defined in hook\_theme() based on the base hook:

```
/**
 * Implements hook_theme().
 */
function mymodule_theme($existing, $type, $theme, $path) {
  return [
    'api_field' => [
      'variables' => [
        'field_name' => '',
        'value' => NULL
      ],
    ],
    'api_field__country' => [
      'base hook' => 'api_field',
    ],
    'api_field__date' => [
      'base hook' => 'api_field',
    ],
  ];
}

```
> 2 votes

---
Tags: theming, 9
---


# Question
Title: Excluding individual page components from caching
I can't seem to find a straight answer online about whether it is possible to exclude just one component of a page from being cached.

My component appears on all pages of the site and comes from a custom theme function rendered in page.html.twig from the following in `mytheme_preprocess_page`:

```
$alerts_renderable = [
'#theme' => 'my_alerts',
];
$variables['alerts'] = $alerts_renderable;

```

I've tried adding `#cache => ['max-age' => 0]` in that render array to no effect. I read elsewhere that changing max-age has no effect on anonymous visitors. Has anyone had success in ever doing this?

The component is an alert bar that site admins can enter text via a settings page on the backend. That message appears in the alert bar on every page of the site. Currently, when admins change the message, it requires a cache clear for the new message to be publicly visible

# Answer
The current limitations on the `max-age` implementation are documented, as are the workarounds.

> Until these (and perhaps other) issues are resolved, beware that setting max-age on a render array included in a page is insufficient to ensure that anonymous users will see a new version after the max-age as elapsed. In the meanwhile, the Cache Control Override contributed module tries to mitigate the problems. You might also have more luck setting a custom cache tag on pages with time-dependent content and invalidating those cache tags manually via hook\_cron(). Good luck!

The paragraph above contains hyperlinks to the referenced resources when viewed on the documentation page.
> 0 votes

---
Tags: caching
---


# Question
Title: How to display Media image with alt attribute in paragraph twig template
I'm trying to access alt attribute as in given example Get Media Image URL in Paragraphs Twig Template - Drupal 8

But there is an example how to access alt and title...

> That's easy, too. You should use the following syntax, switching out the bold for the machine name of your image field: {{ content.field\_custom\_image\['#items'\].alt }}

this is not worked for me

# Answer
> 1 votes
I have worked out this i have access to alt in my case its:

```
 {% if paragraph.field_media_image is not empty %}
    <img src="{{
      file_url(
        paragraph.field_media_image.entity.field_media_image.entity.fileuri
      )
      }}"
      alt="{{
      content.field_media_image[0]['#media'].field_media_image[0].alt
      }}" />
  {% endif %}

```

So solution is:

```
{{ content.field_media_image[0]['#media'].field_media_image[0].alt }}

```

# Answer
> 2 votes
Digging in Twig certainly works, though it does have limitations (such as translation support).

If you need custom output, you could try:

```
function getMediaFieldImage($mediaField = NULL, $imageStyle = NULL) {

  if ($mediaField && $mediaField->entity) {

    $langcode = \Drupal::languageManager()->getCurrentLanguage()->getId();

    // Get image.
    $mediaImage = $mediaField->entity
      ->get('field_media_image');

    // Check for translation.
    if ($mediaField->entity->hasTranslation($langcode)) {

      // Get translated image field.
      $mediaImage = $mediaField->entity->getTranslation($langcode)->get('field_media_image');
    }

    // Get image attributes.
    $alt = $mediaImage->alt;
    $width = $mediaImage->width;
    $height = $mediaImage->height;
    $title = $mediaImage->title;

    // Get image entity.
    $mediaImageEntity = $mediaImage->entity;

    // Get image mime type.
    $mediaImageMimeType = $mediaImageEntity->getMimeType();

    // Get image file URI.
    $mediaImageEntityUri = $mediaImageEntity->getFileUri();

    // Set image URL.
    $url = \Drupal::service('file_url_generator')->generateString($mediaImageEntityUri);

    // Set image style URL if not .svg.
    if ($imageStyle && $mediaImageMimeType !== "image/svg+xml") {
      $url = \Drupal::service('entity_type.manager')
        ->getStorage('image_style')
        ->load($imageStyle)
        ->buildUrl($mediaImageEntityUri);
    }

    return [
      'url' => $url,
      'alt' => $alt,
      'width' => $width,
      'height' => $height,
      'mimeType' => $mediaImageMimeType,
      'title' => $title,
    ];
  }

  return NULL;
}

```

Set it like:

```
function MYTHEME_preprocess_paragraph(&$variables) {
  $variables['mediaImage'] = getMediaFieldImage($paragraph->get('field_name'), 'medium');
}

```

And in Twig:

```
<img src="{{ mediaImage.url }}" width="{{ mediaImage.width }}" height="{{ mediaImage.height }}" alt="{{ mediaImage.alt }}" />

```

---
Tags: theming, entities, media, 9, paragraphs
---


title: Error importing configuration

text:
# Question
Title: Error importing configuration
\[error\] Drupal\Core\Config\ConfigImporterException: There were errors validating the config synchronization.

```
The <em class="placeholder">language.content_settings.media.instagram</em> setting depends on the <em class="placeholder">media.type.instagram</em> setting which will not exist after import.
The <em class="placeholder">medical_network.settings</em> setting depends on the <em class="placeholder">medical_network</em> extension which will not be installed after importing.
The <em class="placeholder">SettingsEmalForm.settings</em> setting depends on the <em class="placeholder">SettingsEmalForm</em> extension which will not be installed after import. in Drupal\Core\Config\ConfigImporter->validate() (line 756 of /app/docroot/core/lib/Drupal/Core/Config/ConfigImporter.php).

```

Maybe someone has an idea on how to solve it.

# Answer
It's all in the error message already. Let me translate:

> Your config folder contains a `medical_network.settings.yml` but your `core.extension.yml` does not contain an entry for the `medical_network` module.

Same for the `SettingsEmalForm` module, which sounds custom and wrong naming (you must only use lower case letters and underscores for module machine names) plus typo "Emal" instead of `_email_`.

And some media type `media.type.instagram` was not exported. But there's config that relies on it.

Fix it by getting a live database and exporting config once. Then restart whatever you were doing, fix naming and typos and export config again before you commit it.
> 1 votes

---
Tags: configuration
---


# Question
Title: Generating forms dynamically from json data
I have a large set of JSON data which I need to process somehow into forms for users to interact with, fill in data and submit.

However, there are far too many to create all the forms by hand and I wonder if anyone can recommend a module/package which I can use to create such large number of forms dynamically.

Below is a very small sample section of json data, each section in the json needs to be processed into a unique step of a multipage form:

```
{
    "one":{
        "Label": "Please provide your age and date-of-birth",
        "fields": [
            "Age",
            "DOB"
        ]
    },
    "two":{
        "Label": "Please provide your address",
        "fields": [
            "Address"
        ]
    },
    "three":{
        "Label": "Please provide your 6 target areas",
        "fields": [
            "Area 1",
            "Area 2",
            "Area 3",
            "Area 4",
            "Area 5",
            "Area 6"
        ]
    }
}

```

As the data above shows, each of the forms have different number of fields. The **labels** will be textfield lables and the **fields** will be textfields.

Can anyone offer some suggestions or recommendations?

# Answer
> 1 votes
I think this is going to be tough, unfortunately.

The Feeds module has good JSON support, so that's a way to get the data in. The problem is: what will you import to? Webform would seem to be an obvious choice, but Feeds only has support for importing webform submissions, not the actual forms themselves.

## Building it yourself

I have built forms using data stored on entities with the JSON Field module.

The basic approach is:

* Create a custom content type or custom entity type (**Custom Form Type**).
* Add a JSON field (**My JSON Form**) to **Custom Form Type**.
* Import the JSON data to create the forms of **Custom Form Type** (using Feeds?).
* Add a custom formatter (extending FormatterBase) to view the form field. (Optional. Users may not need to view the form field, and admins may be OK viewing raw JSON.)
* Add a custom widget (extending StringTextareaWidget if you are using a JSON field) to add the drupal form fields.

How can users submit this form?

One way to do it:

* Add a custom content type or custom entity type (**Custom Form Submission**).
* Add a JSON field (**My JSON Submission**) to **Custom Form Submission**.
* Add an entity reference field to type **Custom Form Type**.
* Add logic to **Custom Form Type** that automatically creates a **Custom Form Submission** when submitted.

What about JSON validation? I built a validator with Opis JSON Schema and then run a check against my custom schema.

## Reference

It might also be helpful to look at the JSON Field Utils module, which seems to be trying to re-implement paragraphs with JSON. This is not what you asked for, but it may give you ideas about how to code your own module.

---
Tags: forms, 9
---


# Question
Title: Why does adding #element_validate give warning about invalid callback?
I have code that adds `#element_validate` to all fields of a certain type (Link fields).

```
$form[$field_name]['widget'][0]['#element_validate'][] = '_fix_link_field_value';
array_unshift($form[$field_name]['widget'][0]['uri']['#element_validate'][0], '_fix_link_field_value');

```

This works fine, but I get this warning in the logs every time an entity with this field type is saved.

> Warning: call\_user\_func\_array() expects parameter 1 to be a valid callback, array must have exactly two members in Drupal\Core\Form\FormValidator-\>doValidateForm() (line 282 of E:\www\Noah\pre\web\core\lib\Drupal\Core\Form\FormValidator.php).

I suspect this is because the existing validator has the format \[class, method\]. Is there any way to mix these validator formats?

# Answer
> 3 votes
`#element_validate` expects an array of validation callbacks.

A callback can either be the function name of a globally accessible function, or an array of a class name and method name.

Now I am supposing that `'_fix_link_field_value'` is the name of a globally available function defined in your module.

So for using it as a validation callback, there is no array required here.

While the first line of your code is adding this callback to the callbacks of `#element_validate`, the second line is prepending it to an existing callback array, resulting in the following '#element\_validate' value:

```
[[
  '_fix_link_field_value',
  (class),
  (method),
]]

```

Which won't work. You'd need:

```
[
  '_fix_link_field_value',
  [
    (class),
    (method),
  ]
]

```

So what you really want to do is to remove the trailing `[0]` from your `array_unshift` call:

```
if (!empty($form[$field_name]['widget'][0]['uri']['#element_validate']) && is_array($form[$field_name]['widget'][0]['uri']['#element_validate'])) {
  array_unshift($form[$field_name]['widget'][0]['uri']['#element_validate'], '_fix_link_field_value');
}
else {
  $form[$field_name]['widget'][0]['uri']['#element_validate'] = [
    '_fix_link_field_value',
  ];
}

```

---
Tags: forms, 9
---


title: Export/import users

text:
# Question
Title: Export/import users
I am looking for a way to export users from one Drupal 8 Site into another Drupal 8 site.

Is it possible to do this by exporting and importing the Users tables? If so which ones?

I see there are user export modules, but I try to avoid those as it seems that the passwords do not get imported.

# Answer
Export/Importing user tables *might* work if you're doing some sort of crude one-and-done migration. The caveat is you're going to have to think through everything in the source userbase you want to migrate so you don't ruin DB referential integrity (e.g. any contrib modules that might be storing its own user-specific data).

A better way to go about it, if you're looking for a more robust, ongoing migration process is to use the D8 migration framework. While there's currently no support for a D8-to-D8 user in the core migration framework, there is a contrib project for it.
> 4 votes

# Answer
About exporting, Drupal 9 has everything you need.

* create a new view at "`/admin/structure/views/add`"
* choose type (user)
* create rest export path

You can choose serialisation as json, xml, csv, etc
> 1 votes

# Answer
You may want to use migrate for this but if it's a simple export and import then this module allows users import through CSV files.

https://www.drupal.org/project/user\_csv\_import

Also Feeds is also a good way of importing users now its ready for use in D8, you can quickly set up a parser for CSV and import.

Feeds d8 module

Heres the documentation for importing. https://www.drupal.org/docs/8/modules/feeds/creating-and-editing-import-feeds
> 0 votes

---
Tags: 8, users, importing-exporting
---


# Question
Title: How to render content entity as a token replacement?
I wonder what's the right way to render entity render array as a token replacement (value). I found 3 different ways in the contrib:

Looking at https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Render%21Renderer.php/function/Renderer%3A%3ArenderPlain/9.3.x, it looks like this method should be the correct one, given the description:

> Useful for instance when rendering the values of tokens or emails, which need a render array being turned into a string

Is that true?

# Answer
No, for example the mentioned AET module is mainly targeted to render entities via the token filter in the body field of other entities. Then the `render` method is more appropriate to bubble up the metadata and also not to replace placeholders too early. But this not perfect, either.

You find a better example in the core media embed filter, where in a token you would merge with `$bubbleable_metadata`:

*\Drupal\media\Plugin\Filter\MediaEmbed::renderIntoDomNode()*

```
  /**
   * Renders the given render array into the given DOM node.
   *
   * @param array $build
   *   The render array to render in isolation.
   * @param \DOMNode $node
   *   The DOM node to render into.
   * @param \Drupal\filter\FilterProcessResult $result
   *   The accumulated result of filter processing, updated with the metadata
   *   bubbled during rendering.
   */
  protected function renderIntoDomNode(array $build, \DOMNode $node, FilterProcessResult &$result) {
    // We need to render the embedded entity:
    // - without replacing placeholders, so that the placeholders are
    //   only replaced at the last possible moment. Hence we cannot use
    //   either renderPlain() or renderRoot(), so we must use render().
    // - without bubbling beyond this filter, because filters must
    //   ensure that the bubbleable metadata for the changes they make
    //   when filtering text makes it onto the FilterProcessResult
    //   object that they return ($result). To prevent that bubbling, we
    //   must wrap the call to render() in a render context.
    $markup = $this->renderer->executeInRenderContext(new RenderContext(), function () use (&$build) {
      return $this->renderer->render($build);
    });
    $result = $result->merge(BubbleableMetadata::createFromRenderArray($build));
    static::replaceNodeContent($node, $markup);
  }

```
> 1 votes

---
Tags: entities, tokens
---


# Question
Title: How to fetch form values for Simple hierarchical select?
I have referenced a field with taxonomy by using simple hierarchical module and now I have to fetch the options programmatically to perform some actions on them. I tried to fetch it like the below it didn't work out.

```
$form['field_delivery_methods']['widget']['#options'];

```

This worked on shs 8.x-1.0-alpha5 but after upgrading to shs 2.0.0-rc3 its not working. Does anyone help me in understanding the latest structure on how to fetch the options?

# Answer
> -3 votes
You can use `field_info_field()` or can `list_allowed_values()`.

```
$field = field_info_field('field_name');
$allowed_values = list_allowed_values($field);

```

---
Tags: forms, 9
---


# Question
Title: Why hook_ENTITY_TYPE_access and hook_ENTITY_TYPE_create_access are not fired?
I'm implementing for nodes `hook_ENTITY_TYPE_access()` and `hook_ENTITY_TYPE_create_access()` for a project and they are not fired even after cleaning the cache many times. I checked the code and there is nothing wrong and there is any message in the logs and I'm logged as Administrator.

# Answer
> 5 votes
The problem here is be logged as Administrator, this is because for determining access rights for an existing node, `\Drupal\node\NodeAccessControlHandler` first checks whether the user has the `bypass node access` permission. Such users have unrestricted access to all nodes and user 1 will always pass this check. And never will go to all implementations of `hook_ENTITY_TYPE_access()` and `hook_ENTITY_TYPE_create_access()` that are called later.

---
Tags: nodes, 9
---


title: Programmatically update products

text:
# Question
Title: Programmatically update products
I am building a site with Drupal 9 and Drupal Commerce 2 (Drupal Commerce Kickstart).

The site is complete and I have already entered all the products via Feed (there are over a million). Now I'm looking for a way to periodically update the products automatically (prices, availability, etc.)

In an old site that I had made and which was developed with Drupal 7 and did not use Drupal Commerce, it was very easy to update the nodes (products) through some scripts I had made, while in this case it is not that simple.

I thought about updating with Feed, but it's really too slow, in fact I can't update more than 20/30 products in each cron cycle; I therefore need to use a customized and faster solution. The first feed upload also took a long time.

I tried to create a php script that calls the entity of the nodes I want to modify like I did with the old site, but I can't figure out how to do it. I tried to follow this guide for Drupal 8, but I'm probably wrong to use some function or something is changed for Drupal 9.

Can someone help me?

# Answer
Using cron to execute feeds is pretty slow, so what about executing feeds with drush?

Here is a simple drush script I use to import feeds.

Execute it like this:

`drush php-script import_feeds.php`

Note that you need to use the Drupal id of each feed to import by ID.

**import\_feeds.php**

```
<?php

/**
 * @file
 * Import feeds.
 */

import_everything_in_order();

/**
 * Import all feeds in order of dependencies.
 */
function import_everything_in_order(): void {
  $id_user = 1;
  $id_media_image = 7;
  $id_page = 3;

  $feeds_to_import = [
    $id_user,
    $id_media_image,
    $id_page,
  ];
  foreach ($feeds_to_import as $feed_to_import) {
    unlock_and_import($feed_to_import);
  }
}

/**
 * Unlock a feed and then import it.
 *
 * This ensures that dependency import doesn't fail
 * due to locked feeds.
 */
function unlock_and_import(int $feed_id): void {
  exec("drush feeds:unlock $feed_id -y");
  exec("drush feeds:import $feed_id -y");
}

```
> 0 votes

---
Tags: commerce, 9
---


title: Theming User Address Book Page

text:
# Question
Title: Theming User Address Book Page
We are using drupal commerce2 on drupal 9, and I am trying to theming the address book tab (add some classes to layout and fields), `/user/*/address-book`.

Unfortunately there isn't any twig template in commerce module, anybody knows how to do this (CSS is ok, but I prefer to use twig)?

# Answer
As you mention there is no template specified for this on Commerce, the controller `\Drupal\commerce_order\Controller\AddressBookController::overviewPage` is composing the address book response using details/containers. You can provide your own controller which will return a template instead (see how to override a controller for a route) so you can deal with it in your theme.

Also, you can do is *theme* the profile entity which is being rendered per address. Since profiles are entities, you can configure the profile display to your needs.
> 0 votes

---
Tags: theming, commerce
---


# Question
Title: How to differentiate the state when a contextual filter is applied?
Hello to all the Drupal community. I've recently faced a challenge to visually modify some parts of my view's template for the state when its contextual filter is applied. Some details are as follows:

* I have a View of the articles previews list. Each article has several tag names (taxonomy terms) applied.
* This view has a Contextual filter set up to filter the list based on the taxonomy Term (tag name). The Term is provided by adding term\_id to URI (like `mysite/blog/12`). If no Term is provided - it just prints all articles.
* I have a separate views block with "Featured article" content, which is placed above my Articles list view and is limited to being visible on "`mysite/blog`" URI. This was made to avoid it from displaying on full articles pages by addressing "`mysite/blog/article-name...`"

Questions:

* How can I add some class names to the views TWIG template to indicate that this view has contextual filters applied from URI?
* How can I show the Featured article block on the "`mysite/blog`" and "`mysite/blog/TID`" pages but not for "`mysite/blog/article-name...`"?

# Answer
> How can I add some class names to the views TWIG template to indicate that this view has contextual filters applied from URI?

The easiest way to do this is inside the `views-view-DISPLAY_TYPE.html.twig` templates (e.g. `views-view-table` or `views-view-unformatted`, whatever display type you are using,...)

In that template you have access to the `view` variable, which contains the entire views object of the current page. The contextual filter values are stored in the args variable of that object, so you need something like
`{% if view.args %}...your logic here...`

> How can I show the Featured article block on the "mysite/blog" and "mysite/blog/TID" pages but not for "mysite/blog/article-name..."?

It seems you have placed that block in regions on the global block layout, while you want to show it only on your views page. So the easist way is to add the block in the view page, and not in one of the theme regions. You can place any block, even other views, in the header of a views page in the Views UI.
> 0 votes

---
Tags: views, taxonomy-terms, blocks
---


# Question
Title: How to hide the tabs on the user account if it is not his account?
My users have permission to view other users' accounts. Only the "View" tab page. This is exactly what I want.

On the user account, by default, there are three tabs:

* View
* Shortcuts
* Edit

If I am user A and I go to my account, I see the tabs. If I'm user A and I go to user B's account, I don't go to his tab (it makes sense).

Now if I create a page view (e.g. bookmarks) with a menu tab, for user accounts. If I'm User A and go to User B's account, I can see the "Bookmarks" tab.

How to hide tabs on user accounts except current user account?

There is no permission to do this.

# Answer
> 1 votes
You can add a RouteSubscriber with a custom access check to accomplish this. Something like:

```
class RouteSubscriber extends RouteSubscriberBase {

  /**
   * {@inheritdoc}
   */
  protected function alterRoutes(RouteCollection $collection) {
    if ($route = $collection->get('entity.user.canonical')) {
      $route->setRequirement('_profile_access', '\Drupal\mymodule\Access\ProfileAccessCheck::access');
    }

    if ($route = $collection->get('entity.user.edit_form')) {
      $route->setRequirement('_user_edit_access', '\Drupal\mymodule\Access\AccountEditCheck::access');
    }

    if ($route = $collection->get('entity.user.delete_form')) {
      $route->setRequirement('_user_delete_access', '\Drupal\mymodule\Access\AccountDeleteCheck::access');
    }

    // more entries...
  }

}

```

and so on, and so forth.

In the access classes you can implement custom logic that should dictate visibility.

---
Tags: views, users, 9
---


# Question
Title: How to loop through and build an array from each referenced entity
I’m trying to create a card grid component using paragraphs. I have a reference entity which references different card types with unlimited cardinality. I’m able to pull the values from the reference entity with the below code but this only pulls the initial values so I’m only getting data from one entity instead of each individual entity as they are added to the grid. I’m not sure why my foreach loop is not working in my preprocess paragraph function, can anyone steer me in the right direction?

```
if ($paragraph->getType() == 'card_grid') {
      if (!$paragraph->field_select_card_type->isEmpty()) {
        $field_select_card_type = $paragraph->field_select_card_type->referencedEntities();
        $card_array = [];
        foreach($field_select_card_type as $key => $card_type) {
          $card_title = "";
          $card_image = "";
          $card_url = "";
          $card_meta_description = "";
$card_type_data = $card_type->get('field_select_a_page')->referencedEntities();

$node_id = $card_type_data[0]->id();
          $node_data = \Drupal\node\Entity\Node::load($node_id);

          if($node_data) {
            $card_title = $node_data->title->value;
            if ($node_data->bundle() == "article") {
              $card_image = !$node_data->field_image->isEmpty() ? $node_data->field_image->entity->getFileUri() : "";
            }
            if ($node_data->bundle() == "page") {
              $card_image = !$node_data->field_featured_image->isEmpty() ? $node_data->field_featured_image->entity->getFileUri() : "";
            }
            $card_url = $node_data->toUrl()->toString();
          }

          $card_title = $card_type->field_override_title_->value ? $card_type->field_override_title_->value : $card_title;
          if($card_type->hasField('field_override_image')){
            $card_image = !$card_type->field_override_image->isEmpty() ? $card_type->field_override_image->entity->getFileUri() : $card_image;
          }
          $card_meta_description = $card_type->field_override_meta_description->value ? $card_type->field_override_meta_description->value : $card_meta_description;

          $card_array[$key]['card_title'] = $card_title;
          $card_array[$key]['card_image'] = $card_image;
          $card_array[$key]['card_url'] = $card_url;
          $card_array[$key]['card_meta_description'] = $card_meta_description;
        }

        $variables['card_array'] = $card_array;
      }

    }

```

# Answer
> 0 votes
I think this is the minimal code necessary to loop through the referenced entities and get a node from a single value field on the second level:

```
if ($paragraph->getType() == 'card_grid') {
  $cards = $paragraph->field_select_card_type->referencedEntities();
  foreach ($cards as $key => $card) {
    $node = $card->field_select_a_page->entity;
    if ($node) {
      // work with $node
    }
  }
}

```

# Answer
> 0 votes
This isn't really a Drupal question, it's a PHP question, but at a glance, I'd say it's because you are overwriting the `$variables['card_array']` on each loop instead of adding to it. You probably want this:

`$variables['card_array'][] = $card_array;`

---
Tags: hooks, paragraphs
---


# Question
Title: How to debug why some content is not migrated from D7 to D8?
I am using migrate\_plus to migrate from D7 to D8 and so far it has been a fairly smooth process.

I have a particular content type that has 10 nodes in D7 but will only migrate one of them to D8.

After running the migration, one node is reported to exist and is successfully migrated. There are no messages related to the migration so I don't have any issue to remedy, yet only one of the ten nodes are migrated.

Can anyone suggest a way to dig into why this might be happening and/or how to get the missing nodes to migrate?

# Answer
This issue was due to not factoring in languages when migrating. So if you have the same issue you'll probably need to look at your i18n migrations.
> 0 votes

# Answer
The Migrate Devel module provides a `--migrate-debug` flag that will show you all source and destination values for each piece of content during the migration. It has been invaluable to me in all of my migration projects:
> 0 votes

---
Tags: 8, migrations, debugging
---


# Question
Title: How to add/install a new field to all bundles of certain entity types?
I need to add a new string field called instagram\_owner to all bundles of nodes, media and file entities. If new bundles are created, I need the field on them too. This is what I have so far in my MODULE\_NAME.module file.

```
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Entity\EntityTypeBundleInfo;
use Drupal\Core\Entity\EntityFieldManager;

/**
 * Implements hook_entity_base_field_info().
 */
function MODULE_NAME_entity_base_field_info(\Drupal\Core\Entity\EntityTypeInterface $entity_type) {
    $entity_type_id = $entity_type->id();
    $field_name = 'instagram_owner';

    // Check for the entity types
    if ($entity_type_id === 'node' || $entity_type_id === 'media' || $entity_type_id === 'file') {

        // Specify new Instagram owner field
        $fields[$field_name] = BaseFieldDefinition::create('string')
            ->setLabel(new TranslatableMarkup("Instagram owner id"))
            ->setDescription(new TranslatableMarkup("This is the owners Instagram ID"))
            ->setSettings(["max_length" => 255, "text_processing" => 0])
            ->setDefaultValue("")
            ->setDisplayOptions("view", ["label" => "above", "type" => "string", "weight" => -3])
            ->setDisplayOptions("form", ["type" => "string_textfield", "weight" => -3]);

        // Get the bundles for this entity type
        $bundle_service = \Drupal::service('entity_type.bundle.info');
        $bundles = $bundle_service->getBundleInfo($entity_type_id);

        foreach($bundles as $bundle_id => $bundle) {

            // Check to see if our field already exists on this bundle
            $bundle_fields = \Drupal::service('entity_field.manager')->getFieldDefinitions($entity_type_id, $bundle_id);
            if (!isset($bundle_fields[$field_name])) {

                // If not, install it...
                // not sure if this will install the field either?
                // Where do I get $storage_definition from? This has never been uncommented.
                // BaseFieldDefinition::installFieldStorageDefinition($field_name, $entity_type_id, $bundle_id, FieldStorageDefinitionInterface $storage_definition);

            }
        }
        return $fields;
    }

}

```

I know that the problematic line seems to be this one. It's this that throws a 503 error page:

```
$bundle_fields = \Drupal::service('entity_field.manager')->getFieldDefinitions($entity_type_id, $bundle_id);

```

In devels php block I get the expected results. I'm using this for testing:

```
    $entity_type_id = 'node';
    $field_name = 'instagram_owner';

    if ($entity_type_id === 'node' || $entity_type_id === 'media' || $entity_type_id === 'file') {

        $bundle_service = \Drupal::service('entity_type.bundle.info');
        $bundles = $bundle_service->getBundleInfo($entity_type_id);
        dpm($bundles);
        $field_service = \Drupal::service('entity_field.manager');
        foreach($bundles as $bundle_id => $bundle) {
            $bundle_fields = $field_service->getFieldDefinitions($entity_type_id, $bundle_id);
            if (!isset($bundle_fields[$field_name])) {

                $ready_to_install = 'yes';
                dpm($ready_to_install);

            }
        }
        dpm($bundle_fields);
    }

```

Any help would be greatly appreciated.

# Answer
> 0 votes
Field storage is not bundle specific. The easiest way is to install the field storage via a config yml file in the module config install folder and then add a bundle field to each existing or later added bundle, like core is doing it for the body field. See Add content type field programmatically

Or remove any existing bundle field with that field name and add a non-bundle-specific base field for each entity type in the hook\_entity\_base\_field\_info() you are already using.

I would recommend the first way via config, this is in general a more reliable way to install and uninstall fields to existing entities.

# Answer
> 0 votes
There were a few pieces of the puzzle I hadn't understood. Firstly, hook\_entity\_base\_field\_info() just defines the specification of the base field. I originally thought I also had to install the field on each bundle within that hook. Not true.

Once the field was defined in this hook, the field appears on every bundle because it is a base field. However values won't actually get saved.

So the next thing I couldn't get my head around was how to install the schema to store the values. I learned that this can be taken care of with hook\_install, hook\_uninstall and if needed hook\_update\_N.

So, 3 days of pain later, this is what I ended up with:

**my\_module.module**

```
/**
 * Implements hook_entity_base_field_info().
 */
function MY_MODULE_entity_base_field_info(\Drupal\Core\Entity\EntityTypeInterface $entity_type) {

    // Only install on nodes and media.
    $entity_type_id = $entity_type->id();
    if ($entity_type_id === 'node' || $entity_type_id === 'media') {
        if ($entity_type_id === 'node') {
            $field_name = 'instagram_owner_display';
        }
        elseif ($entity_type_id === 'media') {
            $field_name = 'instagram_owner_media';
        }

        // Specify new Instagram owner field
        $fields[$field_name] = BaseFieldDefinition::create('string')
            ->setLabel(new TranslatableMarkup("Instagram owner ID"))
            ->setDescription(new TranslatableMarkup("This is the Instagram Account ID of who imported this."))
            ->setSettings(["max_length" => 255, "text_processing" => 0])
            ->setDefaultValue("")
            ->setDisplayOptions("view", ["label" => "above", "type" => "string"])
            ->setDisplayOptions("form", ["type" => "string_textfield"]);
        return $fields;
    }
}

```

**my\_module.install**

```
/**
 * Implements hook_install().
 */
function MY_MODULE_install() {

    // Install Instagram owner field on nodes and media
    $field_manager = \Drupal::service('entity_field.manager');
    $field_storage_manager = \Drupal::service('field_storage_definition.listener');

    $node_definition = $field_manager->getFieldStorageDefinitions('node')['instagram_owner_display'];
    $field_storage_manager->onFieldStorageDefinitionCreate($node_definition);

    $media_definition = $field_manager->getFieldStorageDefinitions('media')['instagram_owner_media'];
    $field_storage_manager->onFieldStorageDefinitionCreate($media_definition);
}

/**
 * Implements hook_uninstall().
 */
function MY_MODULE_uninstall() {

    // Delete Instagram owner field on nodes and media
    $field_manager = \Drupal::service('entity_field.manager');
    $field_storage_manager = \Drupal::service('field_storage_definition.listener');

    $node_definition = $field_manager->getFieldStorageDefinitions('node')['instagram_owner_display'];
    $field_storage_manager->onFieldStorageDefinitionDelete($node_definition);

    $media_definition = $field_manager->getFieldStorageDefinitions('media')['instagram_owner_media'];
    $field_storage_manager->onFieldStorageDefinitionDelete($media_definition);
}

/**
 * Install the new Instagram owner field on existing media and node bundles.
 */
function MY_MODULE_update_N() {

    // Install Instagram owner field on nodes and media
    $field_manager = \Drupal::service('entity_field.manager');
    $field_storage_manager = \Drupal::service('field_storage_definition.listener');

    $node_definition = $field_manager->getFieldStorageDefinitions('node')['instagram_owner_display'];
    $field_storage_manager->onFieldStorageDefinitionCreate($node_definition);

    $media_definition = $field_manager->getFieldStorageDefinitions('media')['instagram_owner_media'];
    $field_storage_manager->onFieldStorageDefinitionCreate($media_definition);
}

```

---
Tags: entities, hooks, 9
---


# Question
Title: Get a list of all entity reference fields that reference specific entity types
Is there a way to get a list of entity reference fields by field type (similar to what is produced by `$all_reference_fields = $this->entityFieldManager->getFieldMapByFieldType('entity_reference');`) but filtered down to just list the entity reference fields that have target entity types and bundles that match a specified list.

I'm not seeing anything in the entityFieldManager that would make it easy to filter the results of the `getFieldMap()` or `getFieldMapByFieldType()` down to just specific reference fields I'm looking for, because the mapping doesn't contain any of the field's storage information, that contains the list of target bundles and handlers.

Looks like the entity\_reference module in core doesn't provide any services that would be the logical place for something like this, so my current thinking is that I'll need to do this in two steps:

1. Call `getFieldMapByFieldType('entity_reference');`.
2. Work through every single entity type in the field map, and call `buildFieldStorageDefinitions($entity_type);` or something of that nature, to figure out the target `entity_type:bundle_name` combinations, and track down fields that reference `'taxonomy_term:tag'`. This seems horribly inefficient, due to the sheer number of entity\_reference type fields in this site, so maybe there is a better way to do this step?

In an ideal world, there'd be just a set of database calls I could make, or even a service in core for entity\_reference module! (wishful thinking) ;)

# Answer
> 2 votes
Answering this myself based on the investigation I did using `field_entity_bundle_delete` for inspiration. Would be great if someone could take this code and improve it.

```
/**
 * Helper method gets a list of all entity reference fields that reference
 * the specified entity type.
 *
 * @param $entity_type string
 * @param $entity_bundle string (optional)
 * @return array
 *   Filtered field map of entity reference fields.
 */
protected function getEntityReferenceFieldsByEntityType($entity_type, $entity_bundle = '') {
  // Gather a list of all entity reference fields.
  $map = \Drupal::service('entity_field.manager')->getFieldMapByFieldType('entity_reference');
  $ids = [];
  foreach ($map as $type => $info) {
    foreach ($info as $name => $data) {
      foreach ($data['bundles'] as $bundle_name) {
        $ids[] = "$type.$bundle_name.$name";
      }
    }
  }
  // Determine if any of the reference fields reference a specific entity type
  // and bundle type.
  $filtered_map = [];
  foreach (FieldConfig::loadMultiple($ids) as $field_config) {
    $field_name = $field_config->getName();
    $target_type = $field_config->getSetting('target_type');
    if (!empty($target_type) && $target_type == $entity_type) {
      if (!empty($entity_bundle)) {
        $handler_settings = $field_config->getSetting('handler_settings');
        if (isset($handler_settings['target_bundles'][$entity_bundle])) {
          $filtered_map[$entity_type][$field_name] = $map[$entity_type][$field_name];
        }
      } else {
        $filtered_map[$entity_type][$field_name] = $map[$entity_type][$field_name];
      }
    }
  }
  return $filtered_map;
}

```

# Answer
> 2 votes
The one-step way to do what you're looking for is `FieldStorageConfig::loadByProperties`.

For example, to find all entity reference fields with target type of `taxonomy_term`, the following code will work:

```
$taxonomy_fields = \Drupal::entityTypeManager->getStorage('field_storage_config')
  ->loadByProperties([
     'type' => 'entity_reference',
     'settings' => [ 'target_type' => 'taxonomy_term' ],
    ]);

```

(This will also work without explicitly including the `'type' => 'entity_reference'` since other types of fields won't have a `target_type` in their settings, but including it makes the code easier to understand.)

And of course, this could be made more generic so that you're passing in the `target_type` to match for. Of course, if you want to know what specific vocabularies are in use for a given taxonomy field, that's in the individual `FieldConfig`'s on each bundle — so for that you'd have to load and examine each configuration for a given field on a bundle type.

For anyone doing follow-up research, the key for me figuring this out was to look at exports of field storage configurations so I could figure out what I was trying to match to in the `loadByProperties` call.

# Answer
> 2 votes
This is a generic function I'm normally using from https://cornel.co/article/get-list-fields-type

```
function getFieldsByTypeAsOptions(string $type, ?array $settings = NULL): array {
  $properties = ['type' => $type];
  if ($settings) {
    $properties = ['settings' => $settings];
  }
  $entityTypeManager = \Drupal::entityTypeManager();
  $entityRefFields = $entityTypeManager
    ->getStorage('field_storage_config')
    ->loadByProperties($properties);
  $options = ['' => '- Select -'];
  foreach ($entityRefFields as $entityRefField) {
    $fieldName = $entityRefField->getName();
    $options[$fieldName] = $fieldName;
  }
  return $options;
}

```

# Answer
> 0 votes
I use this for deleting orphaned references

```
/**
 * Remove Orphaned References
 *
 * @command database_hacks:deleteOrphanedReferences
 * @aliases deleteOrphanedReferences
 */
public function deleteOrphanedReferences(): void
{
    $taxonomy_fields = Drupal::entityTypeManager()->getStorage('field_storage_config')->loadByProperties([
        'type' => 'entity_reference',
        'settings' => [ 'target_type' => 'taxonomy_term' ],
    ]);

    $connection = Drupal::database();
    foreach ($taxonomy_fields as $field) {
        $tableName = str_replace('.', '__', $field->get('originalId'));
        $fieldName = $field->get('field_name') . '_target_id';

        $sql = <<<TXT
            DELETE i
            FROM {$tableName} i
            LEFT JOIN taxonomy_term_field_data d
            ON i.{$fieldName} = d.tid
            WHERE d.name IS NULL;
TXT;

        $connection->query($sql);
        GeneralHelper::message($sql, 'status');
    }

    $sql = <<<TXT
        DELETE i
        FROM taxonomy_index i
        LEFT JOIN taxonomy_term_field_data d
        ON i.tid = d.tid
        WHERE d.name IS NULL;
TXT;

    $connection->query($sql);
    GeneralHelper::message($sql, 'status');
}

```

---
Tags: entities
---


# Question
Title: Service continues to act as shared when shared is set to false
According to Symfony docs, doing `shared: false` on a service should mean that each time you call a service, you get a new instance. However, this doesn't seem to work for me. I am using Drupal 9 which runs on Symfony 4.4.

My services.yml :

```
services:
  my_module.arbitrary_data:
    class: Drupal\my_module\Services\ArbitraryData
    arguments: ['@another_module.contextual_uid']
    shared: false

```

https://symfony.com/doc/4.4/service\_container/shared.html

I've also tried the deprecated `scope: prototype` and `scope: request` methods to no avail. If I load a page, my services outputs unchanged data from the last time the page was loaded until I clear cache.

Regardless of doing this, the services fail to run after the first page load after clearing cache and just proceed to output unchanged data every time. This feels like "unwanted caching".

Edit 11/15 3:47PM The render array from the plugin using the service, as requested:

```
$service = \Drupal::service('my_module.arbitrary_data');
$data = $service->get('acr');
$data = array_shift($data);

return [
  '#markup' => $data['value'],
];

```

# Answer
Thanks to user @Clive 's questioning, it led me to assess this issue as a Plugin problem rather than a Service problem. Since the service is being used in a plugin, and the plugin was being cached (by default), my output was not changing.

Implementing cache max-age into the plugin's render array fixed this issue.

```
return [
  '#markup' => $data['value'],
  '#cache' => [
    'max-age' => 0,
  ],
];

```
> 2 votes

---
Tags: 9, caching, symfony-services
---


# Question
Title: Unable to enter credit card payment information
I just noticed that I'm unable to enter credit card payment information (card number, expiration date, CVV) when going through the Drupal Commerce checkout processing using the Square Connect payment gateway. This was working fine in the past; I'm not sure when it stopped working but it might be related to the newest Commerce Core release on 19 October 2022. The fields are there, but I can't enter text in any of the text boxes. They're blank and read-only. What might have changed, and how can I fix it?

These are the modules I'm using:

* Commerce Core 8.x-2.32 (released 19 October 2022)
* Commerce Square Connect 8.x-1.5 (released 13 April 2022)

# Answer
This is due to an API deprecation by Square that the module was not prepared for in advance. Please test the following patch and comment on the issue if it works for you. Thanks!

https://www.drupal.org/project/commerce\_square/issues/3231283#comment-14772813
> 3 votes

---
Tags: commerce, payment-gateways
---


title: How can I change theme?

text:
# Question
Title: How can I change theme?
I tried `drush disable theme-name` and afterwards `drush enable theme-name`, but it didn't work.

How do you change theme with Drush?

# Answer
Commands to be used in theme using drush :

```
theme-enable        => pm-enable
theme-disable       => pm-disable
theme-info          => pm-info
theme-list          => pm-list --type=theme
theme-list-enabled  => pm-list --type=theme --status=enabled
theme-set-default   => vset theme_default
theme-set-admin     => vset admin_theme
theme-status        => status theme

```
> 13 votes

# Answer
For ***Drush 9.5.2*** and ***Drupal 8.6.5*** I use the following:

```
drush theme:uninstall THEME_MACHINE_NAME
drush theme:enable THEME_MACHINE_NAME
drush config-set system.theme default THEME_MACHINE_NAME

```
> 36 votes

# Answer
With Drush 7 and 8, it is no longer necessary to be so verbose. If you want to enable a theme use the alias:

```
drush en your-theme-name
drush dis your-theme-name

```

For example:

```
drush en seven
drush dis bartik

```

You may want to clear your caches after enabling or disabling themes. For more information please see: DrushCommands.com
> 1 votes

# Answer
If you want to change the admin theme using Drush, you can use below command.

```
drush config-set system.theme admin <theme_machine_name>

```

Eg.

```
drush config-set system.theme admin seven

```

If the theme is not installed, first install the theme using below command

```
drush theme:en seven

```

Again run the above command to set admin theme.
> 1 votes

# Answer
`drush dis` and `drush disable` aren't anymore valid, in Drupal 8. Their Drupal 8 equivalent are the following commands.

```
drush pm-uninstall THEME_MACHINE_NAME
drush pm-uninstall MODULE_MACHINE_NAME

```
> -1 votes

---
Tags: drush
---


# Question
Title: "message": "X-CSRF-Token request header is missing"
When using postman to fire post request I get this message. Does anyone has idea how to disable it? In this case it is post to register user so no authentification is required.

# Answer
One reason you may get an `X-CSRF-Token request header is missing` when testing with Postman is that you are using bearer authentication but you also have a session cookie.

Postman will automatically save session cookies and send them with requests, so if you are trying to debug decoupled registration, you may notice this error.

There is more info in the drupal.org issue here.

To fix it, you can be vigilant about deleting the cookies after each request when testing with Postman, or apply the patch in the linked issue.
> 5 votes

# Answer
This is not recommend to remove the X-CSRF-Token. Instead you should get the token from /rest/session/token and add this token in your header with this value.

But if you want to disable it you can write this below line to your settings.php file $conf\['services\_csrf\_token\_check\_disabled'\] = TRUE;
> 3 votes

# Answer
If you are using Drupal 8 to create a POST rest api with oauth2, and postman to test it, you can, in postman, create a new tab using GET, and point to the url:

```
https://drupal_localhost/rest/session/token

```

Then send the request and copy the response token to the POST tab in postman, under the Headers:

```
X-CSRF-Token          <previous_token>

```
> 0 votes

# Answer
Yeah for Drupal 9 ect you can do the GET "session/token" ect then use the header

but if you think its silly to have to do 2 requests then you could do something like this....

make a Route Subscriber ...

```
class RouteSubscriber extends RouteSubscriberBase {

/**
 * {@inheritdoc}
 */
protected function alterRoutes(RouteCollection $collection) {
//Get the Route name here ..
if ($route = $collection->get('rest.something.POST')) {
   $req = $route->getRequirements();
   unset($req['_csrf_request_header_token']); //<-- this bit
   $route->setRequirements($req);
 }

```

Drupal Docs https://www.drupal.org/docs/drupal-apis/routing-system/altering-existing-routes-and-adding-new-routes-based-on-dynamic-ones

and Credit to @Patrick Kenny because yep postman does that so it will work the Frist time but then wont due to the auto cookie nice catch confusing if using things like the key\_auth module.
> 0 votes

---
Tags: 8
---


# Question
Title: Add theme suggestion to a node depending on the menu it belongs to
I have a mega menu that displays child menu items when you click on a parent menu item in form of a drop-down menu. The thing is that, this menu, also displays cards as nodes and I want to add a theme suggestion only to this card nodes that are inside the menu drop-down.

I can get the node with a simple `MYTHEME_theme_suggestions_node_alter()` hook but I don't know how to get the menu item of it.

I've tried `menu_ui_get_menu_link_defaults($node)` as seen in this question but it always returns 'main', which is correct but, also almost every node on the page apart from the drop-down menu node seems to come from it and, therefore, that's not what I want.

All I need is an exclusive theme suggestion for this nodes represented on the mega menu drop-down

# Answer
> 0 votes
Adding a new *view mode* just for this types of nodes that are rendered on the menu, is the best approach, specially if this nodes are just from one bundle like 'page'.

---
Tags: theming, nodes, hooks, navigation
---


# Question
Title: How can I bust the cache for the toolbar?
I am creating a drupal module and here in the module file i created a check on hook\_toolbar() function that if there are credentials in the database it will show 4 links in dropdown otherwise it will show only 2 links. Initially with no credentials it shows 2 links but whenever i get credentials and update them in the database i have to clear cache in order to update the tray in the hook\_toolbar() in order to show 4 links.

```
function try_toolbar() {
    $items = [];
    \Drupal::service('page_cache_kill_switch')->trigger();
    $items['TRY'] = [
        '#cache' => [
            'contexts' => ['user.permissions'],
        ],
    ];

    if (!\Drupal::currentUser()->hasPermission('Access the Commande overview page')) {
        return $items;
    }

    $credentials = db_select('config', 'n')
        ->fields('n')
        ->condition('collection', 'TRY','=')
        ->execute()
        ->fetchAssoc();
    $opValue = $credentials['data'];

    if($credentials) {
        $items['TRY'] += [
            '#type' => 'toolbar_item',
            '#weight' => 1,
            'tab' => [
                '#type' => 'link',
                '#title' => 'TRY',
                '#url' => \Drupal\Core\Url::fromUri("internal:/admin/try"),
                '#attributes' => [
                    'title' => 'try menu',
                    'class' => ['toolbar-icon', 'toolbar-icon-try'],
                ],
            ],
            'tray' => [

                'configuration' => [
                    '#type' => 'link',
                    '#title' => 'Dashboard',
                    '#url' => \Drupal\Core\Url::fromUri("internal:/admin/try_dashboard"),

                ],[
                    '#type' => 'link',
                    '#title' => 'Notifications',
                    '#url' => \Drupal\Core\Url::fromUri("internal:/admin/try_notifications"),
                ],[
                    '#type' => 'link',
                    '#title' => 'Settings',
                    '#url' => \Drupal\Core\Url::fromUri("internal:/admin/try_settings"),
                ],[
                    '#type' => 'link',
                    '#title' => 'Help',
                    '#url' => \Drupal\Core\Url::fromUri("internal:/admin/try_help"),
                ],

            ],
            '#attached' => array(
                'library' => array(
                    'try/admin',
                ),
            ),

        ];
        return $items;

    } else {
        $items['TRY'] += [
            '#type' => 'toolbar_item',
            '#weight' => 1,
            'tab' => [
                '#type' => 'link',
                '#title' => 'TRY',
                '#url' => \Drupal\Core\Url::fromUri("internal:/admin/try"),
                '#attributes' => [
                    'title' => 'try menu',
                    'class' => ['toolbar-icon', 'toolbar-icon-try'],
                ],
            ],

            'tray' => [

                'configuration' => [
                    '#type' => 'link',
                    '#title' => 'On Board',
                    '#url' => \Drupal\Core\Url::fromUri("internal:/admin/onBoard"),

                ],[
                    '#type' => 'link',
                    '#title' => 'Verify Credentials',
                    '#url' => \Drupal\Core\Url::fromUri("internal:/admin/try_settings/verifyCredentials"),
                ]

            ],
            '#attached' => array(
                'library' => array(
                    'try/admin',
                ),
            ),

        ];
        return $items;
    }
}

```

Here i used the following code to disable the cache

```
\Drupal::service('page_cache_kill_switch')->trigger();

```

But it is not working thus forcing me to manually clear the cache.

Please tell me a way to bust the cache depending on that database result.

# Answer
> 3 votes
Setting max-age to zero, as well as using the killswitch you have in your code `\Drupal::service('page_cache_kill_switch')->trigger();`, are both sledgehammer solutions to a problem that Drupal is built to handle with finesse. Rather than rebuilding the menu on every page load, a cache tag is added to the render array. Then when the DB credentials for that user are cleared, that cache tag is invalidated. The next time it is requested by a user who matches the invalidated cache tage, it will be rebuilt and re-cached.

You can add a cache tag to your existing cache declaration on the render array as follows:

```
'#cache' => [
  'contexts' => ['user.permissions'],
  // Might be 'tag' not 'tags'. I can't remember which.
  // Tag is in the format [IDENTIFIER]:[USERID].
  'tags' => 'example_credentials:' . \Drupal::currentUser()->id(),
],

```

Then, when the toolbar should be rebuilt, which in your case is when the user submits their new credentials to be saved, you invalidate that cache tag:

```
Drupal\Core\Cache\Cache::invalidateTags()

```

If your menu isn't user specific, but rather role specific, permission specific, or some other metric, change the references to current user ID to some other identifier that for that role, or that permission, or whatever suits your needs. If no specificity is required at all - IE the menu items should be built for all users (to whom the cache context applies), you can remove the specific identifier altogether, and just use `[IDENTIFIER]`, which in the above example is `example_credentials`.

---
Tags: caching, toolbar
---


# Question
Title: How do I use $form_state['storage']['my_key']?
The question is clear from the title itself .

I looked in the api specified in : https://www.drupal.org/node/2310411 .

But it only mention to convert

```
$storage = &$form_state['storage'];
$form_state['storage'] = &$storage;

```

to

```
 $storage = &$form_state->getStorage();
 $form_state->setStorage($storage);

```

But not a key in the $form\_state\['storage'\] ? any help is appreciated .

# Answer
The example in the documentation link seemed to cause confusion. Simply set your values in an associative array and use set/get storage.

```
$vals = [
  'name' => 'bob',
  'age' => 50
];

// save the data.
$form_state->setStorage($vals);

// retrieve the data
$vals = $form_state->getStorage();
$str = $vals['name'] . ' is ' . $vals['age'] . ' years old.';

```

https://www.cyberdev.co/how-to-store-temp-form-state-data
> 1 votes

# Answer
In my case updating directly using setStorage breaks my submission. It would be better to get the storage before to update it to avoid to override/delete some stuffs that other modules whould have done before.

```
function hook_form_alter or equivalent () {
  $storage = &$form_state->getStorage();
  $storage['uid'] = $user->id();

  // Or
  $storage =$form_state->getStorage();
  $storage['uid'] = $user->id();
  $form_state->setStorage($storage);
}

// In my submit custom function
function submitCustomFunction () {
  $storage = $form_state->getStorage();
  // You would add some test
  $user = User::load($storage['uid']);
}

```
> 1 votes

# Answer
> How do I use `$form_state['storage']['my_key']`

The confusion is that the above key is for Drupal 7, but the OP is using Drupal 8. As can be seen from the thread title, `$form_state` is an array, but the tags of the thread show the user is on Drupal 8. Between Drupal 7 and Drupal 8, `$form_state` was switched from an array to an object of type `Drupal\Core\Form\FormStateInterface`
> 0 votes

# Answer
The example uses the reference. It's okay if you do not need one. So

```
$storage = $form_state->getStorage();
$form_state->setStorage($storage);

```

also working.
> -1 votes

---
Tags: forms, 8
---