# Question
Title: How do plugins store their configuration/field data?
I'm creating a custom Commerce License and I notice that I'm handling defaultConfiguration(), buildConfigurationForm(), submitConfigurationForm(), and buildFieldDefinitions(), but I cannot figure out where in the database this information is stored. I know that it must exist somewhere as the data loads up when I view the entity, but I cannot seem to find it. It doesn't seem to have anything to do with Configuration that would exist in a sync folder despite the similar names.

I'd assume buildFieldDefinitions() has something to do with it, but I cannot seem to figure out exactly what that method is doing at all.

# Answer
> 1 votes
Sounds like the answer is "the data is probably the config table... but it could also be anywhere else depending on the implementation." In the commerce\_license example I noted, instances of `LicenseTypes` on Product variants get their own entry in `commerce_product_variation__license_type`, where the data for that instance is stored in the `license_type_target_plugin_configration` column. Just like data stored in the `config` table, this is a hex blob which, when decoded, is the config field data as a serialized array.

---
Tags: plugins
---


# Question
Title: Running updatedb fails with UnknownExtensionException error
I am attempting to update my site's database after updating three modules: Configuration Update Base, Search API, and Simple XML Sitemap. Running drush updatedb produces the following error:

```
Drupal\Core\Extension\Exception\UnknownExtensionException: The module devel_generate_example does not exist. [error]in /Applications/MAMP/htdocs/mysite/core/lib/Drupal/Core/Extension/ExtensionList.php:265
Stack trace:#0 /Applications/MAMP/htdocs/mysite/core/lib/Drupal/Core/Extension/ExtensionList.php(579):
Drupal\Core\Extension\ExtensionList->get('devel_generate_...')
#1 /Applications/MAMP/htdocs/mysite/core/includes/update.inc(318):
Drupal\Core\Extension\ExtensionList->checkIncompatibility('devel_generate_...')
#2 /usr/local/Cellar/drush/8.1.12/libexec/commands/core/drupal/update.inc(134): update_get_update_list()
#3 /usr/local/Cellar/drush/8.1.12/libexec/commands/core/core.drush.inc(462): update_main()
#4 /usr/local/Cellar/drush/8.1.12/libexec/includes/command.inc(422): drush_core_updatedb()
#5 /usr/local/Cellar/drush/8.1.12/libexec/includes/command.inc(231): _drush_invoke_hooks(Array, Array)
#6 /usr/local/Cellar/drush/8.1.12/libexec/includes/command.inc(199): drush_command()
#7 /usr/local/Cellar/drush/8.1.12/libexec/lib/Drush/Boot/BaseBoot.php(67): drush_dispatch(Array)
#8 /usr/local/Cellar/drush/8.1.12/libexec/includes/preflight.inc(66):
Drush\Boot\BaseBoot->bootstrap_and_dispatch()
#9 /usr/local/Cellar/drush/8.1.12/libexec/drush.php(12): drush_main()
#10 {main}

```

I have confirmed that Devel and all of its submodules (including devel\_generate and devel\_generate\_example) are installed. I have attempted deactivating, uninstalling, and reinstalling them, but I am still getting the same error. Does this look familiar to anyone?

# Answer
Drupal can't find the module when it's scanning the codebase. You'll have to debug to figure out *why*. Run `drush eval 'print_r(array_map(function ($ext) { return $ext->subpath; }, \Drupal::service("extension.list.module")->getList()));'` to have Drupal dump what *modules it can see* and try see why it can't find the install location location (file permissions?).
> 0 votes

---
Tags: updating
---


# Question
Title: How to check "Show as expanded" by default on the Add menu item page
I need the 'Show as Expanded' checkbox on the Add menu item page to be selected by default.

I created a module, 'expand\_menu\_items', and tried a hook\_form\_alter function to get the id, apparently it's 'menu\_link\_content\_menu\_link\_content\_form'.

I know I'm looking for #default\_value, there are a couple and tried setting them to 'TRUE' but it's not having an effect on the page (xdebug shows the value as true). What could I be doing wrong?

Similar questions exist here:

Here's the function code:

```
function expand_menu_items_form_alter($form, FormStateInterface &$form_state, $form_id) {
if ($form_id == 'menu_link_content_menu_link_content_form') {
    // $form['expanded']['#default_value'] = true; // Doesn't work.
    $form['expanded']['widget']['value']['#default_value'] = true; // Doesn't work either.

}

```

}

Attached below is an image to the form page in question.

# Answer
To set a default value for the menu link entity use hook\_ENTITY\_TYPE\_create:

```
use Drupal\menu_link_content\MenuLinkContentInterface;

/**
 * Implements hook_ENTITY_TYPE_create() for menu_link_content.
 */
function mymodule_menu_link_content_create(MenuLinkContentInterface $menu_link_content) {
  $menu_link_content->expanded->value = 1;
}

```
> 4 votes

# Answer
The "Show as expanded - always" module might be the answer?

https://www.drupal.org/project/show\_as\_expanded\_always
> 0 votes

---
Tags: 8, forms, navigation
---


# Question
Title: Compute values to display on the user profile page based on other user profile field values
I've added fields to user profiles:

* subscriber (yes/no)
* guest subscriber (yes/no)
* print subscription expiration date
* online subscription expiration date

On the user profile page, I want to display things like:

* Because you are a guest subscriber, your subscription never expires.
* Your subscription will expire on `date1` \[the later of the print and online subscription dates\]. Please renew by `date2` for uninterrupted service.
* Your subscription expired `XX days`/`XX weeks`/`XX months` ago on `date`.

These are some examples to give the idea. I need to look at profile field values before the profile is displayed, do some computing, and then add additional, display-only fields to the page or modify the value of existing fields that are displayed on the page.

All I need is a clue about the approach. I already have a custom module, so using something similar to hook\_form\_alter will do nicely. I've read about 20 posts, but none that seem to match.

# Answer
**You can make use of hook\_entity\_extra\_field\_info() . Below is the following code snippet which you can use in your module:**

```
/**
 * Implements hook_entity_extra_field_info().
 */
function my_module_entity_extra_field_info() {
  $extra = array();

    $extra['your_entity']['your_content_type']['display']['my_own_pseudo_field'] = array(
      'label' => t('My own field'),
      'description' => t('This is my own pseudo-field'),
      'weight' => 100,
      'visible' => TRUE,
    );
  }

  return $extra;
}
And you can use hook_ENTITY_TYPE_view
/**
 * Implements hook_ENTITY_TYPE_view().
 */
function my_module_your_entity_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
  if ($display->getComponent('my_own_pseudo_field')) {
      $build['my_own_pseudo_field'] = [
        '#type' => 'markup',
        '#markup' => 'This is my custom content',
    ];
  }
}

```

Please replace the entity and entity type with your requirement. Since it is only for the display this code snippet will work . Clear the cache you will find this field in manage display section .
> 1 votes

---
Tags: 8, users
---


# Question
Title: How to iterate thru a webform checkbox results
How do you iterate thru a webform checkbox array like so :

```
Checkboxes_name :
☒ option 1
☒ option 2

```

`[webform_submission:values:checkboxes_name_:value]` print :

```
option 1, option 2

```

I would like to have

```
- option 1
- option 2

```

I tried something like this and other variants, but no luck :

```
<ul{{ webform_token('[webform_submission:values:checkboxes_name_', webform_submission)}}>
  {% for item in webform_submission.values.checkboxes_name_ %}
    <li>{{ item.value }}</li>
  {% endfor %}
</ul>

```

Thanks for your help

# Answer
> 0 votes
I'm not sure this require a technical answer. We would need more informations about the template you're in.

Usually, when you experience this kind of difficulty to access or decorate data, it means you're at the wrong template level. Manually iterating on elements in a template is not the "Drupal Way".

The rendering engine will do it for you and provide a template name (suggestion, that you could see in the source code with the debug activated)

Check carefully the provided theme suggestions to choose the template in which the actual checkbox is rendered.

Override the template by using a more specific suggestion. Copy the code from the previously used template, you will have to the name and attributes of the checkbox element and it will be much easier to manage the display you want.

---
Tags: webforms
---


# Question
Title: How to get GD2 generate PNG8 when resizing PNG8 images
I have an image field which accepts `jpg, jpeg, png`. I've chosen the `Image style: Medium` on the display of that field. That style is configured at `/admin/config/media/image-styles/manage/medium` and it simply scales the image to 600px width.

On `/admin/config/media/image-toolkit` I can see that GD2 is being used.

My problem is that if the original image on that field is PNG8, the rendered thumbnail (by GD2) is PNG24. This results in much larger file for no reason.

Shouldn't GD2 respect the fact that the source is PNG8? Is there a way to fix this?

# Answer
GD2 indeed doesn't check what palette size is the source image. From `GDToolkit.php`:

```
// Always save PNG images with full transparency.
if ($this->getType() == IMAGETYPE_PNG) {
  imagealphablending($this->getResource(), FALSE);
  imagesavealpha($this->getResource(), TRUE);
}

```

The only way I could hack PNG8 in there was:

```
// Always save PNG images with full transparency.
if ($this->getType() == IMAGETYPE_PNG) {
  imagealphablending($this->getResource(), FALSE);
  imagesavealpha($this->getResource(), TRUE);
  imagetruecolortopalette($this->getResource(), TRUE, 256); // ← hardcoded 256 hack for PNG8
}

```

I couldn't find a way of determining the palette size of the source image. So by leaving that hack of mine in there the risk is that PNG24 source images will be saved in the `styles/` directory as PNG8 files.
> 0 votes

---
Tags: 8
---


# Question
Title: How to get links of translated node edit page in the secondary tabs
In D7, if a node is translated, let say in French and if you are in the entity.node.edit\_form page then you could find 2 secondary tabs: \[French\] and \[English\] pointing to the edit\_form of each language.

To achieve this in D8, I looked at the derivatives, but they are loaded once during cache clear and can't evaluate the current entity.

Following the 4k4 comment I have tried to subclass `LocalTaskDefault` But I am stuck with the following problems:

1-How can I create a route for a defined language (eg: a route to edit a french node)

