# Question
Title: How to create a rule to send an email when someone creates content of selected type(s)?
I'm trying to create a rule (using the Rules module 8.x-3.x-dev) to send an email when someone creates content that is of the type *Announcement* or *Article*, but I can't seem to get the event to trigger properly. It's sending an email for every node that is created. Can anyone help with the proper method of setting the content type? My rule is as follows:

Event: After saving new content (`rules_entity_insert:node`)

Condition: `Node is of type`

Node Value: `@node.node_route_context:node`

Content Type Value: `Announcement`, `Article`

# Answer
> I'm trying to create a rule (using the Rules module 8.x-3.x-dev) to send an email when someone creates content that is of the type Announcement or Article

To my knowledge, the current answer to this question is a ***no go***: You can't do that yet with the most recent Drupal 8 version of the Rules module.

Refer to #d8rules status update November 2017 to get a better understanding of the current status of Rules for D8. Here are some quotes from it:

> * ... Fago can’t dedicate time required to develop the module further. What Rules is really missing at the moment is development capacity to help finish the last milestone.
> * ... Even if we got more funding today, fago the current principal maintainer of the Rules module wouldn’t have enough capacity to do the work himself.

One never realizes what ***has been*** done, only what ***remains to be*** done ... So start here if you wonder how to contribute.

### Plan B

While waiting for Rules to become more mature, you can use the Admin Content Notification module as a temporary alternative (which does have an official D8 release already). Some details about it (from its project page):

> ... can be used for receive email notification when a new content of any content type will be created on your site. Although one can use rules for the same functionality but it's not good to use rules only for notification as it is a huge module, so we can use this module for small websites.

The "*...Although one can use rules for the same functionality ...*" part of this clearly does not apply to the D8 version of Rules (yet).
> 2 votes

# Answer
My experience is that this task is easily accomplished in D8 Rules, and has been working since at least November 2017 when I first started using D8 Rules.

A complete working example of using the "Node is of type" condition to execute an action when content of a specific type is updated was presented in the Rules issue queue last year, see https://www.drupal.org/project/rules/issues/2998793

Here's a slightly modified version of that answer, customized for your situation. This example shows a system warning message instead of sending an e-mail, because a system message is much easier to debug with. This Rule assumes your content type machine names are "announcement" and "article". If you import this Rule into your site, you should see the system warning displayed when a new "announcement" or "article" is created, but not when any other type of content is created. I have tested this on my site and it works.

```
langcode: en
status: true
dependencies: {  }
id: new_announcement_or_article
label: 'New Announcement or Article'
events:
  -
    event_name: 'rules_entity_insert:node'
description: ''
tags: {  }
config_version: '3'
expression:
  id: rules_rule
  uuid: 61868ee0-544e-4d88-92c3-d56f4a1d1c48
  conditions:
    id: rules_and
    uuid: 32d77b80-a17d-4c73-91a0-c9badcb79a4d
    conditions:
      -
        id: rules_condition
        uuid: 641c4be2-61f6-48e9-919d-190982358fe1
        context_values:
          types:
            - announcement
            - article
        context_mapping:
          node: node
        context_processors:
          types:
            rules_tokens: {  }
        provides_mapping: {  }
        condition_id: rules_node_is_of_type
        negate: false
  actions:
    id: rules_action_set
    uuid: 2ab1d627-4ecd-4b4c-9bf0-ad2730fbda14
    actions:
      -
        id: rules_action
        uuid: 88ed24cf-ef02-45bf-a977-96d8069b750e
        context_values:
          message: 'New {{ node.type }} was created'
          type: warning
          repeat: true
        context_mapping: {  }
        context_processors:
          message:
            rules_tokens: {  }
          type:
            rules_tokens: {  }
          repeat:
            rules_tokens: {  }
        provides_mapping: {  }
        action_id: rules_system_message

```
> 0 votes

---
Tags: 8, rules
---


title: Notify node author of new comments

text:
# Question
Title: Notify node author of new comments
Has anyone been able to figure out how to notify the node author when new comments are posted on their content?

I understand Rules for Drupal 8 is still in its infancy. When I used various tokes for the TO filed nothing worked.

If anyone could share their solution that would be great.

# Answer
> ... how to notify the node author when new comments are posted on their content??

To my knowledge, the current answer to this question is: ***not*** possible yet.

### More info

* Refer to #d8rules status update November 2017 to get a better understanding of the current status of Rules for D8. Here are some (scary) quotes from it:

> + ... Fago can’t dedicate time required to develop the module further. What Rules is really missing at the moment is development capacity to help finish the last milestone.
>     + ... Even if we got more funding today, fago the current principal maintainer of the Rules module wouldn’t have enough capacity to do the work himself.
* Start here if you wonder how to contribute.

---

One never realizes what ***has been*** done, only what ***remains to be*** done ...

---

### Plan B

You might want to look at the Message module (and the related modules that belong to the Message Stack), which has a pretty stable release already, and which you could use to create similar functionality.
> 1 votes

# Answer
It's not at all true that this can't be done in Rules.

There's a working example in the Rules issue queue that was posted in November 2016, so this has been possible at least since then. See https://www.drupal.org/project/rules/issues/2828422

Here's a slightly modified version of that answer to suit your use case. You may import this into your site and look at it in the UI to learn how to configure this functionality.

```
langcode: en
status: true
dependencies: {  }
id: '2828422'
label: 'Email Node Author on New Comment - Issue 2828422'
events:
  -
    event_name: 'rules_entity_insert:comment'
description: 'Sends email to Node Author when a New Comment is added.'
tags:
  - node
  - email
  - comment
config_version: '3'
expression:
  id: rules_rule
  uuid: b5276280-d0f2-4f64-9512-06f077793c58
  conditions:
    id: rules_and
    uuid: ebf212fc-d858-417d-977d-af1be2cfd886
    conditions: {  }
  actions:
    id: rules_action_set
    uuid: 88a78280-2bca-4367-a4d3-8bbda9397c2a
    actions:
      -
        id: rules_action
        uuid: 5e6e5aed-b75f-412a-9670-48327eb58ba6
        context_values:
          to:
            - '{{ comment.entity_id.entity.uid.entity.mail }}'
          subject: 'Your content {{ comment.entity_id.entity.title }} has a new comment.'
          message: 'Your content {{ comment.entity_id.entity.title }} has a new comment.'
          reply: ''
          language: ''
        context_mapping: {  }
        context_processors:
          to:
            rules_tokens: {  }
          subject:
            rules_tokens: {  }
          message:
            rules_tokens: {  }
          reply:
            rules_tokens: {  }
          language:
            rules_tokens: {  }
        provides_mapping: {  }
        action_id: rules_send_email

```
> 0 votes

---
Tags: 8, users, rules
---


# Question
Title: How to trigger email by comparing date value in node?
I'm using Drupal 7, with Rules and Rules Scheduler.

I have a content type "Tutorial Class", with fields as below:

* Class Date and Time
* Feedback requested (Radio button: Yes/No, default is no)

I would like to create a Rule, so that whenever the cron runs, it will check on all "Tutorial Class" content type.

If current time is larger than "Class Date and Time" field, and "Feedback requested" is no, an email will be triggered and "Feedback requested" will be changed to Yes.

Currently I know how to trigger email after "Tutorial Class" is created, but I can't get the above Rule done.

Any idea of how to set this rule?

# Answer
Hi You can add a filed in your content type like date\_content\_type . a)chose filed type =date in content type(admin/structure/types/manage/content\_type/fields)

b)add a condition in Rule set c) select condition= data comparison d) click on continue button e) select data selector set your custom date type field f)then add your time() value and save it . now your date condition rule set will be execute i hope it will help you Thanks
> 0 votes

# Answer
This is exactly what the Rules Scheduler is for.

First, whenever you want to create a Reaction Rule, you have to answer the question WHEN do you want an action to happen. You are implying that you want to periodically (via cron) loop over all your nodes and do a date comparison. That's not a good idea, is super inefficient, and that's not the sort of task Rules was designed for. Although, it IS possible to do this in Rules if you really really want to.

Instead, the way you should be thinking about this is, WHEN your node is saved or updated, THEN schedule an e-mail to be sent on the class date. See, you have a WHEN which represents the event, and you have a THEN which represents the action to take. You can also add conditions (IF something is true ...) to this Rule if necessary. Thus, no endless looping and comparing dates is needed - the Rule executes only once and only when needed.

So in this case, the Rule can be described as:

WHEN a "Tutorial Class" is created or updated THEN schedule a Rules Component to be executed on the day of the "Class Date and Time" field.

The Rules Component that you schedule would contain a "Send a mail" action and an action to set the checkbox value to "Yes".

This procedure also works when the "Tutorial Class" is updated with a new date - the scheduling action will overwrite the previously scheduled component and update it with the new date, so the mail will be sent only once, and on the correct date.
> 0 votes

---
Tags: 7, rules
---


# Question
Title: Custom Twig template for confirmation webform page being cached too hard
I've created a custom module which does some additional form handling and styling required for my project - this is all working fine.

Due to the size of the form - 50 odd fields - I'm setting up a Twig file in my module for the confirmation screen as it is far easier to manage it in my IDE than using the GUI. My confirmation page lists all the values styled in a specific way and laid out in a specific way. I've technically got it working by using `hook_theme_suggestions_webform_confirmation_alter` and `hook_theme` to point to my Twig template.

However, I've just recently discovered that, due to Drupal 8 internal page caching being so aggressive for anonymous users, the confirmation page is getting cached for everyone regardless of the actual submission values. So the first user gets it fine but the second submission from then on gets the cached version from the first.

I've read in other places to make use of `hook_preprocess_webform_confirmation` and set `$variables['message']['#cache']['max-age'] = 0;`. However, this is never called which I suspect is due to how I went about using my Twig template mentioned above.

Can someone help point me in the right direction here. Am I supposed to setup some kind of overwriting route in order to change the theme file or is it just a matter of tweaking what I've already done?

Functions in my `.module` file

```
function application_theme($existing, $type, $theme, $path) {
  $info = [
    'gib_application' => [
      'render element' => 'form',
      'template' => 'application-form'
    ],
    'application_form_confirmation' => [
      'template' => 'application-form-confirmation'
    ]
  ];
  return $info;
}

```

And

```
function application_theme_suggestions_webform_confirmation_alter(array &$suggestions, array $variables) {
  if (empty($variables['header'])) {
    $suggestions[] = 'application_form_confirmation';
  }
}

```

**UPDATE**

I've tweaked my `hook_theme` function to the below and also disabled `hook_theme_suggestions_webform_confirmation_alter` assuming it isn't relevant so long as `hook_theme` is defining the correct name.

```
function application_theme($existing, $type, $theme, $path) {
  $info = [
    'gib_application' => [
      'render element' => 'form',
      'template' => 'application-form'
    ],
    'webform_confirmation__application_form' => [
      'template' => 'application-form-confirmation',
      'base hook' => 'webform_confirmation'
    ],
  ];
  return $info;
}

```

