# Question
Title: RuntimeException when patch submission. Module Webform Rest
When i send a PATCH request to my site to /webform\_rest/{webform\_id}/submission/{sid}?\_format=json with the body

```
{
    "data":{
        "sincronizado":1
    }
}

```

or

```
{
  "sincronizado":1
}

```

from postman, I receive a 500 error.

The site log displays the next error:

> RuntimeException: Callable "Drupal\webform\_rest\Plugin\rest\resource\WebformSubmissionResource::patch" requires a value for the "$webform\_data" argument. en Drupal\Component\Utility\ArgumentsResolver-\>handleUnresolvedArgument() (line 142 of /usr/home/example.com/web/core/lib/Drupal/Component/Utility/ArgumentsResolver.php).

Am I making a bad request? What is the `$webform_data` argument? My webform has a field "sincronizado", of type value.

I'm using Drupal 9. REST UI 8.x-1.18. RESTful Web Services 9.0.2 Webform 6.0.0-alpha12 Webform Rest 4.0.0-beta1

---

Same problem sending sid parameter with Webform rest version 8.x-2.0-beta3.

My request from postman, in curl code is

`curl --location --request PATCH 'http://example.com/webform_rest/webform-id-example/submission/36?_format=json' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic (admin user and password in base 64)' \
--data-raw '{
"sincronizado":"1"
}'`

# Answer
> 0 votes
Ok mate if you open up webform\_rest\Plugin\rest\resource\WebformSubmissionResource.php

and find the patch method you will see

```
public function patch($webform_id, $uuid, array $webform_data) { ...

```

looks like Webform Rest 4.0.0-beta1 is now using the submission uuid so

```
/webform_rest/{webform_id}/submission/{sid}

```

"sid" should now be Webform Submission UUID

for the body field or the $webform\_data

the module is looking for

```
  foreach ($webform_data as $field => $value) {
      $webform_submission->setElementData($field, $value);
    }

```

so your json should look like:

```
   {
    "filed_name": "value"
   }

```

because json\_decode($json\_string, true) will return an array.

if that does not work then file a bug ticket

---
Tags: webforms, http-request
---


# Question
Title: Creating a grid of referenced Commerce products
I'm using Drupal 7 along with Commerce 1.x and I have created a content type that has reference field for Commerce Product entities.

And now I would like to render a grid of referenced products i.e. dedicated add to cart form for each product on the node page.

At least so far it seems like an impossible task to do. I've tried with Views, custom form template variable etc. but it always gives errors like

*Notice: Undefined index: #options in function form\_process\_radios() (row 3188*