2-In `.links.task.yml`: should I create as many tabs as there are languages (I don't think so)

Here is my `.links.task.yml`file

```
translated_node_tabs:
  class: Drupal\mymodule\Plugin\Menu\TranslatedNodeTab
  title: 'Translated nodes'
  base_route: entity.node.edit_form
  route_name:  entity.node.edit_form

```

And here is the very beginning of what I have understood from the 4k4 advice

```
class TranslatedNodeTab extends LocalTaskDefault {
  /**
   * {@inheritdoc}
   */
  public function getCacheContexts() {
    return [
        'route'
    ];
  }
  /**
   * {@inheritdoc}
   */
  public function getRouteParameters(RouteMatchInterface $route_match) {
    $current_node = $route_match->getParameter('node');
    if ($current_node instanceof NodeInterface) {
      $nid = $current_node->id();
      return [
          'node' => $nid
      ];
    }
    return [];
  }
}

```

# Answer
> 1 votes
Add a derivative for each language:

*/mymodule/src/Plugin/Derivative/TranslatedNodeTabDeriver.php*

```
<?php

namespace Drupal\mymodule\Plugin\Derivative;

use Drupal\Component\Plugin\Derivative\DeriverBase;
use Drupal\Core\StringTranslation\StringTranslationTrait;

class TranslatedNodeTabDeriver extends DeriverBase {

  use StringTranslationTrait;

  /**
   * {@inheritdoc}
   */
  public function getDerivativeDefinitions($base_plugin_definition) {
    $this->derivatives = [];
    foreach (\Drupal::languageManager()->getLanguages() as $language) {
      $lang_id = $language->getId();
      $this->derivatives[$lang_id] = $base_plugin_definition;
      $this->derivatives[$lang_id]['title'] = $this->t('Translate @language', ['@language' => $language->getName()]);
    }
    return $this->derivatives;
  }

}

```

and then you can get the language id with `$this->getDerivativeId()` in the plugin class:

*/mymodule/src/Plugin/Menu/TranslatedNodeTab.php*

```
<?php

namespace Drupal\mymodule\Plugin\Menu;

use Drupal\Core\Menu\LocalTaskDefault;
use Drupal\Core\Routing\RouteMatchInterface;

class TranslatedNodeTab extends LocalTaskDefault {

  /**
   * {@inheritdoc}
   */
  public function getOptions(RouteMatchInterface $route_match) {
    $options = parent::getOptions($route_match);
    $options['language'] = \Drupal::languageManager()->getLanguage($this->getDerivativeId());
    return $options;
  }

}

```

*/mymodule/mymodule.links.task.yml*

```
translated_node_tabs:
  class: Drupal\mymodule\Plugin\Menu\TranslatedNodeTab
  deriver: Drupal\mymodule\Plugin\Derivative\TranslatedNodeTabDeriver
  base_route: entity.node.canonical
  route_name: entity.node.edit_form

```

---
Tags: 8, navigation
---


# Question
Title: Create nested paragraphs programmatically
Similar to the question here but for D8. I've managed to create the child paragraphs but failing to generate the parent paragraphs and attaching the child to them.

```
$questions = [];

foreach($data['questions'] as $question) {
    $answers = [];
    foreach($question['answers'] as $answer) {
        $correct = $answer['field_correct'] === 'Yes' ? 1 : 0;

        $answers[] = Paragraph::create([
            'type' => 'quiz_answers',
            'field_answer' => $answer['field_answer'],
            'field_correct' => $correct,
        ])->save();
    }

    $questions[] = Paragraph::create([
        'type' => 'quiz_question',
        'field_question' => $question['field_question'],
        'field_answers' => $answers,
    ])->save();
}

$new_submission = Node::create([
    'type' => 'quiz_submissions',
    'title' => 'Quiz Submission',
    'field_quiz' => $data['quizID'],
    'field_question_submission' => $questions,
]);

```

# Answer
`save()` returns the status of the save operation, not the entity. And you probably don't need to save the paragraphs, saving the node should save new paragraphs automatically.

So you can try this version:

```
$questions = [];

foreach($data['questions'] as $question) {
    $answers = [];
    foreach($question['answers'] as $answer) {
        $correct = $answer['field_correct'] === 'Yes' ? 1 : 0;

        $answers[] = Paragraph::create([
            'type' => 'quiz_answers',
            'field_answer' => $answer['field_answer'],
            'field_correct' => $correct,
        ]);
    }

    $questions[] = Paragraph::create([
        'type' => 'quiz_question',
        'field_question' => $question['field_question'],
        'field_answers' => $answers,
    ]);
}

$new_submission = Node::create([
    'type' => 'quiz_submissions',
    'title' => 'Quiz Submission',
    'field_quiz' => $data['quizID'],
    'field_question_submission' => $questions,
]);
$new_submission->save();

```
> 6 votes

---
Tags: paragraphs
---


# Question
Title: Customize Order Items table on admin order screen
On the order edit admin screen at /admin/commerce/orders/270/edit, how do you customize the Order Items table? I've been looking all day and can't figure it out. There's a view that controls this same table on a user's orders tab, but it doesn't seem to affect this screen. All I want to do is add a column for the item's SKU and I would have thought that to be a pretty straightforward change.

Thanks!

# Answer
> 4 votes
I mentioned this above in a comment, but the reason this takes more work than editing a View is because there's no simple way for a field widget to use Views to build part of a form. You can easily use Views to render content, and you can even use Views to construct a complete form, but using it to embed part of a form inside another form is not likely to happen.

There is a more straightforward way to customize the table if you're interested, based on the fact that the Inline Entity Form module gives you two ways to override the fields shown in the table of its "complex" widget.

If you anticipate making more holistic changes to the behavior of the inline form, you might consider setting a custom inline\_form handler for order items via hook\_entity\_type\_alter():

```
use Drupal\custom\Form\CustomOrderItemInlineForm;

/**
 * Implements hook_entity_type_alter().
 */
function custom_entity_type_alter(&$entity_types) {
  $entity_types['commerce_order_item']->setHandlerClass('inline_form', CustomOrderItemInlineForm::class);
}

```

Your handler class would inherit the default OrderItemInlineForm class and override its getTableFields() method to return a different fields array that adds your SKU field in the right place:

```
namespace Drupal\custom\Form;

use Drupal\commerce_order\Form\OrderItemInlineForm;

/**
 * Defines the inline form for order items.
 */
class CustomOrderItemInlineForm extends OrderItemInlineForm {

  /**
   * {@inheritdoc}
   */
  public function getTableFields($bundles) {
    $fields = parent::getTableFields($bundles);

    $fields['sku'] = [
      'type' => 'callback',
      'callback' => 'custom_order_item_sku',
      'label' => t('SKU'),
      'weight' => 2,
    ];

    $fields['unit_price']['weight'] = 3;
    $fields['quantity']['weight'] = 4;

    return $fields;
  }
}

```

Alternately, you can just implement hook\_inline\_entity\_form\_table\_fields\_alter() to do the same thing:

```
/**
 * Implements hook_inline_entity_form_table_fields_alter().
 */
function custom_inline_entity_form_table_fields_alter(&$fields, $context) {
  // Note: you'd want to check the context here to only alter the desired table.
  $fields['sku'] = [
    'type' => 'callback',
    'callback' => 'custom_order_item_sku',
    'label' => t('SKU'),
    'weight' => 2,
  ];

  $fields['unit_price']['weight'] = 3;
  $fields['quantity']['weight'] = 4;
}

```

Note that when you define the field for the Inline Entity Form table to include, since the SKU doesn't come from the order item itself (which is what is rendered in that table), you can't just use the 'field' type - you have to define a custom callback. Your callback is a simple function that can load the purchased entity from the order item, confirm it has a SKU, and then return it for display:

```
/**
 * Returns the SKU for the product referenced by an order item.
 */
function custom_order_item_sku($entity, $variables) {
  // Extract the purchased entity from the order item.
  $purchased_entity = $entity->getPurchasedEntity();

  // If the purchased entity couldn't be loaded or doesn't have a SKU...
  if (!$purchased_entity || !$purchased_entity->hasField('sku')) {
    // Return a placeholder string.
    return '-';
  }
  else {
    // Otherwise, return the SKU itself.
    return $purchased_entity->getSku();
  }
}

```

I tested this myself locally and it worked like a charm. : )

# Answer
> 0 votes
OK, this was far more challenging that I would have ever imagined it would be. I'm posting what I did here in case it helps anyone, but if you have the easy way to do this that I just completely failed to see, by all means share. Thanks!

First, I had to add a hook\_form\_alter to add a 'purchased\_entity' field to the table:

```
/**
 * Implements hook_form_alter().
 */
function mymodule_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id){
  switch($form_id){
    case 'commerce_order_[order_type]_edit_form':
      $form['order_items']['widget']['entities']['#table_fields']['purchased_entity'] = [
        'type' => 'field',
        'label' => 'SKU',
        'weight' => 1,
      ];
      break;
  }
}

```

Then, I had to modify that field. This could be done with a twig template or hook in the theme, but I just kept the hook in the same module. I also checked for a specific order type - you could leave that out if you only have one type.

```
/**
 * Implements hook_preprocess_HOOK() for field.
 */
function mymodule_preprocess_field__purchased_entity(&$vars) {
  $route = \Drupal::routeMatch();
  if($route->getRouteName() != 'entity.commerce_order.edit_form'){
    return;
  }
  $sku = '';
  try {
    $oi = $vars['element']['#object'];
    if ($oi->getOrder()->bundle() != [order_type]) {
      return;
    }
    $sku = $vars['element']['#object']->purchased_entity->referencedEntities()[0]->sku->value;
  }
  catch (Exception $ex){
    \Drupal::logger('mymodule')->error($ex->getMessage());
  }
  $vars['items'][0]['content'] = $sku;
}

```

---
Tags: 8, commerce
---


# Question
Title: How can I embed a view in a template when passing view name and parameters are passed as variables?
Inside my paragraph template I have variables which contain category id and view machine name. So when I print them like this:

```
  {{ content.field_category }}
  {{ content.field_view }}

```

I get correct values.

Then I'm using twig tweak to embed view and if I embed it with hard-coded values, like this:

```
  {{ drupal_view('view_machine_name', 'embed_1', 33) }}

```

it also works. I hard-coded the same values my variables display from above.

Now I want to use my field values instead of hard-coded values:

```
{{ drupal_view(content.field_view, 'embed_1', content.field_category) }}

```

I get error like:

```
Warning: array_flip(): Can only flip STRING and INTEGER values! in Drupal\Core\Entity\EntityStorageBase->loadMultiple() (line 266 of core/lib/Drupal/Core/Entity/EntityStorageBase.php). Warning: Illegal offset type in isset or empty in Drupal\Core\Entity\EntityStorageBase->load() (line 251 of core/lib/Drupal/Core/Entity/EntityStorageBase.php).

```

when I try to replace view parameter and:

```
InvalidArgumentException: Placeholders must have a trailing [] if they are to be expanded with an array of values. in Drupal\Core\Database\Connection->expandArguments() (line 738 of core/lib/Drupal/Core/Database/Connection.php).

```

When I try to replace category parameter.

I guess that `content.field_category` is not an int value and `content.field_view` is not an string, as this twig filter expects but I have no idea how to convert them to those primitive types?

Tried `intval` \- it's not working

Tried `number_format` \- also not working

I guess I would have to somehow get view machine name and category id directly from those objects but I don't know how to achieve that.

Tried `content.field_category.id()` and `content.field_view.id()`

Nothing works.

# Answer
> 0 votes
Try to avoid using `{{ content }}` this way. The position you have found in the render array in your last comment can change anytime when reconfiguring the paragraph type or when installing/updating code. Render arrays are not APIs and they are only required to have valid renderable child elements at the lowest level, but not a fixed structure.

