# Question
Title: Why did my event subscriber suddenly stop working and how can I debug it?
I've been working on a module in which I'm subscribing to commerce\_order.place.post\_transition event. However, it suddenly stopped working. Any ideas how I can debug it? I tried Xdebug but it won't even step in.

PS: Just to be clear, I'm talking about this stage:

Below is my code:

```
<?php

namespace Drupal\aydinlik\EventSubscriber;

use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\user\Entity\User;
use Drupal\commerce_product\Entity\ProductVariation;
use Drupal\state_machine\Event\WorkflowTransitionEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * Assigns the proper subscription when an order is placed.
 */
class OrderPaySubscriber implements EventSubscriberInterface {

  /**
   * Current user account.
   *
   * @var \Drupal\Core\Session\AccountInterface
   */
  protected $current_user;

  /**
   * The entity type manager
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entity_type_manager;

  /**
   * NodeAccessSubscriber constructor.
   *
   * @param \Drupal\Core\Session\AccountInterface $this->current_user
   *   Current user account.
   */
  public function __construct(AccountInterface $current_user, EntityTypeManagerInterface $entity_type_manager) {
    $this->current_user = $this->current_user;
    $this->entity_type_manager = $entity_type_manager;
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    $events = ['commerce_order.place.post_transition' => ['addSubscription', -100]];
    $events = ['commerce_order.place.pre_transition' => ['removeSubscription', -100]];
    return $events;
  }

  /**
   * Adds subscription upon successful payment.
   *
   * @param \Drupal\state_machine\Event\WorkflowTransitionEvent $event
   *   The event we subscribed to.
   */
  public function addSubscription(WorkflowTransitionEvent $event) {
    $dateTime = \DateTime::createFromFormat('Y-m-d',date('Y-m-d'));
    $today = $dateTime->format('Y-m-d');
    $this->current_user = User::load(\Drupal::currentUser()->id());
    /** @var \Drupal\commerce_order\Entity\OrderInterface $order */
    $order = $event->getEntity();
    $order_items = $order->getItems();
    $order_item = reset($order_items);
    $product_variation = $order_item->getPurchasedEntity();
    $sku = $product_variation->getSku();
    $from = ["aylik", "yillik", "-"];
    $to = ["Aylık", "Yıllık", " "];
    $name = ucwords(str_replace($from, $to, $sku));
    $epaper_subscription = $this->entity_type_manager->getStorage('taxonomy_term')->loadByProperties(['name' => 'E-Gazete Aboneliği']);
    $subscription_duration = $this->entity_type_manager->getStorage('taxonomy_term')->loadByProperties(['name' => $name]);
    $this->current_user->field_abonelik_suresi[0] = ['target_id' => reset($subscription_duration)->id()];
    switch ($sku) {
        case 'aylik-abonelik':
            if (!empty($this->current_user->field_abonelik_turu)) {
              unset($this->current_user->field_abonelik_turu);
            }
            $this->current_user->field_abonelik_baslangic_tarihi->value = $today;
            $this->current_user->field_abonelik_bitis_tarihi->value = date('Y-m-d', strtotime('+1 month'));
            $this->current_user->field_abonelik_turu[] = ['target_id' => reset($epaper_subscription)->id()];
            $this->current_user->save();
            break;
        case '3-aylik-abonelik':
            if (!empty($this->current_user->field_abonelik_turu)) {
              unset($this->current_user->field_abonelik_turu);
            }
            $this->current_user->field_abonelik_baslangic_tarihi->value = $today;
            $this->current_user->field_abonelik_bitis_tarihi->value = date('Y-m-d', strtotime('+3 months'));
            $this->current_user->field_abonelik_turu[] = ['target_id' => reset($epaper_subscription)->id()];
            $this->current_user->save();
            break;
        case '6-aylik-abonelik':
            if (!empty($this->current_user->field_abonelik_turu)) {
              unset($this->current_user->field_abonelik_turu);
            }
            $this->current_user->field_abonelik_baslangic_tarihi->value = $today;
            $this->current_user->field_abonelik_bitis_tarihi->value = date('Y-m-d', strtotime('+6 months'));
            $this->current_user->field_abonelik_turu[] = ['target_id' => reset($epaper_subscription)->id()];
            $this->current_user->save();
            break;
        case 'yillik-abonelik':
            if (!empty($this->current_user->field_abonelik_turu)) {
              unset($this->current_user->field_abonelik_turu);
            }
            $this->current_user->field_abonelik_baslangic_tarihi->value = $today;
            $this->current_user->field_abonelik_bitis_tarihi->value = date('Y-m-d', strtotime('+1 year'));
            $earchive_subscription = $this->entity_type_manager->getStorage('taxonomy_term')->loadByProperties(['name' => 'E-Arşiv Aboneliği']);
            $this->current_user->field_abonelik_turu[] = ['target_id' => reset($epaper_subscription)->id()];
            $this->current_user->field_abonelik_turu[] = ['target_id' => reset($earchive_subscription)->id()];
            $this->current_user->save();
        default:
            # code...
            break;
    }
  }

  /*
   * Removes subscription upon pending payment.
   *
   * @param \Drupal\state_machine\Event\WorkflowTransitionEvent $event
   *   The event we subscribed to.
   */
  public function removeSubscription(WorkflowTransitionEvent $event) {
    $this->current_user = User::load(\Drupal::currentUser()->id());
    if ($this->current_user->hasRole('abone')) {
      $this->current_user->removeRole('abone');
      $this->current_user->save();
    }
  }

}

```

# Answer
> 1 votes
You are overriding the array each time in getSubscribedEvents instead of adding entries to it.

It should look more like this:

```
public static function getSubscribedEvents() {
    $events = [];
    $events['commerce_order.place.post_transition'] = ['addSubscription', -100];
    $events['commerce_order.place.pre_transition'] = ['removeSubscription', -100];
    return $events;
  }

```

Or

```
public static function getSubscribedEvents() {
    return [
        'commerce_order.place.post_transition' => ['addSubscription', -100],
        'commerce_order.place.pre_transition' => ['removeSubscription', -100],
    ];
  }

```

Check https://api.drupal.org/api/drupal/vendor%21symfony%21http-kernel%21EventListener%21AbstractSessionListener.php/function/AbstractSessionListener%3A%3AgetSubscribedEvents/9.0.x for an example.

---
Tags: 8, commerce, event-subscribers
---


# Question
Title: Config import same config different position in yml, keeps importing
Best way to describe this is to show image, So this is one example and it keeps happening. I **drush cim** and it imports and then when I do **drush cim** again, it is the same and I can do this 1000 times. Have few of those files

# Answer
> 1 votes
I would typically see this situation when a module adjusts the schema for its config. Usually this would be because they add new config variables or change the existing config variables in some way. Sometimes a module is adding a config schema in the for the first time - they didn't previously have one. Or maybe they're just changing it so it makes more sense. There are any number of reasons they'd change it.

A module will provide an update hook to set new values for any new variables to not break a site. However, the new variables don't always go into the right order in the configuration (they're just being defaulted), it doesn't really matter what order they're in.

However, the config schema will enforce the configuration into a particular format **only** when you export configuration. That is, if you have active configuration, and the variables are in a jumbled order, they'll stay in that order until the configuration is exported (then imported). The export process will export the configuration in a manner that matches the config schema exactly. Then, the next time you import your configuration, the active configuration will be updated to match.

I've only found myself in scenarios like this when I've updated module code and performed the database updates, but forgot to export configuration after the database updates.

---
Tags: 8, configuration
---


title: theme_debug doesn't work

text:
# Question
Title: theme_debug doesn't work
I wrote into my settings.php file (into default.settings.php file too):

```
$conf['theme_debug'] = TRUE;
$settings['theme_debug'] = TRUE;
$settings['theme_auto_reload'] = TRUE;

```

(These files have 777 permission.)

I have the "Theme developer" module.

I cleared all cache.

But the suggestions doesn't appear.

What else should I do?

(I have Drupal 7.)

# Answer
> 0 votes
People have been facing issues with Theme Developer module. If you installed this module just to get template suggestions, you might want to uninstall it and use `theme_debug` (only for d7) variable instead.

Enable this variable by adding `$conf[theme_debug]` to your **settings.php** or `drush vset theme_debug 1`

Then Perform a element inspect (or) view page source to get template suggestions. You may find this article on drupal and the answer in this post helpful- self promoting my answer.

# Answer
> 0 votes
In some installations the minifyhtml module is used. If this is the case, the option “Strip comments from the source HTML” under /admin/config/development/performance/minifyhtml must be deactivated.

---
Tags: 7, theming
---


# Question
Title: How can I have a new dropdown for each entity reference added?
I have a content type with an entity reference to another content type that has over a hundred items. I want to use a dropdown menu to select the entity, since the user won't always know the titles of those entities. However, with so many entities, scrolling through and selecting multiple entities using the Select List widget is not the desired user experience.

Is there a way to make a new field appear per reference, like the autocomplete widget, but with dropdowns?

# Answer
> 0 votes
I would look into the Chosen and/or Select 2 modules. They both work to improve UX for select fields.

I've used the Chosen module multiple times in the past, so that's where I'd lean here. The module improves the UX for users managing multiple selections on a select field. The chosen library alters the UI to allow users to easily select multiple options - it even provides autocomplete functionality to limit the results of the select field.

---
Tags: entities
---


# Question
Title: Which code is responsible for updating the vid field in the node table?
I am working on a project with a non-standard editorial workflow using Drupal 8 and Content Moderation.

The workflow currently has the following states:

* draft
* pre-published
* awaiting review
* published

A content creator can pre-publish a content piece (node), which can then be shared and embedded in other sites, but will not appear on the project's site. For a content to appear on the site and be visible by other users, a review must be requested (put in *awaiting review* state) and then validated by an administrator (put in *published* state). The *pre-published* state does not set the node's status to 1, only the *published* state does so.

This workflow was fairly straightforward to setup, but causes issues with drafts that are created between the *awaiting review* and the *published* states. It is, in fact, important that the author has the possibility to continue working on his content while an old revision is awaiting review. Once approved, it is that old revision that gets published, and a new request for review needs to be submitted if the author wants to publish a more recent revision.

To allow drafts to continue being created, I have forced moderation state changes from *awaiting review* to *published* to not create a new revision using *setSyncing*.

This ensures that new drafts appear in the right order (after the reviewed revision), and can be further edited.

This works fine, but if a draft is created after the revision that is being reviewed, it sometimes becomes the default/current revision. This seems to happen because the *vid* field in the *node* table is not updated when publishing an existing revision. I have tried tracing the code that is responsible for updating the *vid* field in the *node* table using Xdebug, but couldn't.

I know I could eventually update the *node* table directly, but I would hate to have to do that, as I don't know the implications this may have.

Is there an API responsible for letting Drupal if it should update this field or not?

Any help would be highly appreciated!