*Parameter must be an array or an object that implements Countable in function form\_process\_radios() (rivi 3188*

Somehow it is always expecting a radio element with options (which is the default formatting) for multiple products. However, that is not what I want and I've tried to set it as hidden element. I also can see the forms but would like to get rid of errors and create this "by the book".

```
<?php
function mymodule_preprocess_entity(&$variables) {

  $variables['add_to_cart_form'] = '';

  if ($variables['elements']['#entity_type'] == 'commerce_product'){

      $item = $variables['elements']['#entity'];

      if (empty($item->product_id)) {
        return;
      }

      $form_id = commerce_cart_add_to_cart_form_id([$item->product_id]);

      $line_item = commerce_product_line_item_new($item, 1, 0, [], 'custom_owner');
      $line_item->commerce_product = $item->product_id;
      $line_item->data['context']['product_ids'] = array($item->product_id);
      $line_item->data['context']['show_single_product_attributes'] = 1;

      $product_form = drupal_get_form($form_id, $line_item);

      // Trying to change from radio element to hidden
      $product_form['product_id']['#type'] = 'hidden';
      unset($product_form['product_id']['#theme_wrappers']);
      unset($product_form['product_id']['#process']);

      $form_markup = drupal_render($formp);
      $variables['add_to_cart_form'] = array('#markup' => $form_markup);

  }

}?>

```

# Answer
> 1 votes
This is possible out of the box without any custom code, just plain Views. The trick is to make the View based on content of whatever your node type is and set a relationship from the node to the products referenced by its product reference field. Once you have product fields available to the View, Commerce 1.x provides a per-variation Add to Cart form field to drop into the View.

I created a sample View that does this, placing it in a block on node pages of my product display node type. It uses a contextual filter to determine the node ID from the URL, joins to the products via the relationship I described above, and then shows the product title, price, and Add to Cart form in a grid:

Note that the line items added via the product Add to Cart forms do not maintain the context of the node; that's why "Product Three" is rendered as a link in my cart but Two and One are not. It *would* take custom code to ensure those forms have the appropriate context at this point, but that's another question.

In case you're a visual learner, here's the View I constructed to make this work:

---
Tags: commerce
---


# Question
Title: Content type 'Product Display' not available when creating new View
I am working through the "Advanced Product Display Listing using Views" guide here. When creating the new View, I do not have the option to select 'Product Display' as a content type. Is there a configuration setting I have missed when installing Commerce from scratch?

Thanks, Geoff.

Drupal 7.67, Commerce 1

# Answer
> 1 votes
For D7, Commerce 1, unless you use Commerce Kickstart, you have to manually create it. Follow this tutorial.

---
Tags: commerce
---


# Question
Title: Is there a way to add a Tour on all the pages/routes?
I need to create a Tour guide for the generic elements in a page like Search bar, notification, sidebar. These elements appear on all the pages. I want to create a tour which is available on all the pages. The tour is being created using Tour UI module. Is there a way to create a Tour for all the routes available. Most of the pages are Landing page nodes and few view pages.

# Answer
Since you're using the Tour UI module, add the routes to the list

All node pages have the same route, `entity.node.canonical`

For view pages, they are unique. You can use Devel's Webprofiler module to see the route names, ex:

They are basically structured as `view.[view_name].[display_id]`

<sub>**Note:** display\_id is also known as the machine name value.</sub>

---

> Is there a possibility to have wildcards in the routes? Chances are thin

There isn't. You would have to tinker with the Tour UI module's code.

> Also, is there a way to enable tour for a specific node?

There isn't. You'll prob have to use one of the hooks shown in tour\_test.module to unset if the entity/node id is not the one you want.

---

Because of the routing limitation, seems to me like the core tour module was built towards showing how to edit or configure pages for administrators and not catered towards anonymous users. For your use case, you're better off using

**D8: Bootstrap Tour module** which is using the bootstrap tour library

> No need to be familiar with Drupal routing names to be able to assign a tip to a page, this modules works purely on jQuery selectors so you may add the page body class plus some jQuery selectors to target a specific page instead of routing name.
> 2 votes

---
Tags: 8
---


# Question
Title: Tracking how long it takes a user to submit a node edit form?
For a quiz node, I want to track how long it takes a user to submit a node form (the time from Drupal generating the form until the time that the user presses submit), and I want to store this duration in a field on my node.

**Use case**

Each node of content type **Quiz** is a 10 question quiz. I want to track the time that users spend filling out the node in order to track their improvement in speed over time.

I do NOT want to track the time spent on the website in general; for that, I already use Google Analytics with scroll tracking, and there is also the Time Spent module.

**What I tried**

On my node, I added an *Integer* field, **Duration**. My thought was that I could calculate the interval from the timestamp when the form was generated until the time the node was saved by adding code in `hook_node_presave()`:

```
  $original_time = ??? // How do I get the time when the node form was generated?
  $current_time = \Drupal::time()->getCurrentTime();
  $duration = $current_time - $original_time;

```

Where I'm stuck is I don't know how to get the time when the node form was created.

I tried to add a *Datetime* field to my node with a **Default date** of *Current date*, but the current date is not set until the node is saved, so that doesn't work.

So, how can I track the time from generating a node edit form until the time the user presses submit?

# Answer
Here is how I would do it:

```
/*
 * Implements hook_form_FORM_ID_alter().
 */
function mymodule_form_node_quiz_edit_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  $form['field_duration']['widget'][0]['value']['#type'] = 'hidden'; // hide field
  $form['field_duration']['widget'][0]['value']['#default_value'] = time(); // set default value to start time
  array_unshift($form['actions']['submit']['#submit'], 'mymodule_calc_duration'); // adds a custom submit that runs before the default node submit
}

function mymodule_calc_duration(&$form, \Drupal\Core\Form\FormStateInterface $form_state) {
  $start_time = $form_state->getValue('field_duration')[0]['value']; // get default value
  $duration = time() - $start_time; // calculate duration
  $duration_value = [
    ['value' => $duration],
  ];
  $form_state->setValue('field_duration', $duration_value); // set duration value
}

```
> 3 votes

# Answer
Based on NoSssweat's code, I was able to get a working solution for my site.

Note the use of `\Drupal::time()->getCurrentTime()` instead of `time()`; this is necessary if you are using something like the Datetime Testing module to change the time for behat tests, because in that case you have to rely on Drupal's time, not the server time.

```
/*
 * Implements hook_form_FORM_ID_alter().
 */
function mymodule_form_node_quiz_edit_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  $form['field_duration']['widget'][0]['field_duration']['#type'] = 'hidden'; // hide field
  $form['field_duration']['widget'][0]['field_duration']['#default_value'] = \Drupal::time()->getCurrentTime(); // set default value to start time
  $form['#validate'][] = 'mymodule_calc_duration'; // adds custom validation that runs after all other validation passes
}

function mymodule_calc_duration(&$form, \Drupal\Core\Form\FormStateInterface $form_state) {
  $start_time = $form_state->getValue('field_duration'); // get default value
  $duration = \Drupal::time()->getCurrentTime() - $start_time; // calculate duration
  $duration_value = [
    ['value' => $duration],
  ];
  $form_state->setValue('field_duration', $duration_value); // set duration value
}

```
> 1 votes

# Answer
1. create a field in your form and in `Hook_form_alter` and hide it

```
  if ($form_id == 'form_id') {
      $form['field_view_node_start']['#access'] = FALSE;
      $form['field_view_node_start']['widget'][0]['value']['#default_value'] = time();
  }

```
2. at hook\_entity\_presave get time between field\_view\_node\_start and field\_view\_node\_end

```
function hook_entity_presave(Drupal\Core\Entity\EntityInterface $entity) {
      $entity->set("field_view_node_end",time());
}

```
> -1 votes

---
Tags: 8, forms
---


# Question
Title: How to print "node title" in comment.html.twig template?
i am styling my comments in comment.html.twig template and need to show "node title" of the node to which the comments belong.

I've tried a number of options, and the only one that works relatively is below:

```
function enar_preprocess_comment(&$variables){
   $node = \Drupal::request()->attributes->get('node');
   $variables['nodetitle'] = $node->getTitle();
}

```

However, if I click "reply" in the comments, I get this error.

```
Error: Call to a member function getTitle() on null in mytheme_preprocess_comment()

```

My question is, how to print "node title" in comment.html.twig template?

# Answer
> 1 votes
Because the comment reply page/route does not belong to a Node entity

```
$node = \Drupal::request()->attributes->get('node');

```

returns null.

Instead, access the node object with

```
$node = $variables['commented_entity'];

```

---
Tags: 8, theming, comments
---


title: How do I migrate translated content?

text:
# Question
Title: How do I migrate translated content?
I'm working on migration from an old Drupal 8 site to new Drupal 9 site:
I developed a source plugin to get data from D8 database:
My migration works, but it doesn’t migrate all my contents and get this error:

> Drupal\Core\Database\IntegrityConstraintViolationException: SQLSTATE\[23000\]: Integrity constraint violation: 1062 Duplicate entry '8a7e1ba8-9b75-4813-80d6-99104c82efa5' for key 'node\_field\__uuid\__value': INSERT INTO {node} ("vid", "type", "uuid", "langcode") VALUES (:db\_insert\_placeholder\_0, :db\_insert\_placeholder\_1, :db\_insert\_placeholder\_2, :db\_insert\_placeholder\_3); Array

When I debug the issue and I have found that there is some translated nodes have the same **nid** **vid** only **langcode** is different like the example bellow.

I added the langcode as id in my source plugin but it doesn't help:

```
  public function getIds() {
    return [
      'nid' => [
        'type' => 'integer',
        'alias' => 'n',
      ],
      'langcode' => [
        'type' => 'string',
        'alias' => 'n',
      ],
    ];
  }

```

How can i migrate those nodes ?
Used modules: Migrate/ Migrate plus / Migrate Tools .
Drupal Version : 9.0.3

# Answer
> 0 votes
> I have found that there is some translated nodes have the same nid vid only langcode is different

When using translation, that's ok and normal.

---

However, what's never ok and not normal:

> Duplicate entry '8a7e1ba8-9b75-4813-80d6-99104c82efa5' for key 'node\_field\__uuid\__value': INSERT INTO {node} ("vid", "type", "uuid", "langcode")

**U**niversally **U**nique **ID**entifier cannot be the same, has to be unique. The error is telling you that you have two or more nodes, in the node table, with the same UUID.

So either you have 2 or more Nodes in D8 with the same UUID or perhaps you have a node that was already migrated to D9, but your migration is failing to see that and skip it.

If both are on D8, when you find which nodes have the same/duplicate UUID, via Drupal delete one and re-create it. Just in case, check that the other one didn't get deleted as well because it had the same UUID.

---
Tags: migrations, 9
---


# Question
Title: Change placement of 'Read more' link in a teaser
I have a view where the content is displayed as teasers on the page. There is a 'Read more' link that is displayed above the body text for each teaser (refer to the screenshot below, circled in red), but I would like it to sit underneath the body text instead. Any suggestions on how this can be done?

# Answer
I figured out how to move the 'Read more' link to display below the body text for each teaser.

In my Drupal site, I went into 'Structure' in the main administration menu \> 'Content types' \> Selected the content type I created (in this case, it was: 'Blog post') \> Manage display \> and then went into the 'Teaser' tab. I was then able to move around the fields so that the 'Read more' link displayed below the body text.
> 1 votes

---
Tags: theming
---


# Question
Title: In a taxonomy view, enabling aggregation causes HTML tags in description to be output
I created a view of taxonomy terms and turned on aggregation for the view.

My view shows fields, including the description.

However, when I turn on aggregation, HTML tags are output like this:

```
**Term name: Addition**
<p>Learn about addition.</p>

```

When I turn off aggregation, the HTML tags disappear.

Is this a bug in Views?

# Answer
This is unintuitive behavior, but it is Views functioning as designed.

To get the HTML tags to render properly, you need to choose **Aggregation settings** for the taxonomy description and check the box *Format* under **Group columns (additional)**.
> 3 votes

---
Tags: views
---


# Question
Title: How can I count a multivalue field's values in twig?
I want to count the number of values of unlimited field in twig tempalate I tried

`{{ node.field_mytext.count }}` =\> **faced with error**

and in another try

`{{ content.field_mytext.count }}` =\> **nothing returned**

(in this method I checked my field is not in disabled field is display manager).

---

**My question is how can I count the number of items of a field in Twig?**

I hope I face with the solutions expect these solutions :D

# Answer
> 17 votes
**{{ node.field\_mytext.count }} =\> faced with error**

This does not work, because the method `count` is not allowed in twig policies:

> core/lib/Drupal/Core/Template/TwigSandboxPolicy.php

**{{ content.field\_mytext | length }}?**

This does not work, because `content` is a render array with a lot of additional keys.

**This works: Convert field to array and count**

```
{{ node.field_mytext.getvalue | length }}

```

# Answer
> 10 votes
Easiest way is to get the `['#items']|length`. I do it all the time for counting items for view more instances and when loading sliders.

```
{{ content.field_mytext['#items']|length }}

```

# Answer
> 4 votes
I've used own Twig filters to support entity fields, with this you can use fields as native arrays:

```
{{ content.field_mytext|length }}

```

or

```
{{ content.field_mytext|first|value }}

```

or

```
{% if content.field_mytext is empty %}

```

---

You can easily add you own Twig filters via a custom module. You can learn more here: drupal.org/docs/8/creating-custom-modules. In short you need to create a module directory, for example `path/to/drupal/modules/custom/common/`, put there `common.info.yml` with module definition and `common.services.yml` with definition of service (see comments in code) and put my code to `/path/to/drupal/modules/custom/common/src/TwigExtension.php`.

```
<?php
namespace Drupal\common;

use Drupal\Core\Field\FieldItemInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\TypedData\ComplexDataInterface;

/**
 * A class providing Twig extensions.
 *
 * This provides a Twig extension that registers various Field-API-specific
 * extensions to Twig, overriding empty and array related filters.
 *
 * Don't forget about common.services.yml
 * services:
 *   common.twig.TwigExtension:
 *     class: Drupal\common\TwigExtension
 *     tags:
 *       - { name: twig.extension }
 *
 * Usage (in *.html.twig file):
 *   - check is field empty {% if content.field_foo is empty %}
 *   - get field first value {{ content.field_foo|first|value }}
 */
class TwigExtension extends \Twig_Extension {

  /**
   * {@inheritdoc}
   */
  public function getTests() {
    return [
      new \Twig_SimpleTest('empty', [$this, 'twigEmptyField']),
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function getFilters() {
    return [
      new \Twig_SimpleFilter('length', [$this, 'twigLengthFilter'], ['needs_environment' => TRUE]),
      new \Twig_SimpleFilter('slice', [$this, 'twigSlice'], ['needs_environment' => TRUE]),
      new \Twig_SimpleFilter('first', [$this, 'twigFirst'], ['needs_environment' => TRUE]),
      new \Twig_SimpleFilter('last', [$this, 'twigLast'], ['needs_environment' => TRUE]),
      new \Twig_SimpleFilter('value', [$this, 'twigFieldValue']),
    ];
  }

  /**
   * Check if value is field item object.
   *
   * @param mixed $value
   *   Mixed Twig variable.
   *
   * @return \Drupal\Core\Field\FieldItemListInterface|mixed
   *   FieldItemListInterface or same value as passed.
   */
  private function checkItems($value) {
    if (is_array($value) && !empty($value['#items']) && $value['#items'] instanceof FieldItemListInterface) {
      return $value['#items'];
    }
    return $value;
  }

  /**
   * Get field item value.
   *
   * @param object $field
   *   Field object.
   *
   * @return array|mixed
   *   List of values or value.
   */
  public function twigFieldValue($field) {
    if ($field instanceof FieldItemInterface) {
      $prop = $field->mainPropertyName();
      $value = $field->getValue();
      return $prop ? $value[$prop] : $value;
    }
    if ($field instanceof FieldItemListInterface) {
      $value = [];
      foreach ($field as $item) {
        $value[] = $this->twigFieldValue($item);
      }
      return $value;
    }
    return '';
  }

  /**
   * Checks if a variable is empty.
   *
   * @see twig_test_empty
   */
  public function twigEmptyField($value) {
    $value = $this->checkItems($value);
    if ($value instanceof ComplexDataInterface) {
      return $value->isEmpty();
    }
    // Return TRUE, because there is no data only cache and weight.
    elseif (!is_object($value) && isset($value['#cache']) && count($value) == 2) {
      return TRUE;
    }
    return twig_test_empty($value);
  }

  /**
   * Returns the length of a variable.
   *
   * @param \Twig_Environment $env
   *   Twig environment.
   * @param mixed $item
   *   A variable.
   *
   * @return mixed
   *   The first element of the item.
   *
   * @see twig_length_filter
   */
  public function twigLengthFilter(\Twig_Environment $env, $item) {
    $item = $this->checkItems($item);
    return twig_length_filter($env, $item);
  }

  /**
   * Slices a variable.
   *
   * @param \Twig_Environment $env
   *   Twig environment.
   * @param mixed $item
   *   A variable.
   * @param int $start
   *   Start of the slice.
   * @param int $length
   *   Size of the slice.
   * @param bool $preserveKeys
   *   Whether to preserve key or not (when the input is an array)
   *
   * @return mixed
   *   The first element of the item.
   *
   * @see twig_slice
   */
  public function twigSlice(\Twig_Environment $env, $item, $start, $length = NULL, $preserveKeys = FALSE) {
    $item = $this->checkItems($item);
    return twig_slice($env, $item, $start, $length, $preserveKeys);
  }

  /**
   * Returns the first element of the item.
   *
   * @param \Twig_Environment $env
   *   Twig environment.
   * @param mixed $item
   *   A variable.
   *
   * @return mixed
   *   The first element of the item.
   *
   * @see twig_first
   */
  public function twigFirst(\Twig_Environment $env, $item) {
    $item = $this->checkItems($item);
    return twig_first($env, $item);
  }

  /**
   * Returns the last element of the item.
   *
   * @param \Twig_Environment $env
   *   Twig environment.
   * @param mixed $item
   *   A variable.
   *
   * @return mixed
   *   The first element of the item.
   *
   * @see twig_last
   */
  public function twigLast(\Twig_Environment $env, $item) {
    $item = $this->checkItems($item);
    return twig_last($env, $item);
  }

}

```

# Answer
> 1 votes
Works together with https://www.drupal.org/project/twig\_field\_value.

```
{% if content.field_paragraphs|field_value|length > 1 %}
  {# Do something. #}
{% endif %}

```

# Answer
> -1 votes
Use length filter

```
{{ content.field_mytext | length }}

```

---
Tags: theming, 8
---


title: Javascript in Drupal

text:
# Question
Title: Javascript in Drupal
I was following this post on drupal.org - https://www.drupal.org/node/3075055

But I'm not getting the same result. I'm not experienced at all in javascript so maybe I'm missing something. Do I need to indicate where is my js file? The name of the js file is important?

My module code below:

```
function draws_form_alter(&$form, &$form_state, $form_id) {
  switch($form_id) {
    case 'bets_node_form':
      $form['field_possible_returns']['und'][0]['value']['#process'] = array('my_custom_process');
      break;
  }
}

function my_custom_process($element, &$form_state, $complete_form){
  $element['field_possible_returns'] = array(
    '#type' => 'textfield',
    '#size' => 8,
    '#attributes' => array(
      'readonly' => 'readonly',
      'tabindex' => -1,
    ),
  );
  return $element;
}

```

The name of my module is `draws`.

My javascript file (in the same folder of the module file):

```
(function ($) {
  Drupal.behaviors.draws = {
    attach: function (context, settings) {
      alert('Its working!');
      $('.field-name-field-bet-value').on('keyup change', function (){
        var bet_value = $('.field-name-field-bet-value input').val();
        var odd = $('.field-name-field-odd input').val();
        var result = (odd * bet_value).toFixed(2);

        $('.field-name-field-possible-returns input').val(result);
      });
    }
  };
}(jQuery));

```

Here are the field names of my content type `bets`:

Thank you.

# Answer
> Do I need to indicate where is my js file?

Of course, js files do not auto magically get loaded.

You need to tell Drupal about them, There are various ways, see Adding JavaScript to your theme or module.

```
function draws_form_alter(&$form, &$form_state, $form_id) {
  switch($form_id) {
    case 'bets_node_form':
      $form['field_possible_returns']['und'][0]['value']['#process'] = array('my_custom_process');
      // Load JS File
      $form['#attached']['js'] = [
         drupal_get_path('module', 'draws') . '/draws.js',
      ];
      break;
  }
}

```
> 1 votes

---
Tags: 7, javascript
---


# Question
Title: Why taxonomy term view is showing only a single content?
I'm working on customizing some templates on an existing Drupal 8 site. I was about to start working on the taxonomy term page but noticed only a single content is showing in it. I already checked and there are several contents associated with the taxonomy I'm testing.

It's not the pager settings, which could be limiting the results to 1. Neither the filter apparently, I've disabled all filter and sort criteria.

Another thing I tried was clearing the cache. I even disabled the cache for this view, completely.

Finally, it seems the theme has no custom hook that could be changing this view in some way.

Here are the settings I currently have for this view:

What else could I check in order to show the correct results?

# Answer
After following @ShawnConn's advice on enabling the **Show the SQL query** option, I figured out what happened.

The query was indeed returning only one result. But then I remembered the categories were recently changed right on the database. To do that, we've updated the respective field table -- `node__field_categories` in our case. However, the `taxonomy_index` table was not updated. I went ahead and manually (again, I know) updated the `taxonomy_index` table and now the view is showing the expected content. I hope this is the last and only side effect.

The lesson learned is: only touch the database if you really know what you're doing. And even then, think twice. :P
> 2 votes

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


# Question
Title: How do I make a checkbox form initially have all options checked?
I have a drupal form in a module that doesn't pull in information until submitted. Can I make the checkboxes initially checked?

```
  $form['search_block_type'] = array(
    '#description' => "Select content types",
    '#type' => 'checkboxes',
    '#options' => $options,
    '#title' => t('Content types'),
    '#default_value' => $default_types,
  );

```

I assumed it was #checked' =\> 'yes' but that doesn't seem to work.(from a view)

# Answer
The actual form element values when selected are always the keys of what you have inside `$options`. You also can see that when inspecting the markup. So simply use `'#default_value' => array_keys($options)` to have all options preselected.

```
$form['search_block_type'] = [
  '#type' => 'checkboxes',
  '#title' => t('Content types'),
  '#description' => t('Select content types'),
  '#options' => $options,
  '#default_value' => array_keys($options),
];

```
> 0 votes

---
Tags: 7
---


# Question
Title: Assign unique IDs to HTML elements via twig file
I have a "block--system-menu-block.html.twig" file, which prints the menu content into the menu.

```
{# Menu. #}
{% block content %}
  {{ content }}
{% endblock %}

```

However, I would like each menu item (the resulting `<li>` elements) to get a unique ID. For example:

```
<li id="list-item-1">abc</li>
<li id="list-item-2">abc</li>

```

...

The idea is that I can use that in my css to have different colors or hover colors for my menu items. I have already achieved this with JavaScript on the front end, but I would rather have it done in the backend, in the twig files. Is that possible? If so, any ideas?

# Answer
> 0 votes
Copy `/core/themes/bartik/templates/classy/navigation/menu.html.twig`

and modify a bit:

```
{#
/**
 * @file
 * Theme override to display a menu.
 *
 * Available variables:
 * - menu_name: The machine name of the menu.
 * - items: A nested list of menu items. Each menu item contains:
 *   - attributes: HTML attributes for the menu item.
 *   - below: The menu item child items.
 *   - title: The menu link title.
 *   - url: The menu link url, instance of \Drupal\Core\Url
 *   - localized_options: Menu link localized options.
 *   - is_expanded: TRUE if the link has visible children within the current
 *     menu tree.
 *   - is_collapsed: TRUE if the link has children within the current menu tree
 *     that are not currently visible.
 *   - in_active_trail: TRUE if the link is in the active trail.
 */
#}
{% import _self as menus %}

{#
  We call a macro which calls itself to render the full tree.
  @see https://twig.symfony.com/doc/1.x/tags/macro.html
#}
{{ menus.menu_links(items, attributes, 0) }}

{% macro menu_links(items, attributes, menu_level) %}
  {% import _self as menus %}
  {% if items %}
    {% if menu_level == 0 %}
      <ul{{ attributes.addClass('menu') }}>
    {% else %}
      <ul class="menu">
    {% endif %}
    {% set count = 1 %} {# <------------------ Added #}
    {% for item in items %}
      {%
        set classes = [
          'menu-item-' ~ count, {# <------------------ Modified #}
          item.is_expanded ? 'menu-item--expanded',
          item.is_collapsed ? 'menu-item--collapsed',
          item.in_active_trail ? 'menu-item--active-trail',
        ]
      %}
      <li{{ item.attributes.addClass(classes) }}>
        {{ link(item.title, item.url) }}
        {% if item.below %}
          {{ menus.menu_links(item.below, attributes, menu_level + 1) }}
        {% endif %}
      </li>
      {% set count = count + 1 %} {# <------------------ Added #}
    {% endfor %}
    </ul>
  {% endif %}
{% endmacro %}

```

# Result

Then you can do, Ex: `#menu-block-id .menu-item-1 { border: solid green; }`

# Answer
> 0 votes
I used a variation of @no-sssweat 's answer.

```
{#
/**
 * @file
 * Theme override to display a menu.
 *
 * Available variables:
 * - menu_name: The machine name of the menu.
 * - items: A nested list of menu items. Each menu item contains:
 *   - attributes: HTML attributes for the menu item.
 *   - below: The menu item child items.
 *   - title: The menu link title.
 *   - url: The menu link url, instance of \Drupal\Core\Url
 *   - localized_options: Menu link localized options.
 *   - is_expanded: TRUE if the link has visible children within the current
 *     menu tree.
 *   - is_collapsed: TRUE if the link has children within the current menu tree
 *     that are not currently visible.
 *   - in_active_trail: TRUE if the link is in the active trail.
 */
#}
{% import _self as menus %}

{#
  We call a macro which calls itself to render the full tree.
  @see https://twig.symfony.com/doc/1.x/tags/macro.html
#}
{{ menus.menu_links(items, attributes, 0) }}

{% macro menu_links(items, attributes, menu_level) %}
  {% import _self as menus %}
  {% if items %}
    {% if menu_level == 0 %}
      <ul{{ attributes.addClass('menu') }}>
    {% else %}
      <ul class="menu">
    {% endif %}
    {% set count = 1 %} {# <------------------ Added #}
    {% for item in items %}
      <li{{ item.attributes }} class="menu-item-{{ count }}"> {# <------------------ This is more simple than @no-sssweat s answer #}
        {{ link(item.title, item.url) }}
        {% if item.below %}
          {{ menus.menu_links(item.below, attributes, menu_level + 1) }}
        {% endif %}
      </li>
      {% set count = count + 1 %} {# <------------------ Added #}
    {% endfor %}
    </ul>
  {% endif %}
{% endmacro %}

```

---
Tags: theming
---


# Question
Title: Warning: Permission Denied, While clearing the cache
When I clear the cache of the site, I get lot of warnings with

> "Permission denied in drupal\_unlink() (line 2199 of home/public\_html/sitename/includes/file.inc)."

And I am unable to upload any default image to the site with the warning

> "File Could not be uploaded"

# Answer
Check your `temp` folder under "admin \> config \> media \> file system": It should be writeable.
> 2 votes

# Answer
If write permission set already but still not resolve this, try manually delete all files (.css) in "sites\default\files\colorizer" folder first, then Clear Cache again! I have done sucessfully in my Windows 7 OS.

Regards

Chungph
> 1 votes

# Answer
I know an answers already been accepted, but I wanted to add that I found (weirdly) that clearing my browser cache also fixed this issue.
> 1 votes

# Answer
In my case I used nginx and this issue was just related to wrong nginx configurations. This token parameter was totally ignored by Drupal:

```
https://[DRUPAL-URL]/admin/flush?token=[GET-PARAMETER]

```

So the token became empty and it caused the "permission denied" issue. To fix that, I changed the nginx configuration to this:

```
try_files $uri $uri/ /index.php?q=$uri&$args;

```

Seems that resolved the problem for me.
> 0 votes

---
Tags: files
---


# Question
Title: How to add an additional class to each element in the menu-local-task.html.twig template?
I need to change the admin tab template by adding my wrapper and class to it.

This is the default code:

```
<li{{ attributes.addClass(is_active ? 'is-active') }}>{{ link }}</li>

```

My code:

```
<div {{ .attributes.addClass(is_active ? 'DefTabs__tabItem--active') }}>{{ link }}</div>

```

Currently, the "DefTabs\__tabItem--active" class is added to the active link, but I need to add an additional CSS class "DefTabs\__tabItem" to each DIV element. How can I do this?

# Answer
> 1 votes
Create an array, ex:

```
{%
    set classes = [
      is_active ? 'is-active',
      'my-second-class-name',
    ]
%}

<div {{ attributes.addClass(classes) }}>{{ link }}</div>

```

---

> Currently, the "DefTabs\__tabItem--active" class is added to the active link, but I need to add an additional CSS class "DefTabs\__tabItem" to each DIV element.

By the way, no need to repeat yourself with the naming, do this:

```
{%
    set classes = [
      'DefTabs__tabItem',
      is_active ? 'active',
    ]
%}

<div {{ attributes.addClass(classes) }}>{{ link }}</div>

```

Then in CSS you can target the active with `.DefTabs__tabItem.active { ... }`

---
Tags: 8, theming
---


# Question
Title: How to modify field value in other nodes after node update?
After node update I need to modify a field value in several connected nodes.
As I know, I cannot use `hook_entity_update()` since `$node->save()` forms infinite recursion.

How can I modify node fields after a node has been updated? (besides `hook_cron`)

# Answer
> 2 votes
Use hook\_form\_alter or hook\_form\_FORM\_ID\_alter

Add a custom validation that runs after all validation has passed

```
$form['actions']['submit']['#submit'][] = 'mymodule_update_referenced_nodes';

```

Then in that function

```
function mymodule_update_referenced_nodes(&$form, \Drupal\Core\Form\FormStateInterface $form_state){

  $field_other = $form_state->getValue('field_other')[0]['value'];

  $references = $node->get('field_referenced')->referencedEntities();

  foreach ($references as $referenced_node) {
    $referenced_node->field_other->value = $field_other;
    $referenced_node->save();
  }

}

```

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


title: twig dump() creates WSOD error

text:
# Question
Title: twig dump() creates WSOD error
this is my first Drupal installation (I'm a symfony dev) and I've spent several hours trying to get dump() working. However it just causes a WSOD.

Maybe related: I'm unable to install kint, there's issues with it now being a sub-module of devel and I haven't been able to install it.

Settings:

* Drupal version 8.9.1
* memory limit set to 6,000mb
* execution time set to 90 seconds
* Windows
* acquia dev desktop
* php 7.3.15
* Apache/2.4.33 (Win64) OpenSSL/1.1.0h mod\_fcgid/2.3.9

If anyone has suggestions I'm keen to hear it! Drupal is quite interesting from what I've seen so far. It's been a bit frustrating as someone new to Drupal, trying to get basic things working.

== Update ==

I have corrected a config error I made while configuring the site. See here (for correct config).

Calls to `dump()` (in twig) for null variables work, but `{{ dump(items) }}` will hang and then result in a 500 error (see link above).

# Answer
I've solved this.

In Drupal, modules also use composer (which I wasn't aware of). The vardumper module depends on the symfony/var-dumper package.

Running:

composer require --dev symfony/var-dumper

causes dependency conflicts, however using:

composer update

Will install the var-dumper package, fix the problem - now I can see very beautiful variable dumps.

Lesson learnt:

* Always check composer for dependency errors.
> 1 votes

---
Tags: debugging, wsod
---


# Question
Title: How to check config setting in custom service class with dependency injection?
In a custom Service class, I need to check a config setting.

I'm able to do this using `\Drupal::config(static::SETTINGS)` as documented here: https://www.drupal.org/docs/drupal-apis/configuration-api/working-with-configuration-forms

but Coder complains:

> **WARNING** | `\Drupal` calls should be avoided in classes, use dependency injection instead

What service should I inject here?

I only need to see the immutable config value, I don't think I need a `ConfigFactory`.

More info:

When I try to inject the `ConfigFactoryInterface`, using the pattern I have followed for many other services, I get this error:

> Error: Call to undefined method `Drupal\my_custom_module\Api\DataPartner::config()` in `Drupal\my_custom_module\Api\DataPartner->hasDebugPermission()`

The code in the `hasDebugPermission()` method looks like this:

```
  /**
   * Private function to control whether displaying debug info is permitted.
   *
   * @return bool
   *   TRUE if debugging is permitted for current user in current environment.
   */
  private function hasDebugPermission() {
    $config = $this->config(static::SETTINGS);
    $result = DATA_PARTNER_FORMS_DEBUG
      && $config->get('display_debugging_info')
      && $this->account->hasPermission('debug forms');
    return $result;
  }

```

And I have declared `static::SETTINGS` like this:

```
  /**
   * Config settings.
   *
   * @var string
   */
  private const SETTINGS = 'my_custom_module.settings';

```

The call to `$this->account->hasPermission()` works fine after injecting `\Drupal\Core\Session\AccountInterface`, but the call to `$this->config('my_custom_module.settings')->get('display_debugging_info')` does not work after injecting `\Drupal\Core\Config\ConfigFactoryInterface`.

# Answer
> 4 votes
Make sure you inject `config.factory` and then you need to use:

```
$this->config
  ->get('my_custom_module.settings')
  ->get('display_debugging_info');

```

You can see that Drupal::config() is:

```
public static function config($name) {
  return static::getContainer()
    ->get('config.factory')
    ->get($name);
}

```

So after injecting your service, the equivalent of `\Drupal::config('my_custom_module.settings')` is:

```
$this->config->get('my_custom_module.settings');

```

---
Tags: 8, configuration, services, dependency-injection
---


# Question
Title: During checkout, why is the customer skipping the payment step?
I have a situation during the checkout process where the customer is skipping the payment and moved directly to the fulfillment state. I'm using the Commerce PayPal module.

Here's my checkout flow: */admin/commerce/config/checkout-flows/manage/default*

What's odd is the PayPal buttons display when I'm logged in as Admin, but not when non-admin:

I haven't found an option that looks relevant on the permissions screen, nor have I found a configuration option anywhere.

The order type is configured to use the correct checkout flow (Default).

# Answer
> 3 votes
With Commerce Paypal, I ran into the same issue.

I believe the fix for me was to the move the Payment Information (currently disabled) into the Order Information section. Might also work if you move into Review or Payment section, not sure.

Also, since you're using Paypal, I think you need to disable payment process.

Here is my working setup. **Note:** I didn't want users to login nor register.

---
Tags: 8, commerce
---


# Question
Title: Adding a submit button in a themed table doesn't work
When I add a button inside the '#rows' key of a table element, the submit function is not called.

```
class MyForm extends FormBase
{

   public function buildForm(array $form, FormStateInterface $form_state)
    {
        $my_button = [
            '#type' => 'submit',
            '#value' => $this->t("Click"),
            '#submit' => [
                '::custom_submitForm'
            ]
        ];
        $form['my_table'] = [
           // '#tree' => TRUE,
            '#theme' => 'table',
            '#header' => [
                'Column 1','Column 2'
            ],
            '#rows' => [
                [$this->t("Blabla"), ['data'=>$my_button]]
            ],
        ];
        return $form;
    }
    // other stuff

```

What is the best workaround for this?

**EDIT TO ADD:**

As a first try to understand what is going out, I have allowed the children function to consider `'#rows'` as children (see `Drupal\Core\Render\Element::children`)

```
  public static function children(array &$elements, $sort = FALSE) {
     ...
    foreach ($elements as $key => $value) {
      if (is_int($key) || $key === '' || ($key[0] !== '#' || $key=='#rows')) {
     ...

```

This is solving the issue (the handler is called), but of course, this change generate many other problems.. But now, we can understand why the submit handler was not called.

I have added an issue in the drupal queue: https://www.drupal.org/project/drupal/issues/3166899

I am not asking to correct this bug, but what would be the best workaround.

# Answer
Use instead of #theme a form element #type:

```
'#type' => 'table'

```

The table form element has an extra step for processing when used in a form.

You don't need `'#rows'`. Any array key not starting with `#`, also the index added automatically by appending a row with `[]`, is considered to be a renderable child and displayed as row.
> 2 votes

---
Tags: forms
---


title: Are hooks cached?

text:
# Question
Title: Are hooks cached?
I am trying to alter a views result after it's executed, and before it's rendered. I was originally using `hook_views_pre_render(viewExecutable $view)`, but that wasn't updating any of the view results for one reason or another, so I switched over to `hook_views_post_execute(viewExecutable $view)` which DOES update view results, however, both hooks only work immediately after a cache clear.

Is there a reason this was done? It seems pointless to have these hooks if they only fire based on cache clears or cache being updated.

I am using the hook to compare a field in a result row to an array, and if it doesn't match a value in the array, then it removes the views result so it doesn't show up in the view.

Like I said in the post, this works in the initial view visit immediately after a cache clear, but as soon as you refresh the page the view is no longer using the hook. I've disabled views caching in settings, but it still seems to be behaving this way.

I am also curious why my normal views display responds to the hooks, but my REST export display does not. Does it need different hooks?

The exact code I am using is below:

```
function tcrp_server_status_views_post_execute(\Drupal\views\ViewExecutable $view) {
  if ($view->id() == "server_list") {
    $steamid = \Drupal::request()->query->get('steamid');
    if ($steamid == NULL || $steamid == '') {
      unset($view->result);
    }

    $u = \Drupal::entityQuery('user')
    ->condition('field_steam_id',$steamid);
    $result = $u->execute();

    $user = \Drupal\user\Entity\user::load($result[1]);

    foreach ($view->result as $k => $v) {
      $display = false;
      foreach ($v->_entity->field_access_roles->referencedEntities() as $reference) {
        if (array_search($reference->id(),$user->getRoles())) {
         $display = true;
        }
      }

      if (!$display) {
        unset($view->result[$k]);
      }
    }
  }
}

```

# Answer
Your actual issue is this part of the code:

```
if (array_search($reference->id(),$user->getRoles())) {
   $display = true;
}

```

Since `$reference->id()` is a number, this conditional will always fail to pass.

For the conditional to pass, it would have to be:

```
if (array_search('role_machine_name',$user->getRoles())) {
   $display = true;
}

```
> 0 votes

---
Tags: 8, views, caching
---


# Question
Title: Why are there entries in sessions table for uid 0?
I was alarmed to find sessions being written to the table \[sessions\] for uid 0. Do I need to worry or is this normal? I could not find answers by searching. I don't know how the sessions table works. This is Drupal 8.

# Answer
Do not be alarmed, this is normal. Typically seen in Drupal Commerce sites to keep track of anonymous users also known as user 0.
> 0 votes

---
Tags: sessions
---


# Question
Title: Get custom block type image field in Display Suite twig field
I have a custom block type with a link field and an image field. I want to combine those fields to wrap the image in the link.

I created a Display Suite Twig field. What do I use to show the image?

Ideally the image as rendered in *Manage display*, but as long as I can show the image with a certain image style, I'd be very happy.

This is what I have already tried.

```
{{ file_url(node.field_career_highlight_image.entity.uri.value) }}
{{ file_url(content.field_career_highlight_image['#items'].entity.uri.value) }}
{{ file_url(block_content.field_career_highlight_image.0['#item'].entity.uri.value) }}
{{ file_url(node.field_career_highlight_image['#items'].entity.uri.value) }}
{{ block_content.field_career_highlight_image.alt }} - shows alt, just experimenting, so wondering why this didn't work for the image
{{ content.field_career_highlight_image }}
{{ block_content.field_career_highlight_image }} - white screen
{{ block_content.field_career_highlight_image.0 }}
{{ block_content.field_career_highlight_image.0.value }}
{{ block_content.field_career_highlight_image[0] }}
{{ block_content['#block_content'].field_career_highlight_image.value }}
{{ content['#block_content'].field_career_highlight_image.value }}
{{ content['#block_content'].field_career_highlight_image }}

```

# Answer
```
{% set image_uri = block_content.field_feature_row_image['#items'].entity.uri.value %}

<img src="{{ image_uri|image_style('thumbnail') }}"/>

```

OR with a .0

```
{% set image_uri = block_content.field_feature_row_image.0['#items'].entity.uri.value %}

<img src="{{ image_uri|image_style('thumbnail') }}"/>

```

---

If not, try

```
{{ file_url(block_content.field_career_highlight_image.entity.fileuri) }}

```

---

If still no dice, then give this a shot. In /sites/default/**settings.php** add:

```
// Override default twig method whitelist.
$settings['twig_sandbox_whitelisted_methods'] = [
  // Defaults:
  'id',
  'label',
  'bundle',
  'get',
  '__toString',
  'toString',
  // Additions:
  'url',
];

```

and then in your field twig put

```
{{ block_content.field_career_highlight_image.url }}

```
> 0 votes

---
Tags: 8
---


# Question
Title: Redirect to checkout after pressing the "Add to Cart" button
When a user presses the "add to cart" button on a product page, I want to automatically redirect the user to the checkout page.

Drupal 7 has an issue for doing this programatically and an issue for doing this with the Rules module.

Rules is still in alpha for D8, and I tried to make a rule that acts on **after saving a new order**, but I'm getting an error when I try to add an action:

```
Error: Call to a member function getDataType() on null in Drupal\rules\Plugin\RulesAction\EntityCreateDeriver->getDerivativeDefinitions() (line 99 of modules/contrib/rules/src/Plugin/RulesAction/EntityCreateDeriver.php).

```

So **I want to redirect from add to cart to the checkout page programatically.**

But there is no documentation yet. So if anyone can explain how to do this, I would be much obliged.

# Answer
> 3 votes
There's an issue here to allow that through the formatter, it has a MR from me that we are using for a project. Note that it skips the cart completely, there is just checkout.

https://www.drupal.org/node/2810723

# Answer
> 4 votes
you could do something like this:

```
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;

function MYMODULE_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if (strpos($form_id, 'commerce_order_item_add_to_cart_form_commerce_product') !== false) {
    $form['actions']['submit']['#submit'][] = 'MYMODULE_cart_alter_sub';
 }
}
function MYMODULE_cart_alter_sub(&$form, FormStateInterface $form_state) {
  $responce =  new RedirectResponse('/cart');
  $responce->send();
}

```

# Answer
> 3 votes
Commerce Cart Redirection

> Redirect users to checkout, cart, or an arbitrary location immediately after they add a product to their cart, this action is filterable by product variation type.

# Answer
> 2 votes
As there is no rules-based solution yet, I constructed a crappy jquery function to do this.

First, it checks whether Drupal has sent a message that you added a product to your cart, and then performs a simple redirect to the cart page, and there it submits directly to the checkout page.

```
  Drupal.behaviors.donate = {
    attach: function (context, settings) {
        if ($("div[role=contentinfo]").length){
              var str=$("div[role=contentinfo]").html();
              var n=str.includes('Donatie added to <a href="/cart">your cart</a>.');
              if (n){
                  window.location="/cart";
              }
        }
        if ($("#edit-checkout").length){
               $("#edit-checkout").click();
        }

  }
  };

```

# Answer
> 1 votes
Thanks to @Berdir for writing the code for this.

How to use the patch

1. Apply the patch.
2. Go to the Product Types -\> Edit Display page for your product type that you want to skip the cart for (`/admin/commerce/config/product-types/my-product-type/edit/display`).
3. Look for the **Product Variations** field, the format of which should be **Add to cart form**. Click the little gear icon on the right.
4. Check the box for **Skip cart** and press **Update**.

# Answer
> 1 votes
I also needed this redirect (to the cart, but it could also work for the checkout).

There are a few possibilities that appeared to work, but not predictable:

* Rules redirect based on saving an order item
* Event listener on: commerce\_order.place.post\_transition
* Submit handler on the 'add to cart' action. All these solutions may appear to work at first sight but after further testing it appeared that the redirect was sometimes done before adding the item to the cart.

Therefore I fall back on the solution given by Egbert Bleyenburg with the difference that I used hook\_preprocess\_status\_messages(). So I skip the step of rendering the status message and don't use the javascript.

Call your function in hook\_preprocess\_status\_messages():

```
function hook_preprocess_status_messages(&$variables) {
  redirect_order_to_cart($variables['message_list']['status']);
}

```

Above is just an example, in production you'd like to have a condition to check if you are on the correct page and if the status messages are set. Below the custom function you call to redirect:

```
function redirect_order_to_cart(array $status_messages) {
  $cart_path = Url::fromRoute('commerce_cart.page')->getInternalPath();

  foreach ($status_messages as $message) {

    // If we have a status message containing a href with the cart path we know
    // that it's the order item confirm message. This is the moment we want to
    // redirect to the cart.
    if (
      $message instanceof Markup
      && strpos($message->jsonSerialize(), 'href="/' . $cart_path) !== FALSE
    ) {
      // Setting the redirect.
      $response = new RedirectResponse(\Drupal::service('url_generator')
        ->generateFromRoute('commerce_cart.page'));
      $response->send();
      break;
    }
  }
}

```

---
Tags: 8, commerce
---


# Question
Title: Need to limit Commerce Shipping Condition to only fire if there are no items that do not match
We need the condition to trigger only if the cart items match the categories listed and there are no products that do not match.

Is there a way to limit Commerce Shipping Method Conditions (Product-\>Order Contains Product Categories) to trigger only if the order products match the categories and there none that do not match?

# Answer
> 1 votes
Unfortunately, the way that condition was written, it only matches for, "Order contains any products from these categories." The logic you're looking for is, "Order contains *only* products from these categories." For that, you'd need to write a custom condition plugin. This would be a reasonable core feature request for Drupal Commerce and would apply for the other "contains" conditions as well ... which leads me to believe we might implement it as an "operator" select list on the condition itself.

---
Tags: commerce
---


# Question
Title: How do I sign in a user based on custom HTTP headers?
I would like to sign-in a user based on some custom headers in the HTTP request. Let's say I have an administrator account whose username is *admin*. If I send a request to Drupal with a custom header (`X-USER-NAME: admin`), I would like to be logged in with this user.

I tried to develop a custom authentication module to deal with this use-case.

```
public function applies(Request $request) {
  $name = $request->headers->get('X-USER-NAME');

  return isset($name);
}

public function authenticate(Request $request) {
  $name = $request->headers->get('X-USER-NAME');
  $user = user_load_by_name($name);

  return $user;
}

```

I then alter system routes so I can access them with my new authentication method.

```
class AdminRouteSubscriber extends \Drupal\Core\Routing\RouteSubscriberBase {

  /**
   * @inheritDoc
   */
  protected function alterRoutes(RouteCollection $collection) {
    foreach ($collection->all() as $route) {
      $path = $route->getPath();
      if (
        ($path == '/admin' || strpos($path, '/admin/') === 0)
      || ($path == '/node' || strpos($path, '/node/') === 0)
      || ($path == '/user' || strpos($path, '/user/') === 0)
      ) {
        $route->setOption('_auth', ['headers_auth', 'cookie']);
      }
    }
  }

}

```

I can now access a route to add a new content (let's say a new article), but when I submit the form to create this new content, I get the following error.

> The form has become outdated. Press the back button, copy any unsaved work in the form, and then reload the page.

With my new authentication method, no cookie is set in the answer. I guess that there is some kind of CSRF token verification when submitting the form.

Am I on the good way or should I use a different approach?

# Answer
> 0 votes
That sounds like a very insecure way of allowing admin access to your site. Seems like a hacker just has to fake the header in the request to get access.

That said, you probably want to look at the various http authentication modules for Drupal 8 (E.g. google drupal 8 http authentication). Some quick starter links about this in core are:

https://www.drupal.org/docs/8/core/modules/basic\_auth/overview https://www.drupal.org/docs/8/api/authentication-api/overview

As with most open source systems, the best way to figure out how to do something like this is to find code that does something similar and modify it to meet your needs.

---
Tags: 8, authentication-authorization
---


# Question
Title: How can I get a different version of a webform to show dynamically based on a selection value?
I have a contact form currently set up with select options for the nature of the customer's inquiry. The conditionals and email handlers are set up for each selection value. Just now the user has to manually select a subject from the drop down before it displays the corresponding fields. Is it possible to take the user to the form using a parameter in the URL based on the selection option value so all the relevant fields are shown? I have tried using variants and references to show the fields and display them in webform nodes but I wondered what was the best way to go about this as I cannot get the fields to hide using variants. I'm still new to variants so still working all of that out. I have looked through the previously asked questions but I can't find anything for Drupal 8.

# Answer
> 0 votes
If I'm understanding correctly, you want to show/hide certain fields based on the value of the Subject field, and you also want this value to have the ability to be set via a URL parameter?

If that's the case, this can be done in a single form using conditional fields and form settings.

First, in your form Settings, under Form \>\> Form Behaviors \>\> Prepopulate, check `Allow all elements to be populated using query string parameters.`

If this is checked, all elements can be populated using query string parameters. For example, appending ?name=John+Smith to a webform's URL would set the 'name' element's default value to 'John Smith'. Please note that individual elements can also have prepopulation enabled, so you could skip this and allow only the Subject field to be prepopulated if desired.

Next, in "Build" screen, edit one of the conditional fields that depend on the Subject field value. In the "Conditions" tab, you can describe the logic to display or hide the field based on the value of another field, something like

`Visible` if `All` of the following is met:

`Subject[Select]` `Value Is` `'Some subject value'`

I hope I've understood your question correctly! While it doesn't use 'variants', this approach can still help you show a variation of your form depending on how the "Subject" field is filled.

---
Tags: webforms
---


# Question
Title: Custom Webform handler not working on Wizard Webform
I am attempting to write a simple webform handler to add to the end of a multi-step webform, ultimately to generate a barcode with the submitted data. I've had success with other handlers on single step forms but it looks like the handler causes the wizard form to freeze and not progress to the next step.

My suspicion is that I'm missing something in my plugin code but I can't seem to find an answer to the problem in similar issues.

So far there's no functionality attempted in the handler because the form freezes on the first step.

Ultimately I only need this handler to fire upon final submission of my form.

I'm trying to test for the forms state with $webform\_submission-\>getState() but I can't seem to get it right

```
  public function postSave(WebformSubmissionInterface $webform_submission, $update = TRUE) {

   $state = $webform_submission->getWebform()->getSetting('results_disabled') ? WebformSubmissionInterface::STATE_COMPLETED : $webform_submission->getState();
    if ($this->configuration['states'] && in_array($state, $this->configuration['states'])) {
       //do something

    }
  }

```

# Answer
Hopefully this will help someone out there but this is the code I finally got working. It takes the serial value from a webform submission and writes a Png barcode for use in emails. I'm using the Barcodes Module for Drupal 8.

```
use Com\Tecnick\Barcode\Barcode as BarcodeGenerator;

class BarcodeHandler extends WebformHandlerBase {
  /**
   * {@inheritdoc}
   * Write PNG barcode for registration emails
   */
 public function postSave(WebformSubmissionInterface $webform_submission, $update = TRUE) {
   $regId = $webform_submission->serial();
   $type = 'C39';
   $barcode_file = 'registration/barcodes/' . $regId . '.png';
   $barcode = new BarcodeGenerator();
   $barcode_obj = $barcode->getBarcodeObj($type, $regId, 250, 50, 'black');

   file_put_contents($barcode_file, $barcode_obj->getPngData());

  }
}

```
> 1 votes

---
Tags: webforms
---


# Question
Title: Error: Call to undefined function in inc file
I searched for an explanation to this issue but didn't find anything. I have other sites where this is working but not in this one.

So, my module info file (draws.module):

```
name = draws
description = Draws custom module
package = Draws Modules
core = 7.x

files[] = draws.fixturesSavings.inc

```

In my draws.module I have this function (lines 289 to 231):

```
function saveToDatabase($response) {
    fixtures_saveToDatabase($response);
}

```

And then in the same folder of my draws.module I have the inc file (draws.fixturesSaving.inc):

```
<?php
function fixtures_saveToDatabase($response) {

```

And when I call function `saveToDatabase`, I get the following error:

```
Error: Call to undefined function fixtures_saveToDatabase() in saveToDatabase() (line 290 of /home/.../sites/all/modules/custom/draws/draws.module).

```

What am I doing wrong here?

# Answer
> 3 votes
> **files (Optional)**
>
> Drupal supports a dynamic-loading code registry. To support it, all modules must declare any code files containing class or interface declarations in the .info file, like so:
>
> ```
> name = Really Neat Widget
> ...
> files[] = tests/example.test
>
> ```
>
> When a module is enabled, Drupal will rescan all declared files and **index all the classes and interfaces** that it finds. Classes will be loaded automatically by PHP when they are first accessed.
>
> Currently this mechanism does not natively support namespaced classes.
>
> Source: Writing module .info files (Drupal 7.x)

This approach only works with Object Oriented PHP. You would have to create a class.

If you want to keep with your current approach, add this to the top of the draws.module file after the `<?php` open tag.

```
module_load_include('inc', 'draws', 'draws.fixturesSavings');

```

---
Tags: 7
---


title: Using attach_library in a modal

text:
# Question
Title: Using attach_library in a modal
For ref, I'm working on https://www.drupal.org/project/focal\_point/issues/3162218

I have a twig file that handles the contents of a modal window and I want to load a particular CSS file whenever this twig file is loaded. I've added the following to the top of the .twig:

`{{ attach_library('focal_point/drupal.focal_point_preview') }}`

...and in my libraries.yml I have:

```
drupal.focal_point_preview:
  version: VERSION
  js:
      js/focal_point_preview.js: {}
  css:
    theme:
      css/focal_point_preview.css: {}

```

If I put the `attach_library()` call in another (inappropriate) template the js/css is present on the page before the modal is loaded and therefore it works properly, but this is not the correct place for these libraries to be added since they are only needed when the modal is opened.

At some point in the past this worked but as of now it definitely doesn't. Thoughts?

# Answer
> 1 votes
render() only works because of EarlyRenderingControllerWrapperSubscriber, which should have been removed by now:

```
 * In other words: this just exists to ease the transition to Drupal 8: it
 * allows controllers that return render arrays (the majority) and
 * \Drupal\Core\Ajax\AjaxResponse\AjaxResponse objects (a sizable minority that
 * often involve a fair amount of rendering) to still do early rendering. But
 * controllers that return any other kind of response are already expected to
 * do the right thing, so if early rendering is detected in such a case, an
 * exception is thrown.
 *
 * @see \Drupal\Core\Render\RendererInterface
 * @see \Drupal\Core\Render\Renderer
 *
 * @todo Remove in Drupal 9.0.0, by disallowing early rendering.

```

So don't use any render method. Ajax renders HTML content automatically and so makes sure to catch all metadata which bubbles up.

BTW in a module handling AJAX responses you don't need to bubble up attachments through Twig:

```
{{ attach_library('focal_point/drupal.focal_point_preview') }}

```

You can add them directly to the Ajax response:

```
$response->addAttachments(['library' => ['focal_point/drupal.focal_point_preview']]);

```

# Answer
> 0 votes
My issue was caused by using renderPlain() instead of render()

---
Tags: modal-dialogs
---


# Question
Title: How can I save parts of the URL to the database when a certain page is viewed?
Can a page be created the normal way (not by module) in Drupal 7, using Content Type an so forth, yet still trigger a module and pass a variable from the URL.

The idea is to let the web team create their page as normal, but require the last part of the path to be a variable. Then a module is called to take that variable and do magic with it.

We want the module to work with the variable in the background, NOT render a page.

# Answer
> Marketing creates the page with a URL that contains a variable representing the user. User gets an email and clicks on button that goes to page. When they get to the page the module is triggered to collect the variable data from the URL. The module will then save that value to a DB.

Use template\_preprocess\_node

Have the URL in the e-mail formatted like this:

```
example.com/node/1?param1=value1?param2=value2

```

If it's required that the user must be logged in

```
example.com/user/login?destination=node/1?param1=value1?param2=value2

```

I used /node/1 as an example, but you can use its url alias instead if it has one.

Then in your mymodule.module file

```
function mymodule_preprocess_node(&$variables) {
  $node = $variables['node'];
   if ($node->type == 'article') { // checks its Article Content Type
     $params = drupal_get_query_parameters();
     if (!empty($params)) {
       // do more magic to get each param value on its own
       // save to the DB
     }
   }
}

```
> 1 votes

---
Tags: 7
---


# Question
Title: How to get an generic image icon for image field type (like Generic File formatter for file field)
I have media field on a paragraph entity. This field can hold media types, files, image etc.

Looking at admin/structure/media/manage/file/display there is a generic file formatter. However, for image - admin/structure/media/manage/image/display there is not.

So when the data is rendered, I get generic icon for word documents, but not images.

How can I get all my media items to render as generic icons?

# Answer
> 1 votes
It seems this issue is being worked on at : #2568289: Not possible to reuse field formatters between entity\_reference, file, and image fields

For now I've used the following code - included in the mytheme.theme file. (view mode custom\_generic\_file)

```
use Drupal\file\Plugin\Field\FieldType\FileItem;

/**
 * Implements hook_preprocess_field().
 */
  function mytheme_preprocess_field(&$variables, $hook) {
    __mytheme_preprocess_field__generic_download_icons_view_mode($variables, $hook);
  }

/**
 * Ensure generic icon view mode for image media entities.
 *
 * Image field type doesn't have a generic file formatter.
 *
 * Called by hook_preprocess_field().
 *
 * @see Drupal\file\Plugin\Field\FieldFormatter\GenericFileFormatter::viewElements()
 * @see https://www.drupal.org/project/drupal/issues/2568289
 */
   function __mytheme_preprocess_field__generic_download_icons_view_mode(&$variables, $hook) {
  if (isset($variables['entity_type'])
    && ($variables['entity_type'] == 'media')
    && isset($variables['field_type'])
    && ($variables['field_type'] == 'image')
    && isset($variables['element']['#view_mode'])
    && ($variables['element']['#view_mode'] == 'custom_generic_file')) {

    foreach ($variables['items'] as $key => $item) {
      /* @var Drupal\image\Plugin\Field\FieldType\ImageItem */
      if (isset($item['content']['#item']) && $item['content']['#item'] instanceof FileItem) {
        /** @var \Drupal\Core\Entity\Plugin\DataType\EntityReference $entityReference */
        $entityReference = $item['content']['#item']->get('entity');
        /** @var \Drupal\Core\Entity\Plugin\DataType\EntityAdapter $entityAdapter */
        $entityAdapter = $entityReference->getTarget();
        /** @var \Drupal\Core\Entity\EntityInterface $file */
        /** @var \Drupal\file\Entity\File $file */
        $file = $entityAdapter->getValue();
        $item['content'] = [
          '#theme' => 'file_link',
          '#file' => $file,
          '#description' => NULL,
          '#cache' => [
            'tags' => $file->getCacheTags(),
          ],
        ];
        // Replace for real.
        $variables['items'][$key]['content'] = $item['content'];
      }
    }
  }
}

```

---
Tags: 8, media
---


# Question
Title: What's The Security Implications for "Send arbitrary files" in Permissions
For my webforms, I want to receive attachments, when I receive an email. I had issues receiving them until I set the permissions for Anonymous User to allow them to use "Send arbitrary files".

Underneath, there's a warning:

> Give to trusted roles only; this permission has security implications.

Does anyone know what are the security implications?

Thanks!

# Answer
It means that MimeMail (because that's a MimeMail permission) would be able to attach a file that's it not in the public files directory, like private files, settings.php or any other file in your filesystem.

However, using this permission is mandatory to attach private files, for example, because they are outside the public files directory.

What are the security issues? Well, it depends on what you attach to your email and how. For example, if the path of the attached file depends on some user input, the user can potentially craft a special input that may lead to attaching certain files like the settings.php file or any private file (if the malicious user knows the file path, or can guess it). If your code doesn't allow this you are probably safe.

For example, you may have private files in your nodes and your code just emails the private file of a certain node given its `nid`, and you get the `nid` form a button in the full node view page. On this scenario, it seems a malicious user can't craft any submission that attaches an arbitrary file as a result.

In MimeMail words:

> The 'send arbitrary files' permission allows you to attach or embed files located outside Drupal's public files directory. Note that this has security implications: arbitrary includes even your settings.php! Give to trusted roles only!

Also, check how MimeMail uses the 'send arbitrary files' permission
> 1 votes

---
Tags: 7, webforms, security, mimemail
---


# Question
Title: How to get cache tags invalidation working with Varnish Purger
On my server, I've got Varnish 5.2 working, so far so good. However, any changes made on the site are not shown to anonymous visitors, until the cache expires.

I installed the purge module together with the Varnish Purge module to get cache tags invalidation going. Then added a purger there, and another, and another, but no matter which settings I try, the requests keep on being served from cache.

Manually purging works (I am testing on node 1042), like this:

```
curl -X BAN http://127.0.0.1:6081/ -H "Cache-Tags: node:1042"

```

However, when I activate purging through cron, there's this error:

```
purger_varnish_84f7afee13: item failed due GuzzleHttp\Exception\ConnectException, details (JSON): {"msg":"cURL error 28: Operation timed out after 1000 milliseconds with 0 out of 0 bytes received (see https:\/\/curl.haxx.se\/libcurl\/c\/libcurl-errors.html)","uri":"https:\/\/127.0.0.1:6081\/","method":"BAN","guzzle_opt":{"http_errors":true,"connect_timeout":1,"timeout":1,"verify":false},"headers":{"user-agent":"varnish_purger module for Drupal 8.","cache-tags":"config:contact.form.personal"}}

```

**Obviously, I'm doing something wrong, but what?**

In confusion, I tried all of these purger settings without joy:

```
Hostname: 127.0.0.1  Port: 443  Path: /  Request Method: BAN  Scheme https, Verify SSL certificate

127.0.0.1 Port: 80 http

127.0.0.1 Port: 8080 http

localhost Port: 6081 http

localhost Port: 80 http

localhost Port: 6081 https, Verify SSL certificate

127.0.0.1 Port: 8080 https

localhost Port: 8080 https

```

The contents of /etc/varnish/usr.vcl:

```
vcl 4.0;

backend default {
    .host = "127.0.0.1";
    .port = "8080";
}

acl purge {
"127.0.0.1";
}

# Respond to incoming requests.
sub vcl_recv {
# Add an X-Forwarded-For header with the client IP address.
if (req.restarts == 0) {
if (req.http.X-Forwarded-For) {
set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip;
}
else {
set req.http.X-Forwarded-For = client.ip;
}
}
# Only allow PURGE requests from IP addresses in the 'purge' ACL.
if (req.method == "PURGE") {
if (!client.ip ~ purge) {
return (synth(405, "Not allowed."));
}
return (hash);
}
# Only allow BAN requests from IP addresses in the 'purge' ACL.
if (req.method == "BAN") {
# Same ACL check as above:
if (!client.ip ~ purge) {
return (synth(403, "Not allowed."));
}
# Logic for the ban, using the Cache-Tags header. For more info
# see https://github.com/geerlingguy/drupal-vm/issues/397.
if (req.http.Cache-Tags) {
ban("obj.http.Cache-Tags ~ " + req.http.Cache-Tags);
}
else {
return (synth(403, "Cache-Tags header missing."));
}
# Throw a synthetic page so the request won't go to the backend.
return (synth(200, "Ban added."));
}
if (req.method == "URIBAN") {
    ban("req.http.host == " + req.http.host + " && req.url == " + req.url);
    # Throw a synthetic page so the request won't go to the backend.
    return (synth(200, "Ban added."));
  }
# Only cache GET and HEAD requests (pass through POST requests).
if (req.method != "GET" && req.method != "HEAD") {
return (pass);
}
# Pass through any administrative or AJAX-related paths.
if (req.url ~ "^/status.php$" ||
req.url ~ "^/update.php$" ||
req.url ~ "^/admin$" ||
req.url ~ "^/admin/.*$" ||
req.url ~ "^/flag/.*$" ||
req.url ~ "^.*/ajax/.*$" ||
req.url ~ "^.*/ahah/.*$") {
return (pass);
}

# Removing cookies for static content so Varnish caches these files.
if (req.url ~ "(?i).(pdf|asc|dat|txt|doc|xls|ppt|tgz|csv|png|gif|jpeg|jpg|ico|swf|css|js)(\?.*)\?$") {
unset req.http.Cookie;
}

if (req.http.Cookie) {

    set req.http.Cookie = ";" + req.http.Cookie;
    set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";");
    set req.http.Cookie = regsuball(req.http.Cookie, ";(SESS[a-z0-9]+|SSESS[a-z0-9]+|NO_CACHE)=", "; \1=");
    set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "");
    set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "");

    if (req.http.Cookie == "") {
      unset req.http.Cookie;
}
    else {
      return (pass);
    }
}

}
# Set a header to track a cache HITs and MISSes.
sub vcl_deliver {
# Remove ban-lurker friendly custom headers when delivering to client.
unset resp.http.X-Url;
unset resp.http.X-Host;
# Comment these for easier Drupal cache tag debugging in development.
#unset resp.http.Cache-Tags;
#unset resp.http.X-Drupal-Cache-Contexts;
if (obj.hits > 0) {
set resp.http.Cache-Tags = "HIT";
}
else {
set resp.http.Cache-Tags = "MISS";
}
}
# Instruct Varnish what to do in the case of certain backend responses (beresp).
sub vcl_backend_response {
# Set ban-lurker friendly custom headers.
set beresp.http.X-Url = bereq.url;
set beresp.http.X-Host = bereq.http.host;
# Cache 404s, 301s, at 500s with a short lifetime to protect the backend.
if (beresp.status == 404 || beresp.status == 301 || beresp.status == 500) {
set beresp.ttl = 10m;
}
# Don't allow static files to set cookies.
# (?i) denotes case insensitive in PCRE (perl compatible regular expressions).
# This list of extensions appears twice, once here and again in vcl_recv so
# make sure you edit both and keep them equal.

if (bereq.url ~ "(?i).(pdf|asc|dat|txt|doc|xls|ppt|tgz|csv|png|gif|jpeg|jpg|ico|swf|css|js)(\?.*)?$") {
unset beresp.http.set-cookie;
}
# Allow items to remain in cache up to 6 hours past their cache expiration.
set beresp.grace = 6h;
}