The Entity API on the other hand, which you would use to access `{{ paragraph }}` in a paragraph template, does not change, at least not without a transition period while you can still use a deprecated API.

Example:

```
// field value like string or number
{{ paragraph.field_example.value }}

// target id of a reference field
{{ paragraph.field_reference.target_id }}

```

See also https://drupal.stackexchange.com/a/263285/47547.

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


# Question
Title: How to restrict access to files to files of a node while keeping the node itself viewable?
I'm writing a module that allows users to configure special access restrictions on nodes to reflect academic publishing agreements (called 'embargoes'), which are stored in a custom config entity that points to a node and describes what types of access restrictions should be applied, and who is exempt (users, roles, IP ranges, etc). One of the requirements for the module is that users should be able to restrict access to the entire node (a "node embargo"), OR just the files on the node (a 'file embargo') so that the node itself is accessible and shows up in searches, but the files associated with it are not accessible.

I have implemented the 'node embargo' portion of the module using `hook_node_access` and checking a custom service to determine if the user should see the node or not, and returning `\Drupal\Core\Access\AccessResult::forbidden()` if they shouldn't. This works exactly as desired, and not only blocks access to viewing the node, but also access to the files associated with the node.

```
function embargoes_node_access(\Drupal\node\NodeInterface $node, $op, \Drupal\Core\Session\AccountInterface $account) {
  $nid = $node->id();
  $ip = \Drupal::request()->getClientIp();
  $embargoes = \Drupal::service('embargoes.embargoes')->getActiveNodeEmbargoesByNode($nid, $ip, $account);
  if (!empty($embargoes)) {
    $access = \Drupal\Core\Access\AccessResult::forbidden();
  }
  else {
    $access = \Drupal\Core\Access\AccessResult::neutral();
  }
  return $access;
}

```

What I cannot figure out how to do is implement the "file embargoes" in which the node is still viewable but the files are not. Since the private files are no longer accessible when `hook_node_access` returns `\Drupal\Core\Access\AccessResult::forbidden()` on the node they belong to, there must be some system in Drupal that is checking to see what node the files belong too. If I could figure out how to access that I might be able to use `hook_file_download` and check the node the file belongs to and see if the file should be accessible or not; in fact I already have a function in my custom service that does exactly this, but it needs a node ID in order to see what embargoes exist for the node.

Does anyone know how to do this? What is Drupal doing when a private file is accessed to see if the associated node is accessible or not?

# Answer
The answer ended up being the function `file_get_file_references()`, referenced in /core/modules/file/src/FileAccessControlHandler.php

https://api.drupal.org/api/drupal/core%21modules%21file%21file.module/function/file\_get\_file\_references/8.2.x
> 1 votes

---
Tags: 8
---


# Question
Title: How to handle Custom Validation in inline entity Form?
I'm using Drupal8's inline entity form and is having issue with writing custom validation. I found few links and wasn't helpful at all. Does anyone know how to handle this?

# Answer
> 7 votes
You have to use inline form alter for custom validation in module shown below

```
/**
 * {@inheritdoc}
 *
 * Implements hook_form_alter().
 */
function module_inline_entity_form_entity_form_alter(&$entity_form, &$form_state) {

  // Added custom validation
  if ($entity_form['#bundle'] == 'bundle_name') {
    $entity_form['#element_validate'][] = '_custom_validate_function';
  }
}

```

And implement that validation like below.

```
/**
 * Custom validation.
 */
function _custom_validate_function(&$form, FormStateInterface $form_state) {

 $triggering_element = $form_state->getTriggeringElement();
 $values = $form_state->getValues();
 // or you can use $form_state->getValue('field_name')
 // Validate your functionality

 // Set Error for form
 $form_state->setError($form, t("message"));
 // Note: $name may be unknown in $form_state and
 // $form_state->setErrorByName($name, $message) may suppress the error message.
 // hence use above $form_state->setError()
}

```

# Answer
> 3 votes
Set Error on inline entity forms is improved by specifying the actual element like this

```
$form_state->setError($form['field_name']['widget'], t("message"));

```

The above will successfully display the message inline.

---
Tags: 8, entities, forms
---


title: "Content: ID" versus "Content: Nid"

text:
# Question
Title: "Content: ID" versus "Content: Nid"
I'm just getting to know Drupal. I've been manually recreating current Drupal 7 Views from a production installation into a new development install of Drupal 8.85. I've run into some differences between Drupal 7 and Drupal 8, as you might imagine.

In Drupal 7, many views are using *Content: Nid* (for the node ID), which doesn't exist in Drupal 8. I've read here and elsewhere it has been replaced by *Content: ID*, in Drupal 8.

That said, the dialog boxes for each look different when it comes to setting options and parameters. For example, *Content: Nid* has an option/checkbox for *Link this field to the original piece of content*. *Content: ID* doesn't have that option, as I can see.

Additionally, the *Content:ID* dialog has options not seen in the *Content: Nid* dialog, such as the options for *Formatter*, *Thousand marker*, and *Display prefix and suffix*.

Is *Content: ID* really the Drupal 8 equivalent of *Content: Nid*? Where are the options missing in *Content: ID*?

# Answer
> Is Content: ID really the Drupal 8 equivalent of Content: Nid?

Yes

> Additionally, the Content:ID dialog has options not seen in the Content: Nid dialog, such as the options for Formatter, Thousand marker, and Display prefix and suffix.

Thousand marker makes sense. The other two not so much, bug maybe?

> In Drupal 7, many views are using Content: Nid (for the node ID), which doesn't exist in Drupal 8. I've read here and elsewhere it has been replaced by Content: ID, in Drupal 8.

I could see them thinking when developing the D8 version, who links to a Node/Entity using the ID? Using something descriptive like a Title, or "view/edit/delete" text makes a ton more sense, don't really need this feature for ID. Plus having to hover over single digits is not user friendly.

But, if you still want to link using the ID

* Add the ID field and checkmark hide from display.

Then either add field:

* Link to content OR Link to edit content

Under rewrite results:

+ Checkmark override the output of this field with custom text

Example:
> 1 votes

---
Tags: views
---


# Question
Title: Remove Passwords match: text from Registration form
How do I remove/disable "Passwords match:" text in Drupal 8.

# Answer
> 3 votes
This will remove passwords match and add placeholders if you want...

```
/**
 * Implements hook_form_FORM_ID_alter().
 * user_form
 */
function hook_form_user_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  $form['account']['pass']['#process'][] = 'form_user_reset_process_pass';
}

/**
 * Process password fields.
 *
 * @param $element
 * @param \Drupal\Core\Form\FormStateInterface $form_state
 * @param $complete_form
 *
 * @return mixed
 */
function form_user_edit_process_pass(&$element, \Drupal\Core\Form\FormStateInterface $form_state, &$complete_form) {
  $element = \Drupal\Core\Render\Element\PasswordConfirm::processPasswordConfirm($element, $form_state, $complete_form);
  $element['pass1']['#placeholder'] = t('Password');
  $element['pass2']['#placeholder'] = t('Confirm password');
  return $element;
}

```

# Answer
> -1 votes
CSS solution

```
.js-password-confirm-message {
  visibility: hidden;
}

```

---
Tags: 8, users
---


# Question
Title: How to delete 1600 users and 2500 posts?
A couple years ago I configured a site with Drupal 6.9, and then I forgot about it. I have 160 pages of users that are all spammers and I need to delete all but 3. Doing this one page at a time is painfully slow due to the MySQL calls (I guess). I also have about 2500 forum posts to delete.

I'm a little afraid to delete records from the database directly.

I saw a module called "mass delete", but it is for Drupal version 5 and not available for version 6.

# Answer
> 17 votes
You can use Views Bulk Operations, a module that allows to execute bulk operations on nodes, users, comments; it also permits to apply the selected operation to all the nodes, users, or comments using the Batch API. The batch API allows forms processing to be spread out over several page requests, thus ensuring that the processing does not get interrupted because of a PHP timeout, while allowing the user to receive feedback on the progress of the ongoing operations.

# Answer
> 3 votes
This way to kill nodes is very slow, but most safe

```
function MYMODULE_menu(){
  $items['admin/mymodule/killnodes/%'] = array(
      'title' => 'Kill nodes',
      'page callback' => 'kill_nodes',
      'page arguments' => array(3),
      'type' => MENU_CALLBACK,
      'access arguments' => array('administer site configuration'),
  );
  return $items;
}

function kill_nodes($type){
  $query = "SELECT node.nid AS nid FROM {node} node WHERE node.type IN ('%s')";
  $result = db_query($query, $type);
  $count = 0;
  while($row = db_fetch_object($result)){
    node_delete($row->nid);
    $count++;
  }
  $message = t('!count nodes has been killed. Pif-Paf!', array('!count' => $count));
  drupal_set_message($message);
  return t("That's all folks");
}

```

For users, can you programmatically determine the user whom you want to remove? If it possible you can use previous function as example to remove users unwanded.

# Answer
> 3 votes
Instead of creating a custom module for this task, you can use a simple script and execute it with Drush. Since you need to process a lot of users and nodes, usage of the Batch API is recommended (and it can be used with Drush).

# Answer
> 2 votes
If, like me, you prefer a Python approach (rare around here probably, but still), this is a transparent and effective way to fix this problem:

```
import os

# Build up a variable containing the usernames
# This list was built using drush sql-cli, then
# SELECT name FROM users
#   where $your-where-condition
#   order by uid asc
#   INTO
#     OUTFILE '/tmp/users.csv'
#     FIELDS TERMINATED BY ','
#     ENCLOSED BY '"'
#     lines terminated by ', ' ;
users = [result from SQL goes here]

for user in users:
    print("Deleting spam user: %s..." % user),
    os.system('drush --yes -r $your-path-to-drupal -l $your-site-url user-cancel --delete-content %s > /dev/null' % user)
    print 'Done'

```

The steps are basically:

1. Log into your DB with `drush sql-cli -r $your-path-to-drupal -l $your-site-url`
2. Run the SQL above with your own where condition and paste the results into the users variable.
3. Update your drupal path and site name into the drush command
4. Run the script with `python delete-users.py`

I'm sure there's a better way to do this, but this is my hacked solution that works well.

# Answer
> 1 votes
Try these 2 modules for D6:

User Prune https://drupal.org/project/user\_prune and User Delete https://drupal.org/project/user\_delete

User Prune lets you mass delete inactive users based on criteria you specify.

User Delete lets you delete a user and delete all submitted content including nodes and comments

# Answer
> 1 votes
Use advanced user module. This module adds an "advanced" tab to user management page. In that tab, you can filter users by any attribute (role, status etc.) and select all. If you select the deletion method of the users as delete the user and remove all content, you can also delete all content created by them.

# Answer
> 0 votes
The module Delete All could came in handy.

Once installed you can do, for example:

```
drush delete-all articles

```

or

```
drush delete-all users

```

Drupal 6 version in in dev but from the notes:

> Everything should be working except for quick delete.

# Answer
> 0 votes
If you have access to Drush and want a quick solution which lets you whitelist users to keep and doesn't involve installing additional modules:

```
drush @example.org sqlq "SELECT name FROM users WHERE name NOT IN ('keepthisuser1', 'andthisuser2')" | while read NAME; do
  drush -y @example.org user-cancel $NAME ;
done

```

Make sure to adjust both the `@example.org` and list of users to keep `('keepthisuser1', 'andthisuser2')` in the above before copy pasting :)

# Answer
> 0 votes
Original question is for 6, but using Chris Burgess' answer can be applied to Drupal 8 like so;

```
drush sqlq "SELECT name FROM users_field_data WHERE name NOT IN ('admin')" | while read NAME;
  do drush -y user:cancel --delete-content $NAME;
done

```

---
Tags: entities, 6
---


# Question
Title: Using Backup and Restore to transfer drupal configurations but not actual data
I am trying to use backup and restore to transfer configurations in drupal, but not the actual data. The `backup and restore` module allows you to do a backup where you exclude data from certain tables. My question is does restoring have a similar option where you don't wipe all the data and just make changes without wiping all the data?

For example, on our staging instance we added a new field to the User Account called `field_phone_number`. Can I create a backup with the new field configuration on User Account and then "restore" this backup on our production instance without transferring actual user records?

Preferably, I would like to do this via drush so we can implement into our CI/CD process.

# Answer
> 3 votes
For drupal 7 the best way to transfer Drupal configurations but not actual data is to use Features module.
You can create features from your staging env.
and then revert them in production.

---
Tags: 7
---


# Question
Title: Show Comment Form on its own Page or Popup
I am trying to figgure out how to show the comment form on its own page. So far I have been able to show it on a seperate page. All I had to do was to go to field comment setting and uncheck "Show reply form on the same page as comments"

So this allow the comments to show on a new page. The only issue is that the new page still shows body above. Is there any way to hide the body on the comment form page?

Ideally I would like to load the comment form on a popup or modal. Can this be done with bootstrap modal or Colorbox inline?

# Answer
> 2 votes
You can accomplish this using an extra node template for the page where the comment form is displayed:

In your theme file create an extra template suggestion for the comment form:

```
function HOOK_theme_suggestions_node_alter(array &$suggestions, array $variables) {
    $route_name = \Drupal::service('current_route_match')->getRouteName();

    if($route_name === 'comment.reply') {
        $suggestions[] = 'node__commentform';
    }
}

```

Create an extra node template `node--commentform.html.twig`, and remove just about everything. You probably want to leave the node title, but otherwise there's nothing you need there:

```
<article{{ attributes }}>

  {{ title_prefix }}
  {% if not page %}
    <h2{{ title_attributes }}>
      <a href="{{ url }}" rel="bookmark">{{ label }}</a>
    </h2>
  {% endif %}
  {{ title_suffix }}
</article>

```

The comment form is rendered outside this template, so you don't need any of it.

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


# Question
Title: How to get the JSON/array value property name for a field instance?
Given a `Drupal\Core\Field\BaseFieldDefinition` how do you get whether the value is stored by `target_id`, or `value` or `uri` or `color` or ....

it seems `getMainPropertyName()` is what i'm looking, for but it returns `null` for the majority of fields. in my case it's only returning target\_id or value for for created, status, and entity\_id.

# Answer
> 3 votes
I just tested using a variety of field types, and it seems to work OK for me. Here's the code I used for testing:

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

print $node->get('field_test')->getFieldDefinition()->getFieldStorageDefinition()->getMainPropertyName();
print $node->get('field_test_image')->getFieldDefinition()->getFieldStorageDefinition()->getMainPropertyName();
print $node->get('field_test_link')->getFieldDefinition()->getFieldStorageDefinition()->getMainPropertyName();
print $node->get('field_test_email')->getFieldDefinition()->getFieldStorageDefinition()->getMainPropertyName();

```

This returns value, target\_id, uri and value as one would have expected. What kind of fields are giving you trouble? How do you get you `BaseFieldDefinition` class? What kind of entity are they connected to?

I notice that the Views way of getting the property name is also pretty pragmatic:

```
// EntityField.php line 1111
if ($main_property_name = $field_item->mainPropertyName()) {
  $values[] = $field_item->{$main_property_name};
}
else {
  $values[] = $field_item->value;
}

```

Clearly it's not completely unexpected to have this method return `null`.

# Answer
> 2 votes
This code works for getting the main property name of the field for a particular content type

```
$entityFieldManager = \Drupal::service('entity_field.manager');
$fields = $entityFieldManager->getFieldDefinitions('node', 'article');
foreach ($fields as $field_name => $field_definition) {
  if (!empty($field_definition->getTargetBundle())) {
    $storage[$field_name]['storage_value'] = $field_definition->getFieldStorageDefinition()->getMainPropertyName();
  }
}

```

---
Tags: 8, entities
---


# Question
Title: $form_state=>setErrorByName/setError on fieldset/container/etc
I have written a custom validation handler for webform that compares two fields. If the fields are in a container/fieldset/etc., I would like to set the error on the container instead of on the fields (since either of the two fields could be the erroneous field). For example, the fieldset is trip-dates, the fields are start-date and end-date and I want an error if start-date is after end-date.

I can use setErrorByName/setError to set errors on individual fields, but it doesn't work if I try to set an error on the fieldset. When called against a fieldset, setErrorByName/setError call sets the error message at the top of the form, but does nothing to highlight/set an error class on the fieldset.

Webform Source:

```
event_details:
  '#type': fieldset
  '#title': 'Event Details'
  '#attributes':
     name: event-details
  date_container:
    '#type': fieldset
    '#title': 'Travel Dates'
    '#required': true
    '#attributes':
       name: date-container
     departure_date:
       '#type': date
       '#title': 'Departure Date'
       '#required': true
       '#default_value': '+1 day'
       '#format': short
       '#date_date_min': today
       '#datepicker': true
       '#datepicker_button': true
       '#date_date_format': m/d/Y
     return_date:
       '#type': date
       '#title': 'Return Date'
       '#required': true
       '#default_value': '+1 day'
       '#format': short
       '#date_date_min': today
       '#datepicker': true
       '#datepicker_button': true
       '#date_date_format': m/d/Y

```

Class Code:

```
  $errorFields=[
     'date_container',  //sets message, fails to highlight
     'date-container',  //sets message, fails to highlight
     'event_details][date_container',   //sets message, fails to highlight
     'event-details][date-container',   //sets message, fails to highlight
     'return-date',     //sets message, fails to highlight, as expected
     'departure-date',  //sets message, fails to highlight, as expected
     'return_date',     //sets message, highlights single field as expected
     'departure_date',  //sets message, highlights single field as expected
  ];
  foreach($errorsField as $errorField){
    if (!($left_val <= $right_val)) {
      $formState->setErrorByName(
       $errorField,
      $this->t('some weird message'));
    }
  }

```

I have also tried changing the names of the containers to underscores instead of dashes...no luck. If it would just add an error class to the fieldset, I could style it easily enough, but it doesn't seem to change anything about the fieldset.

I have also tried container, details and section instead of fieldset.

# Answer
> -1 votes
I finally got it working by explicitly giving both name and id attributes to the fieldset.

# Answer
> 0 votes
A workaround may be to add a class to the form which you could then use to style the fieldset:

```
$form['#attributes']['class'][] = 'my-fieldset-error';

```

---
Tags: forms, webforms
---


# Question
Title: How to style nested paragraph fields without duplication, in Views (and nested fields appear)
Drupal 8.. This may be a two-part problem. I want to avoid repeated content due to multiple values in a nested paragraph reference, but ALSO put the nested paragraph fields into a custom text field, so I can change how they're rendered.

I have a content type "**episode**", with a field referring to paragraph "**section**", containing several fields. One of those fields inside "section" is a nested reference to a paragraph called "**source**".

I created a view for content type "episode". It pulls the results of "Section" matching a content ID contextual filter. Then I added a reference to the paragraph "section", so I could get individual fields instead of a fully rendered value (I want to do this myself in a custom text field). I also created a reference for the "source" paragraph, to the "section" paragraph.

I'm able to add all the paragraph and nested paragraph fields, but the nested "source" fields are showing blank in the preview below, and it duplicates entries based on number of 'sources' I confirmed the paragraph fields are all set to show in the "manage display" for both paragraphs.

I then tried to see if there was a way I could just use the rendered paragraph "source" on the page. This shows the information, and I can set it to "Display all values in the same row" to eliminate duplicates.

But this prevents exactly what I'm trying to do: custom style the presentation of the information

What I want is to end it all with a custom field something like this:

```
<div class="classname">{{ field_section_timestamp }}
<h3>{{ field_section_title }}</h3>
<p>{{ field_section_description }}</p>
<h4>Sources</h4>
<em>{{ field_source_author }}</em><a href="{{ field_source_link }}">{{ field_source_title }}</a>

```

...And then apply whatever settings that get the sources to show as a list and not duplicate the entire section over-and-over, giving me something like this:

```
Episode
 - Section 1
    - Source 1
    - Source 2

 - Section 2
    - Source 1
    - Source 2

```

I know this can be done with the rendered paragraph and multiple field settings checked to "display all values in a row" But...

What I need is change how each field in Paragraph B is rendered - changing the tags.

But when I try to do this by adding the paragraphs as relationships and using individual fields, I get the repeating issue described above. I added the fields to a custom text field with everything, but this generates repeats.

```
Episode
 - Section 1
    - Source 1 (value blank)

 - Section 1
    - Source 2 (value blank)

 - Section 2
    - Source 1 (value blank)
 - Section 2
    - Source 2 (value blank)

```

Actually... as I'm typing this out and testing, I'm seeing that the paragraph B values aren't even showing at all. Though they take up space. just no content.

Hopefully this gives enough of a starting point for the question?

# Answer
Seems I found an answer. I suddenly remembered there was something called the Views field View module. I installed it, played around with it until I found a "views" field. I was able to create a second view for the nested paragraph, add it to the first paragraph' view, through the and use a conditional field based off 'parent ID' and got exactly what I was looking for.

For reference, this video shows most everything you'd need to know, for using it:
> 3 votes

---
Tags: views, 8
---


# Question
Title: Change the value of a taxonomy field on cron run
I have the article node with two extra fields:

* Taxonomy reference field `field_verification_status` with two possible values:
    + Valid (tid: 272)
    + Expired (tid: 271)
* Date field (`field_article_expiry_date`)

When a user will create a new article, will set:

* Taxonomy reference field `field_verification_status` = Valid (tid: 272)
* Date field (`field_article_expiry_date`) = Any time in the future.

Now using Ultimate Cron Module, I want on every cron run, to:

1. Check if the `field_article_expiry_date` value is less than current time (`now`)
2. if above return true then change the `field_verification_status` value to Expired (`tid: 271`)

To accomplish the above, I have created a new module `custom_cron_expired_articles` and in the `.module` file I added the below codes:

```
<?php