Here are the Twig suggestions:

```
<!-- FILE NAME SUGGESTIONS:
   * webform-confirmation--application-form.html.twig
   x webform-confirmation.html.twig
-->

```

Unfortunately now my Twig template isn't being loaded at all now (due to dropping `hook_theme_suggestions_webform_confirmation_alter`.

# Answer
> 3 votes
Summary of the final answer to my original questions.

`hook_theme` was still required in the module to state that it can be used for suggested Twig templates.

```
function application_theme($existing, $type, $theme, $path) {
  $info = [
    'webform_confirmation__application_form' => [
      'base hook' => 'webform_confirmation'
    ]
  ];
  return $info;
}

```

`hook_theme_suggestions_webform_confirmation_alter` was not required in the end once `hook_theme` was setup correctly.

`hook_theme` needed to have the suggested name as proposed by the Twig debugger. Twig suggested these files:

```
<!-- FILE NAME SUGGESTIONS:
   * webform-confirmation--application-form.html.twig
   x webform-confirmation.html.twig
-->

```

The dashes get converted to underscores i.e. `webform-confirmation--application-form` is translated to `webform_confirmation__application_form`.

The only variable associated with that part of the array was `base hook`. This states to use the initial hook functionality rather than setting it all up again in my module - read more here.

> **base hook**: Used for theme suggestions only: the base theme hook name. Instead of this suggestion's implementation being used directly, the base hook will be invoked with this implementation as its first suggestion. The base hook's files will be included and the base hook's preprocess functions will be called in addition to any suggestion's preprocess functions. If an implementation of hook\_theme\_suggestions\_HOOK() (where HOOK is the base hook) changes the suggestion order, a different suggestion may be used in place of this suggestion. If after hook\_theme\_suggestions\_HOOK() this suggestion remains the first suggestion, then this suggestion's function or template will be used to generate the rendered output.

`template` was not required so long as the filename of my Twig file matched the one Twig was suggesting. For my site it was `webform-confirmation--application-form.html.twig`.

With the above tweaks my Twig file was loading correctly while also still using all of the original hooks from the webform module.

The other issue was the confirmation page being cached for anonymous users. I was able to resolve this by using `\Drupal::service('page_cache_kill_switch')->trigger();` inside `hook_preprocess_webform_confirmation`. After clearing Drupal's cache the confirmation page would then never get cached again.

```
function application_preprocess_webform_confirmation(array &$variables) {
  \Drupal::service('page_cache_kill_switch')->trigger();
}

```

This same logic will apply for updating Twig templates in other modules as well - this is not a webform module only solution.

Thanks to 4k4 and Stefanos for the guidance.

# Answer
> 4 votes
Seems like there are two different issues here:

(a) Loading a twig template from an arbitrary folder.

Could you try setting the `path` theme property and see if that allows your twig template to be loaded? For example:

```
'webform_confirmation__application_form' => [
  'template' => 'application-form-confirmation',
  'base hook' => 'webform_confirmation'
  'path' => \Drupal::moduleHandler()->getModule('application')->getPath() . '/templates',
],

```

(b) Modifying the cache settings for a part of your render variables.

You should check that the cache tags bubble all the way up from the `message` array. Apparently:

> You have to render the content variable to ensure that its cache tags bubble up and end up in the page cache.

as mentioned here =\> (https://www.previousnext.com.au/blog/ensuring-drupal-8-block-cache-tags-bubble-up-page)

So, one place to start would be trying to render the whole `content` variable in your twig template, provided you got past (a)

Update: You could also try calling `\Drupal::service(''page_cache_kill_switch'')->trigger();` in order to avoid Internal Page Cache to interfere with the request and page loading.

A simple way to do this inside a twig template would be using an approach similar to this module =\> https://github.com/stefanospetrakis/twig\_killswitch\_trigger

Good luck!

P.S.: Sample code is also available here =\> https://www.drupal.org/sandbox/stefanospetrakis/3011610, I may promote this to a full project if there is any potential interest.

# Answer
> 0 votes
You can add the following statement to your Twig template to turn off caching.

```
{{ {'#cache': {'max-age': 0}} }}

```

---
Tags: 8, theming, webforms
---


# Question
Title: Is there a built-in "None of the above" checkbox option in webform? and how to create one?
I may be mistaken but I recall seeing such option in webform somewhere before and I don't seem to find it now (in case I'm right). (please see last edit)

I have several questions with big lists of checkboxes and if there's such option buil-in webform it would be great and better than having to do it via a custom jQuery code.

Thank you

**EDIT:**

This is a sample question with a

```
  mywfq:
    '#type': checkboxes
    '#title': 'Please chcek all that applies'
    '#options':
      q1: '....'
      q2: '....'
      q3: '....'
      q4: '.....'
      q5: '.....'
    '#attributes':
      class:
        - mywfq
    '#format_items': ol
  mwwfqnota:
    '#type': checkbox
    '#title': 'None of the above'
    '#attributes':
      class:
        - nota

```

In the above, I created a separate single checkbox element after the multi one and tried to use jQuery to uncheck all the above if this is checked but it's not working yet.

This is my code:

```
 $("input.mywfq).change(function() {
 $("input.nota").not(this).prop('checked', false);
  });

$("input.nota).on('change', function() {
$("input.mywfq").not(this).prop('checked', false);
 });

```

I'm still wondering if no already such built-in option!

**EDIT:** the great Webform team seems to have added the "none of the above" option to the module (x6 but not sure about prev versions).

# Answer
This code was fine but **wasn't working due to iCheck enabled** and then checkboxes "aren't" cleared when the `"None of the above"` is checked although the counting of checked ones was updating correctly (actually the checked state IS cleared but their iCheck-added class is not and that's why their apparent checked state keeps looking as `checked`). I'll try find a fix to keep iCheck and make it work with maybe later but for now the following works as expected.

So for anyone that may need this. Create a single checkbox element after the one with multi checkboxes and call it "`None of the above`" and give it an element custom css ( I called it `'nota'` ) to use in the jQuery code to toggle checked status between the 'nota' and all other checkboxes.

```
 $("input.mywfq).change(function() {
 $("input.nota").not(this).prop('checked', false);
  });

$("input.nota).on('change', function() {
$("input.mywfq").not(this).prop('checked', false);
 });

```

**IMPORTANT:** make sure **iCheck is set to "none"** for this element in case its enabled for the form by default.
> 0 votes

---
Tags: 8, webforms
---


# Question
Title: "public" not supported or disabled in libcurl error
I'm learning how to create a custom JSON migration and referring to the *migrate\_json\_example* module, I see the following code in migrate\_plus.migration.product.yml.

```
urls:
    - 'public://migrate_json_example/products.json'
  # An xpath-like selector corresponding to the items to be imported.
  item_selector: product

```

Can someone please tell me how to use that *public://* part of the URL? I understand it's a path to the JSON file, but it's a relative path. I don't know how *public://* is handled and how Drupal knows where to look for the files.

Both modules are installed on the same site. However, when I try using the same *public://* URL in my module, I get the following error.

> Error message: cURL error 1: Protocol "public" not supported or disabled in libcurl (see http://curl.haxx.se/libcurl/c/libcurl-errors.html) at public://migrate\_stuff/resources/people1.json.

# Answer
`public://` is the sites public file system path. You can change it by navigation to `admin/config/media/file-system`. There you can set the public file system path, the default path is `sites/default/files`.
> 1 votes

---
Tags: 8, migrations
---


# Question
Title: How can I conditionally alter search API relevance score?
I must be missing some core concept of search API somehow, but I am stuck. The goal is to alter search API results depending on a flag, like Give flagged products in search API a higher search score? however this time without SOLR, but with database backend instead.

I can see all flagged fields properly indexed, so there is a line that associates the content entity id with the user who flagged, and now I want to increase the relevance score of the results, so that items flagged by the current user are always shown first.

I have hijacked the SearchApiDbService class and I did add the following line in postQuery (I also wonder why this hook does not exist, but that is not relevant for now):

```
drupal_alter('search_api_db_query_results', $results, $query);

```

This should allow me to alter the search results right before search\_api\_db hands them over to the search API right?

So now I use the alter hook as follows:

```
function mymodule_search_api_db_query_results_alter(&$results, SearchApiQueryInterface $query) {
  global $user;
  $uid = $user->uid;

  // Fetch a list of content entities that the user has flagged.
  $drupal_db_q = db_select('search_api_db_MY_FLAG_FIELD_TABLE', 'f')
    ->fields('f')
    ->condition('value', $uid);
  $items = $drupal_db_q->execute()->fetchCol();

  // Iterate over results and multiply score of flagged items.
  foreach ($results['results'] as $key => &$result) {
    if (in_array($key, $items)) {
      $result['score'] *= 10;
    }
  }

dpm($results);

}

```

In `$results` I can see that the scores have changed, but the order of the items on my views results page has not, even though I am sorting by relevance.

It has to be something simple, or I am completely misunderstanding how the score value works somehow?

p.s. Since this is conditionally I don't think altering the search api query directly makes sense because I found no way to boost any field scores there. Directions on how to achieve that are welcome too.

# Answer
> 2 votes
Since everyone was telling me to solve this during the query, I decided to have another look at this approach. My main issue was not being able to order by the flagged status, which was eventually solved with an expression.

In the end I managed to get what I wanted with an implementation of `hook_search_api_db_query_alter`.

```
function mymodule_search_api_db_query_alter(SelectQueryInterface &$db_query, SearchApiQueryInterface $query) {
  global $user;
  $uid = $user->uid;

  // Left join indexed flag table into search index.
  $db_query->leftJoin('search_api_db_product_index_field_my_flag_field', 'flag', 'flag.item_id = t.item_id');
  // Set a value of 1 for entities flagged by the given uid, 0 otherwise.
  $alias = $db_query->addExpression('CASE WHEN flag.value = :uid THEN 1 ELSE 0 END', 'flagged', array(':uid' => $uid));
  // Order by the flagged value (1 or 0), highest first.
  $db_query->orderBy($alias, 'DESC');
}

```

# Answer
> 1 votes
I did a quick test and found the same as you, i.e. updating the relevance score worked, but the view sort did not seem to take the updated relevance into consideration. As @zaporylie pointed out in the comments, sorting is done in query rather than display, but I'm not sure why the sort you specify in the view settings is not being honoured.

A quick workaround is to sort the results array again in your function after you have updated the relevance, like this:

```
  uasort($results['results'], function($a, $b) {
    return $b['score'] - $a['score'];
  });

```

Bear in mind that paging is also done as part of the query. Suppose you have 200 items, and there are 5 for a given user, and you want them to appear first in your results. If your pager returns 20 results at a time, there is no guarantee that the 5 results for the user will be in the first 20 results returned. The only way to guarantee the 5 results are available before you sort is to return all the results together, i.e. do not use a pager. If you want paged results, it might be possible to do some paging in a late-called views hook such as `hook_views_post_render()` but if that doesn't work you'll have to take a different - and much more complicated - approach. Here is a quick overview of the steps:

Write a custom query handler to execute your search against the Search API index. That way, you will be able to modify the results before they are passed to the view.

You'll need a `hook_views_data_alter()` function to associate queries to the database table with your custom query handler.

You might also need a custom pager plugin (even though you'll be returning all the results, some pager objects might be missing from your view object if you don't specify a pager).

Use a `hook_views_plugins()` function to specify your plugins, something like this:

```
function mymodule_views_plugins() {

  $plugins = array(
    'pager' => array(
      'views_plugin_user_first_search_api_pager' => array(
        'title' => t('Custom pager to put user results first'),
        'handler' => 'views_plugin_user_first_search_api_pager',
        'uses options' => TRUE,
        'parent' => 'full',
      ),
    ),
    'query' => array(
      'my_module_search_api_query' => array(
        'title' => t('My custom Search API query'),
        'help' => t('Custom Search API query to put user results first.'),
        'handler' => 'my_module_search_api_query',
        'parent' => 'SearchApiViewsQuery',
       ),
    ),
  );
  return $plugins;
}

```

The `hook_views_data_alter()` function should look something like this:

```
**
 * Implements hook_views_data_alter().
 */
function hook_views_data_alter(&$data) {

    if (isset($data['search_api_index_my_index']['table']['base']['query class'])) {
      $data['search_api_index_my_index']['table']['base']['query class'] = 'my_module_search_api_query';
    }
}

```

Your search query handler should override the standard SearchAPIViewsQuery handler so it should begin

```
class my_module_search_api_query extends SearchAPIViewsQuery {

    public function execute(&$view) {

        // Your code here
    }
}

```

and your pager plugin should override views\_plugin\_pager\_full, like this:

```
class views_plugin_user_first_search_api_pager extends views_plugin_pager_full {

    function query() {
        // Your code here
    }
}

```

Hopefully the above will point you in the right direction if you need a pager.

---
Tags: 7, search
---


# Question
Title: Send email notification when a new comment is posted
I'm using Drupal 8.1 with Rules 8.x-3.0-alpha1.

I want to create a rule to send an email to the author of a node when a new comment is posted to this node. Problem is I didn't get the email address of the author with rules because the dataset gives me only this values: @node.node\_route\_context:node or comment but under comment I didn't find anything like comment:node:author. In Drupal 7 I have this data. What I have to do in Drupal 8?

# Answer
**Updated Answer**

*Whilst testing this on a fresh install of Drupal 8 with Rules (Alpha 2) I have come across a bug which is preventing a successful test of this, whilst the data selector below is correct I am presently unable to reproduce a working rule.*

*The bug report is here: https://www.drupal.org/node/2770291 \- To summarise this issue Rules is expecting the TO: parameter to be an array and will throw an error when passing the email address token below which returns a string.*

My initial answer holds true for Drupal 7 however for Drupal 8 the situation seems simpler and hinges on a single fact that isn't yet well-documented.

In D7 we're familiar with a syntax resembling: `comment:node:author:mail`

In D8 the same selector (which works) is: `comment.entity_id.entity.uid.entity.mail.value`

Hopes this helps, I'm leaving the previous answer below in case it helps someone else.

**Previous Answer**

\*In general with Rules to use the value of a field the rule must first specifically check for the existence of the field (i.e. that the field has a value in the context the rule is running). If you haven't tried this already you might want to try adding an "Entity has field" condition to the rule to check for the existence of the email address. This should then expose the token for the field.

I've had similar issues executing rules using entity relations (which is more or less what you're doing by referencing the author from the node) checking for the existence of the field (in your case most likely a check that the entity has an author (this should open up access to the user object) then a check against the user object to ensure it has an email address) opened up the available field tokens from the referenced entity.\*
> 5 votes