```

The contents of the nginx server configuration:

```
server {
    listen 443 ssl http2;
    server_name test.example.com;
    port_in_redirect off;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    location / {
      proxy_pass http://127.0.0.1:6081;
      proxy_set_header Host $http_host;
      proxy_set_header X-Forwarded-Host $http_host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto https;
      proxy_set_header HTTPS "on";
      proxy_set_header If-Modified-Since $http_if_modified_since;
      proxy_buffering on;
      proxy_buffer_size   128k;
      proxy_buffers   4 256k;
      proxy_busy_buffers_size   256k;
    }
}

server {
   listen 8080;
   server_name test.example.com;
   root /home/example/domains/test/public_html/web;
   index index.php index.html index.htm index.nginx-debian.html;
   port_in_redirect off;

   location / {
      try_files $uri $uri/ /index.php?$query_string;
   }

   location ~ \.php$ {
      include snippets/fastcgi-php.conf;
      fastcgi_pass 127.0.0.1:9000;
   }
}

server {
    listen 80;
    if ($host = test.example.com) {
        return 301 https://$host$request_uri;
    }
    server_name test.example.com;
    return 404;
}

```

# Answer
So, it was an error in the settings of the purger from the purge module. That became clear after asking this question on Stackoverflow.

Automated Cron or Drush were not able to connect to Varnish on port 6081 over TLS. The purger had to be changed to use plain HTTP In the Drupal UI I changed the purger with host 127.0.0.1 and port 6081 on http at /admin/config/development/performance/purge That solved it!
> 2 votes

---
Tags: 8, caching, proxies
---


# Question
Title: "Deprecated function: implode()" on GMap Drupal module
I have containerised a legacy Drupal 7 website with Docker. This is the docker-compose file:

```
version: '2.0'
services:
    drupal:
        build: .
        ports:
         - "8080:80"
        links:
         - mysql:mysql
    mysql:
        build: ./db
        ports:
         - "6603:3306"