Below is the custom code responsible for moving a revision from the *awaiting review* to *published* state, which happens in a custom form that inherits from NodeForm:

```
public function save(array $form, FormStateInterface $form_state) {
    /** @var \Drupal\node\NodeInterface $node */
    $node = $this->getEntity();

    $is_default_published = $this->moderationInfo->isDefaultRevisionPublished($node);

    // Prevent the creation of a new revision.
    $node->setSyncing(TRUE);

    // Update moderation state.
    $node->set('moderation_state', 'published');

    if ($form_state->has('original_changed')) {
      // Reset changed time to original value.
      $node->setChangedTime($form_state->get('original_changed'));
    }

    $node->save();

    // Set draft forward revisions as non-default.
    if (!$is_default_published) {
      $vid = $node->getRevisionId();

      /** @var \Drupal\node\NodeStorage $node_storage */
      $node_storage = $this->entityTypeManager->getStorage($node->getEntityTypeId());
      foreach ($node_storage->revisionIds($node) as $revision_vid) {
        if ($revision_vid > $vid) {
          /** @var \Drupal\node\entity\Node $revision */
          $revision = $node_storage->loadRevision($revision_vid);

          if (!$revision->isPublished()) {
            $revision->setSyncing(TRUE);
            $revision->isDefaultRevision(FALSE);

            /** @var \Drupal\Core\Entity\ContentEntityTypeInterface $entity_type */
            $entity_type = $revision->getEntityType();

            // Force updating the "revision_default" flag,
            // it is otherwise only updated for new revisions
            // see \Drupal\Core\Entity\ContentEntityStorageBase::doSave.
            $revision_default_key = $entity_type->getRevisionMetadataKey('revision_default');
            $revision->set($revision_default_key, $revision->isDefaultRevision());

            // NOTE: the vid in the node table is not updated !!

            $revision->save();
          }
        }
      }
    }

    $form_state->setRedirectUrl($this->getCancelUrl());
  }

```

# Answer
To answer my own question, the code responsible for updating the *vid* field in the *node* table is in Drupal\Core\Entity\Sql\SqlContentEntityStorage::doSaveFieldItems.

In my particular case, it's line 937.

To fix my issue, I actually simply needed to add the following line before saving the moderated revision (after `$node->set('moderation_state', 'published')`):

```
$node->isDefaultRevision(TRUE);

```

Although the field *revision\_default* was already set to 1 in the *node\_revision* table, the isDefaultRevision flag needs to be set to TRUE in order for the code in Drupal\Core\Entity\Sql\SqlContentEntityStorage::doSaveFieldItems to update the *node* and *node\_field\_data* tables.
> 1 votes

---
Tags: nodes, workflows
---


# Question
Title: Is there a way to sort view asc or desc using twig
Is there a way to sort view asc or desc using

```
drupal_view('vn', 'vmn', sort order)

```

in twig

or Can sort we views\_embed\_view() in controller

# Answer
One alternative approach is to use the exposed sort options provided by Views. Adding exposed sort options is similar to adding exposed filters:

1. Add a sort option in the *Sort Criteria* section of the View UI. (It's right below the Filter Criteria section)
2. For the sort options you want exposed, check the box to "Expose this sort to visitors, to allow them to change it"

This will expose a select widget to the end user allowing them to choose which of the sort criteria should be used to sort the View. For example, if you choose to expose a Title sort and a Date sort, the end user would see a select field allowing them to choose which sort by Title or sort by Date.

Additionally, you can also expose the sort *order* for your exposed sort items. For example, choose whether it's Title ASC or Title DESC. To do this, open the *Exposed Form \> Settings* options, in the *Advanced* tab, and check the box for "Allow people to choose the sort order".

I'd recommend using these options to interface with the backend view and query. If the UX isn't to your liking, perhaps you could render your own select field on the frontend and then set these default views fields per the value selected in your select field.
> 1 votes

---
Tags: views, theming
---


title: Geolocation open InfoWindow on load

text:
# Question
Title: Geolocation open InfoWindow on load
I can't get my head around the following. I'm using the Geolocation module to show a map on my website and I want the `InfoWindow` to be open by default.

I found that this should be possible by using the following code: `infoWindow.open(map,marker);`

Or as the geolocation module does: `infoWindow.open(that.googleMap);`

But because I don't create the markers and infoWindows I don't know what there name is. I tried figuring it out by looking at the code of the Geolocation module by can't seem to find it out. How do I loop passed all `markers` en `infoWindows` to open them when the map is fully loaded?

# Answer
I did some more digging around in the module and decided to not build to loop but just use the one existing in the module. So I created a patch for Geolocation modules adding this line

```
currentInfoWindow.open(map.googleMap, currentMarker);

```

To line 83 of the `geolocation-marker-infowindow.js` file.
> 0 votes

---
Tags: 8, location
---


title: Migrate Paragraphs from CSV file

text:
# Question
Title: Migrate Paragraphs from CSV file
From the continuation of this question I am trying to import paragraphs into my site using migrate from source csv.

I have a single CSV file where there are various fields from those fields I would like to import three fields into paragraph fields, for this process I have created a paragraph type called as `fup_balance` and it has three fields called as `field_upload` , `field_download` and `field_total` which are of type textfield . Paragraph has limit of one value.

I have written a custom yml for the paragraph migration and included it as dependency in node migration yml but the data is not being imported and paragraph is empty after import.

Can anyone please point out why it is failing to import paragraphs ?

I have referenced this example for creating yml .

My node and paragraph import ymls as follows :

**migration\_examples/migrations/article\_csv\_import.yml**

```
id: article_csv_import
label: Import Articles
migration_group: default
migration_tags:
  - Article CSV Migration

source:
  plugin: 'csv'
  # Full path to the file.
  path: public://subscription-list-small-copy.csv
  # Column delimiter. Comma (,) by default.
  delimiter: ','
  enclosure: '"'
  header_offset: 0
  ids:
    - id
  fields:
    0:
      name: id
      label: 'Id'
    1:
      name: title
      label: 'Title'
    2:
      name: body
      label: 'Post body'
    3:
      name: field_activation_date
      label: 'Activation Date'
    4:
      name: field_expiry_date
      label: 'Expiry Date'
    5:
      name: field_upload
      label: 'FUP Balance Upload'
    6:
      name: field_download
      label: 'FUP Balance Download'
    7:
      name: field_total
      label: 'FUP Balance Total'
process:
  title: title
  body: body
  #activation date of the account.
  field_activation_date:
    -
      plugin: format_date
      from_format: Y-m-d H:i:s
      to_format: 'Y-m-d\TH:i:s'
      from_timezone: 'America/Managua'
      to_timezone: 'UTC'
      source: field_activation_date
  # expiry date of the account.
  field_expiry_date:
    -
      plugin: format_date
      from_format: Y-m-d H:i:s
      to_format: 'Y-m-d\TH:i:s'
      from_timezone: 'America/Managua'
      to_timezone: 'UTC'
      source: field_expiry_date
  # paragraph field.
  field_fup_details:
    -
      plugin: sub_process
      source: field_fup_details
      process:
        target_id:
          -
            plugin: migration_lookup
            migration: fup_balance_csv_import
            source: value
            no_stub: TRUE
          -
            plugin: extract
            index:
              - 0
        target_revision_id: '@target_id'
  type:
    plugin: default_value
    default_value: article

destination:
  plugin: entity:node

migration_dependencies:
  required:
    - fup_balance_csv_import
  optional: { }

```

**migration\_examples/migrations/fup\_balance\_csv\_import.yml**

```
id: fup_balance_csv_import
label: FUP details from CSV
migration_group: default
migration_tags:
  - FUP details CSV Migration

source:
  plugin: 'csv'
  # Full path to the file.
  path: public://subscription-list-small-copy.csv
  # Column delimiter. Comma (,) by default.
  delimiter: ','
  # Field enclosure. Double quotation marks (") by default.
  enclosure: '"'
  # The row to be used as the CSV header (indexed from 0),
  # or null if there is no header row.
  header_offset: 0
  # The column(s) to use as a key. Each column specified will
  # create an index in the migration table and too many columns
  # may throw an index size error.

  ids:
    - id
  fields:
    0:
      name: id
      label: 'Id'
    1:
      name: title
      label: 'Title'
    2:
      name: body
      label: 'Post body'
    3:
      name: field_activation_date
      label: 'Activation Date'
    4:
      name: field_expiry_date
      label: 'Expiry Date'
    5:
      name: field_upload
      label: 'FUP Balance Upload'
    6:
      name: field_download
      label: 'FUP Balance Download'
    7:
      name: field_total
      label: 'FUP Balance Total'

process:
  field_upload: field_upload
  field_download: field_download
  field_total: field_total

destination:
  plugin: entity_reference_revisions:paragraph
  default_bundle: fup_balance

migration_dependencies:
  required: {}
  optional: {}

```

Sample CSV Data : **subscription-list-small-copy.csv**

```
id,title,body,field_activation_date,field_expiry_date,field_upload,field_download,field_total
1,Title 1,Body 1,2012-12-22 2:36:03,2013-01-03 0:00:00,NA,NA,"DATA: NA, TIME: NA"
2,Title 2,Body 2,2013-08-16 0:00:00,2013-09-15 0:00:00,NA,NA,"DATA: NA, TIME: NA"
3,Title 3,Body 3,2013-09-14 0:00:00,2013-10-14 0:00:00,NA,NA,"DATA: NA, TIME: NA"
4,Title 4,Body 4,2014-04-08 0:00:00,2014-04-07 23:59:59,NA,NA,"DATA: NA, TIME: NA"
5,Title 5,Body 5,2014-09-30 0:00:00,2015-03-29 11:00:00,NA,35840.0 MB,"DATA: 35840.0 MB, TIME: NA"
6,Title 6,Body 6,2014-12-09 12:29:00,2015-01-09 12:29:00,NA,40960.0 MB,"DATA: 40960.0 MB, TIME: NA"
7,Title 7,Body 7,2014-12-31 11:08:00,2015-06-26 23:59:59,NA,61440.0 MB,"DATA: 61440.0 MB, TIME: NA"
8,Title 8,Body 8,2015-02-25 19:12:00,2015-08-10 23:59:59,NA,35840.0 MB,"DATA: 35840.0 MB, TIME: NA"
9,Title 9,Body 9,2015-03-01 11:19:00,2015-02-28 23:59:59,NA,35840.0 MB,"DATA: 35840.0 MB, TIME: NA"
10,Title 10,Body 10,2015-03-02 18:01:00,2015-08-20 23:59:59,NA,30720.0 MB,"DATA: 30720.0 MB, TIME: NA"

```

# Answer
Don't set `target_id` and `target_revision_id` to the same value, those are two completely different things: The "id" is constant for the paragraph's lifetime, the "revision\_id" will change every time you update your host node.

Try something like this in your node migration:

```
field_fup_details:
  plugin: sub_process
  source: field_fup_details
  process:
    temp_paragraph_keys:
      plugin: migration_lookup
      migration: fup_balance_csv_import
      source: value
      no_stub: TRUE
    target_id:
      plugin: extract
      source: '@temp_paragraph_keys'
      index:
        - 0
    target_revision_id:
      plugin: extract
      source: '@temp_paragraph_keys'
      index:
        - 1

```
> 1 votes

# Answer
So after further debugging I am able to finally import the paragraph data.

For any one who want to debug whether the paragraph data is being imported or not , create the view for the paragraph items so that you can check imported data as paragraphs doesn't have native way to check the data . Thanks to tip fro here

An also some times you might get unmet dependencies errors while importing the paragraphs. In order to solve that mention dependencies as optional dependencies and import the dependencies first manually by using the the migration import command and then import the parent entities.

And coming to the actual answer how I defined my paragraph fields refer below:

```
 pseudo_field_fup_details:
    plugin: migration_lookup
    migration: fup_balance_csv_import
    source: id  # Unique reference id.
  field_fup_details:
    plugin: sub_process
    source:
      - '@pseudo_field_fup_details'
    process:
      target_id: '0'
      target_revision_id: '1'

```

If anyone got any inputs for the approach please suggest.
> 1 votes

---
Tags: 8, migrations, paragraphs
---


# Question
Title: How to put view results in an entity reference field?
So the scenario is like this: I have to create a "node" which has an entity reference field which can hold multiple values. I am looking for a way to be able to select view results to be stored in the entity reference field and I do not know how to do that in Drupal 8.

For Drupal 7 there was this module which does what I need https://www.drupal.org/project/entityreference\_view\_widget

I have tried doing it the custom way by creating views and placing them on the same page as the node create and then getting the resulting values with ajax to store in the field but I do not believe that is the best way to go about it as it does not seem reliable.

Any advice is appreciated.

# Answer
The closest match to the link you shared is the Entity Browser module.

> Goal of this module is to provide a generic entity browser/picker/selector. It can be used in any context where one needs to select few entities and do something with them.

The module allows you to build your own widgets (similar to the Media Library) to use with entity reference fields or in WYSIWYGs, via integration with the Entity Embed module. You can create widgets with multiple options, an option to create new content (with the entity\_form submodule), and select existing content via view displays.
> 2 votes

---
Tags: 8, views, entities
---


# Question
Title: How can I limit an entity reference selection to a specific field value on the reference
I have a content type `Research` which has a an entity reference type of `People`.

The problem is that I don't want to show ALL people but only people which have a certain value under their field named `type`. I was trying to find it here:  Anyone an idea how to only show a content-type for a certain field value of that content type

# Answer
You can create an Entity Reference display in a view and use that to generate the available options.

1. In your view of choice, create a new display of type *Entity Reference* and configure it so that it only shows the content you want.
2. Navigate back to your field configuration screen (the one in your screenshot) and change *Reference Method* from "Default" to "Views: Filter by an entity reference view" and choose the display you created in step 1.
> 4 votes

---
Tags: entities, 9
---


# Question
Title: Hide comment box from node for Anonymous users
**I am trying to hide the comment box for anonymous users. Anonymous users should only be able to view the comments. How can I hide the comment form?**

# Answer
The comment module provides a permission, "Post comments" (`post comments`). Before using any code option, you should remove that permission for anonymous users.
> 3 votes

# Answer
I added this inside my hook and it worked:

```
if($form_id == 'comment_comment_form')
    {
        if (\Drupal::currentUser()->isAnonymous())
        {
           $form['comment_body']['#access'] = FALSE;
         }

     }

```
> 0 votes

---
Tags: 8, entities, hooks, comments
---


title: How do I theme the contact form?

text:
# Question
Title: How do I theme the contact form?
I am trying to create a contact form for users with username, email, message, and submission button, but I want to customize the structure of the form.

Where do I get the structure of the form to customize it?

Contents of ContributeForm.php:

```
<?php

/**
 * @file
 * Contains \Drupal\contact_form\Form\ContributeForm.
 */

namespace Drupal\contact_form\Form;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\ChangedCommand;
use Drupal\Core\Ajax\CssCommand;
use Drupal\Core\Ajax\HtmlCommand;
use Drupal\Core\Ajax\InvokeCommand;

/**
 * Contribute form.
 */

class ContributeForm extends FormBase implements FormInterface{

    protected $accepted_domains = ['gmail.com', 'yahoo.com'];
    /**
     * {@inheritdoc}
     */
    public function getFormId() {
        return 'contact_form_contribute_form';
    }

    /**
     * {@inheritdoc}
     */

    public function buildForm(array $form, FormStateInterface $form_state) {
        /* $form[ '# attributs'] [ 'class'] [] = 'well white-box';*/
        $form['intro'] = array(
            '#markup' => t('Use this form to send a message to an e-mail address. No spamming!'),
        );
        $form['Full Name'] = array(
            '#type' => 'textfield',
            '#title' => '<label class="control-label" for="input01">'.t('Full Name').'</label>',
            '#required' => TRUE,
           /* '#attributes' => array('class' => 'input-xlarge text-tip'),*/
        );
        $form['email'] = array(
            '#type' => 'email',
            '#title' => $this->t('Email address'),
            '#required' => true,
           /* '#prefix' => '<div class="control-label">',
            '#suffix' => '</div>' */

        );

        $form['Type of feedback'] = array(
            '#type' => 'radios',
            '#title' => $this->t('Feedback'),
            '#description' => t('Type of feedback'),
            '#options' => array(
                t('Comments or suggestions'),
                t('Questions'),
                t('Report a problem(s)'),
                t('Other'),
               /* '#prefix' => '<div class="form-horizontal well">',
                '#suffix' => '</div>'*/
            )
        );
        $form['Subject'] = array(
            '#type' => 'textfield',
            '#title' => $this->t('Subject'),
            '#required' => true,
           /* '#prefix' => '<div class="form-horizontal well">',
            '#suffix' => '</div>'*/
        );
        $form['Your Message'] = array(
            '#type' => 'textarea',
            '#title' => $this->t('Your Message'),
            '#required' => true,
            /*'#prefix' => '<div class="form-horizontal well">',
            '#suffix' => '</div>'*/
        );

        $form['my_captcha_element'] = array(
            '#type' => 'captcha',
            '#captcha_type' => 'recaptcha/reCAPTCHA',
            '#required' => true,
          /*  '#prefix' => '<div class="control-group">',
            '#suffix' => '</div>'*/
        );
       /* $form['actions']['#type'] = 'actions';*/
        $form['actions']['sendt'] = array(
            '#type' => 'submit',
            '#value' => $this->t('Send'),
        );
        $form['actions']['cancel'] = array(
            '#name' => 'op',
            '#type' => 'submit',
            '#value' => t('Cancel'),

        );
        return $form;
    }
    /**
     * {@inheritdoc}
     */

    public function validateForm(array &$form, FormStateInterface $form_state) {
        if (!filter_var($form_state->getValue('email'), FILTER_VALIDATE_EMAIL)) {
            $form_state->setError($form['email'], 'Email address is invalid.');
        }

        if (!$this->validEmailAddress($form_state->getValue('email'))) {
            $form_state->setError($form['email'], 'Sorry, we only accept Gmail or Yahoo email addresses at this time.');
        }
    }

    /**
     * {@inheritdoc}
     */
    public function submitForm(array &$form, FormStateInterface $form_state) {
        foreach ($form_state->getValues() as $key => $value) {
            drupal_set_message($key . ': ' . $value);
        }
    }

    protected function validEmailAddress($email) {
        $domain = explode('@', $email)[1];
        return in_array($domain, $this->accepted_domains);

    }

}

```

# Answer
> 1 votes
Drupal 8 contact forms are completely customizable through the UI. Site builders can use the built-in contact forms or can create new ones. The built-in forms have all the standard fields (Name, Email, Subject and Message) but you can also add any other field you need.

To work with contact forms go to Structure \> Contact forms (admin/structure/contact). Here you can select *Manage fields* to add additional fields, *Manage form display* to select which field are visible on the form, and *Manage display* to customise the appearance of individual fields.

# Answer
> 0 votes
Form alteration is done with implementing hook\_form\_alter() in a custom module.

# Answer
> -1 votes
For this problem I think best solution is use module Webform https://www.drupal.org/project/webform, for me this is one of the best Drupal module. Also for this module you have great documentation and demo examples.

---
Tags: theming, forms, 8
---


# Question
Title: Why cannot I get the value of $form_state['value']['ma_so_thue'] when the form is submitted?
I created a module which uses the following code.

```
function module_template_menu() {
  $items = array();

  $items['them-noi-dung'] = array(
    'title' => t('Khai báo hóa chất'),
    'page callback' => 'drupal_get_form',
    'page arguments' => array('module_template_select_form',2),
    'access callback' => true,
  );

  return $items;
}

function module_template_select_form($form, &$form_state) {
  $form = array();

  $form['select'] = array(
    '#type' => 'radios',
    '#title' =>'Lựa chọn hình thức khai báo',
    '#options' => array(
      '0' => t('Khai báo lần đầu'),
      '1' => t('Đã từng khai báo')
    ),
    '#default_value' => '0',
  );

  $form['ma_so_thue'] = array(
    '#type' => 'textfield',
    '#size' => '20',
    '#title' => 'Vui lòng nhập vào Mã Số Thuế',
    '#states' => array(
      'visible' => array(':radio[name="select"]' => array('value'=>'1')),
    ),
  );

  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Tiếp tục'),
  );

  return $form;
}

function module_template_select_form_submit($form, &$form_state) {
  $select = $form_state['values']['select'];
  $masothue = $form_state['values']['ma_so_thue'];

  if (isset($select)) {
    $masothue = $form_state['values']['ma_so_thue'];
    $form_state['redirect'] = 'node/add/khai-bao-hoa-chat';
  }
}

function module_template_form_alter(&$form, &$form_state, $form_id) {
  $masothue = $form_state['values']['ma_so_thue'];

  if ($form_id == 'khai_bao_hoa_chat_node_form') {
    $form['field_ten_to_chuc']['und'][0]['value']['#default_value'] = $masothue;
  }
}

function module_template_theme($existing, $type, $theme, $path) {
  $items = array();

  $items['khai_bao_hoa_chat_node_form'] = array(
    'render element' => 'form',
    'template' => 'khai-bao-hoa-chat',
    'path' => drupal_get_path('module', 'module_template'),
  );

  return $items;
}

```

Why cannot I get the value of `$form_state['value']['ma_so_thue']` in `module_template_form_alter(&$form, &$form_state, $form_id)` when the form is submitted?

# Answer
> 3 votes
The code you are showing is wrong for two reasons:

* `hook_form_alter()` is invoked for every form Drupal is showing; this includes Drupal core forms, as well as forms implemented by third-party modules. It is not invoked for the forms of your own module. So, you first need to check for which form the hook is being invoked, then you can access the form fields the form of your module is using.
* `hook_form_alter()` is not invoked when the form is submitted, but before the form is rendered. So you cannot use `$masothue = $form_state['values']['ma_so_thue'];` there. You need to add a new submission handler from `hook_form_alter()`, and in that submission handler you can get the submitted values, but then you cannot alter the default value for a form field in a submission handler.

As side note, the first argument of `t()` needs to be a string containing an English phrase, since the purpose of `t()` is to translate a phrase shown in the user interface from English to the language set for the site. The value of `$items['them-noi-dung']['title']` doesn't need to be a translated string, as Drupal core will translate it, but it still needs to contain an English phrase.

# Answer
> 0 votes
Because there is no `$form_state['values']['ma_so_thue']` in `hook_form_alter` (even taught you have Ajax or `#rebuild` it in form validation or you are in edit mode),
if you are in edit mode in `hook_form_alter` you can get value from `$form['ma_so_thue']`. ( dpm it and see what you have there, it will be something like `$form['ma_so_thue']['und']['0']['#value']` )

# Answer
> 0 votes
In hook\_form\_alter you won't get `$form_state['values']['ANYFIELD']`. Try `$form_state['build_info']['args'][0]['ANYFIELD']`.

# Answer
> 0 votes
textfield always use `fieldname->und->0->value->` sequence in array so,try this.. `$form['ma_so_thue']['und'][0]['value']`;

# Answer
> -1 votes
```
$store_name = $form_state->getValue('name')[0]['value'];

```

Some input files are multi-value, so you can just use `getValue('field_name')`.

---
Tags: 7, forms
---


# Question
Title: Hide taxonomy term from a view filter where the filter results are empty
I have several nodes and several taxonomies, but only some nodes have taxonomy relationships.

My problem is that the taxonomy filter shows those terms too which don't have any node relationships at all, example:

So even if I don't have any nodes in "Category 1", the term will show up in the filter.

Is there a way to remove those taxonomy terms from the filter which have no content associated to them?

# Answer
Managed to solve this with the combination of the Search API and Facets modules. Actually, it's not that complicated when you know what to do.

1. Created a search index with the content of the categories.
2. Created a new view with a Filter criteria with Content datasource (Content type).
3. Finally, added a new facet where the source is the view display page I have created, and the field is the category.
> 0 votes

# Answer
In Views, there is an option to specify a relationship and to require that relationship. You can find it in your View's config page, under Advanced. Just add a relationship to your taxonomy vocabulary and check the option to require the relationship.

The screen shot below is from the **Content** view that ships with Drupal 8, which is a great example of how to define a required relationship.
> -1 votes

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


# Question
Title: How can I filter nodes by term (entity reference) with jsonapi?
My nodes contain an entity reference field, **Ref Term**. I want to fetch a list of nodes that have a specific term with jsonapi.

In jsonapi, when I fetch nodes, the field with the taxonomy term reference is returned like this:

```
"field_ref_term": {
"type": "taxonomy_term--my_vocabulary",
"id": "b1a97358-9834-499d-aee0-ebb0302fb2c3"
},

```

So, first, I tried this:

```
/jsonapi/node/my_content_type?filter[field_ref_term]=f9c171db-1a1d-4d9a-bb55-5b0f8b033749

```

However, that gave me an error:

```
"title": "Bad Request",
"status": "400",
"detail": "Invalid nested filtering. The field `field_ref_term`, given in the path `field_ref_term` is incomplete, it must end with one of the following specifiers: `id`.",

```

So I tried adding `[id]`:

```
/jsonapi/node/my_content_type?filter[field_ref_term][id]=f9c171db-1a1d-4d9a-bb55-5b0f8b033749

```

That gave me a different error:

```
"detail": "You must provide a valid filter condition. Check that you have set the required keys for your filter.",

```

So I tried a longer version:

```
/jsonapi/node/my_content_type?&filter[term-filter][condition][path]=field_ref_term&filter[term-filter][condition][id]=f9c171db-1a1d-4d9a-bb55-5b0f8b033749

```

That gave me the first error again. I read the documentation on filtering.

How can I filter my nodes based on which are tagged with a specific taxonomy term? (In my case, each node has one and only one taxonomy term in its entity reference field.)

# Answer
> 2 votes
You were close, but your syntax was off. This is documented further down in your linked page, in the Filter Examples \> Get nodes by a value of a entity reference section.

```
SHORT
filter[uid.id][value]=BB09E2CD-9487-44BC-B219-3DC03D6820CD

NORMAL
filter[author-filter][condition][path]=uid.id
filter[author-filter][condition][value]=BB09E2CD-9487-44BC-B219-3DC03D6820CD

```

So, in your example, you'd need to use:

```
SHORT
/jsonapi/node/my_content_type?filter[field_ref_term.id][value]=f9c171db-1a1d-4d9a-bb55-5b0f8b033749

LONG
/jsonapi/node/my_content_type?filter[term-filter][condition][path]=field_ref_term.id&filter[term-filter][condition][value]=f9c171db-1a1d-4d9a-bb55-5b0f8b033749

```

---
Tags: 8
---


# Question
Title: Locked myself out after enabling misconfigured Google Authenticator
I somehow managed to lock myself out of a Drupal 9 installation after setting up TFA with Google Authenticator login. So, i know my user1 name, my user 1 password, but TFA doesn't allow me backend access, because the app is misconfigured. I still have FTP, DB and SSH access.

I already did this two years ago on another site. That time I added a line to settings.php that granted admin role to anonymous user. But I cannot find this solution anymore.

Any help would make my day!

# Answer
I post this as an answer, because someone might be as stupid as I am :) I browsed various old backups and found the settings.php line that grants admin permissions to anonymous user, and it worked.