# Answer
There's a working example in the Rules issue queue that was posted in November 2016, so this has been possible at least since then. See https://www.drupal.org/project/rules/issues/2828422

Here's a slightly modified version of that answer. You may import this into your site and look at it in the UI to learn how to configure this functionality.

```
langcode: en
status: true
dependencies: {  }
id: 'email_node_author_on_new_comment'
label: 'Email Node Author on New Comment - Issue 2828422'
events:
  -
    event_name: 'rules_entity_insert:comment'
description: 'Sends email to Node Author when a New Comment is added.'
tags:
  - node
  - email
  - comment
config_version: '3'
expression:
  id: rules_rule
  uuid: b5276280-d0f2-4f64-9512-06f077793c58
  conditions:
    id: rules_and
    uuid: ebf212fc-d858-417d-977d-af1be2cfd886
    conditions: {  }
  actions:
    id: rules_action_set
    uuid: 88a78280-2bca-4367-a4d3-8bbda9397c2a
    actions:
      -
        id: rules_action
        uuid: 5e6e5aed-b75f-412a-9670-48327eb58ba6
        context_values:
          to:
            - '{{ comment.entity_id.entity.uid.entity.mail }}'
          subject: 'Your content {{ comment.entity_id.entity.title }} has a new comment.'
          message: 'Your content {{ comment.entity_id.entity.title }} has a new comment.'
          reply: ''
          language: ''
        context_mapping: {  }
        context_processors:
          to:
            rules_tokens: {  }
          subject:
            rules_tokens: {  }
          message:
            rules_tokens: {  }
          reply:
            rules_tokens: {  }
          language:
            rules_tokens: {  }
        provides_mapping: {  }
        action_id: rules_send_email

```
> 1 votes

---
Tags: 8, rules
---


# Question
Title: How do I send an email to all users with a particular role?
This was quite straightforward in Drupal 7 as I recall but, with Drupal 8 there's a lot of info I don't understand as a site builder that I am being asked to provide when creating a new rule.

I'd be very grateful for some step by step help.

I want to send an email to all users with the role of "Officer" when a node of type "Agenda" has been updated.

Right now (Feb 10 2018) I have:

```
"drupal/core": "8.4.4"
"drupal/mailsystem": "4.1"
"drupal/swiftmailer": "1.x-dev"
"drupal/rules": "3.x-dev"
"drupal/typed_data": "1.x-dev"

```

# Answer
I'm a bit familiar with the (amazing!) Rules module. But to my knowledge the current answer to this question is a ***No go***, that is: can't do that yet with the most recent D8 version of Rules.

Refer to #d8rules status update November 2017 to get a better understanding of the current status of Rules for D8. Here are some quotes from it:

> * ... Fago can’t dedicate time required to develop the module further. What Rules is really missing at the moment is development capacity to help finish the last milestone.
> * ... Even if we got more funding today, fago the current principal maintainer of the Rules module wouldn’t have enough capacity to do the work himself.

One never realizes what ***has been*** done, only what ***remains to be*** done ... So start here if you wonder how to contribute.

BTW, Rules documentation for D8 contains the official Rules documentation specific for D8.

### Plan B

While waiting for Rules to become more mature, you can use the Admin Content Notification module as a temporary alternative (which does have an official D8 release already). Some details about it (from its project page):

> ... can be used for receive email notification when a new content of any content type will be created on your site. Although one can use rules for the same functionality but it's not good to use rules only for notification as it is a huge module, so we can use this module for small websites.

The "*...Although one can use rules for the same functionality ...*" part of this clearly does not apply to the D8 version of Rules (yet).

The image shown on the project page gives an idea of what this module can be used for.

Obviously, your question is about ***updates*** of content. But even though it doesn't say so (yet) on the project page, just have a look at the issue "Also trigger event on update", which appears to be as in your question.
> 0 votes

# Answer
There are only two Rules actions that haven't been fully ported to D8 yet, and "Send mail to all users of a role" is one of them. When it is finally ported, it should provide the same capability as in D7.

There's a patch in the Rules issue queue which ports this action to D8 - you can try out that patch to see if it solves the issue for you. See: Port Send mail to all users of a role (mail\_to\_users\_of\_role) action to D8

If this action is important to you, please help out in the Rules issue queue by testing the proposed patch, supplying feedback, and helping out with the parts that are still missing from that patch.
> 0 votes

---
Tags: 8, rules, emails
---


title: How do I create a ruleset component?

text:
# Question
Title: How do I create a ruleset component?
I would like to create a custom ruleset component like the one described in How to automatically generate multiple aliases for one node?

That answer is for Drupal 7, and I am using Drupal 8. When I go to Rules/Components, none of the plugin options that I see in screenshots of Drupal 7 appear to be available (e.g. rule set, condition set, action set). Basically, the *Components* tab looks nothing like the one found in Drupal 7, so it's unclear to me how to create a ruleset. I'm not a module developer, but when I look through the module folder, I see a folder named Plugins/RulesExpression which contains files that seem to correspond to these component plugin types. Is there something I have to do to enable them to be available in the administration pages?

The documentation for Drupal 8 Rules is basically empty. The only documentation I found is for contributing developers; it doesn't seem there is any updated documentation for administrator users of the module, and I have searched far and wide for any insight on this and found nothing.

# Answer
> 0 votes
While Rules components may successfully be created and used programmatically, as of Rules 8.x-3.0-alpha4 there is only minimal support for doing this in the UI. Adding these UI features is part of the last meta task needed to be completed before a beta version of Rules is released. You can discover the current status of these UI porting issues by reading the Rules issue queue at https://www.drupal.org/project/issues/rules

---
Tags: 8, rules, plugins
---


# Question
Title: How do I check a custom field has a value?
I'm using the "Entity is of type" condition for the After updating content event, the rule only fire when the field has a value of that updated/created node. The field, which is part of a custom content type.

When I select Entity is of type and try to add Entity(Specifies the entity for which to evaluate the condition.) value like \[node\] and Type(The entity type specified by the condition.) of value like \[node:field\_alias\_1:value\]

I got the following error.

> TypeError: Argument 1 passed to Drupal\rules\Plugin\Condition\EntityHasField::doEvaluate() must implement interface Drupal\Core\Entity\FieldableEntityInterface

If the field has the value of that content type, how do I create a new redirect alias using that field name?

# Answer
To my knowledge the current answer to this question is: you can't do that yet with the most recent D8 version of Rules. Refer to #d8rules status update November 2017 to get a better understanding of the current status of Rules for D8. Here is a quote from it:

> ... Fago can’t dedicate time required to develop the module further. What Rules is really missing at the moment is development capacity to help finish the last milestone.

One never realizes what ***has been*** done, only what ***remains to be*** done ... So start here if you wonder how to contribute.
> 2 votes

# Answer
The "Entity is of type" condition DOES work in Rules for Drupal 8, and has worked for many years.

The reason for the error cited by the original poster is that the D7 token syntax "\[node:field\_alias\_1:value\]" is not used in D8. You must use a token like "{{ node.field\_alias\_1.value }}" in the direct input mode. Likewise, to specify the entity, instead of "\[node\]" simply use "node" in the data selector.

This documentation may help: https://www.drupal.org/docs/8/modules/d8-rules-essentials/token-replacement
> 0 votes