```

The `drupal` container uses the official `drupal:7.72` image, whereas `mysql` stems from `mysql:5`. The database container is responsive and reachable from the Drupal container. The main page of the website loads correctly, but it shows this error message:

> Deprecated function: implode(): Passing glue string after array is deprecated. Swap the parameters in Drupal\gmap\GmapDefaults-\>\__construct() (line 107 of /var/www/html/sites/all/modules/gmap/lib/Drupal/gmap/GmapDefaults.php).

There is a similar error reported for a different function in Drupal 7.70. But apparently it was resolved with 7.71.

How can this particular error be solved? Would editing the `GmapDefaults.php` file be an option?

# Answer
> 3 votes
This answer draws upon the comments above by leymannx. The essential problem is an incompatibility between the GMap module and PHP 7.4, for which a patch is available. In this answer the patch is applied to the code repository itself, prior to any Docker builds, this is possibly the cleanest method.

The first step is to download the patch into the right folder in the repository:

```
cd sites/all/modules/gmap
wget https://www.drupal.org/files/issues/2020-03-06/gmap-php7.4.patch

```

The patch file is encoded for MSDOS, therefore it must be converted before the patch can be applied. Here all the target files are converted too, as a precaution:

```
dos2unix ./gmap-php7.4.patch
dos2unix gmap_test/gmap_test.features.inc
dos2unix lib/Drupal/gmap/GmapDefaults.php
dos2unix tests/inc/gmap_defaults.inc