If you add:

```
$config['user.role.anonymous']['is_admin'] = 'true';

```

in your settings.php, every anonymous user is admin. That way I could get back into admin panel and uninstall TFA and Google Authenticator. Deleted the line, logged back in as user1 and installed both modules again.

Handy way to do it, if you don't have drush. But not recommended for production sites obviously.
> 6 votes

---
Tags: users, 9
---


# Question
Title: What are my options for a url based cache tag?
I have a controller that serves a path, `/get-messages`, which requires a query argument, `path`. An example request to this path will look like `/get-messages?path=/about/team`.

I have a content type, *Message*. Each message has a textarea field that allows the editor to enter paths that the message should appear on. Example content:

```
/about/team
/about/*

```

With javascript, on page load, I make a request to my controller, e.g. `/get-messages?path=/the/current/path`, to get all messages that should be displayed on the current page.

This all works fine and is no problem. The issue I'm having is with how to cache my responses correctly.

With core's default caching options, I might setup a cache render array like:

```
[
  'keys' => ['my_module_get_messages'],
  'contexts' => ['url.query_args'], // or `url.query_args:path`
  'max-age' = Cache::PERMANENT,
]

```

I can even add any message entities as cache dependencies to make sure their cache tags get added and the cache is broken if they're edited. This also works fine.

The issue I'm having is if someone adds a new message that should display on a path that's already cached, by default, creating the new entity won't clear the cache for any already existing cache entries.

I think I need a cache tag based on my url. Is there an existing cache tag I can use, or do I need to create/manage my own custom tags (as described in Implementing Custom Cache Tags)? Or an alternative caching approach?

# Answer
You could add a listing cache tag for the content type:

```
  'tags' => ['node_list:message'],

```

This cache tag was introduced in Drupal 8.9. See the change record Added an ENTITY\_TYPE\_list:BUNDLE cache tag.
> 6 votes

---
Tags: 8, caching
---


# Question
Title: Adding the category for a custom entity reference field add other fields to the same category
I have a custom entity reference field working well, but once I added the category to it the other entity reference fields appeared in the same category.

Here is my code:

```
/**
 * Plugin implementation of the 'region_token' field type.
 *
 * @FieldType(
 *   id = "region_token",
 *   label = @Translation("Region Token"),
 *   description = @Translation("Region custom token."),
 *   category = @Translation("Tokens"),
 *   default_widget = "region_select_widget",
 *   default_formatter = "region_formatter",
 * )
 */
class RegionToken extends EntityReferenceItem {

```

Any idea about how to fix this?

# Answer
I fixed the problem by adding the following code to the class

```
  /**
   * {@inheritdoc}
   */
  public static function getPreconfiguredOptions() {
    return [];
  }

```
> 2 votes

---
Tags: 8, entities
---


# Question
Title: how to create template suggestion for image like image--NODE-TYPE--VIEW-MODE
I'm trying to create a suggestion like image--NODE-TYPE--VIEW-MODE, but in `mytheme_theme_suggestions_image_alter()` $vars i haven't node related info

thanks for help

# Answer
> 2 votes
In the `hook_theme_suggestions_HOOK_alter` the `$variables` contain only informations about the theme of entity in this case theme image:
From documentation:

> array $variables: An array of variables passed to the theme hook. Note that this hook is invoked before any preprocessing.

if you look at `image_theme` you can find all variables passed `uri`, `title` ...

So to access node related info you can use route params like the following.

```
/**
 * Implements hook_theme_suggestions_HOOK_alter().
 */
function THEME_theme_suggestions_image_alter(array &$suggestions, array $variables) {
  $node = \Drupal::routeMatch()->getParameter('node');
  $suggestions [] = "image__" . $node->bundle();
}

```

**Note:** you can't access to **View mode** in this hook because it's not in the **`$variables`** and also ***`the current view mode is not stored in the node object`***

Take a look at this issue Make the current view mode available on the node object

---
Tags: 8, theming
---


# Question
Title: How can I add Commerce Wishlist share mail template variables from form?
I am trying to add 2 additional form fields to the Wishlist Share form where the user input will be rendered in the email. I have been able to add the fields to the form, but I am not sure how to add the user's input in the email twig template.

Here is how I have updated the form() function:

```
  public function form(array $form, FormStateInterface $form_state) {
    $form['#tree'] = TRUE;
    $form['#attached']['library'][] = 'core/drupal.dialog.ajax';
    // Workaround for core bug #2897377.
    $form['#id'] = Html::getId($form_state->getBuildInfo()['form_id']);

    $form['to'] = [
      '#type' => 'email',
      '#title' => $this->t('Recipient Email'),
      '#required' => TRUE,
    ];

// COMBAK my edit

    $form['sender_name'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Your Name'),
      '#required' => FALSE,
    ];

    $form['sender_message'] = [
      '#type' => 'textarea',
      '#title' => $this->t('Your Message'),
      '#required' => FALSE,
    ];

// COMBAK eo my edit

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  protected function actions(array $form, FormStateInterface $form_state) {
    $actions['submit'] = [
      '#type' => 'submit',
      '#value' => $this->t('Send email'),
      '#submit' => ['::submitForm'],
    ];
    if ($this->isAjax()) {
      $actions['submit']['#ajax']['callback'] = '::ajaxSubmit';
    }

    return $actions;
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    /** @var \Drupal\commerce_wishlist\Entity\WishlistInterface $wishlist */
    $wishlist = $this->entity;
    $to = $form_state->getValue('to');

    // COMBAK: my added vars
    $sender_name = $form_state->getValue('sender_name');
    $sender_message = $form_state->getValue('sender_message');

    $this->wishlistShareMail->send($wishlist, $to, $sender_name, $sender_message);

    $this->messenger()->addStatus($this->t('Shared the wishlist to @recipient.', [
      '@recipient' => $to,
    ]));
    $form_state->setRedirectUrl($wishlist->toUrl('user-form'));
  }

```