use Drupal\node\Entity\Node;
use Drupal\taxonomy\Entity\Term;

/**
 * Implements hook_cron().
 */

// On "Cron Run" and "Every Half Hour":
    // Loop through all "Valid" articles with expiry date set to the past,
    // Change the status of each article to "Expired".

function custom_cron_expired_articles_cron() {

  // Get the "cron time" (Return Value is in UNIX Timestamp format)
    //$cron_time = \Drupal::time()->getCurrentTime();
    //date_default_timezone_set('GMT');

// Load all available expired nodes of type 'offer'.
  $storage = \Drupal::entityTypeManager()
    ->getStorage('node');
  $query = \Drupal::entityQuery('node')
      ->accessCheck(FALSE)
      ->condition('type', 'article')
      ->condition('field_verification_status', 272)    // Verification Status = Valid
      ->condition('field_article_expiry_date', strtotime($?????), '<=')  // Something is missing here
      //->range(0,50);
  $nids = $query->execute();

// Loop through all expired nodes.
foreach ($nids as $nid) {

// Load the Node by its ID.
    $node = \Drupal\node\Entity\Node::load($nid);

    // Update the node.
    $node->field_verification_status->target_id = 271; // Verification Status = Expired

    // Save the updated node.
    $node->save();

// resetCache() in such a loop over all entities of one type avoids running out of memory.
\Drupal::entityManager()->getStorage('node')->resetCache(array($nid));
}
}

```

How to compare if the `field_article_expiry_date` is less than the `current_time` ? or by other words, how to load only the nodes with `field_article_expiry_date` less than the `current_time`?

Can somebody tell me what is the missing part ?

# Answer
You store the value returned from `\Drupal::entityTypeManager()
 ->getStorage('node')` in `$storage`, but you don't use it. On the next line you use `\Drupal::entityQuery()`. (I don't recommend it, as it will be deprecated in Drupal 9; you should use the entity type manager.)

The code I would use is the following one.

```
  use Drupal\Core\Datetime\DrupalDateTime;

  // Build Drupal DateTime & set correct format for your query
  $curent_time = new DrupalDateTime('now');
  $curent_time = $curent_time->format('Y-m-d\TH:i:s');

  // Get Entity Manager to build your query
  $storage = \Drupal::entityTypeManager()
      ->getStorage('node');

  // Get all Nodes satisfing your conditions
  $nids = $storage->getQuery()
      ->condition('type', 'article')
      ->condition('field_verification_status', 272)
      ->condition('field_article_expiry_date', $curent_time, '<=')
      ->execute();

  // Load all Node entities according to their IDs
  $nodes = \Drupal\node\Entity\Node::loadMultiple($nids);

  // Do whatever you want with Nodes
  foreach ($nodes as $node) {
    // Do something
    $node->save();
  }

```

### See also
> 1 votes

---
Tags: 8, datetime, cron
---


# Question
Title: How to insert table view inside another view?
I have created a View and two display blocks inside the View and set the format to table on each.

like this:

I will display these two tables at the front page. Now I need to write a common for both tables

```
<div class="col-sm-12 table member">
    <div class="col-sm-12 col-md-7 col-xl-7 member_payments">
        <!--table_1-->
    </div>
    <div class="col-sm-12 col-md-5 col-xl-5 member_payments services">
        <!--table_2-->
    </div>
</div>

```

For this may I need to use table view inside another view?

My tables looks like this

# Answer
You should be able to put `services view block` reference into your `members view block` for example into Header / Footer. Then by overriding template for this view type `view-view--<views_machine_name>` you can easily add Bootstrap classes and wrap each table into specific container / wrapper.

In your main view click on button **Add** at Header section. Add **Rendered entity - block** and type in your second block block\_machine\_name *(it means your second block needs to be added to some region with specific machine name)*.
> 1 votes

---
Tags: views
---


# Question
Title: Date format - @ symbol has unexpected behaviour
I created a date format , then added that date format to a field within a view. But the `@` symbol is automatically appending to the end of the date format (even though i specified it to go into the middle of the date format, and is reflected correctly in the preview). I used PHP:date - Manual as my reference.

My date format: `l, F j @ g:ia` and it displays as: `Wednesday, June 17 @ 4:32pm`

Now when I select that date format for my date field within my view, it outputs the said date as: `Wednesday, June 17 4:32pm @`.

I'm confused because whenever I have put other characters before, it always outputted what I wanted. I've also tried using the html equivalent of `@` but it outputs the @ symbol at the end of the format as well.

I'm just wondering if this is a ~~`views`~~, `php`, or `date` issue? And is there anyway I can output this date as: `Wednesday, June 17 @ 4:32pm` from a date format?

# Answer
I was having the same issue and was able to get this working by escaping the @ symbol.

Example: 'M j, Y \\@ G:i'
> 1 votes

---
Tags: views, datetime
---


# Question
Title: Message (from message stack) not translated into the preferred language of the recipient
Here is a code which can be pasted into devel/php (run php code) if the message template **new\_user\_register** exists with a user reference field called **field\_user\_reference**

This message should be sent when a new user register himself (But this has no link with my problem as the code can be run outside... I provide this information just to give some context)

```
$id=127;
$account=\Drupal\user\Entity\User::load($id);
$message=\Drupal\message\Entity\Message::create([
    'template' => 'new_user_register',
    'uid' => $id
]);
$message->set('field_user_reference', $account);
$message->save();

$subscribers = \Drupal::service('message_subscribe.subscribers');
$notify_options = [];
$subscribe_options = [
    'notify message owner' => TRUE,
    'notify blocked users'=>TRUE, //new user is blocked
    'entity access'=>FALSE, //new user don't have access (blocked)
    'uids' => [new \Drupal\message_subscribe\Subscribers\DeliveryCandidate(['subscribe_user'], ['email'], $id)],
];

$subscribers->sendMessage($account, $message,$notify_options,$subscribe_options);

```

Even if the template is translated, the user 127 will not receive the message in his preferred language but in the site default language.

Is it a bug or am I missing something?

# Answer
I have made a path here: https://www.drupal.org/project/message\_notify/issues/2965975#comment-13559090

Feel free to test it and report any problem
> 0 votes

---
Tags: i18n-l10n, message-subscribe
---


title: How do I sort by day?

text:
# Question
Title: How do I sort by day?
Hi I have a bunch of items which occur on a given day of the week. So i have a text field called Day, and it's populated by the words 'Monday', 'Tuesday', 'Wednesday' etc. Is there a way to sort this in views that will list items in Weekday order. I can only find options for alphabetical order.

# Answer
> 2 votes
This could be working for example if you'd use a taxonomy term reference instead of a text field. Just create a taxonomy with your workdays as terms.

* use these tags on your content
* in views add a field to show the term your content is tagged with
* in the format options choose 'group by' and select your taxonomy field

Now the content should be grouped by the workdays. To achieve the correct sorting order you can either rely on the term-ID (which is created in chronological order) or just arrange your terms with drag and drop (in the terms dialog).

---
Tags: views, 8
---


title: Can you override single submit forms?

text:
# Question
Title: Can you override single submit forms?
I have a form that generates some custom financial reports (can't use Views). It has some typical form elements, a table of results, and three submit buttons: Submit, Reset, and Download.

Submit and Reset do what you think. Download triggers a submit handler that builds a CSV from the `$form['table']` in the handler (which is what the user has generated, and prevents another complicated database query + computations and another route to essentially do the same work), and then spits it out with a `$form_state->setResponse($response)`. This works great.

I discovered an interesting edge case, though, during testing.

core/misc/form.es6.js has a section of code in it (lines 117-134 in Drupal 8.8.5):

```
Drupal.behaviors.formSingleSubmit = {
  attach() {
    function onFormSubmit(e) {
      const $form = $(e.currentTarget);
      const formValues = $form.serialize();
      const previousValues = $form.attr('data-drupal-form-submit-last');
      if (previousValues === formValues) {
        e.preventDefault();
      } else {
        $form.attr('data-drupal-form-submit-last', formValues);
      }
    }

    $('body')
      .once('form-single-submit')
      .on('submit.singleSubmit', 'form:not([method~="GET"])', onFormSubmit);
  },
};

```

This prevents a form from being submitted more than once if it hasn't changed. However, since my Download button is a submit handler, the above code runs, which then prevents the Reset button from working unless another form element has been changed.

My current workaround is a bit of a sledgehammer:

```
Drupal.behaviors.sledgehammer = {
  attach: function (context, settings) {
    $('form.my-form', context).on('submit', function (e) {
      var $form = $(e.currentTarget);
      $form.removeAttr('data-drupal-form-submit-last');
    });
  }
};

```

As far as I can tell this works, but I have BigPipe turned on and am going to AJAX up the form a bit, so I am worried that this may be fragile.

Is there an JS API way to disable the single-submit behavior, or is a workaround the only solution?

# Answer
> 3 votes
If you haven't already, try using button rather than submit type.

```
'#type' => 'button',

```

> When the button is pressed, the form will be submitted to Drupal, where it is validated and rebuilt. **The submit handler is not invoked**.

Perhaps this will prevent that `formSingleSubmit` behavior from running???

---

If the above doesn't work, since all the `formSingleSumit` behaviour does is prevent form from being submitted if it hasn't changed and nothing else. Therefore, you don't need this behaviour and since `Drupal` is global, you could just do in custom.js:

```
delete Drupal.behaviors.formSingleSubmit;

```

OR set it/override it to empty

```
Drupal.behaviors.formSingleSubmit = {};

```

---
Tags: forms
---


# Question
Title: How can I add all the existing content types into a dropdown list?
In Drupal 8, I am using the *Config Pages* module to set up a configuration page for a custom module. How can I add all the existing content types into a dropdown list?

# Answer
> 0 votes
In your custom form, in add `$options` to your content type list field. the following snippet get list of all the content type names for you;

```
   $node_types = \Drupal\node\Entity\NodeType::loadMultiple();
    // If you need to display them in a drop down:
    $options = [];
    foreach ($node_types as $node_type) {
      $options[$node_type->id()] = $node_type->label();
    }