---
Tags: 8, rules
---


title: How do I add a role to new users?

text:
# Question
Title: How do I add a role to new users?
I'm using the Drupal 8 version of the Rules module. How do I add a role to new users with a rule?

I created a rule.

* Name: New user role
* Events: After saving new user
* Action: Add user role
* Data selector: user.roles

I don't know what to set for value. Is my rule correct?

I want to add the *particulier* role to users.

# Answer
I also have tested rules module in drupal8 but data selectors did not worked, as also mentioned here https://groups.drupal.org/node/516054

Then i tried https://www.drupal.org/project/registration\_role which worked for me. You may also try this module if you want to assign a role to a user on registration.

Thanks
> 1 votes

# Answer
This works to set a role for a new user. This rule reacts on a new user being created, and assigns that new user a role with machine name "granted\_by\_rules". You can import this onto your site and see how it's configured.

```
langcode: en
status: true
dependencies: {  }
id: set_a_role_for_new_users
label: 'Set a role for new users.'
events:
  -
    event_name: 'rules_entity_insert:user'
description: ''
tags: {  }
config_version: '3'
expression:
  id: rules_rule
  uuid: 36de9619-1401-4b21-a651-d3927c5b8dac
  conditions:
    id: rules_and
    uuid: 416e90b0-d24c-4f37-8272-de0ecee5c375
    conditions: {  }
  actions:
    id: rules_action_set
    uuid: 2933681a-a079-496d-bc79-f27ff53144eb
    actions:
      -
        id: rules_action
        uuid: 38e8a3bb-0470-427f-80e1-53f6a703e8bf
        context_values:
          roles:
            - granted_by_rules
        context_mapping:
          user: user
        context_processors:
          roles:
            rules_tokens: {  }
        provides_mapping: {  }
        action_id: rules_user_role_add

```
> 0 votes

---
Tags: 8, users, rules
---


title: Sub-roles and role purchase

text:
# Question
Title: Sub-roles and role purchase
I developed a site using Drupal 7 and the Ubercart module, where I sell user roles. I have sub-roles like the following.

* Producer
    + Co-producer
    + Ex-producer

How can I manage this? Is there any sub-role concept existing or manageable with category name in Ubercart?

# Answer
> 1 votes
I think you are looking for something like Sub Users module to set relation between two user types.

I also sell membership with help of Drupal Commerce in D7 & I have used same thing but some modified version of the module which you can find at my given link here --

https://drupal.org/node/2049703

I sell membership to have some access & sometimes I create a usertype who has got authority to create more sub user under him to have access allowed for that particular membership type.

# Answer
> 0 votes
Don't create main role, just create sub roles as a main role. like your roles wil be co-producer and ex-producer.

# Answer
> 0 votes
Drupal CORE has no concept of "sub-roles" - all roles are completely independent. So the relationship between them is just in your imagination unless you add additional function to Drupal core. One module that adds functionality similar to what you describe is https://www.drupal.org/project/role\_inheritance

Regardless, I don't see how the question involves Ubercart. Ubercart grants access based on a role. The details of how that role is created or managed in core Drupal is of no concern to Ubercart.

---
Tags: 7, users
---


# Question
Title: Get difference between two dates programatically
**In summary:**

On a Drupal 8 project, i am trying to programatically get the difference between two different times (current time - Node creation time)

**Use case:**

I have "nodeabc" already available on the site.

When a specific webform is submitted and by using a custom webform handler, I want to get the **difference in minutes** between **current time** and **nodeabc creation time**.

Say **nodeabc** was created on: **24/06/2019 08:00 AM** and the webform is being submitted on: **24/06/2019 07:00 PM**, so the difference between both times will be: **660** minutes.

I have already loaded the node by its nid but how to continue in achieving the above ?

**UPDATE #1:**

From @Prestosaurus answer, I did the below in my webform custom handler php file:

```
$nid = '125';
$node = \Drupal\node\Entity\Node::load($nid);

$creationtime = $node->getCreatedTime();

// Get "Time Diff Since" creation time.
$creationsince = \Drupal::service('date.formatter')->formatTimeDiffSince($creationtime);

```

the above code returned: `7 hours 30 minutes` which is good but then I added the below code to the above one:

```
$totalamount = $creationsince * 5000;

```

But while testing it returns a php error `InvalidArgumentException: $string ("35000") must be a string.`

I believe I am half way to the answer but still need to convert the `$creationsince` value to `450` minutes instead of `7 hours 30 minutes`.

Is that doable ?

# Answer
> 1 votes
Given a node, `$node`:

```
$diffSeconds = time() - $node->getCreatedTime();
$diffHours = (($delta_seconds / 60.0) / 60.0);
$formattedTimeDiff = \Drupal::service('date.formatter')
  ->formatTimeDiffSince($node->getCreatedTime());

```

`$diffSeconds` is the number of seconds between node creation time and now.

Thus `$diffHours` is the number of hours (float) between node creation time and now.

`formatTimeDiffSince()` converts this to a human readable value, e.g. "1 hour 15 minutes"

---

For the webform timestamps:

```
function MYMODULE_preprocess_node(&$variables) {

  $createdTimestamp = $variables['node']->getCreatedTime();

  $webform_submissions = \Drupal::entityTypeManager()
    ->getStorage('webform_submission')
    ->loadByProperties([
    'entity_type' => 'node',
    'entity_id' => $variables['node']->id(),
  ]);

  $submission_timestamps = [];
  $timeDiffs = [];
  $timeAgos = [];

  foreach ($webform_submissions as $submission) {
    $submission_timestamps[] = $submission->completed->value;
    $timeDiffs[] = $submission->completed->value - $createdTimestamp;
    $timeAgos[] = \Drupal::service('date.formatter')
      ->formatTimeDiffSince($submission->completed->value);
  }

}

```

Webform timestamps cover `->created`, `->completed`, and `->changed`.

---
Tags: 8, datetime
---


title: Access user profile data

text:
# Question
Title: Access user profile data
I have a field on a user profile called `field_certified_tap`. When this is equal to `1` or `true` on user update/create, I want to send an email.

Currently, I do not see this field in the Condition-\>Entity Has Value-\>\[data select\].

I am using the 3x-dev version of Rules and the 1x version of token.

What am I doing wrong? Is there currently a way to accomplish this with Rules UI or should I make my own Rule or implement in the user save hook?

Thanks!

# Answer
> 0 votes
In your image, you are configuring the "Entity" parameter of the "Entity has field" condition. That parameter should be set to just "user" in the data selector - it would be wrong to specify a field here since it is calling for the entity that you want to check.

The SECOND parameter should be "Field", and it is there that you would want to enter "field\_certified\_tap" using direct input (not data selector).

Note that the "Entity has field" condition cannot be used to check the value of the field - that has to be done in a separate "Data comparison" condition.

But you are right that even when you properly configure the "Entity has field" condition, your custom field does not show up in the data selector for subsequent actions. I'm not sure why, but there's an open bug report for that in the Rules issue queue: "Entity has field" doesn't actually give access to the field

Instead, use the "Entity is of bundle" condition to get access to the field. Here's an example using a boolean field called "field\_certified\_tap" which I added to the user entity. If you import this Rule and examine it in your UI you will see that after adding the "Entity is of bundle" condition to the rule, the data selector in the "Data comparison" condition and the "Show a system message" action DOES now give you an option of "user.field\_certified\_tap". You can then add a "Data comparison" condition to show the message only when field\_certified\_tap is true.

I'm using "Show a system message" here because it's much easier to use for debugging than "Send mail". You should use this action to test the tokens you plan to use for your email, then when you are sure you have the values you need you can add a "Send mail" action.

```
langcode: en
status: true
dependencies: {  }
id: access_certified_tap_field
label: 'Access user certified tap field'
events:
  -
    event_name: 'rules_entity_update:user'
description: ''
tags: {  }
config_version: '3'
expression:
  id: rules_rule
  uuid: 137a6a57-2d1a-467d-80e6-68091de5eb11
  conditions:
    id: rules_and
    uuid: 098bb2b1-3e95-4efa-9328-07b651591e63
    conditions:
      -
        id: rules_condition
        uuid: 3b23a038-ac0c-4461-b14b-6db518c3261a
        context_values:
          type: user
          bundle: user
        context_mapping:
          entity: user
        context_processors:
          type:
            rules_tokens: {  }
          bundle:
            rules_tokens: {  }
        provides_mapping: {  }
        condition_id: rules_entity_is_of_bundle
        negate: false
      -
        id: rules_condition
        uuid: fbcdef7b-9681-47a2-bcac-94d49c86d7fa
        context_values:
          data: '{{ user.field_certified_tap }}'
          operation: '=='
          value: '1'
        context_mapping: {  }
        context_processors:
          data:
            rules_tokens: {  }
          operation:
            rules_tokens: {  }
          value:
            rules_tokens: {  }
        provides_mapping: {  }
        condition_id: rules_data_comparison
        negate: false
  actions:
    id: rules_action_set
    uuid: d6d904a0-007a-4f7f-97be-ac7c1f64edd2
    actions:
      -
        id: rules_action
        uuid: c5d31406-7355-4d91-b623-2c55dc3d57cb
        context_values:
          message: 'User is certifiable!'
          type: warning
          repeat: false
        context_mapping: {  }
        context_processors:
          message:
            rules_tokens: {  }
          type:
            rules_tokens: {  }
          repeat:
            rules_tokens: {  }
        provides_mapping: {  }
        action_id: rules_system_message

```

---
Tags: 8, rules
---


# Question
Title: Bootstrap dropdown parent link not clickable
This is the first drupal project i'm working on and i'm having the following problem. I have my dropdown menu set up as followed:

The problem is that the parent link "Materialen" is not clickable while the children are. What should i change to be able to click the parent link?

# Answer
> 6 votes
A nice way that work with Drupal 8 would be to override in your subtheme:

```
menu--main.html.twig

```

And remove

```
 data-toggle="dropdown"

```

Cheers

# Answer
> 2 votes
Just remove or comment out from your theme .info file this line:

```
scripts[] = 'bootstrap/js/dropdown.js'

```

It will automatically make navbar dropdown enabled.

# Answer
> 1 votes
Sorry if I'm late but I just discovered after mountains of readings if you take out line 33

```
 $element['#localized_options']['attributes']['data-toggle'] = 'dropdown';

```

of the menu-link.func.php should work

:)

# Answer
> 0 votes
If you are using the Bootstrap theme (or a subtheme of it), you should be able to accomplish this with just some additional CSS.

This Bootply https://www.bootply.com/LcSwSskuR1 provides a nice solution, basically you need to add a :hover to the menu. I believe this works with the Drupal Bootstrap theme:

```
@media screen and (min-width:768px) {
  .navbar-nav .dropdown:hover>.dropdown-menu {
    display:block;margin:0
  }
}

```

You may need to fiddle with the exact @media query you need for your site.