This is the function that calls the mailHandler that I have updated:

```
public function send(WishlistInterface $wishlist, $to, $sender_name, $sender_message) {
    $owner = $wishlist->getOwner();

    $subject = $this->t('Check out my @site-name wishlist', [
      '@site-name' => $this->configFactory->get('system.site')->get('name'),
    ]);
    $body = [
      '#theme' => 'commerce_wishlist_share_mail',
      '#wishlist_entity' => $wishlist,
      // COMBAK: my added vars
      '#sender_name' => $sender_name,
      '#sender_message' => $sender_message,
    ];
    $params = [
      'id' => 'wishlist_share',
      'from' => $owner->getEmail(),
      'wishlist' => $wishlist,
    ];

    return $this->mailHandler->sendMail($to, $subject, $body, $params);
  }

```

And this is the preprocees function provided by the commerce wishlist module:

```
function template_preprocess_commerce_wishlist_share_mail(array &$variables) {
  /** @var Drupal\commerce_wishlist\Entity\WishlistInterface $wishlist */
  $wishlist = $variables['wishlist_entity'];
  $wishlist_url = $wishlist->toUrl('canonical', ['absolute' => TRUE]);

  $variables['wishlist_url'] = $wishlist_url->toString();

  // COMBAK: my added vars
  //$sender_name = $variables['sender_name'];
}

```

And finally the twig template for the email itself:

```
{#
/**
 * @file
 * Template for the wishlist share email.
 *
 * Available variables:
 * - wishlist_entity: The wishlist entity.
 * - wishlist_url: The wishlist url.
 *
 * @ingroup themeable
 */
#}
<p>
  {% trans %}Check out my wishlist!{% endtrans %}
</p>

<p>
  {% trans %}I use my wishlist for keeping track of items I am interested in.{% endtrans %} <br>
  {% trans %}To see the list in the store and buy items from it, <a href="{{ wishlist_url }}">click here</a>.{% endtrans %}
</p>

<p>
  {% trans %}Thanks for having a look!{% endtrans %}
</p>

```

I haven't been able to figure out how to access the variables I added to the body\[\] array in the twig template.

Any help would be greatly appreciated.

Thanks!

# Answer
This is probably not the right way to do it, but I included the form data in the $\_SESSION variable as I could not find a more appropriate way.

```
public function submitForm(array &$form, FormStateInterface $form_state) {
    /** @var \Drupal\commerce_wishlist\Entity\WishlistInterface $wishlist */
    $wishlist = $this->entity;
    $to = $form_state->getValue('to');

    // COMBAK: MY CODE
    $_SESSION['sender_data'] = [];

    $sender_data = [
        '#theme' => 'commerce_wishlist_share_mail',
        '#sender_name' => $form_state->getValue('sender_name'),
        '#sender_message' => $form_state->getValue('sender_message')
    ];

    $_SESSION['sender_data'] = $sender_data;
    // COMBAK: EO MY CODE

    $this->wishlistShareMail->send($wishlist, $to);

    $this->messenger()->addStatus($this->t('Shared the wishlist to @sender_name at the following email address: @recipient.', [
      '@recipient' => $to,
      '@sender_name' => $sender_data['#sender_name']
    ]));
    $form_state->setRedirectUrl($wishlist->toUrl('user-form'));
  }

```

```
function template_preprocess_commerce_wishlist_share_mail(array &$variables) {
  /** @var Drupal\commerce_wishlist\Entity\WishlistInterface $wishlist */
  $wishlist = $variables['wishlist_entity'];
  $wishlist_url = $wishlist->toUrl('canonical', ['absolute' => TRUE]);

  $variables['wishlist_url'] = $wishlist_url->toString();

  // COMBAK: MY CODE
  $sender_data = $_SESSION['sender_data'];
  $variables['sender_name'] = $sender_data['#sender_name'];
  $variables['sender_message'] = $sender_data['#sender_message'];
  $_SESSION['sender_data'] = [];
  // COMBAK: EO MY CODE
}

```
> 0 votes

---
Tags: theming, commerce, emails, 9
---


# Question
Title: Commerce framework: How on earth do I offer recurring license subscriptions?
I'm new to the Commerce framework. My goal is to sell licenses to users (via the commerce\_license module). Purchasing a license should grant the user a particular role for the duration of the license.

I need to offer the license in four different versions, described below. I'm struggling to figure out how to accomplish this:

* License is good for one year; does not auto-renew ($99/year)
* License is good for one year; auto-renews each year (via the commerce\_recurring module) ($89/year)
* License is good for one month; does not auto-renew ($9.99/month)
* License is good for one month; auto-renews each month ($8.99/month)

Can someone please explain to me how to implement this, in straightforward, step-by-step terms? What product types, product variation types, products, product attributes, order types, order item types, etc. do I need to create – and how should they be configured?

(My main problem is that I *really* don't understand the relationships between these various objects. I've read the docs. I've watched tutorial videos. I've scrutinized ERDs. I've spent hours experimenting in the Drupal dashboard. I've *tried* to read the code – but it's too convoluted for me. Maybe I'm dumb, but the Commerce framework is *extremely* confusing and counterintuitive.)

I would prefer to avoid any custom code – I just need the simplest solution that will satisfy the above requirements.

Any guidance ?

# Answer
> 1 votes
Commerce License is in alpha. That means it is not generally ready for production use.

Further, Commerce Recurring is in beta, but the module page itself notes, as of January 2021:

> This module is not production ready! Expect pain.

Using these modules now will require writing custom code and debugging; there is no out-of-the-box easy solution at this time.

However, I needed a license solution today, so I decided to implement one in Commerce without using these modules. Here's a rough sketch of how I did it. **Note that I am renewing the subscriptions manually, which is prone to human error; the following flow only provides a UI for users to purchase and configure the period of their subscriptions.**

However, this example will hopefully give you an idea of the large amount of work involved in getting subscriptions set up. It's not easy; if you want something simpler but still not easy, and in which the subscriptions actually recur properly, you could look at Recurly or other SaaS.

1. Add a role, **Premium user**. Give this role the additional permissions that users will purchase.
2. Add a datetime field to the user account, **Subscription expire date**. Add another list text field to the user account, **Subscription type**.
3. Add custom code to restrict permission for the **Subscription expire date** field to admins only.
4. Configure your store + checkout flow in Commerce.
5. Create a product type "My license." Add product variations "One year autorenew," "One month," etc.
6. Add an EventSubscriber to Commerce to automatically set the user account field **Subscription expire date** when the purchase is complete. Also, add a redirect to skip the cart because for individual users, having a cart makes no sense for licenses + I don't want users to purchase multiple subscriptions.

Skipping carts requires this patch in `composer.json`:

```
    "drupal/commerce": {
        "allow order types to have no carts": "https://www.drupal.org/files/issues/2020-10-05/2810723-130.patch"
    },

```

Even with all this effort, **you will still have to renew the subscriptions manually**. I did this by adding a view for the admin of "expiring subscriptions" and then using the token stored in the user account by Commerce Stripe to make the recurring payment.

**Custom EventSubscriber**

Notes about this code: It includes an additional field, a list text field on the user account to let the users change between different subscription types. This allows members to change from a monthly to an annual subscription, or vice versa.

It also assumes that "monthly" subscriptions are always 30 days.

First, **services.yml**:

```
services:
  mymodule_subscriber:
    class: Drupal\MYMODULE\EventSubscriber\MyModuleEventSubscriber
    arguments: ['@request_stack', '@logger.factory', '@datetime.time']
    tags:
      - { name: 'event_subscriber' }

```

And here's the Event Subscriber from **mymodule/src/EventSubscriber/MyModuleEventSubscriber.php**:

```
<?php

namespace Drupal\MYMODULE\EventSubscriber;

use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\Logger\LoggerChannelFactory;
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface;
use Drupal\state_machine\Event\WorkflowTransitionEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Drupal\commerce_cart\Event\CartEntityAddEvent;
use Drupal\commerce_cart\Event\CartEvents;
use Drupal\Core\Url;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;

/*
 * Event Subscriber MyModuleEventSubscriber.
 */
class MyModuleEventSubscriber implements EventSubscriberInterface {

  /**
   * The request stack.
   *
   * @var \Symfony\Component\HttpFoundation\RequestStack
   */
  protected $requestStack;

  /**
   * Logger factory.
   *
   * @var \Drupal\Core\Logger\LoggerChannelFactory
   */
  protected $loggerFactory;

  /**
   * The time service.
   *
   * @var \Drupal\Component\Datetime\TimeInterface
   */
  protected $time;

  /**
   * MyModuleEventSubscriber constructor.
   *
   * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
   *   The request stack.
   * @param \Drupal\Core\Logger\LoggerChannelFactory $logger_factory
   *   The logger factory.
   * @param \Drupal\Component\Datetime\TimeInterface $time
   *   The time service.
   */
  public function __construct(RequestStack $request_stack, LoggerChannelFactory $logger_factory, TimeInterface $time) {
    $this->requestStack = $request_stack;
    // Specify that logs should be for this module.
    $this->loggerFactory = $logger_factory->get('mymodule');
    $this->time = $time;
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    $events = [
      'commerce_order.place.post_transition' => 'postPlaceTransition',
      'mymodule_order.fulfill.post_transition' => 'onFulfillTransition',
      CartEvents::CART_ENTITY_ADD => 'tryJumpToCheckout',
      KernelEvents::RESPONSE => ['checkRedirectIssued', -10],
    ];
    return $events;
  }

  /**
   * Set fields and roles for user accounts that purchase subscriptions.
   */
  public function postPlaceTransition(WorkflowTransitionEvent $event) {
    $order = $event->getEntity();

    $order_type = $order->bundle();

    if ($order_type === 'MYORDERTYPE') {
      $price_monthly = 500;
      $price_annual = 5000;
      $subscription_monthly = 'monthly';
      $subscription_annual = 'annual';
      $customer = $order->getCustomer();

      $total_price_array = $order->get('total_price')->getValue();
      $total_price = intval(round($total_price_array[0]['number']));
      $drupal_now_timestamp = $this->time->getCurrentTime();
      $days_in_month = 30;
      $seconds_in_month = 60 * 60 * 24 * $days_in_month;
      $seconds_in_year = 60 * 60 * 24 * 365;
      $subscription_end_timestamp = '';
      // If the user has already purchased, extend the subscription.
      if ($customer->hasRole('subscriber')) {
        $current_subscription_datetime = $customer->get('field_datetime_sub_end')->value;
        $current_subscription_datetime_object = \DateTime::createFromFormat(DateTimeItemInterface::DATETIME_STORAGE_FORMAT, $current_subscription_datetime);
        $current_subscription_timestamp = $current_subscription_datetime_object->getTimestamp();
        if ($total_price === $price_monthly) {
          $subscription_end_timestamp = $current_subscription_timestamp + $seconds_in_month;
          $customer->set('field_list_text_sub_period', $subscription_monthly);
        }
        elseif ($total_price === $price_annual) {
          $subscription_end_timestamp = $current_subscription_timestamp + $seconds_in_year;
          $customer->set('field_list_text_sub_period', $subscription_annual);
        }
        else {
          $this->loggerFactory->error('Total price was outside the assigned range for subscription. (has subscriber role)');
        }
      }
      // Set the date for a new subscription.
      else {
        // The user is henceforth a subscriber.
        $customer->addRole('subscriber');

        if ($total_price === $price_monthly) {
          $subscription_end_timestamp = $drupal_now_timestamp + $seconds_in_month;
          $customer->set('field_list_text_sub_period', $subscription_monthly);
        }
        elseif ($total_price === $price_annual) {
          $subscription_end_timestamp = $drupal_now_timestamp + $seconds_in_year;
          $customer->set('field_list_text_sub_period', $subscription_annual);
        }
        else {
          $this->loggerFactory->notice('Total price was outside the assigned range for subscription. (no subscriber role)');
        }
      }
      $subscription_end_date_object = new \DateTime();
      $subscription_end_date_object->setTimezone(timezone_open('UTC'));
      $subscription_end_date_object->setTimestamp("$subscription_end_timestamp");
      $subscription_end_date_value = $subscription_end_date_object->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT);
      $customer->set('field_datetime_sub_end', $subscription_end_date_value);

      $customer->save();
    }
  }

  /**
   * Tries to jump to checkout, skipping cart after adding certain items.
   *
   * @param \Drupal\commerce_cart\Event\CartEntityAddEvent $event
   *   The add to cart event.
   */
  public function tryJumpToCheckout(CartEntityAddEvent $event) {
    // $purchased_entity = $event->getEntity();
    // if ($purchased_entity->bundle() === 'training_event') {
    $checkout_url = Url::fromRoute('commerce_checkout.form', [
      'commerce_order' => $event->getCart()->id(),
    ])->toString();
    $this->requestStack->getCurrentRequest()->attributes->set('mymodule_jump_to_checkout_url', $checkout_url);
    // Clear status message "Product added to your cart".
    // @todo fix deprecated code.
    // drupal_get_messages('status');.
  }

  /**
   * Checks if a redirect url has been set.
   *
   * Redirects to the provided url if there is one.
   *
   * @param \Symfony\Component\HttpKernel\Event\FilterResponseEvent $event
   *   The response event.
   */
  public function checkRedirectIssued(FilterResponseEvent $event) {
    $request = $event->getRequest();
    $redirect_url = $request->attributes->get('mymodule_jump_to_checkout_url');
    if (isset($redirect_url)) {
      $event->setResponse(new RedirectResponse($redirect_url));
    }
  }

}

```

---
Tags: 8, commerce
---


# Question
Title: How can I ensure migration YAML files execute in specified dependency order?
## EDIT: To Answer my own question...

I ended up making multiple migration files like this:

1. Node Type A Part 1 (most fields migrated except the ones that need to reference Node Type B)
2. Node Type B
3. Node Type A Part 2 (now you can add the field referencing Node Type B)
4. etc.

Here's a Github link to my finalized set of real-world migration files which illustrate how I broke up my migration into different sequential parts. Good luck!

---

## Original Question:

My Drupal migration yaml files are not being imported in the correct execution order.

I have 8 migration files, most that depend on another file being executed first. I'm using a Google Spreadsheet as the source, and targeting Drupal 8.9+. I have tagged all my dependencies, and all was going well with my test imports (`using drush migrate:import --tag="Rooster Business"`) and the corresponding rollback commands. But at some point, after adding a few fields, the migrations began to fail because they were being executed out of order (particularly my business\_locations and business\_offers migrations).

Here's the exact error:

```
[error]  Migration rooster_node_business_offers did not meet the requirements.
Missing migrations rooster_node_business_location. requirements: rooster_node_business_location.

```

The new fields themselves don't fail, so it's not that (I wouldn't think). I think I have correctly set up the dependencies in all the files, but they are NOT being respected (at least not completely).

**I have tried the following:**

* Alphabetizing all the migration id's and filenames (to order them by desired import execution order).
* Dropping all migration tables from the database and doing full cache refresh
* Changing the last file I want executed (`rooster_node_business_offers`) to use "optional" dependencies instead of "required." (This causes the failure to go away, but then some of the desired field values are missing from the migration).
* Uninstalling and reinstalling the entire custom migration module.
* I've tried just migrating the "last" migration with `drush migrate:import rooster_node_business_offers --execute-dependencies` command which should in theory execute all the files in order as they all depend in a chain on each other. No dice. I get the same error: `[error] Migration rooster_node_business_offers did not meet the requirements...`

None of these attempts have solved the problem. I have a theory that it has something to do with the fields names of the sources (because I think I may have changed a few of them, and have definitely added quite a few). But that still doesn't account for why the migrations are not respecting the dependency order.

**Bottom line: I have two questions:**

1. Why are the last two migration files (rooster\_node\_business\_location & rooster\_node\_business\_offers) not being executed in order by dependency (and how can I fix this)?
2. If that is not an easy to answer question, what is the logic of the "default" ordering, and how can I game that logic so I can still get my migration files to execute in the desired order?

Here is the order I'd LIKE to have the migrations to execute in:

```
rooster_file_bg_photo
rooster_file_logo
rooster_users
rooster_file_logo_to_media
rooster_file_bg_photo_to_media
rooster_node_parent_business
rooster_node_business_location
rooster_node_business_offers

```

And here is the order that they are actually being migrated in (same as the order displayed after entering the `drush ms` command:

```
  Rooster (Rooster)   rooster_file_bg_photo            Idle
  Rooster (Rooster)   rooster_file_logo                Idle
  Rooster (Rooster)   rooster_users                    Idle
  Rooster (Rooster)   rooster_file_logo_to_media       Idle
  Rooster (Rooster)   rooster_file_bg_photo_to_media   Idle
  Rooster (Rooster)   rooster_node_parent_business     Idle
  Rooster (Rooster)   rooster_node_business_offers     Idle
  Rooster (Rooster)   rooster_node_business_location   Idle

```

I've made a repository of my exact migration files (and I've only redacted the Google Spreadsheet URLs). Here are all the migration files on Github.

Thanks in advance for your help!

# Answer
I was able to solve the migration dependency unmet error.

Here is my approach to resolve the issue.

For example you have three migrations `migration_a` , `migration_b` and `migration_c` , and `migration_a` is dependent on `migration_b` and `migration_b` is dependent on `migration_c`.

What you have to do is define `migration_b` as optional dependency in `migration_a` and similarly define `migration_c` as optional dependency in `migration_a` .

Then import the `migration_c` manually first with the command `drush mim migration_c` and later `migration_b` with command `drush mim migration_b` and finally `drush mim migration_a`

Thus you have your migration imported.

Please let me know if you have any additional suggestions to resolve the issue.

---

There are other solutions which are scattered across the drupal.org to resolve the issue but they did not help me to resolve the issue.

1. Name the migrations in the alphabetical order respective to their migration order.
2. Check whether the line is defined `$settings['cache']['default'] = 'cache.backend.null';` relevant bug
> 0 votes

---
Tags: 8, migrations, configuration, importing-exporting
---


# Question
Title: Moved Site - Can't find original CSS for look other than in the ADVAGG
I've inherited a drupal 7(I'm a beginner) site that had ADVagg installed. I added a stanza in my nginx config to take care of those files. What I'm running into is that there is a button on the original site that has a style which only exists in an aggregate file. I can't find it in any other file in the enitre site. The docroot was zipped and sent to me. I'm just a little miffed as to why the site I've unpacked doesn't have the same styles as the one online currently.

I've disabled the ADVAGG as well with no change.

```
###
    ### advagg_css and advagg_js support
    ###
    location ~* files/advagg_(?:css|js)/ {
      gzip_static on;
      access_log  off;
      expires     max;
      add_header  ETag "";
      add_header  Cache-Control "max-age=31449600, no-transform, public";
      try_files   $uri @rewrite;
    }

```

# Answer
> 0 votes
AdvAgg is used to improve the standard Drupal Core aggregation.

Just disabling AdvAgg won't disable aggregation.

You will need to disable CSS aggregation under the Performance settings, then flush caches, and you should be able to inspect the button CSS again.

---
Tags: 7, theming
---


# Question
Title: What is the recommended jQuery and jQuery UI version?
What is the recommended version of jQuery and jQuery UI that I should use on a Drupal 7.77 site?

I know the latest jQuery version is now 3.5.1, but what is the recommended version for a Drupal 7.77 site?

# Answer
There is usually a difference between the front end, and backend.

Some of the core displays rely on an older version of jquery.

If you install the jquery\_update module, you will be able to select different versions for front end and back end - and it will tell which is the default version for Drupal Core.
> 0 votes

---
Tags: 7, javascript
---


# Question
Title: How to programmatically clear library info definition?
Created a dynamic library which attaches some external CSS & JS thru `hook_library_info_build` hook and this depends on a dynamic config values set by a config form. So whenever that config form saved, how can I make sure the library info is up to date and latest? and users don't have to always do a complete cache rebuild.

Additionally is it possible to clear(or rebuild) just one library definition?

# Answer
> 2 votes
Okay, searching thru core services found this. We can clear all the library definitions like this.

```
\Drupal::service('library.discovery')->clearCachedDefinitions();

```

See Drupal Reference of this method: Reference

Calling this function `Clears static and persistent library definition caches.`

---
Tags: hooks
---


# Question
Title: Error during import (The header record must be an empty or a flat array with unique string values)
I want to import some content into my site from a CSV file (bellow) \[the file is originally an .xlsx and I use a online CSV converter to get the CSV file)

```
format,type,name,address,id,ttx
open,semi-transparent,Thomas Chao,,rk39k3as22,coming soon

```

And here's my migration file:

```
id: migrate_content
label: 'Import content from CSV to CMS'
migration_group: migration
source:
  plugin: csv
  # Full path to the file.
  path: '/var/www/html/myproject/web/sites/default/files/migrations/test_1.csv'
  header_offset: 1
  ids: [id]
  keys:
    - id
  constants:
    status: 1
process:
  title:
    plugin: create_title
  field_format: format
  field_type: type
  field_name: name
# field_address: address
  field_ttx: ttx
  status: constants/status
destination:
  plugin: 'entity:node'
  default_bundle: granularity_type
migration_dependencies:
  required: {  }
  optional: {  }

```