```

---
Tags: 8, nodes
---


# Question
Title: How do I display the date but not the author?
I want articles to show *Submitted on* without showing *Submitted by*. The checkbox on *Display settings* toggles both, not only one of them.
Control/modify display settings (author and date) on posts explains how to do it in Drupal 7.

How should I achieve it in Drupal 8, for example with the *Bartik* theme?

# Answer
> 2 votes
It's enough to edit the node.html.twig template used from the theme. For example, the Bartik theme uses a node.html.twig template containing the following code. (I omitted the documentation comment at the beginning of the file.)

```
{%
  set classes = [
    'node',
    'node--type-' ~ node.bundle|clean_class,
    node.isPromoted() ? 'node--promoted',
    node.isSticky() ? 'node--sticky',
    not node.isPublished() ? 'node--unpublished',
    view_mode ? 'node--view-mode-' ~ view_mode|clean_class,
    'clearfix',
  ]
%}
{{ attach_library('bartik/classy.node') }}
<article{{ attributes.addClass(classes) }}>
  <header>
    {{ title_prefix }}
      {% if label and not page %}
      <h2{{ title_attributes.addClass('node__title') }}>
        <a href="{{ url }}" rel="bookmark">{{ label }}</a>
      </h2>
    {% endif %}
    {{ title_suffix }}
    {% if display_submitted %}
      <div class="node__meta">
        {{ author_picture }}
        <span{{ author_attributes }}>
          {% trans %}Submitted by {{ author_name }} on {{ date }}{% endtrans %}
        </span>
        {{ metadata }}
      </div>
    {% endif %}
  </header>
  <div{{ content_attributes.addClass('node__content', 'clearfix') }}>
    {{ content }}
  </div>
</article>

```

The line printing the name of the user who created the node and when it was posted is the following one.

```
{% trans %}Submitted by {{ author_name }} on {{ date }}{% endtrans %}

```

It's enough to change it and remove the part printing the username. In the case of the Bartik theme, the node.html.twig content will become the following one.

```
{%
  set classes = [
    'node',
    'node--type-' ~ node.bundle|clean_class,
    node.isPromoted() ? 'node--promoted',
    node.isSticky() ? 'node--sticky',
    not node.isPublished() ? 'node--unpublished',
    view_mode ? 'node--view-mode-' ~ view_mode|clean_class,
    'clearfix',
  ]
%}
{{ attach_library('bartik/classy.node') }}
<article{{ attributes.addClass(classes) }}>
  <header>
    {{ title_prefix }}
      {% if label and not page %}
      <h2{{ title_attributes.addClass('node__title') }}>
        <a href="{{ url }}" rel="bookmark">{{ label }}</a>
      </h2>
    {% endif %}
    {{ title_suffix }}
    {% if display_submitted %}
      <div class="node__meta">
        {{ author_picture }}
        <span{{ author_attributes }}>
          {% trans %}Submitted on {{ date }}{% endtrans %}
        </span>
        {{ metadata }}
      </div>
    {% endif %}
  </header>
  <div{{ content_attributes.addClass('node__content', 'clearfix') }}>
    {{ content }}
  </div>
</article>

```

For a different theme, it's enough searching the line of the node.html.twig template containing `{{ author_name }}` and remove it. Clearly, also the sentence containing `{{ author_name }}` needs to be changed to make it grammatical. (*Submitted by on `{{ date }}`* would not be grammatically correct.)

As general suggestion, never change a template file used from a Drupal core theme or a third-party theme. Rather, create a sub-theme using that theme as parent theme, and add the template files you need to change.

---
Tags: 8, theming, nodes
---


title: How to override core history_cron

text:
# Question
Title: How to override core history_cron
I want to display the reading history of nodes using Views.
For this reason there is a history module in core, but the history\_cron hook deletes history older than 1 month.
I want to override this hook so that history is not deleted.
What should i do?

# Answer
> 3 votes
A module can avoid Drupal invokes a hook defined from another module, implementing `hook_module_implements_alter()`. For example, a module using history\_ovverrides as machine name could use the following implementation of that hook.

```
function history_overrides_module_implements_alter(&$implementations, $hook) {
  if ($hook == 'cron') {
    // Remove history_cron() from the list of the hook_cron() implementations.
    unset($implementations['history']);
  }
}

```

The same module could implement `hook_cron()` to delete the History module data basing on different criteria (for example, after 6 months).

# Answer
> 3 votes
With Ultimate Cron you can problably disable it from running using its configuration form.

If you look at its API, it adds a hook\_cron\_alter that you could implement if you wanted to do it by code.

---
Tags: 8, hooks, cron
---


# Question
Title: I get errors when I try to do anything with migrations
So I'm new to Drupal, and I'm trying to set up a migration. I followed a tutorial to import a basic csv as an article yesterday, that worked ok. There are no errors showing using the admin area of Drupal.

I tried to create a new migration following this guide (https://www.cmsdrupal.com/blog/how-import-data-csv-file-drupal-8-best-tools-and-approaches-you-can-use) but modified for a spreadsheet not a csv. I got to step 7 of the first section and Drush throws an error.

I've tried running a migrate status and that too throws an error

```
vendor/bin/drush migrate:status

```

The error I get is:

```
#1 /var/www/pnm.com/html/core/modules/migrate/src/Plugin/Migration.php(625): Drupal\migrate\Plugin\Migration->findMigrationDependencies(NULL)
#2 /var/www/pnm.com/html/core/modules/migrate/src/Plugin/MigrationPluginManager.php(122): Drupal\migrate\Plugin\Migration->getMigrationDependencies()
#3 /var/www/pnm.com/html/modules/contrib/migrate_tools/src/Commands/MigrateToolsCommands.php(701): Drupal\migrate\Plugin\MigrationPluginManager->createInstances(Array)
#4 /var/www/pnm.com/html/modules/contrib/migrate_tools/src/Commands/MigrateToolsCommands.php(140): Drupal\migrate_tools\Commands\MigrateToolsCommands->migrationsList('', Array)
#5 [internal function]: Drupal\migrate_tools\Commands\MigrateToolsCommands->status('', Array)
#6 /var/www/pnm.com/vendor/consolidation/annotated-command/src/CommandProcessor.php(257): call_user_func_array(Array, Array)
#7 /var/www/pnm.com/vendor/consolidation/annotated-command/src/CommandProcessor.php(212): Consolidation\AnnotatedCommand\CommandProcessor->runCommandCallback(Array, Object(Consolidation\AnnotatedCommand\CommandData))
#8 /var/www/pnm.com/vendor/consolidation/annotated-command/src/CommandProcessor.php(176): Consolidation\AnnotatedCommand\CommandProcessor->validateRunAndAlter(Array, Array, Object(Consolidation\AnnotatedCommand\CommandData))
#9 /var/www/pnm.com/vendor/consolidation/annotated-command/src/AnnotatedCommand.php(302): Consolidation\AnnotatedCommand\CommandProcessor->process(Object(Symfony\Component\Console\Output\ConsoleOutput), Array, Array, Object(Consolidation\AnnotatedCommand\CommandData))
#10 /var/www/pnm.com/vendor/symfony/console/Command/Command.php(255): Consolidation\AnnotatedCommand\AnnotatedCommand->execute(Object(Drush\Symfony\DrushArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#11 /var/www/pnm.com/vendor/symfony/console/Application.php(1000): Symfony\Component\Console\Command\Command->run(Object(Drush\Symfony\DrushArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#12 /var/www/pnm.com/vendor/symfony/console/Application.php(255): Symfony\Component\Console\Application->doRunCommand(Object(Consolidation\AnnotatedCommand\AnnotatedCommand), Object(Drush\Symfony\DrushArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#13 /var/www/pnm.com/vendor/symfony/console/Application.php(148): Symfony\Component\Console\Application->doRun(Object(Drush\Symfony\DrushArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#14 /var/www/pnm.com/vendor/drush/drush/src/Runtime/Runtime.php(118): Symfony\Component\Console\Application->run(Object(Drush\Symfony\DrushArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#15 /var/www/pnm.com/vendor/drush/drush/src/Runtime/Runtime.php(49): Drush\Runtime\Runtime->doRun(Array, Object(Symfony\Component\Console\Output\ConsoleOutput))
#16 /var/www/pnm.com/vendor/drush/drush/drush.php(72): Drush\Runtime\Runtime->run(Array)
#17 /var/www/pnm.com/vendor/drush/drush/drush(4): require('/var/www/pnm.co...')
#18 {main}.
TypeError: Argument 1 passed to Drupal\migrate\Plugin\Migration::getProcessNormalized() must be of the type array, null given, called in /var/www/pnm.com/html/core/modules/migrate/src/Plugin/Migration.php on line 640 in /var/www/pnm.com/html/core/modules/migrate/src/Plugin/Migration.php on line 396 #0 /var/www/pnm.com/html/core/modules/migrate/src/Plugin/Migration.php(640): Drupal\migrate\Plugin\Migration->getProcessNormalized(NULL)
#1 /var/www/pnm.com/html/core/modules/migrate/src/Plugin/Migration.php(625): Drupal\migrate\Plugin\Migration->findMigrationDependencies(NULL)
#2 /var/www/pnm.com/html/core/modules/migrate/src/Plugin/MigrationPluginManager.php(122): Drupal\migrate\Plugin\Migration->getMigrationDependencies()
#3 /var/www/pnm.com/html/modules/contrib/migrate_tools/src/Commands/MigrateToolsCommands.php(701): Drupal\migrate\Plugin\MigrationPluginManager->createInstances(Array)
#4 /var/www/pnm.com/html/modules/contrib/migrate_tools/src/Commands/MigrateToolsCommands.php(140): Drupal\migrate_tools\Commands\MigrateToolsCommands->migrationsList('', Array)
#5 [internal function]: Drupal\migrate_tools\Commands\MigrateToolsCommands->status('', Array)
#6 /var/www/pnm.com/vendor/consolidation/annotated-command/src/CommandProcessor.php(257): call_user_func_array(Array, Array)
#7 /var/www/pnm.com/vendor/consolidation/annotated-command/src/CommandProcessor.php(212): Consolidation\AnnotatedCommand\CommandProcessor->runCommandCallback(Array, Object(Consolidation\AnnotatedCommand\CommandData))
#8 /var/www/pnm.com/vendor/consolidation/annotated-command/src/CommandProcessor.php(176): Consolidation\AnnotatedCommand\CommandProcessor->validateRunAndAlter(Array, Array, Object(Consolidation\AnnotatedCommand\CommandData))
#9 /var/www/pnm.com/vendor/consolidation/annotated-command/src/AnnotatedCommand.php(302): Consolidation\AnnotatedCommand\CommandProcessor->process(Object(Symfony\Component\Console\Output\ConsoleOutput), Array, Array, Object(Consolidation\AnnotatedCommand\CommandData))
#10 /var/www/pnm.com/vendor/symfony/console/Command/Command.php(255): Consolidation\AnnotatedCommand\AnnotatedCommand->execute(Object(Drush\Symfony\DrushArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#11 /var/www/pnm.com/vendor/symfony/console/Application.php(1000): Symfony\Component\Console\Command\Command->run(Object(Drush\Symfony\DrushArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#12 /var/www/pnm.com/vendor/symfony/console/Application.php(255): Symfony\Component\Console\Application->doRunCommand(Object(Consolidation\AnnotatedCommand\AnnotatedCommand), Object(Drush\Symfony\DrushArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#13 /var/www/pnm.com/vendor/symfony/console/Application.php(148): Symfony\Component\Console\Application->doRun(Object(Drush\Symfony\DrushArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#14 /var/www/pnm.com/vendor/drush/drush/src/Runtime/Runtime.php(118): Symfony\Component\Console\Application->run(Object(Drush\Symfony\DrushArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#15 /var/www/pnm.com/vendor/drush/drush/src/Runtime/Runtime.php(49): Drush\Runtime\Runtime->doRun(Array, Object(Symfony\Component\Console\Output\ConsoleOutput))
#16 /var/www/pnm.com/vendor/drush/drush/drush.php(72): Drush\Runtime\Runtime->run(Array)
#17 /var/www/pnm.com/vendor/drush/drush/drush(4): require('/var/www/pnm.co...')
#18 {main}
TypeError: Argument 1 passed to Drupal\migrate\Plugin\Migration::getProcessNormalized() must be of the type array, null given, called in /var/www/pnm.com/html/core/modules/migrate/src/Plugin/Migration.php on line 640 in Drupal\migrate\Plugin\Migration->getProcessNormalized() (line 396 of /var/www/pnm.com/html/core/modules/migrate/src/Plugin/Migration.php).
 [warning] Drush command terminated abnormally.

