# Question
Title: Why 'Failed to start the session' when RedirectResponse is sent?
When this code is executed, I have an error message logged.
The code is in `shared_node_access(NodeInterface $node, $op, AccountInterface $account)`

```
if ($node->get('nid')->value == 1) {
  if ($account->isAnonymous()) {
  }
  else {
    $path = Url::fromUserInput('/node/25')->toString();
    $response = new RedirectResponse($path);
    $response->send();
  }
}

```

The error message:

> RuntimeException : Failed to start the session because headers have already been sent by "/home/lejardindf/JdP8/vendor/symfony/http-foundation/Response.php" at line 377. dans Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage-\>start() (/home/lejardindf/JdP8/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php ligne 150)

# Answer
> 0 votes
There are two problems. First, you can't send a response from custom Drupal code. Second, you can't run non access code in an access hook, because access results are cached.

For redirects in Drupal 8 see these change records: drupal\_goto() has been removed and hook\_init() removed.

A different approach might be to let the 403 exception happen and then catch it in an exception event subscriber to do the redirect, see How to redirect an anonymous user to the login form after a 403 error?

# Answer
> 0 votes
Following @4k4's advice, I removed the code from `shared_node_access`.
Then added `shared.services.yml`:

```
services:
  shared.event_subscriber:
    class: Drupal\shared\EventSubscriber\EventSubscriber
    arguments: ['@current_user']
    tags:
      - { name: event_subscriber }

```

and `EventSubscriber.php`:

```
class EventSubscriber implements EventSubscriberInterface {

  protected $currentUser;

  public function __construct(AccountInterface $current_user) {
    $this->currentUser = $current_user;
  }

  public static function getSubscribedEvents() {
    $events[KernelEvents::RESPONSE][] = ['redirectIf'];
    return $events;
  }

  public function redirectIf(FilterResponseEvent $event) {
    $node = $event->getRequest()->attributes->get('node');
    if ($node && $node->get('nid')->value == 1) {
      if (!$this->currentUser->isAnonymous()) {
        $path = Url::fromUserInput('/node/25')->toString();
        $event->setResponse(new RedirectResponse($path));
      }
    }
  }
}

```

---
Tags: 8, sessions
---


# Question
Title: How to add password reset link to user page?
Is there an easy way to add a password reset button to the user page in drupal 8? For user management I need the admin to be able to send password recovery link to users AFTER the user account is created. This button should only be visible to admins.

# Answer
You can create a custom module for that.

### resetpassword.info.yml

```
name: 'Reset Password'
type: module
description: 'Reset Password link for administrators'
core: 8.x

```

### resetpassword.module

```
<?php

/**
 * @file
 * Hook implementations for the Reset Password module.
 */

use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Url;
use Drupal\Component\Utility\Html;

/**
 * Alter the user edit form
 *
 * @param $form
 * @param \Drupal\Core\Form\FormStateInterface $form_state
 * @param $form_id
 */
function resetpassword_form_user_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  $user = \Drupal::currentUser()->getRoles();
  if (in_array("administrator", $user)) {
    $form['actions']['sendresetlink'] = [
      '#type' => 'submit',
      '#weight' => 999,
      '#limit_validation_errors' => [],
      '#button_type' => 'danger',
      '#submit' => [
        'resetpassword_send_reset_link_to_account_submit'
      ],
      '#value' => t('Sent reset link to account email'),
    ];
  }
}

/**
 * Submission handler for the password reset button.
 *
 * @param $form
 * @param \Drupal\Core\Form\FormStateInterface $form_state
 */
function resetpassword_send_reset_link_to_account_submit(&$form, \Drupal\Core\Form\FormStateInterface $form_state) {
  // Load the user entity of the form.
  $account = $form_state->getFormObject()->getEntity();

  // Create a timestamp.
  $timestamp = \Drupal::time()->getRequestTime();
  // Set the redirect location after the user of the one time login.
  $path = '';

  // Create the login link from the route.
  $link = Url::fromRoute(
    'user.reset.login', ['uid' => $account->id(),
      'timestamp' => $timestamp,
      'hash' => user_pass_rehash($account, $timestamp),
    ],
    ['absolute' => true,
      'query' => $path ? ['destination' => $path] : [],
      'language' => \Drupal::languageManager()->getLanguage($account->getPreferredLangcode()),
    ]
  )->toString();

  // Genereate mail.
  $mailManager = \Drupal::service('plugin.manager.mail');
  $module = 'resetpassword';
  $key = 'user_reset_links';
  $to = $account->getEmail();
  $langcode = \Drupal::currentUser()->getPreferredLangcode();

  // Set the message and the subject.
  $params['message'] = $link;
  $params['title'] = t("One time login link");

  // Send mail and collect the result.
  $result = $mailManager->mail($module, $key, $to, $langcode, $params);
  if (!$result['result']) {
    \Drupal::messenger()->addError(t('There was a problem sending your email notification to @email.', array('@email' => $to)));
    \Drupal::logger('mail-log')->error('There was a problem sending your email notification to @email.', array('@email' => $to));
    return;
  }

  \Drupal::messenger()->addMessage(t('An email notification has been sent to @email ', array('@email' => $to)));
  \Drupal::logger('mail-log')->notice('An email notification has been sent to @email ', array('@email' => $to));
}

/**
 * Implements hook_mail().
 */
function resetpassword_mail($key, &$message, $params) {
  $options = array(
    'langcode' => $message['langcode'],
  );

  if ($key == 'user_reset_links') {
    $message['from'] = \Drupal::config('system.site')->get('mail');
    $message['subject'] = t('Your mail subject Here: @title', array('@title' => $params['title']), $options);
    $message['body'][] = Html::escape($params['message']);
  }
}

```
> 3 votes

---
Tags: 8, users
---


# Question
Title: How to include or hit a php file from custom module in Drupal 8
I am working on a custom Drupal 8 module. I have a seperate php script as a .php file. I want to include that file in my Drupal 8 module, in simple words I want to hit that .php file by running my module.

What is the best way to do this?

Here is my module code:

```
    function mymodule_cron(){
     //include('myphpscript.php');
    }

```

Thanks

# Answer
Standard PHP `include`, `require`, and `require_once` need a known path. Often times this is not known when making Drupal contributed modules.

In Drupal 7, the standard way to include a file inside a module was using the `module_load_include` function. This is still available, but may not be suitable for test-driven development.

In Drupal 8, as @Jaypan references in a comment above, Structure of a a service file, we can create services and use methods on a class to do things. This has the benefit of injecting dependencies to do things.

```
function mymodule_cron() {
  // This still works, but shouldn't be used for classes in the autoloader. Generally the ".inc" file extension was used instead of ".php", but it would work.
  module_load_include('php', 'mymodule', 'myphpscript');

  // Implementing your own service if you want to use \Drupal.
  \Drupal::service('mymodule.myservice')->callMethodToDoThingOnCron();
}

```
> 0 votes

---
Tags: hooks, cron
---


# Question
Title: What's the easiest way of importing content of a custom D6 content type into a D8 site?
I have a Drupal 6 site with three custom content types. We have tried using the Migrate Drupal UI module to migrate these to our new Drupal 8 site, but this resulted in all of the plain text fields being imported as long text fields (field type `string_long` when they should be `string`).

To fix this, I deleted all content of those types, exported the configuration created by the UI module with `drush cex` and used `drush cim` to re-import the YAML config files after changing all instances of `string_long` to `string`.

After about 3 hours of fiddling with this, I finally had a working D8 configuration with the same fields, forms and views as the original D6 site. Now it's time to migrate the content data across.

I have spent another ~6 hours researching and experimenting on how to do this, having tried the views\_data\_export and Feeds modules, as well as reading several resources on creating custom migration modules.

The former solution was tedious to set up and the default form for creating a feed type wouldn't allow me to create nodes with the original node IDs. So I tried to step through the code and figure out how to extend the module by myself, since the API documentation is severely outdated. This got me nowhere but extremely tired, confused and frustrated, and about 2 hours closer to my eventual demise.

I'm not even game to try the latter solution, since that would probably be just as hard. So now I've started investigating the DB structure in the hope of writing my own SQL update script...only to discover that there are not only `node`, `node_field_data`, `node_revision` and `node_field_revision` tables to contend with, but also `node__<field_machine_name>` and `node_revision__<field_machine_name>` tables for **every defined field** (35 of them in my case)!

This seriously can't be this hard! Surely I must be missing some crucial piece of documentation from my Google search results. So what would be the **easiest** method to accomplish what I want?

# Answer
The two options here is the inline D6\>D8 migration, or to use the Migrate API + Migrate Plus (if needed) directly to write your own migrations. The latter has example migrations you can look at. There is never going to be a case or scenario where you will want to write a manual SQL migration script. You should not need Views or Feeds for this - the Migrate API has source plugins that can connect to databases or other data sources to query and pull data.

Here is a docs page outlining how to migrate from a SQL source:

https://www.drupal.org/docs/8/api/migrate-api/migrate-source-plugins/migrating-data-from-a-sql-source

You would set the two databases side by side in MySQL, create a connection setting as mentioned and create a source. The class controls certain aspects of querying and the migration YAML(s) map the fields to their new destinations.

For all the nuanced aspects, I would recommend joining the migration channel in the Drupal Slack, people are always willing to help there.
> 0 votes

---
Tags: migrations
---


# Question
Title: Trying to list all articles where category field is empty
I have drupal 7 site and I'm trying to listing all articles (with title) and where category field is empty (taxonomy). I'm running this code in my page with -\>isNull and without, but not any results. Can someone explain what I'm doing wrong in here and why this is not working?

```
$query = db_select('node', 'n')
  ->fields('n', array('nid'))
  ->condition('n.type', 'article')
  ->condition('n.status', 1)
  ->isNull('n.field_tags')
  ->range(0, 10);

  $results = $query->execute();

```

I'm get this error all the time:

> PDOException: SQLSTATE\[42S22\]: Column not found: 1054 Unknown column 'n.field\_tags' in 'where clause': SELECT n.nid AS nid FROM {node} n WHERE (n.type = :db\_condition\_placeholder\_0) AND (n.status = :db\_condition\_placeholder\_1) AND (n.field\_tags IS NULL ) LIMIT 10 OFFSET 0; Array ( \[:db\_condition\_placeholder\_0\] =\> article \[:db\_condition\_placeholder\_1\] =\> 1 ) in eval() (line 17 of /sites/site.com/modules/php/php.module(80) : eval()'d code).

# Answer
It seems to me your mistake is you are requesting the column field\_tags from the table node, which is not a column from node, so doesn't exist.
Unless you have a very specific database structure, your "field\_tags" should be contained in the table `field_data_field_tags`, so you may have to make an `INNER JOIN` between these tables in your query (maybe using `field_data_field_tags.entity_id = n.id`), and then check if the `n.id` exists in `field_data_field_tags.entity_id`, or (maybe better) use a `LEFT JOIN` between `field_data_field_tags` and `node`, so only the node with a n.id existing in field\_data\_field\_tags will be returned.
> 3 votes

---
Tags: 7, nodes
---


# Question
Title: Why do all product display nodes with same referenced product (SKU) appear in 1 order view
Each time an order is added to cart, the `admin/commerce/orders/11/view`, for example, shows ***all*** product display nodes ever created on the site for that SKU.

I suspect that this is not the normal behaviour I should see because if it were, over time, these order views on the administrative pages would grow endlessly long.

However, the Cart Form shows only 1 item and that appears to be correct. I suspect there is something incorrect with my Line Items view. `admin/structure/views/view/commerce_line_item_table/edit/default?destination=admin/commerce/orders/11/view`

Please see my attached images.

# Answer
It's a result of your relationships: you're connecting each order item to the product it represents and then each product to each node that references it. Because of the way that database query works, it returns a unique result for every combination and renders them into your View.

Judging by your View's configuration, this was the simplest way for it to include the course type, teacher, etc. fields from the node. You're going to have to filter the result set somehow ... unfortunately, the data you need to be able to do that (the add to cart context from the $line\_item-\>data array) isn't exposed to Views.

To see how that array gets built, check out `commerce_cart_field_attach_view_alter()`. You have two basic options for that data: create a custom Views filter that will allow you to filter the result set of your Views based on the values in the `$line_item->data['context']['entity']` array or else remove the relationship from the View and switch to rendering the line item using a custom view mode, loading the data you need from the related entities manually.

(Note: I was going to suggest that if you only have one active node selling each product at any given point in time (unclear from your question), you could just add a filter to your View that checks to ensure the node referencing the product is published. That would get rid of the duplication but screw up your historical orders who now appear to show the wrong content.)
> 0 votes

---
Tags: 7, commerce
---


title: Form Select not rendering as a dropdown

text:
# Question
Title: Form Select not rendering as a dropdown
I'm building a form that contains a `select` but it's not rendering as a dropdown. It's rendering with a scrollbar and a dropdown down arrow

```
$form['my_select'] = [
  '#type' => 'select',
  '#empty_option' => '- None -',
  '#title' => $this->t('My Select'),
  '#options' => ['Option1', 'Option2'],
  '#size' => 6,
  '#weight' => '0',
];

```

What am I doing wrong?

# Answer
> 5 votes
It's rendering as a list because you have set `#size` to 6, which means 6 rows will be visible. Either remove the `#size` property completely, or set it to 1 to display a normal dropdown.

From the documentation:

> #size: The number of rows in the list that should be visible at one time.

---
Tags: 8, forms
---


# Question
Title: What Commcerce event is fired when a payment is made?
There seem to be a few bugs in Commerce (8.x-2.17) related to admins making payments against a Cart. I am trying to fix some of these in my own custom module (rather than wait for people to agree these are bugs). Some, but not all, include:

1. payments made are not reflected anywhere.
2. when paid in full the order is not "completed" (not sure if this is correct term, in D7 i think the term was "checked out").
3. payments can be made beyond the full amount of the order (or the balance)

I think it should be possible to address some of these by subscribing to a Payment event and going in and cleaning things up (not sure where or how to clean up; but baby steps).

I have seen a post listing: commerce\_order.order.paid as an event that is fired when the order is paid in full; but this is not fired (as far as i can tell) when a payment is made which completes the order (neither from admin paying or standard checkout flow).

I have also seen commerce\_payment.commerce\_payment.insert, which is also not fired during payment or checkout flow. To be honest i don't understand the naming related to payments: add payment, insert, update? Why is this not "make" a payment as this is more grammatically correct.

Does anyone know what event is triggered when a payment is made (or ideally when a payment covers the balance owing on an order)?

# Answer
> 2 votes
You seem to misunderstand the term payment here. It should not be seen in the context of a regular payment that you make or complete in a store. In this context payments are entities and the events match those of database transactions (insert, update, delete, etc.).

Theoretically the combination of these 3 events should allow you to determine if a payment has been made or altered or deleted, but you need to subscribe to all of them to be updated on all changes. (If you only subscribe to inserts (new payments) but not to deletes (removed payments) you might miss data.)

The `commerce_order.order.paid` or the safer `\Drupal\commerce_order\Event\OrderEvents::ORDER_PAID` event has the following documentation:

```
/**
 * Name of the event fired after the order has been fully paid.
 *
 * Guaranteed to only fire once, when the order balance reaches zero.
 * Subsequent changes to the balance won't redispatch the event (e.g. in case
 * of a refund followed by an additional payment).
 *
 * Fired before the order is saved.
 *
 * @Event
 *
 * @see \Drupal\commerce_order\OrderInterface::getBalance()
 * @see \Drupal\commerce_order\Event\OrderEvent
 */
const ORDER_PAID = 'commerce_order.order.paid';

```

It is called from `doOrderPreSave()` in OrderStorage.php, but only if the event has not dispatched before:

```
  if ($order->getData('paid_event_dispatched') === FALSE) {
    $event = new OrderEvent($order);
    $this->eventDispatcher->dispatch(OrderEvents::ORDER_PAID, $event);
    $order->setData('paid_event_dispatched', TRUE);
  }

```

When a payment is made, the order is listed in the `commerce_payment.order_updater` service which during its destruct will update and save all listed orders. Those in turn will determine if the total order balance has been reduced to zero and emit the event. It looks sensible to me.

Could it be that you have been testing with the same order over and over and that event already fired once?

---
Tags: 8, commerce
---


# Question
Title: Given a taxonomy term id, how do we get the value of other fields; specifically the machine_id?
A good example of getting the children is posted How to get fields...

I need the machine\_id of the parent (or target)

Code below fetches the name;

```
$product_name_id = $product_name_reference->getValue()[0]['target_id'];
$product_name = \Drupal\taxonomy\Entity\Term::load($product_name_id)->label();

```

The machine\_name is visible under 'values'. How do I get it!

# Answer
The **machine name** is the **vid**:
if you search for `machine_id` inside taxonomy module there is no `machine_id` field declared.

But if you look at `core/modules/taxonomy/config/schema/taxonomy.schema.yml` you can see that:

```
vid:
  type: string
  label: 'Machine name'

```

So to get the vid (Machine name) you should use `getVocabularyId` something like:

```
$product_name_id = $product_name_reference->getValue()[0]['target_id'];;
$product_name = \Drupal\taxonomy\Entity\Term::load($product_name_id);
// Vid or machine name.
$vid = $product_name->getVocabularyId();

```
> 1 votes

# Answer
I was way overthinking it...

Solution:

```
$product = $entity->get('field_products')->entity;
$product_name = $product->get('machine_name')->value;

```

$product gets the object from the taxonomy item $product\_name gets machine name
> 1 votes

---
Tags: entities
---


# Question
Title: How to disable a file upload button for anonymous users?
I've created a commerce add to cart form with a file upload field. The user can use this to upload a logo but I don't want anonymous users to be able to do this. I can see that the file module uses ajax to handle the upload but I can't see how you can disable the upload button for non logged in users.

# Answer
The Field permissions module should help you achieve this.

> The Field Permissions module allows site administrators to set field-level permissions to edit, view and create fields on any entity.
>
> Enable field permissions on any entity, not just nodes.
>
> Role-based field permissions allowing different viewing patterned based on what access the user has.
>
> Author-level permissions allow viewing and editing of fields based on who the entity owner is.
>
> Permissions for each field are not enabled by default. Instead, administrators can enable these permissions explicitly for the fields where this feature is needed.
> 0 votes

# Answer
A directed `hook_form_alter` can be used to do this. Add to cart forms are special breed in that the form ID's include hashes for uniqueness, so you **can't** use `hook_form_FORM_ID_alter`:

```
function MY_MODULE_form_alter(array &$form, FormStateInterface $form_state, string $form_id){
  // This will get all Add To Cart Forms. If you need something more specific, you'll have to tailor it for such.
  if (strpos($form_id, 'commerce_order_item_add_to_cart_form_') === 0) {
    if (\Drupal::currentUser()->isAnonymous()) {
      ... unset() the $form elements representing the upload stuff here.
      ... I would delete the file input and the upload button.
    }
  }
}

```
> 0 votes

---
Tags: ajax, files
---


# Question
Title: How do I add the "onload" attribute to a script tag?
I need to add the onload event in jquery script tag as advagg does. I have done a bit of research, and I found that they are actually invoking `hook_element_info_alter()` and thereby add their `hook_advagg_modify_js_pre_render()` implementation into it. Then, they alter the child elements.

When I do the same in a `hook_element_info_alter()` implementation, `type['script']` is not there.

Am I missing something?

# Answer
If you want to make sure you're javascript is loaded in the header:

**For drupal 7**

`/sites/default/themes/yourtheme/template.php`

```
function theme_preprocess_html(&$var) {
      $path = $GLOBALS['base_url'] . '/' . path_to_theme() . '/js/yourscript-min.js';
      $script = array(
        '#tag' => 'script',
        '#attributes' => array(
            'type' => 'text/javascript',
            'src' => $path
        ),
        '#value' => '',
       );
       drupal_add_html_head($script, 'script');
    }

```

or if you want it loaded in the page:

```
function theme_preprocess_html(&$var) {
      $script = array(
        '#tag' => 'script',
        '#attributes' => array('type' => 'text/javascript'),
        '#value' => 'Add your javascript here',
       );
       drupal_add_html_head($script, 'script');
    }

```

**For drupal 8**

In the yourtheme.libraries.yml you need to create a library like so:

`yourtheme.libraries.yml`

```
library-name:
  header: true
  js:
    js/yourSrctipForTheHeader.js: {}

```

Also in the `theme.info.yml` you need to add this library, then it will automatically comes in head tag and will be available before the page load, if you remove `header:true` the script will be loaded after the page load.

`theme.info.yml`

```
libraries:
  - yourtheme/library-name

```

Alternativly, you can make use of this module: https://www.drupal.org/project/header\_and\_footer\_scripts and put the scipts in manually in the position that you want. But to be honest, i think the first solution is the more elegant way.
> 0 votes

---
Tags: 7, forms
---


# Question
Title: Do path parameters need to be sanitized before using in the controller action method?
I was surprised to not see anything in the documentation as far as whether or not wildcard routing parameters need to be sanitized before using them in the controller action method.

In Using parameters in routes, there doesn't seem to be any mention about whether or not the Symfony routing takes care of the sensitization or not unless I'm missing something.

This is my test.routing.yml file.

```
test.test_controller_doTest:
  path: '/test/hello/{name}'
  defaults:
    _controller: '\Drupal\test\Controller\TestController::doTest'
    _title: 'This is the page title - nothing more Yo'
    name: "Rumplestiltskin"
  requirements:
    _permission: 'access content'

```

It seems that others are having a question about this as well:

> Obviously anything in the path could be altered by a user so you’ll want to test for valid values and otherwise ensure that these values are safe to use. I can’t tell if the system does any sanitization of these values or if this is a straight pass-through of whatever is in the url, so I’d probably assume that I need to type hint and sanitize these values as necessary for my code to work.

Based on some additional research it looks like they are not sanitized by default. See https://stackoverflow.com/questions/24880067/are-symfony-2-0-route-wildcards-sanitized.
This seems like it's ripe for a code injection attack via something like the following.

```
$res = eval('return 1 + '. $_GET['crazy']+ ';'); with ?crazy=0;exec("rm+-rf+/")

```

Can anyone confirm that we do need to sanitize and if so a recommendation for sanitizing string input in a standard way?

# Answer
> 1 votes
How to sanitize something depends on what you want to use it for.

It's entirely different if you want to protect against SQL injection in a database query or XSS when printing something.

PHP tried to do magic things on input but those features were removed a long time ago, see http://php.net/manual/en/security.magicquotes.whynot.php for example.

Protecting against SQL injecting is easy with the provided tools, Drupal 8 also autoescapes all output unless its told that something is safe. And simply don't use eval(), ever.

# Answer
> 0 votes
Well, actually according to Drupal official docs you can specify validation criteria on `*.routing.yml` level file. The only thing to do is to add another section/sections on `requirements` property. Here's the example of filtering parameter {name} to allow to use only lower and upper characters from `[a-z]` and \[A-Z\]:

```
example.user
  path: '/example/{name}'
  defaults:
    _controller: '\Drupal\example\Controller\ExampleController::content'
  requirements:
    _permission: 'access content'
    name: '[a-z]+'

```

If you have more than just one parameter, include it in next line, like so:

```
example.user
  path: '/example/{name}/{surname}'
  defaults:
    _controller: '\Drupal\example\Controller\ExampleController::content'
  requirements:
    _permission: 'access content'
    name: '[a-zA-Z]+'
    surname: '[a-zA-Z]+'

```

---
Tags: 8, routes
---


# Question
Title: How can I render an image stocked in a custom module with an image style?
I'am learning Drupal 8, and I would like create a custom module who create a block to add share button. The link of this button should be an image who stocked in my custom module. I would like use an image style on my picture.

Last but not least, i want use a render array.

In my build() method of my customblock.php i have whrite :

```
//create url link
$url = Url::fromUri('https://www.facebook.com/sharer/sharer.php?u='.$base_url.Url::fromRoute('<current>')->toString());

//create uri image
$pathmodule=drupal_get_path('module', 'share_configurable');
$urifacebook=$pathmodule.'/src/img/facebook.png';

//render array of link
if ($this->configuration['network']['facebook']=='facebook'){
  $build['link_facebook'] = [
    '#title' => [
      '#theme' => 'image_style',
      '#style_name' => 'thumbnail',
      '#uri' => $urifacebook,
    ],
    '#type' => 'link',
    '#url' => $url
  ];
}

```

The link is create, but the image is not render... Can you help me please ?

# Answer
Thank to Hudri : Image styles only work with managed files (uploaded, with entry in DB), not with static assets. Since this is a static asset anyway, just provide the correct size in your module.
> 1 votes

---
Tags: 8, theming
---


# Question
Title: Modify the display of one field by the value of another field
We have a content type with a date range element on our D8 site. I got a request to hide the display of the end date if the content editor decided so.

From testing, the content editor can't delete the end date-- the field fails validation if an end date has already been specified. And anyways, they don't want to delete the end date-- they want to maintain that information-- they only want it not to display to the public audience, in certain circumstances.

I started to approach this by adding a second field to the content type, a boolean checkbox "Hide End Date". I wrote a `hook_preprocess_field` in our .theme file in order to change the display of the date range value. But after debugging the variables, I realized that the date range field doesn't have any information about the value of the "hide end date" field, of course.

I'm not sure how best to proceed. Is `hook_preprocess_node` the place where I can look at both field values, and alter the value of the date range field? Will that affect display of the field throughout the site, including views?

# Answer
Add a boolean field as a condition to hide the end-date is a fine solution. For hiding the field you can either check for the boolean in the template:

```
{% if $node->field_hide_end_date->value %}
    {{ $node->field_range->value|format_date('my_custom_date_format') }}
{% else %}
    {# Original version of the field #}
    {{ $content['field_range'] }}
{% endif %}

```

Or change the value in a preprocess method

```
function custom_module_preprocess_node(&$variables) {
  if (array_key_exists('field_period', $variables['elements'])) {
    $node = $variables['elements']['#node'];

    if ($node->field_hide_end_date->value) {
      $variables['elements']['field_period'] = [
        '#markup' => (new DrupalDateTime($node->field_period->value))->format('d-m-Y'),
      ];
    }
    // else: business as usual.
  }
}

```
> 1 votes

---
Tags: hooks
---


# Question
Title: Drupal 8 Accessing Menu Tree in a Block's JS
How can I pass the menu into a block's javascript?

I am trying to build a block for a custom mobile menu (client wants specific logic/animations/etc) and use that in Structure \> Block layout \> Main Navigation.

They want me to do it via jQuery for reasons, but I cannot find how to get access to the menu tree in the javascript of the block. I feel like this should be simple enough with the API but the documentation seems to be all focused on PHP.

Any help is appreciated, thanks!

***NOTE***

I did find this post but I'm honestly not sure what it is trying to do, it is from about 4 years ago, and making/bundling libraries to just access the menu seems like it is probably not the ideal way to do this. Also I am using Bootstrap's theme and I do not see a template.php. Thanks again!

# Answer
> 1 votes
The documentation is inevitably focused on PHP, since Drupal is written in PHP and server-side renders. And the answer to getting info from PHP/server side to JS/client side is not really Drupal specific. Like any other situation of this ilk in web development, you have two basic choices. Either annotate your HTML with enough elements, IDs and classes that you can pull the necessary info out of the DOM, or expose an endpoint containing the info in a convenient-for-JS-consumption format like JSON for your javascript to fetch.

As for the latter, if you don't feel like rolling your own endpoint, there seem to be one, two three and maybe more modules, although I cannot vouch for any of them.

---
Tags: javascript, blocks, navigation
---


# Question
Title: How can I update the length of a base field definition in an update hook?
I'm struggling with writing an update hook that will simply update the length of a text base field attached to an entity of mine.

Here's my update hook:

```
function my_module_update_8001() {
  // Collect all existing story run data.
  $database = \Drupal::database();

  // Gather all the existing story run data.
  $tables = [
    'content_tile_field_data',
    'content_tile_field_revision',
  ];
  $existing_data = [];
  foreach ($tables as $table) {
    $existing_data[$table] = $database->select($table)
      ->fields($table)
      ->execute()
      ->fetchAll(PDO::FETCH_ASSOC);
    $database->truncate($table)->execute();
  }

  // Update the "name" base field definition to a new max length
  $update_manager = \Drupal::entityDefinitionUpdateManager();
  $name_field = $update_manager->getFieldStorageDefinition('name', 'content_tile');
  $name_field->setSetting('max_length', 100);
  $update_manager->updateFieldStorageDefinition($name_field);

  // Restore the data.
  foreach ($tables as $table) {
    $insert_query = $database
      ->insert($table)
      ->fields(array_keys(end($existing_data[$table])));
    foreach ($existing_data[$table] as $row) {
      $insert_query->values(array_values($row));
    }
    $insert_query->execute();
  }
}

```

After running this, the `name` field is clearly dropped and re-added (I know because it now appears at the end of the list of columns in the table), but the length is still set to 50, the old value.

I've narrowed this down to BaseFieldDefinition::getSchema():

```
  public function getSchema() {
    if (!isset($this->schema)) {
      // Get the schema from the field item class.
      $definition = \Drupal::service('plugin.manager.field.field_type')->getDefinition($this->getType());
      $class = $definition['class'];
      $schema = $class::schema($this);
      // Fill in default values.
      $schema += array(
        'columns' => array(),
        'unique keys' => array(),
        'indexes' => array(),
        'foreign keys' => array(),
      );

      // Merge custom indexes with those specified by the field type. Custom
      // indexes prevail.
      $schema['indexes'] = $this->indexes + $schema['indexes'];

      $this->schema = $schema;
    }

    return $this->schema;
  }

```

The schema definition is cached, so the update process gets the old schema data instead of regenerating it. There appears to be no way to clear this internal cache.

If I comment out the code related to the caching, it works as expected.

Is there another approach to this that I'm missing?

**EDIT:** The approach I took instead is to just load the *current* definition and pass that through to the update manager, like this:

```
  $update_manager = \Drupal::entityDefinitionUpdateManager();
  $definitions = \Drupal::entityManager()->getFieldStorageDefinitions('content_tile');
  $name_field_definition = $definitions['name'];
  $update_manager->updateFieldStorageDefinition($name_field_definition);

```

I guess this is not recommended normally, but it worked just fine.

# Answer
I was having the exact same issue, trying to update the "max\_length" of the name field of a custom entity. I did a hook\_update like that :

```
function mymodule_update_8005() {
  $entity_definition_update_manager = \Drupal::service('entity.definition_update_manager');
  $field_definition = $entity_definition_update_manager->getFieldStorageDefinition('name', 'myentityid');
  $field_definition->setSetting('max_length', 255);
  $entity_definition_update_manager->updateFieldStorageDefinition($field_definition);
}

```

But then, even if the fieldDefinition had correctly changed, I was still having the old length limitation.

Finally, what I had forgotten to do was changing this max\_length in my entity definition itself, here :

```
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
  $fields['name'] = BaseFieldDefinition::create('string')
  ->setLabel(t('Title'))
  ->setSettings(array(
    'max_length' => 255,
    'text_processing' => 0,
  ));
  ...

```

After that, it worked as desired.
> 2 votes

# Answer
Offical Drupal documentation in the section "Altering the length of a field with data" has a example function for achieving that https://www.drupal.org/docs/8/api/update-api/updating-database-schema-andor-data-in-drupal-8#s-altering-the-length-of-a-field-with-data
> 2 votes

# Answer
In latest version of Drupal seems to work only reinstall option, so basic flow is:

```
$entityUpdateManager = \Drupal::entityDefinitionUpdateManager();
  $field_definition = $entityUpdateManager->getFieldStorageDefinition($fieldName, $entityTypeId);
  $entityUpdateManager->uninstallFieldStorageDefinition($field_definition);
  $newStorageDefinition = BaseFieldDefinition::create('string')
    ->setLabel(t('Label'))
    ->setSetting('max_length', 191)
    ->setDescription(t('Description.'))
    ->setDisplayConfigurable('form', TRUE)
    ->setDisplayConfigurable('view', TRUE); // Same as in entity type class.
  $entityUpdateManager->installFieldStorageDefinition(
    $fieldName, $entityTypeId, $moduleName, $newStorageDefinition
  );

```
> 1 votes

# Answer
It is it bit confusing and, unless I've missed it, not well documented. I think the answer is to study what the devel\_entity\_updates module does, not to reproduce it in entirety but to see what you need to do for a specific field.

There are several services involved in updating a field. The one that does the work is FieldStorageDefinitionListener. Note that it does not work for a field with data so you probably need to copy to a temporary field and back.

Final code needs to be something like this:

```
/** @var \Drupal\Core\Entity\EntityFieldManagerInterface $efm */
$efm = \Drupal::service('entity_field.manager');
$storage_definitions = $efm->getFieldStorageDefinitions('test_entity');
$new_field_def = $storage_definitions['field1'];

/** @var \Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface $elisr */
$elisr = \Drupal::service('entity.last_installed_schema.repository');
$original_storage_definitions = $elisr->getLastInstalledFieldStorageDefinitions('test_entity');
$orig_field_def = $original_storage_definitions['field1'];

/** @var \Drupal\Core\Field\FieldStorageDefinitionListenerInterface $fsdl */
$fsdl = \Drupal::service('field_storage_definition.listener');

$fsdl->onFieldStorageDefinitionUpdate($new_field_def, $orig_field_def);

```

That will update the schema.
> 0 votes

---
Tags: 8
---


# Question
Title: Alter a path alias depending on a node property
I use the Pathauto module and I'm trying to get, for the same content type, two different path aliases depending on a Boolean field that content type has.

I would like to have a path alias like mysite/node\_name if the Boolean field value is false and mysite/\[a generic term\]/node\_name if its value is true.

Is there a way to do this?

# Answer
if you don't won’t to create a new token as @Clive mentioned in comment, you can use `hook_pathauto_alias_alter` in your custom module like the following.

```
/**
 * Implements hook_pathauto_alias_alter().
 */
function MY_MODULE_pathauto_alias_alter(&$alias, array &$context) {
  if ($context['module'] === 'node' && $context['bundle'] === 'MY_BUNDLE') {
    // Get the node.
    $node = $context['data']['node'];

    // Clean string service.
    $clean_string_service = \Drupal::service('pathauto.alias_cleaner');

    $is_checked = $node->field_SOME_NAME->value;
    //   If your field is checked.
    if ($is_checked === 1) {
      $alias = '/mysite/term/' . $clean_string_service->cleanString($node->label());
    }
    else {
      $alias = '/mysite/' . $clean_string_service->cleanString($node->label());
    }
  }
}

```
> 1 votes

---
Tags: uri
---


# Question
Title: Set up a cron job to run drush migrate command
I have a custom module which migrates articles from a remote xml file. Because the RSS feed changes, I want my Drupal site to be in sync with the RSS feed. How do add e.g this command `drush mim xml_content` to my cron job, so it will update by each cron interval?

Or how do I add it to my custom module with hook\_cron()?

# Answer
While it's certainly possible programmatically invoke a Drush command in a custom hook handler (via `drush_invoke_process()`), you shouldn't do this.

Cron tasks are designed to handle periodic, smallish, update tasks on hourly, or sub-hourly, intervals. Migration jobs can get pretty I/O heavy so you shouldn't couple them on the same schedule as ongoing cron maintenance, lest you add potential instability based on some outside service/feed.

You should add a new cron job to your cron runner (e.g. crontab, Jenkins, etc.) that executes the `drush mim xml_content` on its own schedule. Depending on where your cron system is, the cron job will evoke `drush mim xml_content` or `drush @host-alias mim xml_content` (if your cron runner is outside the Drupal host machine).
> 1 votes

---
Tags: migrations, cron
---


title: How can I re-install a module?

text:
# Question
Title: How can I re-install a module?
I am creating on Drupal 8 module. I have used a custom table to store the data collected from forms. Somehow during installation, tables are not created due to an issue in the install file. Now I have fixed the issue, and I want to install the module again.

How can I re-install a module?

From this and this discussions, I know the *Disable module* functionality has been removed.

Is there any other way to re-install a module so that its database tables are created?

# Answer
> 22 votes
The Devel module can also help here.

It makes a "Reinstall modules" page available at /devel/reinstall, which lets you re-install modules in bulk.

It's also worth mentioning Drush; `dis` (obviously) doesn't work any more, but `pm-uninstall` and `en` still do. And if you have Devel installed, you can invoke a reinstall with

```
drush dre module1 module2

```

# Answer
> 10 votes
As you said "Disable functionality is removed from Drupal 8" ..

The short answer is - you probably are looking for the "Uninstall" tab found on the "Extend" (Modules) page /admin/modules/uninstall

There is no longer any grey area between a module being on and active vs off and "purged". "Disabled" is no longer a thing. **Uninstalling a module means removing all traces of it.**

Go to admin/modules/uninstall and uninstall module... Then enabled the module from modules list page. That should install the module again.

For Example ....

Before Installing Ban Module in Drupal 8 ... ban\_ip module doesn't exist in database..

After Installing Ban Module in Drupal 8... ban\_ip table is created and module cannot be disabled but can be uninstalled in admin/modules/uninstall

Now if you uninstall module.. Table will be removed from database and module can be installed again which will create tables in the database..

# Answer
> 5 votes
**Solution 1: Uninstall and Install again manually**

Using the Drupal UI:

* Go to the *Extend* page from the admin menu
* Go to the uninstall module page
* Uninstall the module you wish to
* Go to the *Extend* page again (where you have a list of modules)
* Install the module you just uninstalled

Using Drush (you should try it if you don't use it):

* `drush pm-uninstall MODULE -y && drush pm-enable MODULE -y`
* OR in short `drush pmu MODULE -y && drush en MODULE -y`

Replace MODULE with the name of your module.

**Solution 2: Reinstall using Devel module**

Assuming you have the devel module installed.

Using Drupal UI:

* Visit the path `/devel/reinstall`
* Re-install the modules you wish to

Using Drush:

* `drush devel-reinstall MODULE -y`
* OR in short `drush dre MODULE -y`

Replace MODULE with the name of your module.

# Answer
> 5 votes
If you want to re-install (reload) the install config for a specific module you can use this drush command:

```
drush cim --partial --source=modules/custom/MY_MODULE/config/install

```

# Answer
> 2 votes
If nothing else works you can try the below for Drupal 8.

1. Remove the problematic module files and it's folder

* rm -rf modules/your\_problematic\_module
2. Remove the cached twig templates

* rm -rf sites/default/files/php
3. Clear the Drupal cache

NOTE: Make sure to backup the code and Database before doing this

---
Tags: 8
---


# Question
Title: hook_views_post_execute() don't work on AJAX View with exposed filters after 1st refresh
I have a View which returns 5 entities of the same type. AJAX - enabled, filters and exposed filters, all working fine.

I need to add a new result, a user - defined entity, at the top of the View results. This programmatically added row should not be affected when the exposed filters are used and should remain at the top of the View, on top of the other 5 returned results, no matter what.

I managed to add this with hook\_views\_post\_execute() but when I use the exposed filters the View returns to its original results and my addition is lost, because AJAX is enabled on this View. `hook_views_post_execute()` doesn't seem to have any effect after the initial page load.

What is a good alternative for this scenario ie alter the View in a way that's not affected by the AJAX refresh?

# Answer
When checking the current route match in a Views Ajax request you get the route of the Views Ajax endpoint `views/ajax` and not the route of the page where the View is placed on.

However, Ajax requests contain the original path of the View and `ViewAjaxController::ajaxView()` puts this path in the global current path stack (for the pager to work correctly).

So if the path is no longer in the request

```
$path = \Drupal::request()->request->get('view_path');

```

it should be transfered to:

```
$path = \Drupal::service('path.current')->getPath();

```

Which should then point to the node route you are looking for.
> 0 votes

---
Tags: views, ajax
---


# Question
Title: How to save values on each form submit without overriding saved datas?
i am having a form with 2 values to save on submit:

```
 public function submitForm(array &$form, FormStateInterface $form_state) {
    if ($_POST['op'] == 'Import Accounts') {
      $filter = $form_state->getValue('ldap_filter');
      \Drupal::configFactory()->getEditable('amu_import_ldap.settings')
        ->set('ldap_filter', $filter)
        ->save();

      $roles = $form_state->getValue('roles_list');
      \Drupal::configFactory()->getEditable('amu_import_ldap.settings')
        ->set('roles', $roles)
        ->save();
      }

```

It is working but each save override the previous one.

How can i structure the yml to save a list of datas iterately

/config/install/my\_module.settings.yml

```
ldap_filter: ""
roles: null

```

i have been trying a schema file although i am not sure it if it is considered at all

/config/schema/my\_module.schema.yml

```
amu_import_ldap.settings:
  type: config_object
  label: 'couple filtreLDAP / roles'
  mapping:
    ldap_filter:
      type: text
      label: 'Filtre LDAP'
    role:
      type: array
      label: 'Rôles'

```

i have seen things like

> node.type.\*:

?

# Answer
Config items can be arrays, so something like this should work. (Note that I haven't actually set it up to try it).

```
      $new_filter = $form_state->getValue('ldap_filter');
      $filters = \Drupal::configFactory()->getEditable('amu_import_ldap.settings')
        ->get('ldap_filter');
      $filters[] = $new_filter;
      \Drupal::configFactory()->getEditable('amu_import_ldap.settings')
        ->set('ldap_filter', $filters)
        ->save();

```

Of course that's a very naive example, you may wish to check you are only adding unique items to the array, and so on.
> 1 votes

---
Tags: forms, configuration
---


# Question
Title: How to embed HTML and CSS in a custom form element?
This worked in Drupal 7 but isn't in Drupal 8.

```
$form['covid-19'] = array(
    '#markup' => '<div style="border: 2px solid red;padding:10px;margin-bottom:10px;"><strong>Due to the COVID-19 situation, we will only be purchasing e-books and e-audiobooks at this time.</strong> You are welcome to enter your information for print books, DVDs, or CDs, and they will be purchased when the libraries re-open.  Inter-library Loans [loans from outside Yavapai County] are suspended for now.</div>',
);

```

I want the div with style info to stay intact so I can just comment it out when the crisis is over. Then I want to leave it there as a placeholder ready for the next crisis.

In this example, the strong tag makes it through but the div does not.

I also tried setting the div info as a #prefix and #suffix but that didn't work either.

Is there a way to do this?

Thank you!

# Answer
> 1 votes
Markup strips away some tags and attributes. Here is a way to do it.

Add a class to your form

```
$form['#attributes']['class'][] = 'crisis';

```

Add css rule to your theme's css

```
.crisis {
    display: none;
}

```

if you do not have a library and a .css file to use, you need to create them. Define a library in your theme or module in your `THEMEorMODULE.libraries.yml`

```
crisis:
  version: 1.x
  css:
    theme:
      css/crisis.css: {}

```

create `css/crisis.css` file and put your css rule(s) in it

and attach the library to your form

```
$form['#attached']['library'][] = 'THEMEorMODULE/crisis'

```

and clear cache

NOTE: The above (pseudo)code is not tested. For more information please have a look here

---
Tags: theming, forms
---


# Question
Title: The email doesn't have the DKIM signature it would get from mail()
My web host (HostGator shared server) normally signs outbound emails with DKIM. When I send emails from Drupal 7.69 (and Webform 7.x-4.22 for compatibility with CiviCRM), however, there's no DKIM. Thoughts?

drupal\_email\_test is a simple webform node that sends an email.

>

host\_email\_test.php is PHP script that calls `mail()` and `phpinfo()`.

>

The email from drupal\_email\_test doesn't have a DKIM section.

```
Delivered-To: wjcaway@gmail.com
Received: by 2002:ac8:82c:0:0:0:0:0 with SMTP id u41csp1168755qth;
        Wed, 25 Mar 2020 16:51:26 -0700 (PDT)
X-Google-Smtp-Source: ADFU+vvnBvwzKRbgGvFqhHvys6G5bkmSPqrZQ7yL/hKlukMe0LLzAttQHbqXILe4pidK7bzYhSPv
X-Received: by 2002:a50:baef:: with SMTP id x102mr5586983ede.238.1585180286135;
        Wed, 25 Mar 2020 16:51:26 -0700 (PDT)
ARC-Seal: i=1; a=rsa-sha256; t=1585180286; cv=none;
        d=google.com; s=arc-20160816;
        b=tVYoRjo8M4yalE1lA5boYt8xwbpprqjfxgOMns2QsGK07XA6/TF7XmJOoS3inP3EuB
         PMbKfKebyTyPWPwpV07Imz/vQaeVjvE1lsuFvVhBS7mudD7gGINm6FiOB3LP3n1beSFJ
         qOksOAgoeEddRt5k9o3KwzQkaKAWqW2gKQFfd/y4EMEyCMplz+yeA+BQ4Q3gZHpHUyQy
         A8NqHojzHQBzKEYlikLahS+5G9SKsfnYI47/CoTcEZ6gRGL+maenhz+tDNPe05vi4wes
         lqjEr2mYdw/UIbXd19iRg+XaAxWQgZgPexfImUuR534FrDY+kPoYHNNtsz6p0wZRi9qs
         OZ5Q==
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816;
        h=date:message-id:reply-to:from:content-transfer-encoding
         :mime-version:subject:to;
        bh=5urliemGVkGxGHJiDO8WhZkb/ihL1brX33ZfPAwo4z4=;
        b=RH8M7dQczy8TaRLjAg+SVI/RURig/J1qXvhUxvMqeaabpqS7bIqzzhAawGzQq0YAYk
         wlXXLqjRKHngAYYSCPj8A1r1PfqEYdlE3ukfpJ7KuQpdj+y2B8NDCc6l3J3uuxAtLgAJ
         OhNNZhmaU+xPihJFlSa4ihW0kRmCPU86Qc2oev44Qy++3Yfyg5AOj5xonfSBNhfNy5wu
         r4BVr813Oye6DEL3Ax1TWcn6j32/LDO0y2TwEa50ymaqec404ywz3Sv16WtxOvbuxzP7
         4y0ZWw8wHltD3kU8CAlIQ2PU9mmjXuJGpIgpVdMutgurQ1ksw8ES21ovvCE+lpRA0wm2
         snsg==
ARC-Authentication-Results: i=1; mx.google.com;
       spf=pass (google.com: domain of it@unidosnow.org designates 192.185.50.73 as permitted sender) smtp.mailfrom=it@unidosnow.org
Return-Path: <it@unidosnow.org>
Received: from gateway24.websitewelcome.com (gateway24.websitewelcome.com. [192.185.50.73])
        by mx.google.com with ESMTPS id e27si310612edc.194.2020.03.25.16.51.25
        for <wjcaway@gmail.com>
        (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);
        Wed, 25 Mar 2020 16:51:26 -0700 (PDT)
Received-SPF: pass (google.com: domain of it@unidosnow.org designates 192.185.50.73 as permitted sender) client-ip=192.185.50.73;
Authentication-Results: mx.google.com;
       spf=pass (google.com: domain of it@unidosnow.org designates 192.185.50.73 as permitted sender) smtp.mailfrom=it@unidosnow.org
Received: from cm11.websitewelcome.com (cm11.websitewelcome.com [100.42.49.5])
    by gateway24.websitewelcome.com (Postfix) with ESMTP id DD81447A8C
    for <wjcaway@gmail.com>; Wed, 25 Mar 2020 18:51:24 -0500 (CDT)
Received: from cloud150.hostgator.com ([108.167.158.90])
    by cmsmtp with SMTP
    id HFnwjVvjpSl8qHFnwj3Eri; Wed, 25 Mar 2020 18:51:24 -0500
X-Authority-Reason: ss=1
Received: from y2dg1g3q by cloud150.hostgator.com with local (Exim 4.92)
    (envelope-from <it@unidosnow.org>)
    id 1jHFnw-000R1R-OG
    for wjcaway@gmail.com; Wed, 25 Mar 2020 18:51:24 -0500
To: wjcaway@gmail.com
Subject: Form submission from: email test
X-PHP-Script:  for
X-PHP-Originating-Script: 648:system.mail.inc
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed; delsp=yes
Content-Transfer-Encoding: 8Bit
X-Mailer: Drupal Webform
From: "Hallo via UnidosNow" <info@unidosnow.org>
Reply-To: "Hallo" <info@unidosnow.org>
Message-Id: <E1jHFnw-000R1R-OG@cloud150.hostgator.com>
Date: Wed, 25 Mar 2020 18:51:24 -0500
X-AntiAbuse: This header was added to track abuse, please include it with any abuse report
X-AntiAbuse: Primary Hostname - cloud150.hostgator.com
X-AntiAbuse: Original Domain - gmail.com
X-AntiAbuse: Originator/Caller UID/GID - [648 501] / [47 12]
X-AntiAbuse: Sender Address Domain - unidosnow.org
X-BWhitelist: no
X-Source-IP:
X-Source-L: No
X-Exim-ID: 1jHFnw-000R1R-OG
X-Source:
X-Source-Args:
X-Source-Dir: unidosnow.co:/cc-unidosnow-co
X-Source-Sender:
X-Source-Auth: y2dg1g3q
X-Email-Count: 9
X-Source-Cap: eTJkZzFnM3E7eTJkZzFnM3E7Y2xvdWQxNTAuaG9zdGdhdG9yLmNvbQ==
X-Local-Domain: no

Submitted on Wednesday, March 25, 2020 - 19:51
Submitted by user: Anonymous
Submitted values are:

email from: info@unidosnow.org
email to: wjcaway@gmail.com
email line: Line from Drupal - test from Drupal Webform

```

The email from host\_email\_test.php contains the DKIM signature.

```
Delivered-To: wjcaway@gmail.com
Received: by 2002:ac8:82c:0:0:0:0:0 with SMTP id u41csp1164145qth;
        Wed, 25 Mar 2020 16:45:10 -0700 (PDT)
X-Google-Smtp-Source: ADFU+vudAdnQKbLNwwcVPJnEA9xaqcvZnn6JsNAQgwj7AteKAgYcaG/7Z3fPiHUSrqHsTXiNlrUo
X-Received: by 2002:a17:907:11cc:: with SMTP id va12mr5334563ejb.225.1585179910035;
        Wed, 25 Mar 2020 16:45:10 -0700 (PDT)
ARC-Seal: i=1; a=rsa-sha256; t=1585179910; cv=none;
        d=google.com; s=arc-20160816;
        b=PWe68maxwiuMNl6acYdK6ftBihsoDxvajKxfwVds93nyCGLZQ1Hj2Y4hFxv2pDzfdK
         pqypMhaJqbos5JeizBnXip8NTG5nhnmyGx0P6jMfLM6GlR1a2nt9cz7+KP46Ze8it4wq
         EXxR2EOHYqOpVoXpU2HuyPxKZbn0++wi7xxw82aTWKzxDq5CDMlfRPb6UKMvuteXVr59
         W26r6+WLE0+Yk21/EmZv984joRJFiWTZa6kG70WIdKoWT3ZmKAhlVqO68x5EKQvR3PIM
         /bqaegmW1m0xFL4C/M+FUUhqwGoY74EAlihyg2bUeftU8ICOKSyRWsetRTPN/MXmJWg0
         vB1Q==
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816;
        h=date:message-id:from:subject:to:dkim-signature;
        bh=M0VMoOovcbMGQ4upi/77pqMguHM5hO8iG91ARyXv/ho=;
        b=m73KZDNfwBtEzbHd2EtvVfw9D/VMOkbOArQ8m9/R172PJCE0TmQcaGMKwAreZA1PeH
         O9gOy2I6M1LW0a6ZrBeucDP8QjtoT+JNuhOj1rsnbevXwqJk2YXBmBjtyTJr5tndiBte
         FIp2MKuZ5nLtJvamvi7aPBAyXWm/795WauFCYfM61Ihh4ATQINvWVUHb9rb4eiQnxFLC
         PuywZ1ck31o603lpkSvfjW7xIbTXl0Zm4bEE3PZRSpyg1Hn6i2iyvLbGRMfnH7j6bR+f
         aAWpVBx2FXu63h6Bhpt8p8KdDVMV04LNlet1C8rlsugsVauzaj1lY9VF7I2Jy2upVP9A
         TKSw==
ARC-Authentication-Results: i=1; mx.google.com;
       dkim=pass header.i=@unidosnow.co header.s=default header.b=A8IkBXOE;
       spf=pass (google.com: domain of y2dg1g3q@cloud150.hostgator.com designates 192.185.145.170 as permitted sender) smtp.mailfrom=y2dg1g3q@cloud150.hostgator.com
Return-Path: <y2dg1g3q@cloud150.hostgator.com>
Received: from gateway32.websitewelcome.com (gateway32.websitewelcome.com. [192.185.145.170])
        by mx.google.com with ESMTPS id t4si278257edy.487.2020.03.25.16.45.09
        for <wjcaway@gmail.com>
        (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);
        Wed, 25 Mar 2020 16:45:10 -0700 (PDT)
Received-SPF: pass (google.com: domain of y2dg1g3q@cloud150.hostgator.com designates 192.185.145.170 as permitted sender) client-ip=192.185.145.170;
Authentication-Results: mx.google.com;
       dkim=pass header.i=@unidosnow.co header.s=default header.b=A8IkBXOE;
       spf=pass (google.com: domain of y2dg1g3q@cloud150.hostgator.com designates 192.185.145.170 as permitted sender) smtp.mailfrom=y2dg1g3q@cloud150.hostgator.com
Received: from cm14.websitewelcome.com (cm14.websitewelcome.com [100.42.49.7])
    by gateway32.websitewelcome.com (Postfix) with ESMTP id BA603208E2
    for <wjcaway@gmail.com>; Wed, 25 Mar 2020 18:45:08 -0500 (CDT)
Received: from cloud150.hostgator.com ([108.167.158.90])
    by cmsmtp with SMTP
    id HFhsjbetAXVkQHFhsjrhYK; Wed, 25 Mar 2020 18:45:08 -0500
X-Authority-Reason: ss=1
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;
    d=unidosnow.co; s=default; h=Date:Message-Id:From:Subject:To:Sender:Reply-To:
    Cc:MIME-Version:Content-Type:Content-Transfer-Encoding:Content-ID:
    Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc
    :Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe:
    List-Subscribe:List-Post:List-Owner:List-Archive;
    bh=M0VMoOovcbMGQ4upi/77pqMguHM5hO8iG91ARyXv/ho=; b=A8IkBXOER8wH9EqwIb2cZ6cM8T
    Joz6/OQ3eEE97kNVUxlMR1vwblgRskjcbN/0tk+7JCWnyydQsw09gDmc1tgudsYLIWOuNOiczpROA
    sawfsxhAidgo/O2odaQnqIBGSsfUlpTF+Q942j5lb0zU6ib0CrJqGEjM56hTcev2ENihq7x/GfFTC
    cpxcXTahPbHjR8Abbaa7FWySBbuikDjvwUaVQhAIsPQfFeqxAk8OI/+mumwtmdpzjjEV/s8N2XPuD
    6cTgxSQNhIHEuZ27ViqPTOeJ4PTyzIglsyMaucMHOxhCJq7mk4kFtV5oQ5FNc/Tx+zdKSl83KxpwI
    lTYp5l/Q==;
Received: from y2dg1g3q by cloud150.hostgator.com with local (Exim 4.92)
    (envelope-from <y2dg1g3q@cloud150.hostgator.com>)
    id 1jHFhs-000PWJ-Ju
    for wjcaway@gmail.com; Wed, 25 Mar 2020 18:45:08 -0500
To: wjcaway@gmail.com
Subject: An Email direct from the host!
X-PHP-Script:  for
X-PHP-Originating-Script: 648:host_email_test.php
From: info@unidosnow.org
Message-Id: <E1jHFhs-000PWJ-Ju@cloud150.hostgator.com>
Date: Wed, 25 Mar 2020 18:45:08 -0500
X-AntiAbuse: This header was added to track abuse, please include it with any abuse report
X-AntiAbuse: Primary Hostname - cloud150.hostgator.com
X-AntiAbuse: Original Domain - gmail.com
X-AntiAbuse: Originator/Caller UID/GID - [648 501] / [47 12]
X-AntiAbuse: Sender Address Domain - cloud150.hostgator.com
X-BWhitelist: no
X-Source-IP:
X-Source-L: No
X-Exim-ID: 1jHFhs-000PWJ-Ju
X-Source:
X-Source-Args:
X-Source-Dir: unidosnow.co:/cc-unidosnow-co
X-Source-Sender:
X-Source-Auth: y2dg1g3q
X-Email-Count: 8
X-Source-Cap: eTJkZzFnM3E7eTJkZzFnM3E7Y2xvdWQxNTAuaG9zdGdhdG9yLmNvbQ==
X-Local-Domain: yes

From email: info@unidosnow.org
Comments: Test from php mail()

```

# Answer
> 0 votes
This is likely a HostGator-specific issue. Drupal sets Return-Path: from https://example.org/admin/config/system/site-information. Since our email domain is different from our hosting domain, HostGator refrained from producing a DKIM signature in the outgoing emails. I expected Drupal to set From: and/or Reply-To:, not Return-Path:. Bad expectations on my part.

---
Tags: 7, webforms, emails
---


# Question
Title: Pre-populate an entity reference field (media image) when creating a node
I am trying to open a node creation form (for example, `/node/add/article`) and to have an Entity Reference field pre-populated.

My field (`field_image`) is an **Entity Reference** to a **Media** of type **Image** and the form uses the **Media Library widget**.

I essentially tried doing that by implementing `hook_form_alter` in a custom module but nothing that I have tried worked. I saw solutions like this one. It works with other field types that I have tried. For example:

```
// Pre-populate Entity Reference field to taxonomy term

$term = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->load(13);
$form['field_category']['widget'][0]['target_id']['#default_value'] = $term;

```

The above works just fine. But the below doesn't.

```
// Pre-populate Entity Reference field to Media Image

$media = \Drupal::entityTypeManager()->getStorage('media')->load(38);
$form['field_image']['widget'][0]['target_id']['#default_value'] = $media;

```

I also tried by providing just the media id instead of the entity but it didn't work.

I have tried the Prepopulate module too but couldn't get it to work either although it works with all other field types that I have tried.

Anyone knows if this is feasible and how?

*Edit: I should perhaps mention that I am not looking for a solution on how to set a default value for that field. The referenced entity must be set dynamically*

For reference, here is my complete code:

```
/**
 * Implements hook_form_alter().
 */
function siteconfig_form_alter(&$form, FormStateInterface $form_state, $form_id) {

  if ($form_id == 'node_article_form') {

    // This works
    $term = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->load(13);
    $form['field_category']['widget'][0]['target_id']['#default_value'] = $term;

    // This doesn't work
    $media = \Drupal::entityTypeManager()->getStorage('media')->load(38);
    $form['field_image']['widget'][0]['target_id']['#default_value'] = $media;
  }
}

```

# Answer
It's much easier to prepopulate field values on entity level rather than on form level:

```
/**
 * Implements hook_ENTITY_TYPE_create() for 'node'.
 */
function mymodule_node_create(\Drupal\node\NodeInterface $node) {

  if ($node->getType() == 'my_content_type') {
    $media = \Drupal::entityTypeManager()->getStorage('media')->load(38);
    $node->field_image[] = $media;
  }

}

```
> 1 votes

---
Tags: 8, nodes
---


title: Deactivate system path

text:
# Question
Title: Deactivate system path
I want to deactivate the system path which comes with Drupal. I've installed the pathauto, so when I create a new page, it automatically changes **domain.com/node/12** to **domain.com/books/jacks-journey**

But both page exist. I only want the **/books/jacks-journey** to exist and deactive the **/node/12**. Is it possible to do that?

# Answer
Deactivating the internal path is technically route normalization by redirecting incoming requests, which in D8 is provided by the module Redirect:

> D8: Maintaining a canonical path and redirecting alternative URL's like non-aliased path, path without language prefixes and so on (Previously provided by Global redirect)

https://www.drupal.org/project/redirect
> 3 votes

---
Tags: nodes, path-aliases
---


# Question
Title: Sub-theme adding prefix to all block machine names
On my site, I have created a sub-theme of a sub-theme using this as a guide to set this up https://www.drupal.org/docs/8/theming-drupal-8/creating-a-drupal-8-sub-theme-or-sub-theme-of-sub-theme and it does work with carrying over all of the css/js/regions but for some reason, it is renaming all of the blocks with the prefix of the sub-theme.

So, for example, I have a block with a machine name of mainnavigation when I install/set as default the sub-theme it will change this block to theme3\_mainnavigation.

I have tried removing the block and placing it back in with the same name of mainnavigation but I run into an issue where a message will appear that says this machine name already exists.

Does anyone know how to get around this so the sub-theme will use the machine names of already existing names instead of creating a prefix?

Thanks for any help!

# Answer
> 0 votes
You can't.

This behavior is core functionality from the Block module that's enforcing its data model. Each time you place a block, you're creating a unique Block entity that has a `theme` property tied to it. Thus, the `mainnavigation` block entity can't simultaneously be used on the default theme as well as `theme3`.

This is why Drupal defaults to generating `${theme_machine_name}_${block_machine_name}` so the user doesn't have to think about it.

---
Tags: theming, blocks
---


# Question
Title: XML parser selector skips mixed content in migration
I am trying to migrate and map the source fields of an external rss/xml file into Drupal.

I have built a custom module:

In `config/install` folder I have my `yml` file `modules/custom/import_rss/config/install/migrate_plus.migration.xml_articles.yml`:

```
id: xml_articles
label: 'Import articles'
status: true
source:
  plugin: url
  data_fetcher_plugin: http
  urls: 'https://myrss.xml'
  data_parser_plugin: simple_xml
  item_selector: /rss/channel/item
  fields:
    -
      name: guid
      label: GUID
      selector: guid
    -
      name: title
      label: Title
      selector: title
    -
      name: pub_date
      label: 'Publication date'
      selector: pubDate
    -
      name: link
      label: 'Origin link'
      selector: link
    -
      name: summary
      label: Summary
      selector: description
  ids:
    guid:
      type: string
destination:
  plugin: 'entity:node'
process:
  title:
    plugin: get
    source: title
  field_remote_url: link
  body: summary
  created:
    plugin: format_date
    from_format: 'D, d M Y H:i:s O'
    to_format: 'U'
    source: pub_date
  status:
    plugin: default_value
    default_value: 1
  type:
    plugin: default_value
    default_value: my_article

```

After running `drush mim xml_articles` all the items are imported except the `body` field in Drupal nodes are empty?

If I look at the source xml file the `<description>` tag looks like this:

```
<description><div class="field field-name-body field-type-text-with-summary field-label-hidden text-content text-secondary"><div class="field-items"><div class="field-item even"><p>You might have noticed some changes on Drupalize.Me lately. We've just wrapped up a huge content archiving project and I'd like to share what we did and how this will help us move forward with a library of tutorials for Drupal learners that we're committed to keeping up-to-date.</p>
</div></div></div></description>

```

In the XML source the `<description>` has 3 `<div>` tags `<description><div><div><div>Text</div></div></div></description>`

I tried as selector `description/*`, but that's not working either.

How do I get this working?

# Answer
> 0 votes
By adding `description/div/div/div/*` to the selector.

---
Tags: 8, migrations, feeds
---


# Question
Title: How to remove link from around the rendered entity inside view header
I use rendered entity inside my view header. It is a page. When the view displays, the rendered page title in the header has link around it.

I've tried to prepare my own display mode for page type of content and remove link items from them, moved them to hidden. Nothing helped.

Any suggestions appreciated.

# Answer
Here's the How:

```
 {% set headline %}
   {{ label }}
 {% endset %}
 {{ headline|striptags }}

```

as found **here**
> 1 votes

# Answer
Did you also create a new .html.twig template file that has the title without the link?

Use that new display mode, just also make sure to create a new template file: node--content-type--display-name.html.twig or whatever you need

could be in page.html.twig
> 0 votes

---
Tags: views, 8
---


# Question
Title: Impossible to html_entity_decode the button title in a render array
Here is the code that reside in my extended class of the `RegisterForm`:

```
$title=$this->t("M'inscrire") // notice the apostrophe in French
// the $element variable is the action sub array of the form
$element['submit']['#value'] = html_entity_decode($title, ENT_QUOTES, 'UTF-8');
dpm(html_entity_decode($title, ENT_QUOTES, 'UTF-8'));

```

Unfortunately, my submit button is displayed like `M&#039inscrire` And strangely, the dpm function print it as it should be

Edit to add, the following does not work:

```
$element['submit']['#value'] = $this->t("M'inscrire"); //NOT WORKING
$element['submit']['#value'] = "M'inscrire"; //NOT WORKING

```

# Answer
> 0 votes
As pointed out by Jaypan, it was due to a bug in the bootstrap\_barrio theme.

I have posted a patch for it: https://www.drupal.org/project/bootstrap\_barrio/issues/3083728#comment-13527917

---
Tags: forms
---


# Question
Title: How to clear form element values after validation error
I have a rather complex form validation depending on multiple fields. If validation fails, I would like to set the form values (of all or some explicit fields) to an empty value. This is what I tried, but none of the three approaches works:

```
public function validateForm(array &$form, FormStateInterface $form_state) {
  ...
  if (!$authorized) {

    $this->messenger->addError($this->t('An error occured.'));

    $form['name']['#value']=''; // approach 1

    $form_state->setValue('name',''); // approach 2

    $form_state->setValueForElement($form['name'], ''); // approach 3

    $form_state->setRebuild();
   }
 }

```

# Answer
Have you looked at `unsetValue()`?

Example usage:

```
public function validateForm(array &$form, FormStateInterface $form_state) {
  ...
  if (!$authorized) {

    $this->messenger->addError($this->t('An error occurred.'));

    $form_state->unsetValue('name');

   }
 }

```

From the doc:

> Removes a specific key from the submitted form values.
>
> * @param string|array $key
> * Values are stored as a multi-dimensional associative array. If $key is a string, it will use unset($values\[$key\]). If $key is an array, each element of the array will be used as a nested key. If $key = array('foo', 'bar') it will use unset($values\['foo'\]\['bar'\]).
> 1 votes

# Answer
This does the trick for all the form fields:

```
 $form_state->setUserInput([]);

```

I think it should not be used for field validations but for error handling for example.

```
try {
  $res = $this->client->request('GET', '/demandes/' . $demandeId, [
    'headers' => ['Accept' => 'application/json'],
  ]);
  $demandeObject = Json::decode($res->getBody());
}
catch (ConnectException $e) {
  \Drupal::messenger()->addError(t("Une erreur est survenue: Le document n'a pas été ajouté. Veuillez contacter l'administrateur du site si le problème persiste."));
  // Rebuild form
  $form_state->setRebuild();
  // Reset all form fields
  $form_state->setUserInput([]);
}

```
> 0 votes

---
Tags: 8, forms
---


# Question
Title: How to get a parameter value from the current URL in views-view-fields.html.twig?
I need the argument value in the theme templates and using the `views-views-fields--view_name--block_1.jhtml.twig`.

---

I'm current getting the current URL like that:

```
{% set url = url('current')%}

```

Which outputs:

```
https://example.com/questions/12225

```

---

But I need only the **12225** value from the current url. How can I get the last parameter from the current URL in Twig?

# Answer
You could use Twig's `split` filter, though I don't recommend scripting too much inside templates.

Instead I recommend to pass the value over to Twig from a preprocess function from inside your theme or a custom module via `template_preprocess_views_view_fields`.

```
/**
 * Implements template_preprocess_views_view_fields().
 */
function MYTHEME/MYMODULE_preprocess_views_view_fields(&$variables) {

  // Retrieve an array which contains the path pieces.
  $current_path = \Drupal::service('path.current')->getPath();

  if ($current_path[0] == 'questions') {
    $variables['question_id'] = $current_path[1];
  }
}

```

And then inside your template print it for example like so:

```
{% if question_id %}
  <div id="{{ question_id }}">Question ID: {{ question_id }}</div>
{% endif %}

```
> 9 votes

# Answer
I don't know it is best way or not but can help you You are using the {% set url = url('current\>') %} After dump, it turned out that's what

```
array(3) {
    ["#markup"]=> string(23) "http://example.com/category"
    ["#cache"]=> array(3) {
         ["contexts"]=> array(2) {
                [0]=> string(5) "route"
                [1]=>string(8) "url.site"
         }
         ["tags"]=> array(0) { }
         ["max-age"]=> int(-1)
    }
    ["#attached"]=> array(0) { }
}

```

Convert array to sting

```
{% set url = url('<current>')['#markup'] %}

{{ url|split('/')|last }}

```

you will get the last value part of the URL
> 7 votes

# Answer
I was also trying to get the url parameters, but the current path was only returning the path without the parameters.

The following solution worked for me in a page preprocess function, I haven't tried with views fields but it should work also.

```
function yourtheme_preprocess_views_view_fields(&$variables) {

  // Retrieve an array which contains the path parameters.
  $variables['params']['parameter_name'] = $_GET['parameter_name'];
}

```
> 0 votes

# Answer
To fetch the current path with query string in views you can also use the Views Current Path (Global: Current Path) module.

> Provides a Views field that displays the URL of the current page being viewed.
> -2 votes

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


# Question
Title: How to restrict access to view a block for a certain role?
I have some custom roles such as Premium Membership and I don't want to allow access to this category.

The authenticated role is included to Premium Membership or Moderator users because every registered user has this authenticated role assigned to them by default.

I want to hide a block and display only for authenticated users that do not have other roles assigned to them.

What can I do?

# Answer
> 0 votes
Visibility Block base on the Role is built-in Drupal 8 feature.

go to `admin/structure/block` and click on your desire block `configure` button

then in Visibility section, there is `Role` that you can define for which role your module show , or not to show.

---
Tags: 8, users, blocks
---


# Question
Title: How might a user configure which video is shown on page without editing the page?
A Drupal 7 site has an embedded YouTube video on the home page. It is not always displayed. Sometimes the video being displayed is changed. The home page is arranged by a Page Manager Variant, and the container with the video is "Custom Content". When someone wants to hide/show the video or change the link, they have to ask me because the Page Manager can only be accessed by an administrator. I want to give certain users the ability to show/hide the video and change the video to which it links, but without changing other content on the home page or modifying the layout of the site.

I don't really know what I'm doing when it comes to Drupal, and I'm having trouble figuring out the right things to search for to accomplish this.

I want the appropriate users to be able to choose which YouTube video is embedded and whether it is shown. What is the best way to do that?

# Answer
## Step 1

1. Create a content type: e.g. "Home Page Video".
2. Add fields: YouTube, text area, image, etc. Basically all the fields you would want to structure that "section" on the home page.
3. Give permissions for the fields with field permissions (additional security measure, you'll see why later)

## Step 2

1. Create a few nodes for "Home Page Video"
2. Set your view modes

## Step 3

1. Create a View to show only "Home Page Video" content.
2. Choose Bootstrap Grid (Views Bootstrap module and Bootstrap Field Group module) and add fields
OR
Choose unformatted list: Rendered entity and a View Mode
3. Set a filter: "promoted to front page"
4. Set a Pager: Display a specified number of items and choose 1, More link: no
5. Set a sort criteria: "Content: Updated date" (The date the content was last updated.) and set it to "descending"
6. Create a pane view from this view.
7. Save

## Step 4

1. Enable: `System - page_manager - node_edit - Node add/edit form -
/node/%node/edit`
2. Create a new variant of node\_edit template in Page Manager
3. Selection rule: Node being edited is bundle "Home Page Video"
4. Selection rule: Logged in user has one of "my user role"
5. Content: Add the form fields you want this user to edit AND add the base form (General Form) in order to get the submit button. If you have set certain fields to be required on your Home Page Video content type, they will show in the base form UNLESS you add them in through the cog wheel "Add content" and choose FORM and then choose the specific form field that is required. Like that you have the ability to choose where that field goes in your edit form layout. More control.
6. Save

## Step 5

1. Add your pane view of "Home Page Video" to your Home Page Page Variant at the position where you want it to show up on your Home Page.
2. In order for your pane view to show up, you might have to clear the cache. If you use Drush, simply type: drush cc all
3. Go look again for that pane view and add it.
4. Save

Et voilá. No need for a custom module. Permissions are dealt with by the 'selection rules' in your node\_edit page variant.
> 1 votes

---
Tags: panels
---


# Question
Title: PHP query in a view will cause website error
I'm using a global PHP query in a View to find out the count of membership users. The first query, that extracts the total number of users from the database works fine, but when I use the *WHERE* clause in a query for a comparison with a string, I received a website error like in the image attached below.

This is the query:

```
<?php
$count_users_premium = db_query('SELECT COUNT(license_id) FROM {commerce_license} WHERE state="active"')->fetchField();
print $count_users_premium;
?>

```

So, if I want to use *WHERE some\_number=3*, it will work, but comparison with a string didn't work. (Drupal 8 version)

# Answer
You cannot directly insert values into queries in Drupal. They need to be escaped. You would want something like this:

```
$count_users_premium = db_query('SELECT COUNT(license_id) FROM {commerce_license} WHERE state=:active', [':active' => 'active'])->fetchField();

```
> 2 votes

---
Tags: views, database
---


# Question
Title: Geting values for multipart form elements using Twig
Whereever you are, I hope you're fairing well under the circumstances. To some of the hardest hit areas, we are thinking of you *constantly*.

**Webform Advanced Elements**

I am having difficulty retrieving submitted values from Drupal 8.8.4 Webform 5.9 multipart elements using Twig. Standard, single form field, values work fine, however elements such as Name and Advanced Address do not. Both of latter elements have multiple form fields (e.g. first, middle, last name; or street, city, country...) and may be dynamic (e.g. pick a country before completing address).

In my case, I am using the Attachment PDF and a custom Twig template to generate a PDF file attachment that is returned to the user, however I can see the same result using Twig in an e-mail, or the generated test e-mail preview.

**Testing:**

A simple text field works correctly:

`<p>Dated: {{ data.date }}</p>` (works)

Name and Advanced Address are blank:

`<p>{{ data.my_name }}</p>` (blank)

`<p>{{ data.my_address }}</p>` (blank)

**Tokens Work, Sort Of**

For what it's worth, the multipart values are available using tokens in the e-mail body, albeit I can't get portions of the values, which is the objective. What I mean by this is that an entire complete address will be returned, on multiple lines, but getting just the street name doesn't work (for me).

Using the examples above:

`[webform_submission:values:my_name] (returns John Smith)`

It also wasn't possible to retrieve just a street address:

`[webform_submission:values:address] (returns stree, city, state/prov., country on mutiple lines)`

I've really been stumped, and I'm surprised it is so hard to find the answer. Perhaps I'm not working the question correctly, this is more of a hobby project. Thank you for suggestions.

# Answer
I think you are just overlooking something simple here. The 'multi part form elements' is called a composite element. And it holds an array of values of its subfields.

Let's say the composite parent is called 'name', and it has a subfield called `first_name`, then you can use `{{ data.name.first_name }}` to get the first name in twig.

As for webform submission token, you can try something like `[webform_submissions:values:name:first_name]`
> 0 votes

# Answer
Ok, I kept trying cchen's suggestion and made some discoveries.

**Twig**

Since the following did not work, I did not try sub-elements.

`{{ data.my_address }}`

Although the whole element does not work (whole elements work with tokens) the sub-elements are still addressable. You can find the sub-element names by looking at submitted form results, under Data (YAML) tab.

`{{ data.my_address.address_line1 }}`

Lesson learned: don't give up.

**Tokens**

The following works. I have no idea how I missed this in testing.

`[webform_submission:values:my_name:first]`

With respect to the address example, the correct field name was address\_line1, and it was not one of the variations I guessed (e.g. address, address1, street1, etc.)

Thanks all
> 0 votes

---
Tags: theming, webforms
---


# Question
Title: How do I programmatically "place" an order?
When making a payment through the Commerce admin interface; the Orders do not get completed. I can see a Place Order button when viewing a cart Order; which seems to do the trick. I need to do this in code.

I know that i need to react to the the commerce\_order.order.paid event but I am not sure what to do there.

I found this post: How do I programmatically update the order status? which suggests i need to "apply a transition". But the suggestion there doesn't work.

I opened a new question for this as I am specifically asking about "placing an order"; whereas that question was asking about simply changing Order status.

# Answer
A little digging and I figured it out on my own:

Event handler for for this event: commerce\_order.order.paid

and with this handler code:

```
  public function paymentCompletedHandler($event) {
    $order = $event->getOrder();
    $order->getState()->applyTransitionById('place');
    return;
  }

```
> 1 votes

---
Tags: 8, commerce
---


# Question
Title: Use drush to install a module on all of the sites of a multisite at once
I have a Drupal 8 multisite, setup with 6 different sites. I want to install Admin Toolbar on all of them on my local dev environment (mamp / terminal / drush). I have downloaded that module using composer:

```
composer require drupal/admin_toolbar

```

Is there a single drush command that will install this module on all six of the sites at once? If not, what is the most efficient way to install it to each?

# Answer
> 0 votes
1. If you are using **Acquia Cloud Site Factory (ACSF)** then you can use ACSF command `acsf-tools-ml`

**acsf-tools-ml (sfml)**: This command will run any Drush command against all sites in your factory. `drush @coolsites.01dev sfml en admin_toolbar`

2. **Other solution:** It's not recommended to enable/disable module directly on the server in this way you lose access to Configuration management.(It will become difficult to manage it)

Recommended Approach:

* Enable module in your local environment and then export it via \`drush config:export\`
* import the configuration on the respected server via \`drush config:import\`
* You can write a simple bash command to automate drush config:import on all the websites.

---
Tags: drush, installation, multi-sites
---


# Question
Title: How can i enable automatic path creating for all nodes?
In Drupal 7.12 i use pathauto, cleanurls, transliteration, i18n.

When i edit one node i saw that, "Generate automatic URL alias" in unchecked. Then i checked other nodes and saw that for all type of nodes it became unchecked.

I'm pretty sure that it was checked until last week.

The last modifications i made: I updated Pathauto module, installed Transliteration, installed Debug Cron module.

So, how can i re-enable this checkbox in node settings page automatically ?

(Of course i can i that manually, by editing every node, and checking the check-box)

Thank you very much for your help.

# Answer
> 6 votes
If you have Pathauto installed, it will generate path aliases for your nodes. It unchecks the box when there's already a path alias, letting you know that it won't change the alias if you change the content. You can change this behavior with the 'Update action' setting here: `/admin/config/search/path/settings`

# Answer
> 3 votes
Read the documentation page on How does Pathauto determine if the 'Automatic URL alias' checkbox should be checked or not?.

If the checkbox is unchecked on existing nodes it means that the current alias for the node does not match the alias that Pathauto "would" generate for the node. Maybe if you changed the patterns for your nodes, it would mean they're "out of sync" with the real patterns and then Pathauto un-checks the checkbox by default.

# Answer
> 3 votes
if you want to force it, even if it's unchecked,just create a module as follow :

```
<?php
function pathauto_checkbox_node_presave($node){
  global $user;
  if($node->type=='you_content_type'){
    $node->path['pathauto']=1;
  }
}
?>

```

if you want for every type just remove the "if" condition

# Answer
> 1 votes
Also you can do it using:

```
$node->path['pathauto'] = TRUE;

```

# Answer
> 0 votes
Some of my contents url were manually generated , some other not. I wanted to homogenize all content by content types and did not want to do it one by one

I have defined patterns in

```
admin/config/search/path/patterns

```

then

```
  delete all alias and did a bulk update

```

this action reset all content to automatically generated alias

# Answer
> 0 votes
You can do this using View's arbitrary script also for the node which is already created and the automatic path creating for all nodes in false (i.e "Generate automatic URL alias" is not checked.)

Here I have created a view to updating the path from "node/\[node-id\]" to "automatically generated URL".

Follow the below steps.

1. Create the view as shown in the above image
2. Go to the view page.
3. Select the option from the dropdown and the node from the list for which you want to check the checkbox "Generate automatic URL alias" as shown in the below image.
4. Click on execute. Now on next step enter the code. Then

> ```
> $node = node_load($entity->nid);
> $node->path['pathauto'] = TRUE;
> node_save($entity);
>
> ```

5. Click on confirm. Once completed, go to that node.
6. edit the node and check the checkbox "Generate automatic URL alias" is checked now. and path is also created automatically

---
Tags: path-aliases
---


# Question
Title: How do I resolve a unresolved dependency error after using Composer to install modules?
I'm going to pull my hair out if I stare at this problem any longer. I've seen the similar questions and tried everything but I can't fix this issue with module dependency versions.

I'm using `Composer require drupal/<module_name>` and I've tried including specific versions too but that hasn't worked. I see that the current version number isn't being displayed at the end of the error message which makes me wonder whether the system knows what version is even installed?

I also don't understand how so many modules can be asking for different versions of the same dependency. How can you possibly resolve that :|

I should also add that I was in the process of converting manually installed modules into Composer controlled dependencies. I'm not sure if that would make a difference.

It really seems to me that Drupal doesn't know what versions of Modifiers and Paragraphs are installed but I don't see how.

# Answer
> -1 votes
So, the system couldn't decide what version of the modules were installed. Here is a fix:

https://www.drupal.org/project/modifiers/issues/3052416

Basically, install ***Git Deploy*** module to add versioning details to modules .info files.

---
Tags: composer
---


title: Embedded remote video not showing

text:
# Question
Title: Embedded remote video not showing
I am new to Drupal and setting up my first site. I am keeping it fairly basic and have not added on much. I am able to embed uploaded videos without any problem, but when I attempt to embed a remote video in an article, the video does not show, instead it shows the word 'media'. I have tried uploading the video through the Content -\> Media and also during the creation of the article. I have tried embedding a youtube video and a vimeo video and they both respond the same way. I wonder if the cause of the problem is that the max\_width and max\_height are both set to 0, if so, I have not seen any place that I can change that.

```
<div data-quickedit-field-id="node/8/field_media/en/full" class="field field--name-field-media field--type-entity-reference field--label-above">
<div class="field__label">Media</div>
          <div class="field__item"><article data-quickedit-entity-id="media/9" class="contextual-region media media--type-remote-video media--view-mode-default">

```

```
        <div data-quickedit-field-id="media/9/field_media_oembed_video/en/default" class="field field--name-field-media-oembed-video field--type-string field--label-hidden field__item"><iframe src="https://www.vimeo.com/media/oembed?url=https%3A//youtu.be/-XjIoKCiHgM&max_width=0&max_height=0&hash=cxX4QeYu6zssU9WW-q1T_OhN4mwlmUoOFZfWI05j5Fs" frameborder="0" allowtransparency width="480" height="270" class="media-oembed-content" title="From my Blowhole to your Ear Hole by Whales of Ontario"></iframe>

```

Here is a link to the page that I pulled the code from, http://www.boundlessmotion.com/online/node/8

Any help is appreciated.

# Answer
> 0 votes
My solution was not the most effective, but ultimately, it solved the problem. I added the Video Embed Field module which allows a video to embedded into the body of an article. For some reason, this method allowed the video to be viewed whereas the approach of using the media oembed in the core module does not work for me.

# Answer
> 0 votes
If you check your console in your `DevTools`, you can see the `error message` says:

It says that `Vimeo` allows the content to be displayed only from the Same Domain. The Vimeo videos provide links in the following format which can be embedded in external websites.

```
https://player.vimeo.com/video/12345.

```

You can try embedding video in the above format.

---
Tags: 8
---


# Question
Title: Date picker libraries are missing in specific page
I am adding jquery date picker feature using date field in profile edit page it is working fine .

But when i am adding same jquery datepicker in custom module, datepicker function is not working.

After seeing view page source i have found these three libraries are including in profile edit page where date picker is working.

```
<link rel="stylesheet" href="/core/assets/vendor/jquery.ui/themes/base/datepicker.css?q7wdca" media="all" />
<script src="/core/assets/vendor/jquery.ui/ui/widgets/datepicker-min.js?v=1.12.1"></script>
<script src="/core/modules/locale/locale.datepicker.js?v=8.6.15"></script>

```

But i am not able to figure out why these libraries are not including in custom form page.

# Answer
Do you have a custom theme? If so, the easiest way to ensure `jquery.ui.datepicker` loads on every page is to list it as a dependency in your theme libraries file. E.g.

```
# @file /themes/custom/my_theme/my_theme.libraries.yml

# My theme global library.
global:
  js:
    js/my_theme.js: {}
  css:
    theme:
      css/my_theme.css: {}
  dependencies:
    - core/jquery
    - ...
    - core/jquery.ui.datepicker

```

Alternatively, you can add it via a theme or custom module.

```
/**
 * Implements hook_preprocess_page().
 */
function my_theme_or_module_preprocess_page(&$variables) {
  $variables['#attached']['library'][] = 'core/drupal.date';
}

```
> 2 votes

---
Tags: 8
---


title: Filter nodes by today's date

text:
# Question
Title: Filter nodes by today's date
Following what described in Views filter criteria date field is greater than current date, I have used `operator >= today` with some success. I would like to create "future" nodes and they should be filtered out as well. What I need is for a date and time field to be filtered for today's date only. I have tried many things to include:

* operator = today + either value type, machine readable or offset (returns no results)
* operator = now + either value type, machine readable or offset (returns no results)
* contextual filter: summary links (granularity not adjustable that I can find so returns multiple summary links for a single date & summary + a summary link is not a good UI for the application)
* contextual filter: default value - "current date" (doesn't work; known issue with variably effective patch to core which I'd like to avoid) ref: https://www.drupal.org/project/drupal/issues/2325899
* date only field (doesn't work due to UTC time & changes during daylight savings)

# Answer
> 1 votes
Figured this out. Have to add the following 2 filters:

operator is "Is greater than or equal to" value is *today*

AND

operator is "Is less than" value is *today +24 hours*

*Notes:*

Must use "Is greater than or equal to" to include today at midnight and must use "Is less than" to filter out tomorrow at midnight.

It does not matter what value type you select, machine readable or offset.

The value "today" literally returns the time of midnight on today's date. This means setting operator Is equal to "today" only returns results dated on exactly midnight of today, hence why zero results were returned.

SQL for "today" taken from Views query:

DATE\_FORMAT(('2020-03-29T07:00:00' **\+ INTERVAL -25200 SECOND**), '%Y-%m-%d\T%H:%i:%s'))

"+ INTERVAL -25200 SECOND" is -7 hours correction for my time zone so time is T00:00:00 or midnight.

---
Tags: views, 8, datetime
---


# Question
Title: Create a cron job to automatically clear cache
I'm trying to clear cache automatically with a cron job but it didn't work. I'm debugging simply on the browser at this link *website-url/cronjob.php*. I think it's a problem with the syntax, I have tried to *truncate* the tables from database.

As you can see in the code attached below, I've tried two methods, but neither one works.

```
\Drupal::database()->truncate('cache_config')->execute();
mysql_query('TRUNCATE TABLE yqxq_cache_config');
mysql_query('TRUNCATE TABLE yqxq_cache_container');
mysql_query('TRUNCATE TABLE yqxq_cache_data');
mysql_query('TRUNCATE TABLE yqxq_cache_default');
mysql_query('TRUNCATE TABLE yqxq_cache_discovery');
mysql_query('TRUNCATE TABLE yqxq_cache_dynamic_page_cache');
mysql_query('TRUNCATE TABLE yqxq_cache_entity');
mysql_query('TRUNCATE TABLE yqxq_cache_menu');
mysql_query('TRUNCATE TABLE yqxq_cache_render');
mysql_query('TRUNCATE TABLE yqxq_cache_toolbar');
?>

```

What do I need to change to make this script work?

This is an example of query from the statistics view, which doesn't update if I don't run clear cache.

```
<?php
$count_users_tot = db_query('SELECT COUNT(uid) FROM {users}')->fetchField();
print $count_users_tot;
?>

```

# Answer
Thanks to *@No Sssweat*, *@kiamlaluno*, *@Rick B*, I've got an answer. Firstly, I learned that is not a good practice to clear cache automatically every minute or so often. Secondly, I figured out that I can solve this problem without using a cron job at all, but I have to understand these tag based caching mechanisms.

The problem was as in the image attached below, *Page-Caching was Tag Based*, so selecting *None* option solved my issue.
> 2 votes

---
Tags: cron
---


# Question
Title: Unable to add images to content "Image field is required"
Developing a new site with Drupal 8, I was attempting to add an image to a custom block. In the editor I clicked the image icon and got a dialog to upload an image. After specifying a file (making sure it was within the upload file size), I got a strange error "Image field is required."

I took the error message literally, and created a new custom block type, adding a field of type "image" to the block. So now in the form, I have a Body and an Image field. If I try to upload using the "image" field below the body, I get the same error "Image field is required."

I tried again using the Content / Media tab, to add an image file, and get the same error:

(I also notice that there's a "Caption" checkbox but no field to enter a caption. I'm assuming I'll have a text field once the image is uploaded.)

Drupal 8.8, all current.

# Answer
The error message appears to be a red herring. Even though I thought I had fixed the nginx upload file size limit, I found that it was still at the default of 1mb. I fixed the upload limits to be sufficiently large in both nginx and php, and I was able to successfully add media content.
> 0 votes

---
Tags: media
---


title: How remove/hide an action field link?

text:
# Question
Title: How remove/hide an action field link?
On a node field form (admin/structure/types/manage/article/fields), I have a dropdown with action links for all fields.

* Edit
* Storage Settings
* Delete

I would like know if it's possible to unset the "Delete" link for a field please. I have try with hook\_link\_alter() but I don't know how find and remove the link for a specific field (by example field\_image).

Thanks.

# Answer
Assuming those operations check access correctly (not doing so would be a bug), you can use `hook_ENTITY_TYPE_access`, e.g. in your case `hook_field_config_access`, there you can deny delete access for a field with a given name.
> 0 votes

# Answer
to find the location of the field you want to unset, use the Devel Module:

> Helper functions for Drupal developers and inquisitive admins. This module can print a summary of all database queries for each page request at the bottom of each page. The summary includes how many times each query was executed on a page (shouldn't run same query multiple times), and how long each query took (short is good - use cache for complex queries). Also a dprint\_r($array) function is provided, which pretty prints arrays. Useful during development. Similarly, a ddebug\_backtrace() is offerred. much more. See this helpful demo page.

then you could use hook\_form\_alter() to actually unset the value. to get the form information, something like:

```
hook_form_alter(&$form, &$form_state, $form_id)
{
  dpm($form); // from devel module

  if($form_id == FORM_ID_THAT_HOLDS_ELEMENT_TO_HIDE)
  {
    unset($form[field]...);
  }
}

```

dpm will show the structure of any array, including the form - you can drill down into the data to find the exact location of the item you want to unset
> 0 votes

# Answer
The page you are seeing is an admin form, by default Drupal has not created permissions for the action buttons/ Actions on this form.
> 0 votes

---
Tags: 8
---