# Answer
> 0 votes
Overide the menu.html.twig and Remove that line {% set link\_attributes = link\_attributes.addClass('dropdown-toggle').setAttribute('data-toggle', 'dropdown') %}

with {% set link\_attributes = link\_attributes.addClass('dropdown-toggle').removeAttribute('data-toggle', 'dropdown') %}

i.e setAttribute('data-toggle', 'dropdown') to removeAttribute('data-toggle', 'dropdown')

---
Tags: theming, navigation
---


title: Login using REST request gives 404

text:
# Question
Title: Login using REST request gives 404
This is so simple login request but cannot figure out why I am getting such error message when trying to login using Postman.

I use url `http://localhost:8080/user/login?_format=json` and input in the header `Content-Type:application/json` and I have in my body `{"name":"user", "pass":"pass"}` but I am getting this error message

> { "message": "The \\"user\\" parameter was not converted for the path \\"/user/{user}\\" (route name: \\"rest.entity.user.GET\\")" }

Using curl works though:

```
curl --header "Content-type: application/json" --request POST --data '{"name":"admin", "pass":"pass"}' http://localhost:8080/user/login?_format=json

```

curl result:

> {"current\_user":{"uid":"1","roles":\["authenticated","administrator"\],"name":"admin"},"csrf\_token":"XXXXX","logout\_token":"XXXXX"}

# Answer
I have faced the same issue and resolved it by selecting "POST" method from dropdown list.

Find the below image:-

**OUTPUT:-** { "current\_user": { "uid": "1", "roles": \[ "authenticated", "administrator" \], "name": "admin" }, "csrf\_token": "XXXXXXXXXXXX", "logout\_token": "XXXXXXXXXXX" }

**Note:** we can get this output for the first time, if we try for the second time we will get message like

> { "message": "This route can only be accessed by anonymous users." }

because postman works as a browser. To get it work for the second time we need to remove the cookie from postman.

Kindly let me know if I am wrong. Thanks..
> 1 votes

# Answer
This works for me (leave it on multiple lines):

```
$ curl --insecure \
  --header "Content-type: application/json" \
  --request POST "https://bo.mywebsite.com:8001/user/login?_format=json" \
  --data '{"name":"admin", "pass":"SuperSecret123&"}'

```

> Note: `--insecure` is used to skip SSL verification.
> 0 votes

---
Tags: users, 8
---


title: Getting translated version of Menu

text:
# Question
Title: Getting translated version of Menu
I'm trying to get translated variant of Manu, but I can't make it work. This is code of what I'm trying to do, but this is for content node.

```
$entitytype_manager = \Drupal::service('entity_type.manager');
$storageNode = $entitytype_manager->getStorage('node');
$node = $storageNode->loadByProperties(['title' => $title_fr]);
$node->getTranslation('fr');

```

Anyone know how I could do this?

**EDIT**

As someone said, I was not clear enough. Above code is working example for content, but I can't figure out how to make analog code to this but for Menu.

# Answer
Use /admin/config/regional/language/detection to set how language is detected. Add the language switcher module someplace to let a user change language. I find that when I switch a language, menu items adjust to the current language. So create the menu item to /somelink and change my language to Japanese, change the link to /ja/somelink when the menu generates again.

I worry about the path you're going down... what if a node hasn't been translated?
> 1 votes

---
Tags: i18n-l10n, navigation
---


title: Cloning entities

text:
# Question
Title: Cloning entities
i have 3 different entities build with help of EntityApi module. They connected with each other with ID column in tables.

```
Entity - "Purchase"
Entity - "Catalog" has 'purchase_id' column in table
Entity - "Product" has 'catalog_id' column in its table.

```

What is the way to clone in one click some already active "Purchase" with all catalogs and product which it ccontains?

# Answer
https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21Entity.php/function/Entity%3A%3AcreateDuplicate/8.2.x

Check that out. You can use it by doing something like:

```
// Load the entity you want.
$entity = \Drupal::entityTypeManager()
 ->getStorage('my_entity')
 ->load('1');

// Copy it.
$duplicate = $entity->createDuplicate();
$duplicate->save();

```
> 1 votes

# Answer
I believe node\_clone can clone entities and their fields for you. There is an API to call it programmatically, or if you have Admin pages created for your entity I believe you can make a "save and clone" or "clone" button show up there.
> 0 votes

---
Tags: entities
---


# Question
Title: Can Drush 9 be used with this core version?
I have a Drupal 7 site that was not built with Composer. I have been using Drush 7 with it, but about a week ago, `drush wd-show --tail` stopped working, I'm not getting any output. I installed Drush 9, but I'm having difficulty configuring it.

I created an XML file, per the example., Instructions say to put aliases in `$PROJECT/drush/sites/self.site.yml` but I don't have a project root with a `composer.json` – can I get this to work without using Composer to build my site? Or is Drush 9 depending on the Drupal site using Composer?

I'm running the local version of the site in MAMP on my Mac. I created `sites/drush/sites/self.site.yml` – it contains:

```
local:
  root: /Users/pglatz/dev/wdocs/wdocs-code/www
  uri: 'https://www.whiskerdocs-local-qa.pglatz.com/'

```

The command I'm using is:

```
$ drush9 @local --alias-path=/Users/pglatz/dev/wdocs/wdocs-code/www/sites/drush/sites --root=/Users/pglatz/dev/wdocs/wdocs-code/www

```

When I run it, I get the error:

> Command wd-show was not found. Pass --root or a @siteAlias in order to run Drupal-specific commands.

But I am passing `--root` and a site alias. Likely a dumb syntax error on my part, but I can't figure it out. What am I doing wrong? And how can I get Drush to be working properly again?

# Answer
> 1 votes
No. Drupal 7 requires Drush 8.

See https://www.drush.org/latest/install/#drupal-compatibility

---

Furthermore, Drush 9 can't be installed globally.

See https://www.drush.org/latest/install/

---
Tags: 7, drush
---


# Question
Title: How do I allow custom .php files to be accessable?
I have already looked at the How do I call legacy PHP files? answers and they didn't fix my problem.

I have a custom php file in my Drupal site (Hosted on Acquia Cloud and I am working on a local version of the site using Acquia Dev Desktop) that needs to be accessable, I added these lines to my .htaccess file trying to allow access to the php file

```
RewriteCond %{REQUEST_URI} !^/learning/
RewriteCond %{REQUEST_URI} !^/learning/sales/[^/]*\.php$
RewriteCond %{REQUEST_URI} !^/learning/sales/index.php
RewriteCond %{REQUEST_URI} !^/learning/sales/ajax/[^/]*\.php$

```

But I still get this response trying to go to the index.php file. "Forbidden You don't have permission to access /learning/sales/ on this server."

How can I fix this?