```

running other drush commands seems to work fine.

The yaml file I imported is:

```
id: loopy_releases_spreadsheet_import3
label: Import Casio Loopy releases
migration_groups:
  - releases

source:
  plugin: spreadsheet
  file: /var/www/pnm.com/imports/loopy.releases.ods
  worksheet: 'releases'
  origin: A2
  header_row: 1

  columns:
    - ID
    - 'Game Title'
    - 'System  ID'
    - 'Release Title'
    - 'Original Title (If Not English)'
    - Developer
    - Publisher
    - Label
    - Region
    - 'Release Day'
    - 'Release Month'
    - 'Release Year'
    - 'Manufacturer Code'
    - Barcode
    - Rarity
    - Description
    - 'Genres(s)'
    - Media
    - Body
    - Verified
    - 'Internal Notes'
    - Sources

  row_index_column: 'Row no.'

  keys:
    ID:
      type: string

  # Handle mapping of fields and processing here
  process:
    field_release_internal_id: ID
    title: 'Release Title'
    body: Description

  destination:
    plugin: entity:node
    default_bundle: release

```

The migration does not show up anywhere in structure migrations.

Looking at the import I did yesterday I can view the fields using:

```
vendor/bin/drush migrate:import article_csv_import

```

but looking at the import I just tried I get the same error as above:

```
vendor/bin/drush migrate:fields-source loopy_releases_spreadsheet_import

```

# Answer
> 0 votes
In the end I uninstalled all the migration module except for the base module, then I reinstalled them again. This seems to have cleared up the drush errors.

# Answer
> 0 votes
You might just be missing dependencies...

```
type: module
name: Joomla Migrate
description: 'Joomla 3.5 to Drupal 8 migration.'
package: Migration
# core: 8.x
dependencies:
 - drupal:migrate
 - migrate_plus:migrate_plus
 - migrate_drupal_ui
 - migrate_tools
 - migrate_file

# version: '8.x-3.0-beta1'
# core: '8.x'

# Information added by Drupal.org packaging script on 2017-04-29
version: '8.x-1.x-dev'
core: '8.x'
project: 'joomla_migrate'
datestamp: 1493431790

```

---
Tags: drush, migrations
---


# Question
Title: How to get BundleKey in EntityManager after getting storage of entity?
I want to get bundleKey of any entity type after is loading from

```
$node = \Drupal::entityManager()->getStorage('node');

```

After getStorage I am getting bundleKey Value as "type", but how to render that, as it is saying that is a protected value. Tried to fetch like:

```
-> $node->get('bundleKey')->Value();
-> $node->getField('bundleKey')->getValue();
-> $node->bundleKey;

```

All above methods i tried to fetch Values but still no luck.

Anyone Knows how to fetch bundleKey.

# Answer
> -1 votes
**Found Solution:**

Rather that loading complete storage, we can use entityDefinitionUpdateManager and get keys where you will get all id, bundle, label, etc

```
$manager = \Drupal::entityTypeManager();
$entity_type = $manager->getEntityType('commerce_product');
$entity_keys = $entity_type->getKeys();
$bundle = $entity_keys['bundle'];

```

# Answer
> 0 votes
You can get `bundleKey` of your entity type by this way:

```
$type = 'commerce_product';
$bundle_key = \Drupal::entityTypeManager()->getDefinition($type)->getKey('bundle');

```

---
Tags: 8, entities
---


title: $base_root problem

text:
# Question
Title: $base_root problem
In /core/lib/Drupal/Core/DrupalKernal.php the $base\_root shows incorrect value:

Line 1113 protected function initializeRequestGlobals(Request $request) { global $base\_url; // Set and derived from $base\_url by this function. global $base\_path, $base\_root; global $base\_secure\_url, $base\_insecure\_url;

```
// Create base URL.
$base_root = $request->getSchemeAndHttpHost();

```

The value the $base\_root is showing is the machine name, not the requested url. Specifically, the $base\_root value is like: https://machinename.windows.domain.com instead of the request url like: https://ourcompany.com

I've searched the database, exported configs, and all files in the installation for the "machinename", but the only place it exists is on the windows server as "my computer" name.

Our environment is set up with an AWS loadbalancer, AWS cert on loadbalancer, that relays traffic to the windows EC2 server.

Running very recent Apache, PHP and Drupal 8.7.14. Running updated modules using composer. I don't think this is a bug.

The problems this causes is that when there is a redirect url, or self reference, such as in the webform or workflow module, you get an error because the machinename url is not accessible externally.

I wrote code to hack DrupalKernel.php that changes the $base\_root using str\_replace(). Also did this to RedirectResponseSubscriber.php, which FIXES my problem. But, this is the worst kind of hack programming.

Is there a way to force symfony $request-\>getSchemeAndHttpHost() to give my proper url? Maybe a setting I missed?

I've been very reluctant to post this question because of the obvious criticism it can draw. I've seen a lot of "working as intended" responses around $base\_url issues which don't help my case.

# Answer
Check the "Reverse Proxy Configuration" in settings.php:

```
/**
 * Reverse Proxy Configuration:
 *
 * Reverse proxy servers are often used to enhance the performance
 * of heavily visited sites and may also provide other site caching,
 * security, or encryption benefits. In an environment where Drupal
 * is behind a reverse proxy, the real IP address of the client should
 * be determined such that the correct client IP address is available
 * to Drupal's logging, statistics, and access management systems. In
 * the most simple scenario, the proxy server will add an
 * X-Forwarded-For header to the request that contains the client IP
 * address. However, HTTP headers are vulnerable to spoofing, where a
 * malicious client could bypass restrictions by setting the
 * X-Forwarded-For header directly. Therefore, Drupal's proxy
 * configuration requires the IP addresses of all remote proxies to be
 * specified in $settings['reverse_proxy_addresses'] to work correctly.
 *
 * Enable this setting to get Drupal to determine the client IP from the
 * X-Forwarded-For header. If you are unsure about this setting, do not have a
 * reverse proxy, or Drupal operates in a shared hosting environment, this
 * setting should remain commented out.
 *
 * In order for this setting to be used you must specify every possible
 * reverse proxy IP address in $settings['reverse_proxy_addresses'].
 * If a complete list of reverse proxies is not available in your
 * environment (for example, if you use a CDN) you may set the
 * $_SERVER['REMOTE_ADDR'] variable directly in settings.php.
 * Be aware, however, that it is likely that this would allow IP
 * address spoofing unless more advanced precautions are taken.
 */
# $settings['reverse_proxy'] = TRUE;

/**
 * Specify every reverse proxy IP address in your environment.
 * This setting is required if $settings['reverse_proxy'] is TRUE.
 */
# $settings['reverse_proxy_addresses'] = ['a.b.c.d', ...];

/**
 * Reverse proxy trusted headers.
 *
 * Sets which headers to trust from your reverse proxy.
 *
 * Common values are:
 * - \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_ALL
 * - \Symfony\Component\HttpFoundation\Request::HEADER_FORWARDED
 *
 * Note the default value of
 * @code
 * \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_ALL | \Symfony\Component\HttpFoundation\Request::HEADER_FORWARDED
 * @endcode
 * is not secure by default. The value should be set to only the specific
 * headers the reverse proxy uses. For example:
 * @code
 * \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_ALL
 * @endcode
 * This would trust the following headers:
 * - X_FORWARDED_FOR
 * - X_FORWARDED_HOST
 * - X_FORWARDED_PROTO
 * - X_FORWARDED_PORT
 *
 * @see \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_ALL
 * @see \Symfony\Component\HttpFoundation\Request::HEADER_FORWARDED
 * @see \Symfony\Component\HttpFoundation\Request::setTrustedProxies
 */
# $settings['reverse_proxy_trusted_headers'] = \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_ALL | \Symfony\Component\HttpFoundation\Request::HEADER_FORWARDED;

```

There are more infos in the symfony documentation https://symfony.com/doc/current/deployment/proxies.html

**Debugging**

For debugging add a line to index.php and check the headers the CDN sending:

*index.php:*

```
<?php

/**
 * @file
 * The PHP page that serves all page requests on a Drupal installation.
 *
 * All Drupal code is released under the GNU General Public License.
 * See COPYRIGHT.txt and LICENSE.txt files in the "core" directory.
 */

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

// remove after debugging
var_dump($_SERVER);

```
> 3 votes

---
Tags: uri, symfony-services
---


# Question
Title: Where can I set the default filter for webforms?
When I go to https://example.com/admin/structure/webform

I would like to have the webform filtered by active ones.

Where do I change that?

# Answer
There is no UI setting for that.

You have to change it programmatically via custom module in `mymodule.module` file or via theme in `mytheme.theme` file.

Example:

**mytheme.theme**

```
/*
 * Implements hook_form_FORM_ID_alter()
 */
function mytheme_form_webform_filter_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  $form['filter']['state']['#default_value'] = 'open';
}