```

The patch can now be applied. Since this is a git repository, the `git` command itself can not be used.

```
patch -p1 -i ./gmap-php7.4.patch

```

Finally remove all the extra files the process may have created. They are not needed in the container.

```
rm *.patch gmap_test/gmap_test.features.inc.orig lib/Drupal/gmap/GmapDefaults.php.orig tests/inc/gmap_defaults.inc.orig

```

---
Tags: 7
---


# Question
Title: How to change the e-mail output of a Entity type field in a webform
I have a content type **Agenda**. In this content type I can create paragaphs of the type **Date**. This paragraph has a field **date** and a field **location**.

Now people can attend to **agenda** items by submitting a webform (using the webform module).

In this webform use a Entity type field together with views to make a reference to **date** paragraphs. This reference works perfectly and creates a select with options showing the name of the name together with date and location. But in the e-mail confirmation I don't see the paragraph fields. Only the name of the node. I want to be able to manage how the output looks in the email confirmations.

At the moment I use `[webform_submission:values:agenda]` to get the value from the submission.

The way it looks now is: `Node:title > Content type [NID]` But I want to be able to see something like: `Node:title | Paragraph:Date | Paragraph Location`

How or where can I change this output?

# Answer
> 0 votes
Because I was in quite a hurry, I ended up creating hidden fields in my form for **date** and **location**. Using javascript I fetch the information from the Select field and add them to these hidden field. This way this information is send with the submission.

Not the prettiest way to do it but it works.

---
Tags: 8, webforms
---


# Question
Title: What's the best way to allow a user to save variables/options
I have a user who wanted to save some configuration options for his site. I had initially created a content type of *Options*, then created a node for that user so they could edit it, and didn't allow them to delete or create any other nodes of this content type. But it feels like this isn't what content creation was created for!

Am I missing a trick in allowing users to save options, or should I just create a custom form and save it to db?

# Answer
> 7 votes
Yes, instead of content entities you can use config entities. But for only a few configuration options this is too much effort. In this case you can use the Simple Configuration API, either by creating your own form

https://www.drupal.org/docs/drupal-apis/configuration-api/working-with-configuration-forms

or by adding form values to existing admin forms in a form alter hook.

See for example how the core dblog module adds an option to /admin/config/development/logging when it is enabled:

```
/**
 * Implements hook_form_FORM_ID_alter() for system_logging_settings().
 */