When I run `drush migration:import migrate_content`, I get this error.

> The header record must be an empty or a flat array with unique string values.

# Answer
> 1 votes
Ok so the answer was pretty obvious `header_offset` should be `0`

---
Tags: migrations, 9
---


# Question
Title: URL Redirects and Configuration Management
I have installed Drupal's Redirect module to redirect from old URL's to new ones. I have added the required redirects in my local environment, ran `drush cex` but can not see the redirects in the export directory. Are URL redirects are content and not config? Therefore can not be exported via configuration management and have to be added manually per environment?

# Answer
> 1 votes
Yes indeed. If you wish to carry the redirects around you should probably export

Or manually create the file if they are not too many.

I would recommend a csv file. You can check this for reference How do I export the list of URL alias into an excel or csv?

Then I would write a simple drupal migrate process to re import them in any environment. If you use csv file it should be quite simple for the redirects.

---
Tags: redirection, configuration
---


# Question
Title: Change max length of title in a custom block added via a template file
A drupal 7 website has a custom block added via a template file. The block displays previews of article content type belonging to a certain rubric. It uses the following line to do so:

```
$block = module_invoke('views', 'block_view', 'given-block-name'); echo render($block['content']);

```

The articles displayed have their titles truncated at the length of 50 characters. I could not find the number 50 in the files on the hosting, so it should be somewhere in the database, and so somehow changeable via the admin panel. Yet I am having a very hard time finding where to change this number. I have changed the length of the teaser for the article content, but that apparently bears no influence on what is displayed in the given block.

# Answer
> 0 votes
Turns out the setting was hidden block display -\> preview -\> edit directly in preview.

---
Tags: nodes, blocks
---


# Question
Title: Why does the upload progress bar reset at 40% when uploading large files?
I'm uploading a 5 GB file and the upload progress bar resets at 40%.

When it gets to 40% it starts counting again from 0%.

Eventually the file does upload completely but this is not good UX.

I was wondering if any knows how I can make the progress bar reach 100% like it should.

EDIT:

Here are some configuration settings requested in the comments:

```
post_max_size = 6G
upload_max_filesize = 6G
default_socket_timeout = 60
max_execution_time = 7200
max_input_time = 7200

```

This doesn't happen for smaller sized files.

When uploading the 5G file, the file upload does end. It doesn't get to 40% again after it resets to 0. It seems to get stuck at 19%.

All this time the file is being correctly uploaded to the temporary directory like it should. Like when the bar reaches 40% the file will continue to upload the temp file until it reaches the full 5G.

# Answer
> 1 votes
I was able to fix the Upload Progress so that it didn't stop at 40% (2 GB).

This is a temporary fix:

I uncommented the ondrej repo in the sources list (/etc/apt). This gave me access to uploadprogress 1.1.3-3 which has a couple of patches that the PECL repo doesn't have.

Then I got the source code:

```
apt source php7.3-uploadprogress

cd php-uploadprogress-1.1.3

```

And changed:

```
int read_bytes;

```

to:

```
unsigned long int read_bytes;

```

and recompiled from the source:

```
phpize; ./configure; make; make test; sudo make install; sudo service apache2 reload

```

It seems like the references to int were all changed except the reference to `read_bytes`. The maximum value of an `int` is 2GB.

---
Tags: files, 9
---


title: Create taxonomy terms

text:
# Question
Title: Create taxonomy terms
i'm new to drupal (just installed v9) and want to add a bunch of content. like in the question asked years ago (Create taxonomy terms on the fly) i want to add taxonomy terms on the fly while adding new content and not having to add them first in the taxonomy module.

the links provided in the old thread are for v7 and v8 and seem not to work

if the code thats posted there is still a valid solution can one tell me where to add it? thanks

# Answer
As always there is more than one way of doing things in Drupal.

I'll guess that one of the popular ways of solving this problem currently is with the Inline Entity Form module.

Once you have it installed you can go to the "Manage form display" of your Content type and choose the Inline entity form Simple or Complex for your Taxonomy ER field (Complex allows you to also add existing entities, not only create new ones on the fly). Adjust the settings to your needs.
> 1 votes

---
Tags: taxonomy-terms, 9
---


title: Trouble after updating to 2.0

text:
# Question
Title: Trouble after updating to 2.0
I got a notice to update composer to 2.0 today and gave it a try, using "composer self-update --2". Now when I run composer update, I'm seeing this message.

> The "grasmash/composerize-drupal" plugin was skipped because it requires a Plugin API version ("^1.0.0") that does not match your Composer installation ("2.0.0"). You may need to run composer update with the "--no-plugins" option.

I then tried installing colorbox and see "drupal/colorbox": "^1.6" in composer.json, but it does not appear when I refresh the extend page; is this related to the above problem?

Next, I tried updating core from 8.9.6 to 8.9.7, following a message I saw, I tried `composer update drupal/core-recommended --with-dependencies -W --no-plugins` and now I see this message.

```
  Problem 1
    - Root composer.json requires composer/installers ^1.2 -> satisfiable by composer/installers[v1.7.0].
    - composer/installers v1.7.0 requires composer-plugin-api ^1.0 -> found composer-plugin-api[2.0.0] but it does not match the constraint.
  Problem 2
    - composer/installers v1.7.0 requires composer-plugin-api ^1.0 -> found composer-plugin-api[2.0.0] but it does not match the constraint.
    - signature_pad/signature_pad 2.3.0 requires composer/installers ~1.0 -> satisfiable by composer/installers[v1.7.0].
    - signature_pad/signature_pad is locked to version 2.3.0 and an update of this package was not requested.

```

I don't understand all these errors, and I am afraid to do anything else. How do I get out of this without reverting composer to 1.x?

# Answer
> 17 votes
In order to resolve the composer/installers ^1.7 issue you can require composer/installers ^1.9. More details can be found from Drupal's Preparing your site for Composer 2.

```
composer require "composer/installers:^1.9"

```

# Answer
> 4 votes
First of all, instead of being afraid of losing everything, you should **back up your site**.

You should never make changes to composer using the only copy of your site; it's highly unnecessary risk. Always make changes to a copy of the site first.

Next, the warning about the `Plugin API version ("^1.0.0")` means that you need to use Composer 1.x with that plugin; it's not ready for 2.x.

So you have to either update the plugin, remove the plugin, or revert to Composer 1.x.

If you look at the plugin's repo, you see that the current version is still requiring 1.x (as of November 1, 2020). So your choice is to remove the plugin or revert to composer 1.x.

I would try removing the plugin, deleting `composer.lock` and the `vendor` directory, and then running `composer update`.

Or, you can just go back to `Composer 1.x` for now. If you immediately update whenever you get an update notice, you can often have problems like this, so if you're not confident about handling the errors, you can wait awhile until plugins and modules get updated to support new versions.

# Answer
> 4 votes
grasmash/composerize-drupal is used to convert a Drupal site that wasn't created with Composer into a Drupal site managed with Composer.
Once the plugin converted the site, it can be removed. After the plugin is removed, modules and themes must be added with `composer require`, not downloading the archive containing the module/theme files.

If that is the only plugin that isn't compatible with Composer 2.x, you can remove it, as it's not necessary to keep it installed.
Drupal 8.9 is compatible with Composer 2.x; it should not create issues with that Composer version.

---
Tags: composer
---


# Question
Title: How to cache a custom rest resource when using Url::fromUri
I have a custom rest resource that is returning data using new ResourceResponse():

```
$node = Node::load($nid);
$data = load_data('node', $node);
$response = new ResourceResponse($data);
$response->addCacheableDependency($node);
return $response;

```

This works fine, but if I use the function Url::fromUri into the load\_data function I get the error:

```
LogicException: The controller result claims to be providing relevant cache metadata, but leaked metadata was detected. Please ensure you are not rendering content too early.

```

I can get it to work if I use ModifiedResourceResponse instead of ResourceResponse, but as far as I understand this will disable all caching. As this resource might end up getting intensive I want to make sure it is cached - how can I do this?

Many thanks in advance!

# Answer
> 2 votes
This is the answer:

```
Url::fromUri($var)->toString(TRUE)->getGeneratedUrl();

```

Found here: https://www.lullabot.com/articles/early-rendering-a-lesson-in-debugging-drupal-8

---
Tags: 8
---


# Question
Title: Search API Database Search score calculation
I'm trying to understand how the Search API Database Search calculates the score for a search result. I understand Solr uses the Lucene scoring model and there's also command that can be used to output the actual calculation (debugQuery=true).

Is there documentation and/or a debug command I could use to understand how the engine is coming up with the score for a result?

# Answer
> 0 votes
When you use **debugQuery=true** in a query, you can see all debug informations and how solr calculate scores for the result documents.

---
Tags: 8, search
---