Note: if I change the file to be index.html it works just fine (well my ajax call in it doesn't work but it atleast loads) but if it is index.php it returns with the 403 error.

# Answer
This should do the trick:

```
 RewriteCond %{REQUEST_URI} !/learning/[^/]*\.php$

```

For more info please look at this thread, unable to run custom php script inside drupal.
> 2 votes

---
Tags: .htaccess
---


title: How to make a lock forget?

text:
# Question
Title: How to make a lock forget?
I understand how locks work, thanks to this post. Very straightforward:

```
function mymodule_long_operation() {
  if (lock_acquire('mymodule_long_operation')) {
    // Do the long operation here.
    // ...
    lock_release('mymodule_long_operation');
  }
}

```

My problem is that my function can get "stuck" if lock\_release is never hit. So how can I get my function to work again if something goes wrong here:

```
function mymodule_long_operation() {
  if (lock_acquire('mymodule_long_operation')) {
    // SOMETHING GOES WRONG HERE!
    lock_release('mymodule_long_operation');
  }
}

```

Yes, I can put the whole function around a try/catch and release the lock in the catch. But as a developer, I often add "die()" in my code when working. So I can easily trigger this function into an unexecutable state.

Is there some way to make the lock expire after a while? Or to make the lock expire as part of some gauranteed garbage collection function?

Any ideas would be highly appreciated! Thanks!

\** UPDATE \**

Nevermind me adding die() in my code. What if the function times out? Then it wont reach the release. I'm sure there are more cases to validate this as a problem.

# Answer
> Is there some way to make the lock expire after a while?

`lock_acquire` takes a second parameter, defining the lifetime of the lock:

https://api.drupal.org/api/drupal/includes%21lock.inc/function/lock\_acquire/7.x

The Drupal 8 version would be:

`lock->acquire($name, $timeout);`

https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Lock%21DatabaseLockBackend.php/function/DatabaseLockBackend%3A%3Aacquire/8.2.x
> 1 votes

---
Tags: 8
---


# Question
Title: Vertical alignment of table content in a view
I have a table view with two columns, one of which contains an image which is quite high.

The text in the second column is relatively brief but is displaying in the vertical centre of its cell (where I would like to align it to the top of the cell).

Is this possible?

# Answer
You'll probably want to set `td {vertical-align: top;}` in your theme css for the cell with text in it.
> 0 votes

# Answer
I have been doing something similar and put this code in each of the cells where I wanted the information top aligned . . .

```
<td style="vertical-align:top">

```

It has worked well for me. Overrides the CSS as I only needed it in select cells.
> 0 votes

---
Tags: views, 8
---


# Question
Title: How do I programmatically close webform by node date field?
**Background:** I'm adding an events (custom content type) & registrations feature to an existing drupal 8 website. *My experience in drupal is pretty minimal.* But I can find my ways around code.

These events can be conferences, seminars, training spanning 1-N days with N number of seats.

**What I have got so far** is creating content type & referencing webform.

**What I want** Ways to disable/close form before event starts or as per a date field (ie, registration will be disabled).

**What I have found** which looks pretty close to what I want

Disable (Close) webform form dynamically

Close a webform when total seats reach a maximum

# Answer
> 0 votes
I haven't tried this module, but you might look at "Scheduled Updates"

Here's a walk through: https://www.mediacurrent.com/blog/scheduling-content-changes-drupal-8/

---
Tags: webforms
---


title: Vanilla Javascript Firing Twice

text:
# Question
Title: Vanilla Javascript Firing Twice
I have some simple dom manipulation I want to make using javascript without jquery. I can't seem to figure out how to prevent this code from firing twice.

Almost all examples I find use jQuery, but I do not want to add jQuery just for this. I'm trying to use es6 with babel here.

```
((() => {
  Drupal.behaviors.node_page_filters_sales = {
    attach: (context, settings) => {

      const usaButton = document.querySelector('[data-sales-switcher="83"]');
      usaButton.style.border = '6px solid orange';
    }
  };
})());

```

This code works, but it is run twice. Once when there selector queried does not exist, giving me a typeError, and one when it does, executing the code as expected.

It seems like it's related to BigPipe. If i turn that off, things seem to work as normal, firing once. But I obviously want BigPipe turned on. I'm clearly missing something that needs to be done when dealing with it.

For a little more detail, this is in a custom module. The custom module creates a block plugin. The javascript (snippet above) is part of the custom module's library that's attached to the block template.

---

UPDATED CODE EXAMPLE

The inline style was just for testing purposes. I'm attempting to check multiple buttons and add/remove classes based on a variable. See below.

```
// Determine default region.
let defaultLocation = '83';

if (defaultLocation === '83') {
    document.querySelector('.tid-83').classList.add('active');
}

```

I also notice that the javascript works as expected and is only executed once if I'm not logged in. When logged in, it fires twice.

# Answer
I don't think you can force javascript to only run once. In addition to big pipe, any lazy loader, ajax form update (consider entity reference fields), or other ajax functionality on the page can trigger javascript to run again.

This is the issue that jQuery.once() addresses, and the reason it is used. It adds a class on the element, then executes on elements that do not have the class and adds the class. I expect you could reproduce this with something like the following.

```
const usaButton = document.querySelector('[data-sales-switcher="83"]');
if (!usaButton.classList.contains('node-page-filters-sales-once') {
  usaButton.style.border = '6px solid orange';
  usaButton.classList.add('node-page-filters-sales-once');
}

```
> 2 votes

---
Tags: 8, javascript
---


# Question
Title: How to have all options of some menu on the same line?
In the mayo theme I use for my site, I have a footer menu.
By default, the options of this menu are displayed vertically:

I'd like to have the options displayed horizontally.
How can I do that?

# Answer
> 1 votes
The HTML code for the menu was:

```
<ul class="menu">
    <li> <a href="/contact">Contact</a> </li>
    <li> <a href="/faq">FAQ</a> </li>
</ul>

```

In the CSS file of my theme, I found `ul.menu` but also `ul.inline`.
Once replaced .menu by .inline in my browser inspector, I had what I expected.
So I digged - a lot - in Twig debug (never could make work either `{{ dump(something) }}` or `{{ kint(something) }}` probably because of memory issues).
I finally used

```
<!-- FILE NAME SUGGESTIONS:
   * menu--footer.html.twig
   x menu.html.twig
-->

```

I duplicated `menu.html.twig` into `menu--footer.html.twig` and replaced
`<ul{{ attributes.addClass('menu') }}>` by `<ul{{ attributes.addClass('inline') }}>`
and voilà !

---
Tags: 8, navigation
---


# Question
Title: hook_form_alter() on a view exposed filter form
I am trying to add a disable attribute in a field using the hook\_form\_id\_alter function. I created a module and built the function

```
function disableIncentiveform_form_views_exposed_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  if ($form['#id'] == 'views-exposed-form-drive-clean-incentive-search-page-1'){
    $form['field_new_used']['#attributes']['disabled'] = 'disabled';
  }
}

```

However, this does not add an attribute to the form.

I know there used to be a hook\_form\_views\_exposed\_form\_alter function in D7 but I can't find anything specific for D8. Is there a correct way to do this?

# Answer
This code should do it:

```
function MYMODULE_form_views_exposed_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  $view_ids = ['YOUR_VIEW_ID'];
  if ($form_id == 'views_exposed_form' && in_array($form_state->get('view')->id(), $view_ids)) {
    $form['field_new_used']['#attributes']['disabled'] = 'disabled';
  }
}

```
> 3 votes

---
Tags: views, 8, forms
---


# Question
Title: How to scan a directory to list all sub folders not files
I have a folder (root folder) with thousands of sub folders and `*.json` files inside sub folders. How can I get list of sub folder names inside folder (root folder) using `file_scan_directory`?

# Answer
> 1 votes
I'd use RecursiveDirectoryIterator for that.

```
$path = '/your/awesome/absolute/path';
$dir = new RecursiveDirectoryIterator($path);
$json_files = new RegexIterator($dir, '/\.json$/');
foreach ($json_files as $file) {
  // Do you stuff here.
  echo "$file";
}

```

# Answer
> 0 votes
If `file_scan_directory` usually returns directories then perhaps you can use the regex mask to search for names that don't have a dot (.) in them.

There are very few files in a Drupal installation that don't have an extension, and I imagine there will be none in your folder structure if all it contains is .json files...

```
file_scan_directory($your_root_folder, '/^[^\.]+$/');

```

The above *should* match all items in the directory structure that don't contain a dot, thanks to this answer.

---
Tags: 7, files
---


# Question
Title: How to send email to submitter in a webform?
I have a webform and i want to send by mail this webform to submitter. For the moment, i created an hidden field with token \[current-user:mail\] and i chose this field in adress. I think it isn't very well. Can I do it in hook\_form\_alter ? if yes, how to do it?

# Answer
> 0 votes
You can set a e-mail field in the webform, whether it is hidden or not is up to you. You should then set the current users e-mail address as the default value. For this, you will need hook\_form\_alter()

```
function YOURMODULE_form_alter(&$form, $form_state, $form_id) {
  //drupal_set_message($form_id); (uncomment this to get form id)
  if ($form_id == 'your_webform_id') {
    global user;
    if ( $user->uid ) { //check user is logged in
    $form['field_email']['und'][0]['value']['#default_value'] = $user->mail;
    }
  }
}

```

# Answer
> 0 votes
In Drupal 8 you can go to webform settings-\> email/handler -\> add email then select current user email address for **To email**.

---
Tags: webforms, emails, forms
---


# Question
Title: How to prevent programmatically created blocks from caching
I've been working with Drupal 7 for a couple of years but am new to Drupal 8, and am just getting into building custom modules.

What I have built is a module that alters Drupal Commerce in order to make it work smoother for sponsoring children (so that it doesn't feel like you are buying children).

It does a couple of things: 1. If you add a second product to the cart, it deletes your old cart. 2. After clicking add to cart, it redirects you to an information page. 3. That page contains a module-generated block with a "continue" button that takes the customer to checkout.

The issue I am hitting is that the code which generates the checkout button block is getting cached, and is pulling an old, no longer existing order ID number.

Is there a way to prevent the block from getting cached, or a better way to programmatically set up a custom block?

Here is my code:

\src\Plugin\Block\ContinueCheckoutBlock.php

```
<?php
/**
 * @file
 * Contains \Drupal\commerce_custom\Plugin\Block\ContinueCheckoutBlock.
 */
namespace Drupal\commerce_custom\Plugin\Block;
use Drupal\Core\Block\BlockBase;
use Symfony\Component\HttpFoundation;

/**
 * Provides a 'Continue Checkout' block.
 *
 * @Block(
 *   id = "continue_checkout",
 *   admin_label = @Translation("Continue Checkout"),
 *   category = @Translation("Continue Checkout Custom Block")
 * )
 */
class ContinueCheckoutBlock extends BlockBase {
  /**
   * {@inheritdoc}
   */

   public function build() {

      $user = \Drupal::currentUser()->id();
        $connection = \Drupal::database();
    $user_ip = \Drupal::request()->getClientIp();
        $query = $connection->query("select * from commerce_order_item join commerce_order on commerce_order_item.order_id = commerce_order.order_id where uid = :user and state = 'draft' and commerce_order.ip_address = :user_ip order by commerce_order.changed asc limit 1", [':user' => $user, ':user_ip' => $user_ip]);
        $result = $query->fetchAll();
        $order_id = $result[0]->order_id;
    drupal_set_message($order_id);

        return array(
            '#type' =>'markup',
            '#markup' => '<a href=checkout/' . $order_id . '/login class=button>Continue</a>',
            '#cache' => array('max_age'=> 0),
        );
   }
}

```

commerce\_custom.module

```
<?php

use Drupal\Core\Form\FormStateInterface;
use Drupal\commerce_order\Entity\Order;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation;

/**
 * Implements hook_form_FORM_ID_alter().
 */
function commerce_custom_form_commerce_order_item_add_to_cart_form_alter(&$form, FormStateInterface $form_state, $form_id) {
   $form['actions']['submit']['#value']='Sponsor';
   $form['#validate'][] = 'commerce_custom_form_validate';
   $form['actions']['submit']['#submit'][] = 'commerce_custom_cart_alter_redirect';
}

function commerce_custom_form_validate(array &$form, FormStateInterface $form_state) {

    $user = \Drupal::currentUser()->id();
    $connection = \Drupal::database();
    $user_ip = \Drupal::request()->getClientIp();
    $query = $connection->query("select * from commerce_order_item join commerce_order on commerce_order_item.order_id = commerce_order.order_id where uid = :user and state = 'draft' and commerce_order.ip_address = :user_ip order by commerce_order.changed desc limit 1", [':user' => $user, ':user_ip' => $user_ip]);
    $result = $query->fetchAll();

    $cart_count = $result[0]->quantity;
    $order_id = $result[0]->order_id;

    if ($cart_count > 0 && $order_id) {
        $order = \Drupal::entityTypeManager()->getStorage('commerce_order')->load($order_id);
        $items = $order->getItems();
        $order->delete();
    }
}

function commerce_custom_cart_alter_redirect(&$form, FormStateInterface $form_state) {
  $responce =  new RedirectResponse('/how-it-works');
  $responce->send();
}

```

# Answer
The bug is in your code. `max_age` should actually be `max-age`.

See the documentation page for more information: https://www.drupal.org/docs/8/api/cache-api/cache-max-age

You could also set the max age in Jdrupal's answer.
> 1 votes

# Answer
```
public function getCacheMaxAge() {
    return 0;
}

```

Add the above code after block's build function.
> 0 votes

---
Tags: commerce
---


title: Today is in list of dates

text:
# Question
Title: Today is in list of dates
Trying to check if variable 'today' is in a list of dates in Views Conditional Field. Both values print out nicely.

Today (var php): 24/06/2019

List of dates (var field\_dates): 24/06/2019, 25/06/2019, 26/06/2019

However; when I to this, it returns false? How come?

```
{% if php in field_dates %}
  True
{% else %}
  False
{% endif %}

```

# Answer
Figured it out. Had to use the `striptags` filter. This works like a charm!

```
{% if php|striptags in field_dates|striptags %}
  True
{% else %}
  False
{% endif %}

```
> 0 votes

---
Tags: views, theming
---


# Question
Title: Is it possible to change the value of the field based on the the browser's language?
On my Drupal 8 website I have a content type "Video" which has an "Embed Code" field. Later the user is able to watch the video inside the platform. The value for this field usually looks like this:

```
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/some_link" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>

```

Is there a way to change the source link based on the language of the browser? So for example when the user browser's language is set to "FR", then I would like to append to the emded link the french captions, so that the link looks following ?

https://www.youtube-nocookie.com/embed/some\_link?cc\_load\_policy=1&cc\_lang\_pref=fr

# Answer
This is the plugin what also core using for browser language negotiation. You can have a closer look what the plugin exactly does: `\Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationBrowser`

**The code**

```
$language_negotiation_method_manager = $this->container->get('plugin.manager.language_negotiation_method');
$plugin_id = LanguageNegotiationBrowser::METHOD_ID;
/** @var \Drupal\language\LanguageNegotiationMethodInterface $language_negotiation_method */
$language_negotiation_method = $language_negotiation_method_manager->createInstance($plugin_id);
$request = $this->container->get('request_stack')->getCurrentRequest();
$browser_langcode = $language_negotiation_method->getLangcode($request);

```

This will either give you back a valid language code or FALSE if the negotiation was unsuccessful.

**Regarding the dependencies**

1. `$container` is only used as an example to show which services are being used.
2. `Request` is always present as an argument when you are in a controller.
> 1 votes

---
Tags: 8
---


title: Force allowed in hook_node_access

text:
# Question
Title: Force allowed in hook_node_access
Is there a way to force node access to allowed if there is a hook in a different module marking it as forbidden?

I have a custom module where i implement hook\_node\_access, returning allowed should certain conditions apply, but the result is being override by a contrib module that sets node access to forbidden.

Can i force my result?

# Answer
> 3 votes
The only way i found to fix this was preventing the conflicting hook from running:

```
function myModule_module_implements_alter(&$implementations, $hook) {

    if ($hook == 'node_access') {

      unset($implementations['conflicting_module']); // Not any more
    }
}

```

As it contains useful functionality, i'm running it in my own code, should my conditions for allowed not apply:

```
function myModule_node_access(NodeInterface $node, $op, AccountInterface $account) {

  if ($account->isAuthenticated() and myConditionIsTrue()) {

      return AccessResult::allowed();
  }

  // Run removed hook

  if (function_exists('conflicting_module_node_access')) {

    return conflicting_module_node_access($node, $op, $account);
  }

  return AccessResult::neutral();
}

```

This is less than ideal and i would prefer an alternative.

# Answer
> 0 votes
I believe it's best to not remove the conflict implementation of the same hook (Unless you REALLY need that and you know what you are doing). Instead you can follow the Drupal documentation of hook\_module\_implements\_alter and move your hook to the end of the implementations list to override the conflict and not ignore it at all.

```
function YOURMODULENAME_module_implements_alter(&$implementations, $hook) {
  if ($hook == 'node_access') {

    // Move my module implementation of node_access to the end of the list.
    // \Drupal::moduleHandler()->getImplementations()
    // iterates through $implementations with a foreach loop which PHP iterates
    // in the order that the items were added, so to move an item to the end of
    // the array, we remove it and then add it.
    $group = $implementations['YOURMODULENAME'];
    unset($implementations['YOURMODULENAME']);
    $implementations['YOURMODULENAME'] = $group;
  }
}

```

---
Tags: 8, users
---


# Question
Title: Hide fields in Paragraphs conditionally using Form API #states
Because the Conditional Fields module doesn't work with paragraphs for Drupal 8, I've followed the instructions in Conditional Fields in Paragraphs Using the Javascript States API for Drupal 8 to hide some paragraphs fields, depending on the value asigned to another field.

But it only works when the dependee field value changes, when the node is edited or when a new paragraph is created, until I change the value in the dependee field manually, the dependent value is always visible.

Does anyone know how can I have those fields hidden when a value is already selected in the dependee field?

# Answer
I had to do something similar for having localized paragraphs for foreign languages with an option to hide the paragraph (until release date).

The paragraph types I needed this I added a "Display Languages" checkboxes field with the options of All, supported languages, Hide. For example, you could create a paragraph and tick the DE option and the Hide option. This paragraph was hidden until the Hide tick mark was removed and then it only showed when the language was DE.

Here's an example of the code I used for my announcement\_banner paragraph type. If you need it for more types, just implement the hook code for that type.

```
/**
 * Implements hook_preprocess_paragraph__announcement_banner().
 *
 * Handles language display for paragraph type.
 *
 * @param array $variables
 */
function MY_MODULE_preprocess_paragraph__announcement_banner(&$variables) {
  $paragraph = $variables['paragraph'];
  if (!MY_MODULE_can_display($paragraph)) {
    $variables['attributes']['style'][] = 'display: none;';
    $variables['content'] = [];
  }
}
/**
 * Checks if a paragraph can be displayed for the current language.
 *
 * @param stdClass $paragraph
 *   The paragraph entity to be tested.
 * @return boolean
 *   True if it can be displayed / False if it can't
 */
function MY_MODULE_can_display( $paragraph ) {
  // Transition check remove once new corporate branding active.
  if (!isset($paragraph->field_display_languages)  || $paragraph->field_display_languages->count() == 0) {
    return TRUE;
  }
  $lang = \Drupal::languageManager()->getCurrentLanguage()->getId();
  $hide = FALSE;
  $allowed = FALSE;
  foreach ($paragraph->field_display_languages as $value ) {
    $langCode = $value->getValue()['value'];
    if ( $langCode == 'hide' ) {
      $hide = TRUE;
    }
    if ( $langCode == 'all'  || $langCode == $lang ) {
      $allowed = TRUE;
    }
  }
  // Hide if hidden option checked.
  if ($hide) {
    return FALSE;
  }
  // Show if nothing is checked or match found.
  return $allowed;
}

```
> 1 votes

---
Tags: 8, forms, paragraphs
---


# Question
Title: Aggregating JavaScript generates errors and breaks JS functionality
My website is working well but I was required to aggregate CSS/JS by enabling the `system.performance.js.preprocess` config key. Once the JS code is within one single file I got some errors that doesn't show up when JavaScript is not aggregated:

```
Uncaught TypeError: Cannot read property 'bindAjaxLinks' of undefined
    at HTMLDocument.<anonymous> (js_gQksidT9DzO4kWsJTVsAaOllA_i35znbvgoaoo5Ut8c.js:579)
    at HTMLDocument.dispatch (js_gQksidT9DzO4kWsJTVsAaOllA_i35znbvgoaoo5Ut8c.js:3)
    at HTMLDocument.q.handle (js_gQksidT9DzO4kWsJTVsAaOllA_i35znbvgoaoo5Ut8c.js:3)
    at Object.trigger (js_gQksidT9DzO4kWsJTVsAaOllA_i35znbvgoaoo5Ut8c.js:4)
    at HTMLDocument.<anonymous> (js_gQksidT9DzO4kWsJTVsAaOllA_i35znbvgoaoo5Ut8c.js:4)
    at Function.each (js_gQksidT9DzO4kWsJTVsAaOllA_i35znbvgoaoo5Ut8c.js:2)
    at r.fn.init.each (js_gQksidT9DzO4kWsJTVsAaOllA_i35znbvgoaoo5Ut8c.js:2)
    at r.fn.init.trigger (js_gQksidT9DzO4kWsJTVsAaOllA_i35znbvgoaoo5Ut8c.js:4)
    at initContextual (js_gQksidT9DzO4kWsJTVsAaOllA_i35znbvgoaoo5Ut8c.js:500)
    at js_gQksidT9DzO4kWsJTVsAaOllA_i35znbvgoaoo5Ut8c.js:532
Uncaught TypeError: $autocomplete.autocomplete is not a function
    at Object.attach (js_gQksidT9DzO4kWsJTVsAaOllA_i35znbvgoaoo5Ut8c.js:899)
    at js_gQksidT9DzO4kWsJTVsAaOllA_i35znbvgoaoo5Ut8c.js:174
    at Array.forEach (<anonymous>)
    at Object.Drupal.attachBehaviors (js_gQksidT9DzO4kWsJTVsAaOllA_i35znbvgoaoo5Ut8c.js:171)
    at js_gQksidT9DzO4kWsJTVsAaOllA_i35znbvgoaoo5Ut8c.js:356
    at HTMLDocument.t (js_BKcMdIbOMdbTdLn9dkUq3KCJfIKKo2SvKoQ1AnB8D-g.js:4)

```

This breaks the entire JS functionality of my site like drop-down menus and slideshows.

I'm using a custom theme based on Acquia's Cog. My theme looks like this:

```
name: 'My Theme'
type: theme
description: 'Custom Cog subtheme for my website.'
core: 8.x
base theme: cog
libraries:
  - mytheme/fonts
  - mytheme/fontawesome
  - mytheme/global_styles
  - mytheme/slick
regions:
...

```

And my theme's libraries file:

```
global_styles:
  css:
    theme:
      css/styles.css: {}
  js:
    js/dist/scripts.js: {}

```

The `js/dist/scripts.js` file is a JS file built with npm and gulp.

I have read in other answers this may be caused of undeclared dependencies since the *undefined* variables could be loading before the Drupal ones. I tried to split it into another library and set dependencies like this:

```
global_scripts:
  js:
    js/dist/scripts.js: {}
  dependencies:
    - core/drupal
    - core/drupalSettings
    - core/jquery
    - core/jquery.once

```

But there's no effect at all. Any hints on how to solve this?

# Answer
This issue is usually -- but not always -- because someone has written Javascript without adding semicolons in the appropriate places. JS is valid without them but only when there is also a line-end at that point. Many JS preprocessors remove line breaks, so making the JS invalid.

This can be resolved by examining the JS source for missing semicolons and adding them; a good JS IDE will be able to guide you as to where.

Another issue that sometimes occurs is when the JS code has not been properly context-wrapped. Drupal standard practice is to include a `function() { js(); code(); here(); } ();` wrapper around code blocks because that limits the scope of names to that block; without it, the scope could be global and thus can be interfered with by other blocks of code.

The Drupal solution, which also solves another problem, is to use the "Drupal.behaviours". construct. Check the Drupal JS files for that string for examples.
> 1 votes

---
Tags: 8, javascript, css-js-aggregation
---


# Question
Title: Update the actual file associated with a file entity while keeping the fid?
Media module provides a generic.png file that it copies into /sites/default/media-icons/generic. That file is used on my site ~300 times, but I'd like to replace it with another PNG. Is it possible to replace the actual file that is associated with that file entity? Ideally I'd keep the generic.png name, but I can use an updated file name if needed.

I've tried simply replacing the file in /sites/default but that had no effect.

# Answer
As @clive noted in the comments, all that is needed is to replace the file itself. We were having some other server issues that were causing the change not to show up. You may need to flush your image styles in order for those to pick up the new image, though.
> 0 votes

---
Tags: media
---


title: jQuery not working

text:
# Question
Title: jQuery not working
I have this code in page.tpl.php which is a link that toggles an option menu and makes the first link "I'm a link" become red:

```
<a href="www.google.com" class="select1">I'm a link</a>
<a href="javascript:void(0);" class="select_button1">Click me!</a>
<br/>
<select class="select2" size="5" style="display:none">
    <option name="test" value="" class="first">Select</option>
    <option name="test" value="" class="">Opt1</option>
    <option name="test" value="" class="">Opt2</option>
</select>

```

Then in template.php I have this code, which injects the script on every page:

```
function basic_preprocess_html(&$variables) {
  drupal_add_js(drupal_get_path('theme', 'basic') . '/js/script.js', array(
    'scope' => 'footer',
    'weight' => '15'
  ));
}

```

Finally, in script.js I have this that I suspect being the culprit:

```
(function ($) {
$('.select_button1').click(function() {
    $('.select1').css('color', 'red');
    $('.select2').toggle();
});
}(jQuery));

```

What's the problem? The problem is that when I click on the "Click me!" link nothing happens..

In JsFiddle it works just fine http://jsfiddle.net/WYm4H/120/

# Answer
> 1 votes
You can achieve this using Drupal.behaviors. Save the following code below into a JS file and add it to your THEMENAME.info file.

```
(function($){

/**
* Change color of link.
*/
Drupal.behaviors.themeChangeColors = {
  attach: function(context, settings) {
    $('.select_button1').click(function() {
      $('.select1').css('color', 'red');
      $('.select2').toggle();
    });
  }
};

})(jQuery);

```

# Answer
> 0 votes
I found what was wrong..Here is how I adapted the code to Drupal.

```
(function ($) {
  Drupal.behaviors.scriptjs =  {
    attach: function(context, settings) {

      $('.select_button1').click(function() {
    $('.select1').css('color', 'red');
    $('.select2').toggle();
});

    }
  };
})(jQuery);

```

Made a "boilerplate" for other people who struggle with this.

```
(function ($) { // <--------------------------- Add
  Drupal.behaviors./* Put the name of your script/module/whatever in place of this comment (if you have no idea the name of the script file should suffice) */ =  { // <---------- this
    attach: function(context, settings) { // <- first

       //Replace this with your jQuery code (leave the rest untouched until necessary!)//

    } // <---------- Add
  }; // <----------- this
})(jQuery); // <---- last

```

# Answer
> 0 votes
Simply use `jQuery` instead `$` For this case jQuery :contains() Selector need use not

```
drupal_add_js('
            $(document).ready(function(){
                $("p:contains(is)").css("background-color", "yellow");
            });
        ', array('type' => 'inline', 'scope' => 'footer', 'defer' => TRUE));

```

but

```
drupal_add_js('
            jQuery(document).ready(function(){
                jQuery("p:contains(is)").css("background-color", "yellow");
            });
        ', array('type' => 'inline', 'scope' => 'footer', 'defer' => TRUE));

```

And not need

```
<script src="https://ajax.googleapis.com

```

---
Tags: 7, javascript
---


# Question
Title: Force one config to be imported before another?
Hitting an issue when installing a site from config and I think the order of operations may be the issue. Is there some way to ensure that one config is imported before another one?

Edit: sorry, guess this wasn't specific enough for some people. Issues are:

* encryption profile set up with the encrypt module/key/real\_aes
* encryption enabled in relaxed module
* error during installation of relaxed config settings because the encryption entities provided by encrypt don't exist yet.
* setting encrypt as a dependency didn't seem to solve my problem
* realizing that maybe I'd need to add real\_aes as a dependency as well

# Answer
> 0 votes
I'm already using Config Split for this site, so as a workaround I've added the problematic dependent config to the various split directories. This seems to have done the trick, but still curious if there are any other methods available.

---
Tags: 8, configuration
---


title: Can't access specific admin pages

text:
# Question
Title: Can't access specific admin pages
I have a Drupal 8 site set up in Docksal. It was version 8.6.15, and needed updates to core and several modules. Bear with me - I don't have complete notes, because I thought everything had worked. I'm more than happy to debug... I just don't know where/how/what to look for in this case.

I would just roll back to a backed up version of the site. But that is missing ( My own fault)

The first problem I encountered, was not being able to update with Drush anymore. So I used composer to to attempt updating, with "composer require drupal/core --update-with-all-dependencies" - this was my first time doing so.

It didn't work. I had to update composer in order to continue on. After using "composer prohibits Drupal/core:8.7.3," I got several results, so I went ahead and updated them. I would tell you all I uploaded, but that was yesterday and I did not save those notes. Sorry. I also did an update of composer itself, all the packages. that appeared out of date. There were a couple that would not update, rejected by constraints.

Updated composer, and Drupal is now 8.7.3. I also did a bunch of module updates on the site as well.

I have an issue where the admin area shows I'm still on Drupal 8.6.15, even though Composer shows the latest version. I assumed this was a separate issue, but maybe it's related. There is an issue with this site being set up with drupal/drupal and not drupal/core. Something to do with the composer json.

Everything seemed fine, but when I tried to navigate to some of the admin pages (Content, Configuration or People page), I get an error:

> **Fatal error: require(): Failed opening required** '/var/www/docroot/vendor/composer/../doctrine/common/lib/Doctrine/Common/Reflection/ClassFinderInterface.php' (include\_path='.:/usr/local/lib/php') in /var/www/docroot/vendor/symfony/class-loader/ApcClassLoader.php on line 112

Not even sure what first steps might be on this. When I type composer outdated, I don't see anything called class-loader or classfinder

Looking at ApcClassLoader.php, I see 'require $file;' on line 112:

```
 public function loadClass($class)
    {
        if ($file = $this->findFile($class)) {
            require $file;

            return true;
        }
    }

```

# Answer
Not sure whether or not this will actually fix your issue, but I'd try:

* update the drupal/core version to in composer.json to be ^8.7.0
* if you're using webflo/drupal-core-require-dev, update that to ^8.7.0 as per https://www.drupal.org/docs/8/update/update-core-via-composer
* run `composer update drupal/core webflo/drupal-core-require-dev --with-dependencies`
* run your database updates, `drush updb` or site.com/update.php

If that still doesn't work, try:

* deleting your vendor directory, core directory, and composer.lock
* run `composer install`
> 1 votes

---
Tags: 8
---


# Question
Title: How to restrict previous date display in custom forms?
I created a custom module for a form which accepts **from date** and **to date** as user input. I would like to restrict the user from selecting a date prior to current date.

**Code snippet of my code**

```
$form['oneway']['from_date'] = array (
  '#type' => 'date',
  '#title' => t('From Date'),
  '#date_year_range' => '-80:0',
  '#required' => TRUE,
);

```

Can someone please help me out?

# Answer
***Approach to get today's date as Minimum date***

Pass the JS options in '`#datepicker_options`'

```
$form['oneway']['from_date'] = array(
  '#title' => t('From Date'),
  '#type' => 'date_popup',
  '#date_format' => 'Y-m-d',
  '#date_year_range' => '-80:0',
  '#required' => TRUE,
  '#datepicker_options' => array(
    'minDate' => 0,
  ),
);

```

> minDate =\> 0 (Sets the min date to today's date)
>
> minDate =\> -1 (Sets the min date to yesterday's date)

More info: http://api.jqueryui.com/datepicker/#option-minDate
> 2 votes

# Answer
```
    $form['oneway']['from_date'] = array(
      '#title' => t('From Date'),
      '#type' => 'datetime',
      '#date_format' => 'Y-m-d',
      '#date_year_range' => '-80:0',
      '#required' => TRUE,
      '#attributes' => [
        'min' =>  \Drupal::service('date.formatter')->format(REQUEST_TIME, 'custom', 'Y-m-d'),
    ],
    );

```

**date\_popup** is not going to work in drupal 8.x, use **datetime**
> 0 votes

---
Tags: forms, 8
---


# Question
Title: AJAX not working in views for anonymous users
I have a view in Drupal 8 with an exposed form with AJAX enabled. It works fine for admin user, but it doesn't for anonymous users.

I have included in my theme libraries file:

```
dependencies:
  - core/drupal.ajax

```

But it's still not working.

# Answer
> 0 votes
Solved.

The problem was that I had a template file for html.html.twig, where the main content was being wrapped in two divs. The problem was that the code

```
<js-bottom-placeholder token="{{ placeholder_token|raw }}">

```

was being wrapped too making the AJAX fail, although I don't know why only for users that were not administrators.

Moving this piece of code to the bottom, just before the closing tag for the body, solves it and everything works fine.

---
Tags: views, 8, ajax
---


# Question
Title: How to delete paragraph when uninstalling the module?
I have been creating the custom module which have the paragraph configuration, when installing the custom module, the paragraph config will be stored in the database and then It will be available in the paragraph types.(/custom\_module/config/install)

When uninstalling the custom module, the paragraph types are not getting uninstalled. By Manually, I am deleting it after the uninstalled.

Is there any possible way to delete the paragraph types when uninstalling the custom module?

Because of this, we are unable to fix some issues

```
Drupal\Core\Database\DatabaseExceptionWrapper: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'field_example_ch_hero_video_target_id' in 'where clause': SELECT 1 AS expression FROM {paragraph_revision__field_example_ch_hero_video} t WHERE field_example_ch_hero_video_target_id IS NOT NULL

```

I have replaced the hero video field with some other machine name. then I could not delete the paragraph or install the module.

Can anyone give some valuable advice?

# Answer
Add this to the relevant config file(s) in config/install:

```
dependencies:
  enforced:
    module:
      - custom_module

```

That will force the config item(s) to be removed when the module is uninstalled.
> 0 votes

---
Tags: 8, configuration, paragraphs, installation
---


# Question
Title: Entity access controler not called from custom route
I define a custom entity named "Politician", where I set the class PoliticianAccessControl as an access handler. This is working fine for the canonical url of the entity set in the following way:

```
entity.politician.canonical:
  path: '/politician/{politician}'
  defaults:
    _controller: '\Drupal\pw_basic\Controller\EntityViewController\PoliticianViewController::view'
    _title_callback: '\Drupal\pw_basic\Controller\EntityViewController\PoliticianViewController::title'
  requirements:
    _entity_access: 'politician.view'

```

See the entity access requirement? Here the method PoliticianAccessControl-\>checkAccess() ist called, everything works just fine.

But when I try the same with another custom route the PoliticianAccessControl class gets not called and I always get an access denied message:

```
entity.politician.about_me:
  path: '/politician/{politician}/about-me'
  defaults:
    _controller: '\Drupal\pw_basic\Controller\PoliticianFrontend\AboutMe::build'
    _title_callback: '\Drupal\pw_basic\Controller\PoliticianFrontend\AboutMe::title'
  requirements:
    _entity_access: 'politician.view'

```

What do I forget?

# Answer
You need to give the router a nudge towards what `$politician` is supposed to be for the automatic up-casting to kick in. There are two ways to do that:

1. Type-hint the variable in the controller method:

```
function build(Politician $politician) {

```

See EntityResolverManager::setParametersFromReflection for details
2. Explicitly set the parameter type in the route config (which is pretty much what the first method does for you)

```
options:
  parameters:
    politician:
      type: 'entity:politician'

```
> 3 votes

# Answer
I guess you need to do a route parameter upcasting:

```
entity.politician.about_me:
  path: '/politician/{politician}/about-me'
  defaults:
    _controller: '\Drupal\pw_basic\Controller\PoliticianFrontend\AboutMe::build'
    _title_callback: '\Drupal\pw_basic\Controller\PoliticianFrontend\AboutMe::title'
  requirements:
    _entity_access: 'politician.view'
  options:
    parameters:
      politician:
        type: entity:politician

```
> 3 votes

---
Tags: 8, entities, routes
---