function dblog_form_system_logging_settings_alter(&$form, FormStateInterface $form_state) {
  $row_limits = [100, 1000, 10000, 100000, 1000000];
  $form['dblog_row_limit'] = [
    '#type' => 'select',
    '#title' => t('Database log messages to keep'),
    '#default_value' => \Drupal::configFactory()->getEditable('dblog.settings')->get('row_limit'),
    '#options' => [0 => t('All')] + array_combine($row_limits, $row_limits),
    '#description' => t('The maximum number of messages to keep in the database log. Requires a <a href=":cron">cron maintenance task</a>.', [':cron' => Url::fromRoute('system.status')->toString()]),
  ];

  $form['#submit'][] = 'dblog_logging_settings_submit';
}

/**
 * Form submission handler for system_logging_settings().
 *
 * @see dblog_form_system_logging_settings_alter()
 */
function dblog_logging_settings_submit($form, FormStateInterface $form_state) {
  \Drupal::configFactory()->getEditable('dblog.settings')->set('row_limit', $form_state->getValue('dblog_row_limit'))->save();
}

```

# Answer
> 2 votes
In some cases it may be preferable for your configuration to actually be stored as content, you may not want it managed as part of the configuration system and/or it may be easier to work with if it's content. In those cases, the Config Pages module is great.

From the module's *Do I need it* section:

> At some point I was tired of creating custom pages using menu and form API, writing tons of code just to have a page with an ugly form where a client can enter some settings, and as soon as a client wants to add some interactions to the page (drag&drop, ajax etc) things starts to get hairy. The same story was with the creation of dedicated CT just to theme a single page (like homepage) and explaining why you can only have 1 node of this type, or force it programmatically.

Some of these things aren't an issue in D8+ like they were in D7 and below, but the Config Form system still isn't 1:1 with Content Entity Forms.

**Some of the main features are:**

> Create fieldable entity using BO. FieldAPI, Features, views and other entity related modules are supported.

This gives you the ability to add fields and manage your form exactly the same way you would a node's form. It has a *Manage Fields* UI as well as a *Form Display* UI where you can build and manage your form without custom code.

> Mount your config page into menu structure as you like You can choose how (where) user will access this config page, so it can have a proper path like "admin/config/mysettings" and not explain to customer that he needs to create "a special node" in node/add.

The ability to place your form into the menu wherever you want and keep it out of the Content (nodes) area of your site. As you'd expect, the module provides its own permissions allowing you to give users the ability to edit or manage some or all of the *config\_page* entities on the site.

> You no longer need to create a new content type that will store fields for your singleton pages like homepage and explain to a client that this page is content but can't create 2 nodes in it.

No need to worry about a second version of the page getting added and messing things up. That's all taken care of.

> Config pages are themable as any other entity, so with proper view mode configuration you can just drop CCT provided by this module on the Page (in Panel module) and have your config page rendered.

This is a really great feature - you can reference and render *config\_page* entities just like any other content entity. This can be useful when you need to create a configuration form and then render some of that information in different places (e.g. some basic site information may need to render in header and footer). You can create and render view modes or programmatically render fields (using the config set in the UI). I find this to be significantly easier than trying to manually build a render array to render a value from my custom config form.

---

If you really want your configuration to act as configuration, i.e. live within the configuration management system and get pushed around environments via code, then a normal config entity/form is the right option. However, if you don't want or care about that, the Config Pages module is a great alternative and allows you to manage your config form and displays easily via the UI, the same way you'd manage a node's form and displays.

---
Tags: forms
---


# Question
Title: How to Reload a Custom Drupal Theme (Without the Command Line)
How do I reliably reload a custom Drupal theme I am developing without access to the command line? Just clearing the caches before I perform the load only works sometimes.

FWIW, we are promised command-line access in the future (security issues yet to be ironed out) but not anytime soon.

# Answer
> 1 votes
The steps that so far work reliably for me with Drupal 8.9.1 to load a custom theme again without command-line access are:

1. Install and enable the Devel module. (You will only need to do this once.)
2. Put your site into maintenance mode.
3. Turn on Devel -\> Settings -\> Rebuild the theme registry on every page load.
4. Clear the caches.
5. Load the new copy of the theme from Appearance -\> Install new theme -\> Upload a module or theme archive to install.
6. Clear the caches.
7. Reload one of your pages to verify your theme changes.

The second "Clear the caches" (6) might be redundant.

So far, this has worked like a champ once I figured out all of the necessary steps.

---
Tags: theming
---


# Question
Title: Is there a working example of programmatically creating a webform?
Is there a working example of programmatically creating a webform?

I just need to see what works. The smallest excerpt will be helping out a lot. I can build on a foundation.

# Answer
When you look around how to programmatically create a node you will finde patterns like this:

> ```
> $node = Node::create([
>   'type'        => 'article',
>   'title'       => 'Druplicon test',
>   'field_image' => [
>     'target_id' => $file->id(),
>     'alt' => 'Hello world',
>     'title' => 'Goodbye world'
>   ],
> ]);
> $node->save();
>
> ```

Maybe that's similar for webforms or webform submissions? Okay, let's scan Webform's codebase for the following patterns: `Webform::create` and `WebformSubmission::create`. Wow! Lots of samples just in the module's code! Let's take these two as a start:

Note that you also automatically can create webforms (not webform submissions, but webforms) by exporting config on one environment and importing it on different environments.
> 3 votes

---
Tags: webforms, 9
---


# Question
Title: Views will display entities the user does not have "view" access permission
I have a custom entity type that can be viewed by certain people only. This works just fine, when people go to "mysite.com/custom-entity/8" some can see the info, some get "access denied" error.

The problem is I created a view to display a list of those entities and all of them are shown to all users, even if certain users shouldn't have "view" access permission.

LE: Caching is set to "None"

Any ideas on how to fix this? Thanks.

# Answer
> -1 votes
**Option A**

Create a custom access handler for your view.

Drupal 8 - Views Custom Access with a Plugin is a great guide. It seems like your scenario may fit the use case outlined in the beginning:

"... prohibit the display of a Drupal 8 View dependent upon some custom rules that don't fit easily with Drupal's permissions model ..."

*Pro:* You will get exactly the control features you want.

*Con:* A lot of custom code.

**Option B**

If you want permission for viewing the entity to be directly tied to the view access, there is an "Access" section on the view configuration form. Select "Permission" and then select the permission for viewing the entity you have created.

*Pro:* Easy to set up.

*Con:* Your use case must fit into Drupal's permissions system.

---
Tags: 8, views
---


title: Debugging Ajax Callback

text:
# Question
Title: Debugging Ajax Callback
Goal: Print/dump `$formState` values to debug

I am altering a form and the functionality works:

```
$form['elements']['location']['deparment']['#ajax'] = [
  'callback' => 'myAjaxCallback',
  'event' => 'change',
  'progress' => [
    'type' => 'throbber',
    'message' => t('Verifying entry...'),
  ]
];