```
> 0 votes

# Answer
You might need to override and extend the \Drupal\webform\WebformSubmissionListBuilder.
> 0 votes

# Answer
Since the webform 8.x-5.9

you can change (your filteroptions) under

/admin/structure/webform/config

FORM OVERVIEW SETTINGS Filter webforms default category?

Select the filter webforms default category selected on the webform overview page. Filter webforms default state?

Thanks Jake.
> 0 votes

---
Tags: webforms
---


# Question
Title: How do I attach a webform to another webform's submission?
I found a demo for the Webform module which includes 2 forms: *application* and *application evaluation*. Once the *application* form is submitted, the *application evaluation* is attached at the bottom of the page showing the submitted data for the *application* form.

I tried to do the same with two webforms I created: *PO* and *PO Approval*. I want to attach the *PO Approval* webform to the submission of the *PO* webform.

I did the the follow setup(Structure-\>Block layout).

>

>

Then I tested it.

>

Differently from the demo, the webform was not attached the webform submission page of the other webform.

How do I attach a webform to another webform's submission?

**UPDATE:** I found if I do "flush plugins cache" then it will show up at bottom of the submission. I tested every single "flush", only "flush plugins cache" works.

here is the pic before "flush plugins cache"

here is the pic after "flush plugins cache"

As far as I know, after "flush", the submission page became "content" and before "flush" it was not "content"(Webform UI ?).

It is still not exactly same as the demo does. Hopefully this update can give more information to someone who can help me.

# Answer
I eventually find what the problem is. There are two solutions can solve this issue: 1) change the default administrative theme to default theme

2) Follow the demo to make a block YAML file like this: /my\_module/config/optional/block.block.seven\_webform\_demo\_application\_evaluation.yml

Hope this can help someone else has the same issue.
> 0 votes

---
Tags: webforms
---


# Question
Title: How do I pass arguments from URL into panel page block?
I have created a view with a contextual filter set to a taxonomy term. I am attempting to use the view block in a panels (page manager) page and pass the taxonomy term from the URL into the block. I could do this in Drupal 7 but I can't seem to figure it out in D8.

The page URL will be something like /reports/term1. I would like to pass term1 into the block.

For the panel page I have a URL like /reports/! (I also tried % as the place holder). Though I have seen some recommendations to use a context to pass the term, I have not been able to do so.

I am working with Drupal 8.7.1, Panels 8.x-4.4, Page Manager 8.4-4.0.

Any suggestions on how to accomplish this?

# Answer
> 1 votes
I have not used Panels with D8, but...

With D7 Panels I remember there was a way to set/pass a contextual filter value, but one thing I noticed was if I did not set it in Panels and instead set it directly in the View's settings, it also worked.

So all you have to do is edit your View block, under Advanced, for contextual filters add `Has taxonomy term ID`

In the settings for that, select `Provide default value` and for type use `Taxonomy term ID from URL`

---

Alternatively, you could do

# Answer
> 0 votes
This answer doesn't have anything to do with panels, but it will work for generally setting `$args` (contextual filter values) for views.

```
function hook_views_pre_view(\Drupal\views\ViewExecutable $view, $display_id, array &$args) {

  // You'll likely be able to get your term ID from the current route and/or the current path

  $route = \Drupal::routeMatch(); // get the current route
  $params = $route->getParameters(); // get the names of any parameters on the route
  $your_param_val = $route->getParameter('your_param'); // gets the value of a param, given that it exists in $params

  $current_path = \Drupal::service('path.current')->getPath(); //gets the current path
  $path_components = explode('/', $current_path); // gives you an array of the path components

  switch ($view->id()) {
    case 'your_view_id': // the machine name of your view
      if ($display_id === 'block_1') { // the machine name for your display

        $args[0] = $tid; // will set the value of the first contextual filter to the value of $tid;
        $args[1] = $another_fun_value; // will set the value of the second contextual filter, etc
        break;
      }
  }
}

```

Then the settings for the Contextual Filter (show all results, hide view, view) will be used as the fallback if the above code doesn't set the value of the filter for whatever reason.

# Answer
> 0 votes
Finally figured out how to get this to work. The missing element was the correct way to add a placeholder to the path in D8 page manager and panels. The path needs to be something like /something/{args}. ! or % does not appear to work.

Then I added a page manager context (under the Variants section) of the data type "string". When adding this context I set the context value to "string."

In the view, I added a taxonomy term relationship and selected (within the relationship) the intended vocabulary. Then I added a contextual filter of the type Taxonomy term: name. Note, you must enter "name" in the contextual filter search box to find the correct filter.

Then I selected "Raw value from the URL", and in this case, path component 2. I also added a validator of "Taxonomy term name" to the view contextual filter.

---
Tags: 8, panels
---


# Question
Title: How do I migrate the "Created" and "Modified" date fields?
I created a migration script to test this out.

This is the code I used.

```
id: article_csv_import
class: null
field_plugin_method: null
cck_plugin_method: null
migration_tags: null
migration_group: Import articles
label: 'Import articles'
source:
  plugin: csv
  path: 'modules/custom/sigtarp_migrate/data/articles.csv'
  header_row_count: 1
  ids:
    - id
process:
  nid: id
  title: title
  body/format:
    plugin: default_value
    default_value: full_html
  body/value: body
  changed:
    plugin: callback
    source: update
    callable: strtotime
    created: date
  created:
    plugin: callback
    source: update
    callable: strtotime
    created: DateCreated
  status: Status
  type:
    plugin: default_value
    default_value: article
destination:
  plugin: 'entity:node'
migration_dependencies:
  required: {  }

```

When I run the migration script, this is what happen when both the *Changed* and *Created* fields are entered.

>

>

This is the content of the CSV file used for the migration.

>

Why is the date off? How can I fix it?

# Answer
> 7 votes
Turns out that for created & changed dates, they are stored differently than field\_date's, you must convert these to Unix universal time.

```
  changed:
    plugin: format_date
    source: update
    from_format: 'm/d/Y'
    to_format: 'U'
    from_timezone: 'UTC'
    to_timezone: 'UTC'
  created:
    plugin: format_date
    source: DateCreated
    from_format: 'm/d/Y'
    to_format: 'U'
    from_timezone: 'UTC'
    to_timezone: 'UTC'

```

---
Tags: nodes, migrations
---


title: Programmatically create a user account

text:
# Question
Title: Programmatically create a user account
I know that I can programmatically create a user using the following code, in Drupal 7.

```
$new_user = array(
  'name' => $name,
  'pass' => $sifra, // note: do not md5 the password
  'mail' => $email,
  'status' => 1,
  'init' => $email,
  'roles' => array(
    DRUPAL_AUTHENTICATED_RID => 'authenticated user',
    3 => 'custom role',
  ),
);

// The first parameter is sent blank so a new user is created.
user_save('', $new_user);

```

What is the equivalent code in Drupal 8?

# Answer
You should use the suiting entity class. In case of a user it would be `Drupal\user\Entity\User`and you can use it as follows:

```
Drupal\user\Entity\User::create([
  'name' => $name,
  'pass' => $sifra,
  …
])->save();

```

Make sure to check the *Create* section on Working with the Entity API.
> 7 votes

# Answer
For Drupal 8, the code to create a user entity is the following one.

```
$language = \Drupal::languageManager()->getCurrentLanguage()->getId();
$user = \Drupal\user\Entity\User::create();

// Mandatory.
$user->setPassword('password');
$user->enforceIsNew();
$user->setEmail('email');
$user->setUsername('user_name');

// Optional.
$user->set('init', 'email');
$user->set('langcode', $language);
$user->set('preferred_langcode', $language);
$user->set('preferred_admin_langcode', $language);
$user->set('setting_name', 'setting_value');
$user->addRole('rid');
$user->activate();

// Save user account.
$result = $user->save();

```

The code can be found on Create a user account programmatically in Drupal 8.
> 14 votes

# Answer
**For beyond Drupal 8.3.**

```
<?php

use Drupal\user\Entity\User;

// Create user object.
$user = User::create();

//Mandatory settings
$user->setPassword("password");
$user->enforceIsNew();
$user->setEmail("email");
$user->setUsername("username"); //This username must be unique and accept only a-Z,0-9, - _ @ .
$user->addRole('role_name'); //E.g: authenticated

```

To Set custom field values

```
$user->set("field_machine_name", 'value');

```
> 3 votes

# Answer
This is the code I used to migrate old Drupal 6 user records to Drupal 8. I used the *entity\_type.manager* service to create user entities.

```
$values = [
  'name'                     => $data['name'],
  'pass'                     => $data['pass'],
  'mail'                     => $data['mail'],
  'init'                     => $data['init'],
  'status'                   => $data['status'],
  'timezone'                 => $data['timezone_name'],
  'created'                  => $data['created'],
  'access'                   => $data['access'],
  'login'                    => $data['login'],
  'langcode'                 => $data['language'],
  'preferred_langcode'       => $data['language'],
  'preferred_admin_langcode' => $data['language'],
];

if (!empty($data['picture'])) {
  $file_remote_url = $remoteBaseUrl . $data['picture'];
  $file_content = file_get_contents($file_remote_url);
  $file_name = basename($data['picture']);
  $file_uri = 'public://' . $file_name;

  if (!empty($file_content)) {
    $file = file_save_data($file_content, $file_uri, FILE_EXISTS_REPLACE);
    if ($file) {
      $values['user_picture'] = $file->id();
    }
  }
}

/** @var \Drupal\user\Entity\User $entity */
$entity = \Drupal::entityTypeManager()
  ->getStorage('user')
  ->create($values);
$entity->save();

```
> 1 votes

# Answer
For Drupal 8 I use this code to create a user with a predefined uid and an already hashed password from Drupal 7:

```
        $user = User::create(array(
          'uid' => $data[0],
          'name' => $data[1],
          'pass' => $data[2],
          'mail' => $data[3],
          'status' => $data[4],
          'access' => $data[6],
          'login' => $data[7],
          'timezone' => $data[8],
          'langcode' => $data[9],
          'preferred_langcode' => $data[9],
          'preferred_admin_langcode' => $data[9],
          'init' => $data[10],
        ));
        $user->created = $data[5];
        $roles = explode(",", $data[11]);
        foreach ($roles as $role) {
          switch ($role) {
            case 3:
              $user->addRole('administrator');
              break;

            case 4:
              $user->addRole('contributeur');
              break;

            case 6:
              $user->addRole('admin_m2');
              break;
          }
        }
        // Save user account.
        $user->save();

        $database = \Drupal::database();
        // Dirty overwrite of the re-hashed hash.
        $database->merge('users_field_data')
          ->fields(['pass' => 'YOUR_D7_HASH_HERE'])
          ->keys(array('uid' => $data[0]))
          ->execute();

```
> 1 votes

---
Tags: users, 8
---


# Question
Title: How do I set the default value of an exposed filter to a value that is not "-Any-"?
I have a view with exposed filters, in Drupal 8. I need to set the default value of a filter to its title or custom text. I also need to unset/remove the *\- Any -* option from the select list.

How can I achieve this?

Here is my code:

```
    function bootstrap_barrio_subtheme_form_alter(&$form, FormStateInterface
    $form_state, $form_id) {
        if ($form_state['view'] == 'office_locations_doctor_detail') {
            $form['field_doctor_reference_target_id_1']['#default_value'] =
            'Select Doctor';
        }
     }

```

Cleared the cache and reload the page but nothing changed.

# Answer
Try this:

```
/**
 * Implements hook_form_BASE_FORM_ID_alter().
 */
function bootstrap_barrio_subtheme_form_views_exposed_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if ( $form_state->get('view')->id() == 'office_locations_doctor_detail'){
     // Set the default value as tid not the name of term.
     // Change 'Select Doctor' by the tid of it.
    $form['field_doctor_reference_target_id_1']['#default_value'] = '1';
    // Remove - Any - option.
    unset($form['field_doctor_reference_target_id_1']['#options']['All']);
  }
}

```
> 2 votes

---
Tags: views, 8
---