# Question
Title: How do I set filters to reset automatically on new search?
I have a search and some filters on a drupal 7 site. If I search a term, for example "stuff", and there are 30 results, I can click a checkbox filter (let's call it FilterA) on the side and narrow my results down. But now if I type "things" in the search bar and submit it, FilterA is still clicked when the results come up. I need for all the filters to be unchecked when I perform a new search. I've gone through I feel every setting in the view and all the search and filter settings and still nothing. Thank you for any help you can provide.

# Answer
To fix this I created a new block and inserted this code:

```
<script>
    //unchecks all checkboxes
    function clearCheckBoxes(){
        var uncheck=document.getElementsByTagName('input');
                    for(var i=0;i<uncheck.length;i++){
                        if(uncheck[i].type=='checkbox'){
                            uncheck[i].checked=false;
                        }
                    }
    }
    //this function makes sure that new searches aren't hindered by filters set for previous searches.
    jQuery(function(){
        if(typeof(Storage) !== "undefined"){
            //retrieve what's in search box and remove whitespace
            var currentsearch = document.getElementById("searchbar").value;
            currentsearch = currentsearch.trim();

            //if search box has a value that differs from the session storage search value then filter checkboxes are unchecked and url is sanitized of categories
            if (currentsearch.length > 0){
                if (sessionStorage.getItem("squery")) {
                    let oldsearch = sessionStorage.getItem("squery");
                    if(currentsearch !== oldsearch){
                        clearCheckBoxes();
                        location.pathname = 'simplepathname';
                    }
                }
                // set session storage search value equal to current value
                sessionStorage.setItem("squery", currentsearch);
            }
        }
    });
</script>

```
> 0 votes

---
Tags: views, search
---


# Question
Title: Unable to get titles to show up as higher priority in search than content
I have a website I am working on that has a TON of content. The client has noticed that when searching for titles in the site search, it seems to prioritize the body content over the title.

So I changed the search index for titles to be fulltext with a boost of 13. With the rendered output set to a boost of 1. Then I reindexed and that didn't fix it. I did a full rebuild of tracking information. Same problem.

I found this article: https://medium.com/@easternstandard/how-to-configure-drupal-8-text-search-to-return-better-more-intuitive-search-results-fe0a78136ad7

And followed the instructions there (pretty much what I had already done) and reindexed. Same issue.

An example of this is that we have an article about the response to covid where the phrase "response to covid" is part of the title. When I search for that phrase I do not see it in any of the first-page search results. It is set to show 20 items. In fact, the article in question doesn't come up until result number 39. None of the prior articles seem to have covid in the title at all. Even searching with quotations makes no difference.

This is currently using the database search/index. I am tempted to implement Solr. But that is a whole-nother ball of wax and I am on a deadline right now.

We are running Drupal 8.9.9 and the Search API 8.x-1.18.

What can I do differently to make it value the title over the rendered content?

# Answer
Make sure your view's topmost sort is set to "Search: Relevance (**desc**)" to sort your results from most relevant to least relevant.

---

Add the "Search: Relevance" field to your displayed fields while configuring your index. You'll see each result's relevance score inline - it's super helpful to see the impact of your various index adjustments. E.g. How much does boosting the title field by `8.0` affect a result's total score.
> 4 votes

---
Tags: 8, database, search
---


# Question
Title: I cannot sign into my drupal site. The login page just refreshes and there are no error messages
I cannot login into any account from the login page. I can get to the admin page by `doing drush user-login` but if I log out of admin and try logging in again, the login page just refreshes and I do not get signed into the account; no errors messages, even if I put in an incorrect username and/or password. After nuking my local repo a couple times, I found out that if I put in the wrong username and/or password or if I log in and out a bunch of times, I will not be able to sign in to any other account. The login page will just refresh.

I tried doing stack traces using `debug_print_backtrace()` in the UserLoginForm.php located in core/modules/user/src/form but my computer just freezes. Normally, when I actually log into an account, the console on the browser under network shows a 303 which redirects, but when I cannot login, that request is not present. I've cleared cache, cleared cookies, tried different browsers, but nothing seems to work. The watchdog log messages just say a session has been started by a user and

`Notice: Undefined index: function in Drupal\Core\Database\Log->findCaller() (line 154 of /app/core/lib/Drupal/Core/Database/Log.php)`.

I'm making a custom theme and module if that helps. Any ideas would be greatly appreciated. Thanks.

# Answer
> 1 votes
So after failing to log in a couple times, drupal will block your ip and makes it so you can't login until some arbitrary amount of time, which explains a lot. To unblock ip addresses use `drush sql-query "delete from flood"` I also did not have the error messages popping up when you put in a wrong password.

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


# Question
Title: Page title and body field of specific page
I have a page--front.html.twig file. I can't figure out how to show a specific node title and body summary on the frontpage with only using twig. I know I can create a view of something like that and show it with: `{{ drupal_view('viewmachinename', 'blockname') }}`, but in my opinion it's a little bit overkill for just showing the title and body of specific node.

Normally I show the current node title and body summary with `{{ node.label }}` and `{{node.body.summary}}`, but I don't know how to show the page title and body summary with an other nid.

I try to show the page title and body summary with `nid 2` on the frontpage.

# Answer
If you must do this in twig only, you can use the drupal\_field() function provided by the Twig Tweak module.

For example, to print the title of node 2:

```
{{ drupal_field('title', 'node', 2) }}

```

Or to print the body field for node 2 using the field's configuration from the teaser view mode:

```
{{ drupal_field('body', 'node', 2, 'teaser') }}

```

Or to print an image field with custom formatter settings:

```
{{ drupal_field('field_image', 'node', 2, {type: 'image_url', settings: {image_style: 'large'}}) }}

```

I'd probably aim to create a custom view mode here and then print the whole view mode as one chunk with the drupal\_entity() function. For example:

```
{{ drupal_entity('node', 2, 'my_custom_view_mode') }}

```
> 1 votes

---
Tags: 8, theming
---


title: Programmatically log in a user

text:
# Question
Title: Programmatically log in a user
I am trying to authenticate users as below. I don't get any error, but it doesn't log in users.

autoLogin.php is located in the root folder. Visiting http://example.com/drupal8/autoLogin.php shows me the *Login required* page every time.

```
use Drupal\Core\DrupalKernel;
use Symfony\Component\HttpFoundation\Request;

$autoloader = require_once 'autoload.php';

$kernel = new DrupalKernel('prod', $autoloader);

$request = Request::createFromGlobals();
$response = $kernel->handle($request);

$uid = 1;
$user = Drupal\user\Entity\User::load(1);
$kernel->prepareLegacyRequest($request);
user_login_finalize($user);
$response->send();
$kernel->terminate($request, $response);

```

# Answer
The code shown in the question would throw an error about `user_login_finalize()` not being defined. The code isn't loading the User module and the `DrupalKernel` class doesn't load any module.

I generally use the code shown in authorize.php as guideline on how to bootstrap and programmatically log in a user. In this case, to programmatically log in the user whose ID is 1, I would use the following code.

```
use Drupal\Core\DrupalKernel;
use Drupal\user\Entity\User;
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Route;

$autoloader = (require_once 'autoload.php');

try {
  $request = Request::createFromGlobals();
  $kernel = DrupalKernel::createFromRequest($request, $autoloader, 'prod');
  $kernel->boot();

  // A route is required for route matching.
  $request->attributes->set(RouteObjectInterface::ROUTE_OBJECT, new Route('<none>'));
  $request->attributes->set(RouteObjectInterface::ROUTE_NAME, '<none>');
  $kernel->preHandle($request);

  if (PHP_SAPI !== 'cli') {
    $request->setSession($kernel->getContainer()->get('session'));
  }
} catch (HttpExceptionInterface $e) {
  $response = new Response('', $e->getStatusCode());
  $response->prepare($request)->send();
  exit;
}

\Drupal::moduleHandler()->addModule('system', 'core/modules/system');
\Drupal::moduleHandler()->addModule('user', 'core/modules/user');
\Drupal::moduleHandler()->load('system');
\Drupal::moduleHandler()->load('user');
if ($account = User::load(1)) {
  \Drupal::currentUser()->setAccount($account);
  // Add your code.
  $response->setStatusCode(200);
  $response->send();
}

```

Since it seems you are trying to access a specific page after logging in the user #1, it's probable you need to change the two lines following the *A route is required for route matching.* comment and use a different route name.
> 1 votes

---
Tags: 8, authentication-authorization, bootstrapping, external-scripts
---


# Question
Title: Can use Webform for add combobox for select language on the site?
I want to know how I can add a combobox to a page. For example, on the front page, I want to add a combobox for selecting the language. I use the default modules for creating multilingual sites. Languages are displayed as a list on the page. I want to display a combobox instead of the extended list.

Can I do this with the Webform module?

# Answer
> 1 votes
No, you can't do this with webform. Webform's purpose is to collect and store user submitted data.

You can create a language dropdown by creating an override template for `links--language-block.html.twig` in your custom theme.

---
Tags: blocks
---


# Question
Title: How to change order of taxonomy terms related to specific node field?
As in question. I have multivalued taxonomy field. Is this possible to control terms weight, which are belongs to specific node field?

As a term weight, I mean weight inside single node. It's just a field value delta.

# Answer
> 1 votes
I found one way to do this. We need to change the taxonomy field widget to autocomplete. Then you can swap the words there, thus changing the delta.

---
Tags: 7, nodes, taxonomy-terms, entities
---


# Question
Title: How do Image Optimize pipelines coexist with core's Image toolkit optimization?
I have the Image Optimize module installed. I've also installed and configured Image Optimize Binaries and Image Optimize reSmush.it.

I've created a simple pipeline that processes an image through reSmush.it's magic, setting the desired quality to 80%. This basic setup allows me to apply an optimization process to images after they have an image style applied. (The Image Optimize module adds an option to the image style creation form to choose your optimization pipeline.)

From my understanding, for any particular image, core's process might look like:

1. Original image uploaded via image field (1200x800px, unoptimized).
2. In my display, I apply the image style to *scale and crop* this image to 300x200px.
3. When this image is accessed, the image is scaled and cropped to 300x200px, and then **core's JPEG quality** would take effect and optimize this cropped image.

With the Image Optimize pipelines, I'm not sure if core's JPEG quality settings are still used: does the image get core's optimization plus the Image Optimize pipeline? or does the Image Optimize pipeline override core's optimization? I can't seem to find an answer to this anywhere. How do these options coexist?

# Answer
> 2 votes
> With the Image Optimize pipelines, I'm not sure if core's JPEG quality settings are still used: does the image get core's optimization plus the Image Optimize pipeline?

Yes

> does the Image Optimize pipeline override core's optimization?

No

According to the module's creator you should set your core's image toolkit to `100%`; otherwise, you will endup with double compression and lower image quality.

---
Tags: 8
---


# Question
Title: Is it possible to dynamically disable a module at runtime?
Background:
I've got a multi-user/multi-channel project. Some channels are "classic" websites, but I've also got a channel that targets a non-interactive TV display. All channels are rendered using Drupal's templating (Technically a "channel" is just a theme, selected by a custom ThemeNegotiator acting on the current subdomain.) The problem is that some modules like e.g. `Google Tag Manager` or `EU Cookie Compliance` are unnecessary and disruptive on my TV channel.

**Is there a simple way to dynamically disable certain modules at runtime?**

The module should not be uninstalled, just inactive/dormant for the current request. I know that I could write module-specific hooks for each module I want to suppress. But I was wondering if - instead of writing a couple of different hooks - there is a single universal shortcut, something like the pseudo-code below:

```
if ($isMyCondition) {
  $modulesToDisable = ['eu_cookie_compliance', 'google_tag', 'foo_module', 'bar_module'];
  foreach ($modulesToDisable as $module) {
    \Drupal::something()->disableModuleForThisRequest($module);
  }
}

```

# Answer
The concept of disabling modules (separate to uninstalling them), did exist in Drupal 7, but it was removed in Drupal 8.

You will either need to uninstall the modules, or find a different way to disable the specific behaviours which are causing you problems, via events/hooks/etc.
> 3 votes

---
Tags: 8, hooks
---


# Question
Title: How can I load a JavaScript file only when a page has an element whose class is "test"?
In my develop process, I meet a scenario: I only want to load a JavaScript file when a page has an element whose class is `test`, so what can I do? How to know a page whether has this element?

# Answer
Well one way would be to just add the script always and check for the existence of test class there.

```
(function ($, Drupal) {
    Drupal.behaviors.tester = {

        attach: function (context) {
           if (context.querySelector('.test')) {
               // Do something
               // Or maybe load another JS file dynamically
           }
        }

})(jQuery, Drupal);

```
> 0 votes

---
Tags: theming, javascript
---