```

but what I want is to be able to print out `$formState` in myAjaxCallback

```
function myAjaxCallback(array &$form, FormStateInterface $formState){
 $response = new AjaxResponse();
 print_r($formState); //I've tried, with memory_limit=-1 . it just hangs
 dump($formState); //gives me File upload exceeds. This comes from issue with using dump in ajax
                     https://drupal.stackexchange.com/questions/250078/ajax-submission-leads-to-an-unrecoverable-error-occurred-the-uploaded-file-l

 return $response
}

```

I have also read https://www.drupal.org/docs/drupal-apis/javascript-api/ajax-forms and tried their Debugging AJAX Callback Functions, which has:

```
$response = new AjaxResponse();
$debugOut = @Kint::dump($formState); //but this uses dump too, which gives me ajax errors

```

so `dd($formState->getValues());` kind of works. This is what it shows me. So, as you can see, I can now see the variables. It's not the best, but readable.

whereas if I go to \[website\]/webform?ajax\_form=1 , it's not even readable.

I am running out of ideas to be able to debug the variable `$formState` .

# Answer
@sonfd Xdebug helps print out the values beautifully. No more print\_r() or kint() errors.
> 2 votes

---
Tags: 8, ajax, debugging
---


title: Hook on drush cache:rebuild

text:
# Question
Title: Hook on drush cache:rebuild
Is it possible to hook on `drush cache:rebuild` before the command is executed? I've seen some hooks for afterwards, but I am trying to compile my `less` files into `css` before cache the is rebuild. I'd be fine with it simply being just for the `drush cr` command in terminal, any way to automate the compiling on cache rebuild would be great!

All of the modules I've found for compiling less files requires you to do it manually, but not whenever cache is rebuilt like in D7.

Any ideas on how this could be accomplished?

# Answer
Drush uses the underlying Drupal function, `drupal_flush_all_caches()`, which invocates of a couple hooks:

But these hooks are used for flushing/rebuilding cache data that any module is storing.

Given that you might not always need CSS compilation when clearing all caches (e.g. needing to refresh module metadata or do route rebuilding), you're better off coupling cache-clearing/CSS compilation at the shell command level (e.g. custom shell script, drush command, etc.) where it can be executed in a build process, and not at the application level.
> 2 votes

# Answer
Yes drush has hooks for running code before all commands or in this case just before cache:rebuild. See https://github.com/consolidation/annotated-command#hooks. See @pre-command hook for example.
> 1 votes

---
Tags: 8, hooks, drush
---


# Question
Title: Order quantity increment condition for payment method
I need to set order increment quantities in my Commerce 2 website. The website has two stores: retail and wholesale. Customers who are shopping in my "retail consumers" store must have increments of 6 products in their cart in order to check out (6, 12, 18, 24, etc). Customers in my "wholesale consumers" store must have at least 4 products in their cart in order to check out (4, 8, 12, 16, etc).

My plan is to add a custom Condition that can be used for the two payment gateways that will be used in the stores (one for each store). That custom Condition would allow me to designate an increment value for the product quantity for each gateway. "Make this gateway available if the cart contains an increment of 6 products".

I recently created a similar plugin for product quantity minimums in the cart, and I think I can re-use most of that code with a few adjustments. I am just not sure how to factor in the incremental requirement. It would be acceptable to hard-code the increments of 6 if that is the best/easiest way to do it; I could then create two separate condition plugins, one for 6 and one for 4.

Below is the Condition plugin code I have so far:

```
<?php

namespace Drupal\order_total_quantity_increments\Plugin\Commerce\Condition;

use Drupal\commerce\Plugin\Commerce\Condition\ConditionBase;
use Drupal\commerce_price\Calculator;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;

/**
 * Provides the quantity increment condition for order items.
 *
 * @CommerceCondition(
 *   id = "order_total_quantity_increments",
 *   label = @Translation("Quantity Increment"),
 *   display_label = @Translation("Limit by quantity increments"),
 *   category = @Translation("Products"),
 *   entity_type = "commerce_order",
 *   weight = 10,
 * )
 */
class OrderTotalQuantityIncrements extends ConditionBase {

  /**
   * {@inheritdoc}
   */
  public function defaultConfiguration() {
    return [
      'increment' => NULL,
    ] + parent::defaultConfiguration();
  }

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
    $form = parent::buildConfigurationForm($form, $form_state);

    $increment = $this->configuration['increment'];

    if (isset($increment) && !isset($increment['number'])) {
      $increment = NULL;
    }

    $form['increment'] = [
      '#type' => 'number',
      '#title' => t('Increment'),
      '#default_value' => $this->configuration['increment'],
      '#min' => 1,
      '#required' => TRUE,
    ];

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
    parent::submitConfigurationForm($form, $form_state);

    $values = $form_state->getValue($form['#parents']);
    $this->configuration['increment'] = $values['increment'];
  }

  /**
   * {@inheritdoc}
   */
  public function evaluate(EntityInterface $entity) {
    $this->assertEntity($entity);
    /** @var \Drupal\commerce_order\Entity\OrderInterface $order */
    $order = $entity;
    $increment = '0';
    foreach ($order->getItems() as $order_item) {
      $increment = Calculator::add($increment, $order_item->getQuantity());
    }

  }

}

```

I believe I have to modify the last part of the code (below) or add something after it.

```
  public function evaluate(EntityInterface $entity) {
    $this->assertEntity($entity);
    /** @var \Drupal\commerce_order\Entity\OrderInterface $order */
    $order = $entity;
    $increment = '0';
    foreach ($order->getItems() as $order_item) {
      $increment = Calculator::add($increment, $order_item->getQuantity());
    }

  }

```

Can anyone please provide me with a direction to go in/guidance on how I should modify the code to meet my objective?

# Answer
> 1 votes
Per OP's comment, updated solution:

```
 public function evaluate(EntityInterface $entity) {
    $this->assertEntity($entity);
    /** @var \Drupal\commerce_order\Entity\OrderInterface $order */
    $order = $entity;
    $increment = $this->configuration['increment'];
    $total = 0;

    foreach ($order->getItems() as $order_item) {
      $total += $order_item->getQuantity();
    }
    if ($total % $increment !== 0) {  return FALSE;  }

    return TRUE;
  }

```

---
Tags: 8, commerce
---