title: Failed updating from 8.8.8 to 8.9.2

text:
# Question
Title: Failed updating from 8.8.8 to 8.9.2
I want to update my Drupal website from 8.8.8 to 8.9.2.

I have separately tried each of the below:

1. Run `composer update`
2. Removing both `Vendor` directory and `composer.lock` file then run `composer install`
3. Removing both `Vendor` directory and `composer.lock` file then run `composer update`
4. Manually changing all lines in `composer.json` file (`"drupal/core-composer-scaffold"` and `"drupal/core-project-message"` and `"drupal/core-recommended"`) from `^8.8` to `^8.9` then run `composer install`

None of the above worked for me and the site still until now running on "Drupal 8.8.8"

I have my own backup in case something wrong happened :)

For example when I removing both `Vendor` directory and `composer.lock` file then ran `composer update` command, I received the below:

```
user@user.com [~/public_html/dev.example.com]# composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 1 install, 28 updates, 0 removals
  - Updating drupal/core-composer-scaffold (8.8.5 => 8.9.2): Downloading (100%)
  - Updating drupal/core-project-message (8.8.5 => 8.9.2): Downloading (100%)
  - Updating composer/installers (v1.7.0 => v1.9.0): Loading from cache
  - Installing symfony/polyfill-php80 (v1.18.0): Loading from cache
  - Updating symfony/polyfill-php72 (v1.16.0 => v1.18.0): Loading from cache
  - Updating symfony/var-dumper (v4.4.8 => v4.4.11): Loading from cache
  - Updating webmozart/assert (1.8.0 => 1.9.1): Loading from cache
  - Updating drupal/better_exposed_filters (4.0.0-beta1 => 4.0.0-beta2): Downloading (100%)
  - Updating drupal/conditional_fields (1.0.0-alpha8 => 1.0.0-alpha9): Downloading (100%)
  - Updating drupal/flag (4.0.0-beta1 => 4.0.0-beta2): Downloading (100%)
  - Updating drupal/fontawesome (2.16.0 => 2.17.0): Loading from cache
  - Updating drupal/simplify (1.1.0 => 1.2.0): Loading from cache
  - Updating drupal/sms_simplegateway (1.1.0 => 1.2.0): Loading from cache
  - Updating drupal/webform (6.0.0-alpha8 => 6.0.0-alpha12):  Checking out 6.0.0-alpha12
  - Updating symfony/finder (v4.4.8 => v4.4.11): Downloading (100%)
  - Updating nikic/php-parser (v4.4.0 => v4.7.0): Loading from cache
  - Updating consolidation/site-alias (3.0.0 => 3.0.1): Loading from cache
  - Updating symfony/filesystem (v4.4.8 => v4.4.11): Downloading (100%)
  - Updating chi-teck/drupal-code-generator (1.32.0 => 1.32.1): Loading from cache
  - Updating drush/drush (10.2.2 => 10.3.1): Downloading (100%)
  - Updating algolia/places (1.17.1 => 1.18.2): Loading from cache
  - Updating codemirror/codemirror (5.51.0 => 5.53.2): Loading from cache
  - Updating jquery/image-picker (0.3.0 => 0.3.1): Loading from cache
  - Updating jquery/select2 (4.0.12 => 4.0.13): Loading from cache
  - Updating jquery/textcounter (0.8.0 => 0.9.0): Loading from cache
  - Updating jquery/timepicker (1.13.0 => 1.13.10): Loading from cache
  - Updating progress-tracker/progress-tracker (1.4.0 => 2.0.6): Loading from cache
  - Updating giggsey/locale (1.8 => 1.9): Loading from cache
  - Updating giggsey/libphonenumber-for-php (8.12.3 => 8.12.4): Loading from cache
Package container-interop/container-interop is abandoned, you should avoid using it. Use psr/container instead.
Package zendframework/zend-diactoros is abandoned, you should avoid using it. Use laminas/laminas-diactoros instead.
Package zendframework/zend-escaper is abandoned, you should avoid using it. Use laminas/laminas-escaper instead.
Package zendframework/zend-feed is abandoned, you should avoid using it. Use laminas/laminas-feed instead.
Package zendframework/zend-stdlib is abandoned, you should avoid using it. Use laminas/laminas-stdlib instead.
Writing lock file
Generating autoload files
Scaffolding files for drupal/core:
  - Copy [project-root]/.editorconfig from assets/scaffold/files/editorconfig
  - Copy [project-root]/.gitattributes from assets/scaffold/files/gitattributes
  - Copy [web-root]/.csslintrc from assets/scaffold/files/csslintrc
  - Copy [web-root]/.eslintignore from assets/scaffold/files/eslintignore
  - Copy [web-root]/.eslintrc.json from assets/scaffold/files/eslintrc.json
  - Copy [web-root]/.ht.router.php from assets/scaffold/files/ht.router.php
  - Copy [web-root]/.htaccess from assets/scaffold/files/htaccess
  - Copy [web-root]/example.gitignore from assets/scaffold/files/example.gitignore
  - Copy [web-root]/index.php from assets/scaffold/files/index.php
  - Copy [web-root]/INSTALL.txt from assets/scaffold/files/drupal.INSTALL.txt
  - Copy [web-root]/README.txt from assets/scaffold/files/drupal.README.txt
  - Copy [web-root]/robots.txt from assets/scaffold/files/robots.txt
  - Copy [web-root]/update.php from assets/scaffold/files/update.php
  - Copy [web-root]/web.config from assets/scaffold/files/web.config
  - Copy [web-root]/sites/README.txt from assets/scaffold/files/sites.README.txt
  - Copy [web-root]/sites/development.services.yml from assets/scaffold/files/development.services.yml
  - Copy [web-root]/sites/example.settings.local.php from assets/scaffold/files/example.settings.local.php
  - Copy [web-root]/sites/example.sites.php from assets/scaffold/files/example.sites.php
  - Copy [web-root]/sites/default/default.services.yml from assets/scaffold/files/default.services.yml
  - Copy [web-root]/sites/default/default.settings.php from assets/scaffold/files/default.settings.php
  - Copy [web-root]/modules/README.txt from assets/scaffold/files/modules.README.txt
  - Copy [web-root]/profiles/README.txt from assets/scaffold/files/profiles.README.txt
  - Copy [web-root]/themes/README.txt from assets/scaffold/files/themes.README.txt

```

Yet the site is running on 8.8.8 Core and the `/admin/reports/updates/update` section of my site still asking me to update `core` from `8.8.8` to `8.9.2`

As shown above, there is no errors at all and the update seems to be running smoothly.

Any idea what I am missing here ?

**UPDATE #1:**

I have tried `composer update --with-dependencies` and got the below output:

```
  - Updating drupal/core-composer-scaffold (8.8.5 => 8.9.2): Loading from cache
  - Updating drupal/core-project-message (8.8.5 => 8.9.2): Loading from cache
  - Updating composer/installers (v1.7.0 => v1.9.0): Loading from cache
  - Installing symfony/polyfill-php80 (v1.18.0): Loading from cache
  - Updating symfony/polyfill-php72 (v1.16.0 => v1.18.0): Loading from cache
  - Updating symfony/var-dumper (v4.4.8 => v4.4.11): Loading from cache
  - Updating webmozart/assert (1.8.0 => 1.9.1): Loading from cache
  - Updating drupal/better_exposed_filters (4.0.0-beta1 => 4.0.0-beta2): Loading from cache
  - Updating drupal/conditional_fields (1.0.0-alpha8 => 1.0.0-alpha9): Loading from cache
  - Updating drupal/flag (4.0.0-beta1 => 4.0.0-beta2): Loading from cache
  - Updating drupal/fontawesome (2.16.0 => 2.17.0): Loading from cache
  - Updating drupal/simplify (1.1.0 => 1.2.0): Loading from cache
  - Updating drupal/sms_simplegateway (1.1.0 => 1.2.0): Loading from cache
  - Updating drupal/webform (6.0.0-alpha8 => 6.0.0-alpha12):  Checking out 6.0.0-alpha12
  - Updating symfony/finder (v4.4.8 => v4.4.11): Loading from cache
  - Updating nikic/php-parser (v4.4.0 => v4.7.0): Loading from cache
  - Updating consolidation/site-alias (3.0.0 => 3.0.1): Loading from cache
  - Updating symfony/filesystem (v4.4.8 => v4.4.11): Loading from cache
  - Updating chi-teck/drupal-code-generator (1.32.0 => 1.32.1): Loading from cache
  - Updating drush/drush (10.2.2 => 10.3.1): Loading from cache
  - Updating algolia/places (1.17.1 => 1.18.2): Loading from cache
  - Updating codemirror/codemirror (5.51.0 => 5.53.2): Loading from cache
  - Updating jquery/image-picker (0.3.0 => 0.3.1): Loading from cache
  - Updating jquery/select2 (4.0.12 => 4.0.13): Loading from cache
  - Updating jquery/textcounter (0.8.0 => 0.9.0): Loading from cache
  - Updating jquery/timepicker (1.13.0 => 1.13.10): Loading from cache
  - Updating progress-tracker/progress-tracker (1.4.0 => 2.0.6): Loading from cache
  - Updating giggsey/locale (1.8 => 1.9): Loading from cache
  - Updating giggsey/libphonenumber-for-php (8.12.3 => 8.12.4): Loading from cache

```

then I ran `drush updb` and `drush cr` and yet the site still running on Core 8.8.8 !?!?!

Also, I have tried to run `composer prohibits drupal/core` to see what is preventing the site update and I got the below results:

```
user@example.com [~/public_html/dev.example.com]# composer prohibits drupal/core
drupal/addtoany                    1.14.0        requires  drupal/core (^8 || ^9)
drupal/admin_toolbar               2.3.0         requires  drupal/core (^8.8.0 || ^9.0)
drupal/better_exposed_filters      4.0.0-beta1   requires  drupal/core (^8 || ^9)
drupal/blazy                       2.1.0         requires  drupal/core (^8.8 || ^9)
drupal/business_rules              1.0.0-beta10  requires  drupal/core (~8.0)
drupal/captcha                     1.1.0         requires  drupal/core (^8.8 || ^9)
drupal/change_pwd_page             1.0.0         requires  drupal/core (^8 || ^9)
drupal/colorbox                    1.6.0         requires  drupal/core (^8.8 || ^9)
drupal/conditional_fields          1.0.0-alpha8  requires  drupal/core (*)
drupal/core-recommended            8.8.8         requires  drupal/core (8.8.8)
drupal/ctools                      3.4.0         requires  drupal/core (^8.7.7 || ^9)
drupal/dbug                        1.0.0         requires  drupal/core (~8.0)
drupal/dynamic_entity_reference    1.10.0        requires  drupal/core (^8.7.7 || ^9)
drupal/entity_reference_revisions  1.8.0         requires  drupal/core (^8.7.7 || ^9)
drupal/eva                         2.1.0         requires  drupal/core (^8 || ^9)
drupal/field_group                 3.1.0         requires  drupal/core (^8.8 || ^9)
drupal/field_permissions           1.0.0         requires  drupal/core (^8 || ^9)
drupal/field_timer                 1.x-dev       requires  drupal/core (^8 || ^9)
drupal/firebase                    2.0.0         requires  drupal/core (^8.3.0)
drupal/flag                        4.0.0-beta1   requires  drupal/core (~8.0)
drupal/fontawesome                 2.16.0        requires  drupal/core (^8 || ^9)
drupal/google_analytics            3.1.0         requires  drupal/core (^8.8.6|^9.0)
drupal/jquery_ui                   1.4.0         requires  drupal/core (^8 || ^9)
drupal/jquery_ui_accordion         1.1.0         requires  drupal/core (^8 || ^9)
drupal/jquery_ui_checkboxradio     1.2.0         requires  drupal/core (^8 || ^9)
drupal/jquery_ui_datepicker        1.0.0         requires  drupal/core (^8 || ^9)
drupal/jquery_ui_tabs              1.1.0         requires  drupal/core (^8 || ^9)
drupal/jquery_ui_tooltip           1.1.0         requires  drupal/core (^8 || ^9)
drupal/module_filter               3.1.0         requires  drupal/core (~8.0)
drupal/pathauto                    1.8.0         requires  drupal/core (^8.8 || ^9)
drupal/persistent_login            1.3.0         requires  drupal/core (^8.3 || ^9.0)
drupal/reroute_email               1.2.0         requires  drupal/core (^8 || ^9)
drupal/simple_fb_connect           3.1.0         requires  drupal/core (~8.0)
drupal/simplify                    1.1.0         requires  drupal/core (~8.0)
drupal/sitewide_alert              1.3.0         requires  drupal/core (^8 || ^9)
drupal/slick                       2.2.0         requires  drupal/core (^8.8 || ^9)
drupal/slick_views                 2.3.0         requires  drupal/core (^8 || ^9)
drupal/sms                         1.3.0         requires  drupal/core (>=8.6 <8.9)
drupal/sms_simplegateway           1.1.0         requires  drupal/core (~8.0)
drupal/smsframework                1.3.0         requires  drupal/core (~8.0)
drupal/subpathauto                 1.1.0         requires  drupal/core (^8.8 || ^9)
drupal/telephone_validation        2.3.0         requires  drupal/core (^8 || ^9)
drupal/token                       1.7.0         requires  drupal/core (^8.7.7 || ^9)
drupal/token_filter                1.2.0         requires  drupal/core (^8 || ^9)
drupal/ultimate_cron               2.0.0-alpha4  requires  drupal/core (~8.0)
drupal/video                       1.4.0         requires  drupal/core (*)
drupal/views_infinite_scroll       1.7.0         requires  drupal/core (^8.8 || ^9)
drupal/webform                     6.0.0-alpha8  requires  drupal/core (^8.8 || ^9)

```

Thank you,

# Answer
Looking at your prohibits output, `drupal/sms` is blocking the update:

> requires drupal/core (\>=8.6 \<8.9)

You can try switching to smsframework.
> 1 votes

# Answer
You should run:

```
composer update --with-dependencies

```

If that doesn't work, run:

```
composer prohibits drupal/core

```

That should tell you what is holding back the update of drupal/core.
> 0 votes

---
Tags: 8, composer
---


# Question
Title: How can I get the form builder service using dependency injection?
How can I change form builder call in class in to dependency injection method?

My current code:

```
class CustomBlock extends BlockBase {

  /**
   * {@inheritdoc}
   */
  public function build() {
    $form = \Drupal::formBuilder()->getForm('Drupal\custom_module\Form\CustomForm');
    return $form;
  }

}

```

And I tried:

```
class CustomBlock extends BlockBase {

  /**
   * formBuilder.   *
   */
  protected $formBuilder;

  /**
   * Class constructor.
   */
  public function __construct($formBuilder) {
    $this->formBuilder = $formBuilder;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
        $container->get('form_builder')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function build() {
    $form = $this->formBuilder->getForm('Drupal\custom_module\Form\CustomForm');
    return $form;
  }

}

```

But getting following error:

> Fatal error: Call to a member function getForm() on a non-object in H:\wamp\www\myproject\modules\custom\custom\_module\src\Plugin\Block\CustomBlock.php on line 44

# Answer
> 3 votes
You have to implement the `\Drupal\Core\Plugin\ContainerFactoryPluginInterface`. The `\Drupal\Core\Block\BlockBase` doesn't implement it by default.

Also, your IDE is probably not that good since it would show you the `create()` method is not implemented.

# Answer
> 3 votes
AJAX form test mock module's `AjaxFormBlock.php` is quite a nice example for getting both in one, the form builder and the form interface! Look how it `implements FormInterface, ContainerFactoryPluginInterface` to then provide the form from within the block and injecting the form builder via dependency injection to then be used to get the form in the block's `build()` method at the same time.

Of course, when you only need the form builder, you don't need to implement the `FormInterface`! Then you just need the `ContainerFactoryPluginInterface`.

> ```
> namespace Drupal\ajax_forms_test\Plugin\Block;
>
> use Drupal\Core\Block\BlockBase;
> use Drupal\Core\Form\FormBuilderInterface;
> use Drupal\Core\Form\FormInterface;
> use Drupal\Core\Form\FormStateInterface;
> use Drupal\Core\Messenger\MessengerInterface;
> use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
> use Symfony\Component\DependencyInjection\ContainerInterface;
>
> /**
>  * Provides an AJAX form block.
>  *
>  * @Block(
>  *   id = "ajax_forms_test_block",
>  *   admin_label = @Translation("AJAX test form"),
>  *   category = @Translation("Forms")
>  * )
>  */
> class AjaxFormBlock extends BlockBase implements FormInterface, ContainerFactoryPluginInterface {
>
>   /**
>    * The form builder.
>    *
>    * @var \Drupal\Core\Form\FormBuilderInterface
>    */
>   protected $formBuilder;
>
>   /**
>    * The messenger.
>    *
>    * @var \Drupal\Core\Messenger\MessengerInterface
>    */
>   protected $messenger;
>
>   /**
>    * Constructs a new AjaxFormBlock.
>    *
>    * @param array $configuration
>    *   A configuration array containing information about the plugin instance.
>    * @param string $plugin_id
>    *   The plugin ID for the plugin instance.
>    * @param mixed $plugin_definition
>    *   The plugin implementation definition.
>    * @param \Drupal\Core\Form\FormBuilderInterface $form_builder
>    *   The form builder.
>    * @param \Drupal\Core\Messenger\MessengerInterface $messenger
>    *   The messenger.
>    */
>   public function __construct(array $configuration, $plugin_id, $plugin_definition, FormBuilderInterface $form_builder, MessengerInterface $messenger) {
>     parent::__construct($configuration, $plugin_id, $plugin_definition);
>     $this->formBuilder = $form_builder;
>     $this->messenger = $messenger;
>   }
>
>   /**
>    * {@inheritdoc}
>    */
>   public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
>     return new static(
>       $configuration,
>       $plugin_id,
>       $plugin_definition,
>       $container->get('form_builder'),
>       $container->get('messenger')
>     );
>   }
>
>   /**
>    * {@inheritdoc}
>    */
>   public function build() {
>     return $this->formBuilder->getForm($this);
>   }
>
>   /**
>    * {@inheritdoc}
>    */
>   public function getFormId() {
>     return 'ajax_forms_test_block';
>   }
>
>   /**
>    * {@inheritdoc}
>    */
>   public function buildForm(array $form, FormStateInterface $form_state) {
>     $form['test1'] = [
>       '#type' => 'select',
>       '#title' => $this->t('Test 1'),
>       '#required' => TRUE,
>       '#options' => [
>         'option1' => $this->t('Option 1'),
>         'option2' => $this->t('Option 2'),
>       ],
>       '#ajax' => [
>         'callback' => '::updateOptions',
>         'wrapper' => 'edit-test1-wrapper',
>       ],
>       '#prefix' => '<div id="edit-test1-wrapper">',
>       '#suffix' => '</div>',
>     ];
>     $form['actions'] = [
>       '#type' => 'actions',
>     ];
>     $form['actions']['submit'] = [
>       '#type' => 'submit',
>       '#value' => $this->t('Submit'),
>     ];
>     return $form;
>   }
>
>   /**
>    * Updates the options of a select list.
>    *
>    * @param array $form
>    *   An associative array containing the structure of the form.
>    * @param \Drupal\Core\Form\FormStateInterface $form_state
>    *   The current state of the form.
>    *
>    * @return array
>    *   The updated form element.
>    */
>   public function updateOptions(array $form, FormStateInterface $form_state) {
>     $form['test1']['#options']['option1'] = $this->t('Option 1!!!');
>     $form['test1']['#options'] += [
>       'option3' => $this->t('Option 3'),
>       'option4' => $this->t('Option 4'),
>     ];
>     return $form['test1'];
>   }
>
>   /**
>    * {@inheritdoc}
>    */
>   public function validateForm(array &$form, FormStateInterface $form_state) {
>   }
>
>   /**
>    * {@inheritdoc}
>    */
>   public function submitForm(array &$form, FormStateInterface $form_state) {
>     $this->messenger->addStatus('Submission successful.');
>   }
>
> }
>
> ```

---

Another nice example is core's `SearchBlock.php`.

Also worth checking out the docs on Dependency injection in Plugin (Block).

# Answer
> 1 votes
Try this this solution will work.

```
<?php

namespace Drupal\firstcustommodule\Plugin\Block;

use Drupal\Core\Block\BlockBase;
use Drupal\Core\Form\FormBuilderInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Provides a 'Hello' block.
 *
 * @Block(
 *   id = "hello_block",
 *   admin_label = @Translation("Hello Block")
 * )
 */
class HelloBlock extends BlockBase implements ContainerFactoryPluginInterface {

  /**
   * The form builder service.
   *
   * @var \Drupal\Core\Form\FormBuilderInterface
   */
  protected $formBuilder;

  /**
   * Constructs a HelloBlock object.
   *
   * @param array $configuration
   *   A configuration array containing information about the plugin instance.
   * @param string $plugin_id
   *   The plugin ID for the plugin instance.
   * @param mixed $plugin_definition
   *   The plugin implementation definition.
   * @param \Drupal\Core\Form\FormBuilderInterface $form_builder
   *   The form builder.
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, FormBuilderInterface $form_builder) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->formBuilder = $form_builder;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    // Instantiate this block class.
    return new static($configuration, $plugin_id, $plugin_definition,
      // Load the service required to construct this class.
      $container->get('form_builder')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function build() {
    return $this->formBuilder->getForm('Drupal\firstcustommodule\Form\CompanyAddForm');
  }

}

```

# Answer
> -2 votes
Simple Answer with updated code you just forgot to Import namespace at top and you have not defined the **FormBuilderInterface** type of object @ constructor

```
 use Drupal\Core\Form\FormBuilderInterface;
 class CustomBlock extends BlockBase {

  /**
   * The form builder.
   *
   * @var \Drupal\Core\Form\FormBuilderInterface
   */
   protected $formBuilder;

  /**
   * @param \Drupal\Core\Form\FormBuilderInterface $form_builder The Form Builder.
   */

  public function __construct(FormBuilderInterface $formBuilder) {
    $this->formBuilder = $formBuilder;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
        $container->get('form_builder')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function build() {
    $form = $this->formBuilder->getForm('Drupal\custom_module\Form\CustomForm');
    return $form;
  }

}

```

---
Tags: 8, dependency-injection
---


# Question
Title: Show views active filter values as pills without using Facets
I have this requirement where selected filter values need to appear as "pills" on the page with an "x" which, when clicked, would unset the filter and reload the search without that value. I've used Active Facet Pills once before to achieve this. However, the view I'm working with is just a plain vanilla view (no facets). I've done a lot of searching, but nothing seems to come up on how to implement this.

How does one achieve this in D7 views?

# Answer
> 0 votes
Facet API seems to be the common module for Facets in D7.

It seems there is the "Summary" option that is the "pills" feature you're looking for.

---
Tags: 7, views
---


# Question
Title: I would like to create a content type - a static page that can be updated and searched for - that contains multiple content types in a specific order
The "new content type" would consist of several other content types. 1) Company with multiple fields (text, URL etc.) 2) product class (label, text) 3) product class description (label, text) 4) product (text) 5) Notes (text) to be updated 6) events (text)

There would be 100s of companies, product classes, products, events etc. and I would like to be able to pick one from each content type to make the "new content type"

# Answer
It seems that your structural needs would be best solved with creating a separate Content Type for each of the combination of data that can meaningfully stand independently on its own.

Company seems to be one, you'll probably need one CT for Companies.

If Product type info always comes together in one whole then it makes sense to create a CT for Product. But if different product info are independent then they should be just fields in your "global", "combination" Content Type.

That last CT should reference a Company through an Entity Reference field and include other text fields for your Product data, or one ER field if Product is an independent CT.

With the help of Inline Entity Form module you can make the Company nodes automatically when creating your global node, if you need that feature, but sort out your structure before you play with this.

You can use Paragraphs module to rearrange references to other CTs in your global CT, so they are different in each node, but it doesn't seem that you need that, or the Layout builder module to override layout for each global node.

You need to be able to pick new combinations from existing data then it makes sense to create Content Types and Taxonomy Vocabularies and terms, and then create the final Content Type that references those CTs and Taxonomies.

There are various options available on how to display the referenced data on the final CT pages.

I don't think you need to learn about Views to solve this problem. But the concept of Content types and Taxonomies is the basis for Drupal and web dev Information Architecture in general. You can find tutorials about those basics online, Drupal specifically so I expect you can easily solve your problem with these instructions after you learn the basics.
> 1 votes

---
Tags: entities
---


title: How to add fields to menu items

text:
# Question
Title: How to add fields to menu items
I need to build a main menu that is a subset of the regular menu. The design team thinks it would be better for user to have only the most important links in the main menu and not have everything. Some links are top level menu and some are sub menus. For this I was hoping to be able to add a field to the menu link item form as a drop down. When creating a link the user could use this dropdown to "promoteToMainMenuAsBigLink" or "promoteToMainMenuAsSmallLink" or leave none to not show the item on the main menu.

I'm looking for a similar solution as this Drupal 7 solution but for Drupal 8.

I was hoping to be able to add a column in the table menu\_link\_content\_data beside 'expanded'. I was hoping not to have to record this information in an other table like shown in the d7 solution.

I was able to add a field to the link form in a custom module I build, just for test purpose I only added a text field to start with:

custom\_menu.module:

```
function custom_menu_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if($form_id == 'menu_link_content_menu_link_content_form') {
    $form['promoteToMainMenu'] = array(
      '#type' => 'textfield',
      '#title' => t('Promote to main menu'),
      '#description' => t('Promote link menu to main menu.'),
      '#default_value' => '',
      '#weight' => -9
    );
  }
}

```

The field is indeed shown in the link form but it is never recorded.

Can someone help me with this?

# Answer
Check the Menu Item Extras module.
> 16 votes

# Answer
You can use `hook_entity_base_field_info` to add an additional field to the `menu_link_content` entity with the following code:

```
/**
 * Implements hook_entity_base_field_info().
 */
function MYMODULE_entity_base_field_info(\Drupal\Core\Entity\EntityTypeInterface $entity_type) {
  $fields = [];

  if ($entity_type->id() == 'menu_link_content') {
    $fields['FIELD_NAME'] = \Drupal\Core\Field\BaseFieldDefinition::create('FIELD_TYPE')
      ->setLabel(t('FIELD_LABEL'))
      ->setDescription(t('FIELD_DESCRIPTION '))
      ->setDisplayOptions('form', ['type' => 'FIELD_TYPE', 'weight' => 0]);
  }

  return $fields;
}

```

See https://www.drupal.org/docs/8/api/entity-api/defining-and-using-content-entity-field-definitions for more details on `BaseFieldDefinition`.

After which, you'll need `hook_form_menu_link_content_menu_link_content_form_alter()` to add a field to the form.
> 12 votes

# Answer
Unfortunately there is indeed no fields UI for menu links by default in Drupal 8 as @MatthieuScarset said. But `menu_link_content` is a content entity in Drupal 8, so it is possible to add fields to it.

**Option #1** Of course you can do it programmatically as @Decipher suggested.

**Option #2** But there is another workaround to enable fields UI for menu links temporary:

1. Open `Drupal\menu_link_content\Entity\MenuLinkContent`
2. Add `field_ui_base_route = "entity.menu.add_link_form"` to the annotation
3. Rebuild cache
4. Visit `/admin/structure/menu/manage/main/add/fields`
5. Manage all your fields, displays
6. Export your site configuration (`drush cex -y`).
7. Remove `field_ui_base_route = "entity.menu.add_link_form"` from the annotation at `Drupal\menu_link_content\Entity\MenuLinkContent`
8. Rebuild cache.
> 3 votes

# Answer
You could use Colossal Menu to add the field instead of the core Menu module.
> 3 votes

# Answer
"Menu item extras" is one way to achieve this, as @Mykhailo Gurei suggested.

But in my case I had to add extra fields and to use Mega menu module. I was using "We mega menu" and with it "Menu item extras" is not working. Simply menu is not shown on front-end (some templates override issue).

So other option that works with "We mega menu" is "Menu item content fields":

https://www.drupal.org/project/menu\_item\_fields

Has the same functionality and doesn't have conflict with We mega menu module.
> 0 votes

# Answer
A newer solution could be menu item content fields

According to the project description its **features** are:

* Add fields to menu items and sort their display.
* Show fielded menu items with a block chosing the view mode.
* Configure additional options on the formatter like the rel and target attributes.
* Add more attributes with the Link attributes module.
* Optionally have a field on the menu link entity that overrides the display mode.
    + Is up to the site builder to create it.
    + This field needs to store the string value of the display mode, for example: 'mega'.
> 0 votes

# Answer
Unfortunately, Drupal 8 core developers have not made Menu links fieldable. So it is not possible to add fields to menu links for now.

The site builder "work around" is to create a custom vocabulary which can have custom fields.
> -3 votes

---
Tags: 8, navigation
---


# Question
Title: How do I store custom block content as configuration?
I'm creating custom pages using Pages + Layout Builder. These layouts need to be stored in GIT as config files (`drush cex`). Currently, the layouts themselves are stored fine.

The main problem is that custom block contents are stored in the database and if someone clones the repository and applies changes using `drush cim`, they are missing the block contents.

# Answer
> 6 votes
Then don't use custom block types because they are stored in content entities.

Use blocks storing only configuration. You can build a custom block plugin, even with a body field. See Custom block build function to display wysiwyg body text

There are also some contrib options like Simple Block which is implementing a config entity for blocks.

---
Tags: 8, configuration, layout-builder
---


# Question
Title: How to override configuration from a file?
I have been playing a lot lately with an import configuration to Drupal 8. And I notice that all documentation show you how to edit value per value instead of overriding the entire config file. You can find more information about this at Configuration override system page.

I notice that DrupalConsole and Drush have the ability of overriding configuration by file.

* Using Drush, you can run `drush config-import`
* Using DrupalConsole, you can run `drupal config-import`

This will override the entire configuration base on the configuration file. How can I achieve this on the code? Hopefully, I will like to edit my configuration when I'm installation my module on **hook\_install**.

# Answer
> 8 votes
To override config on code is simple. Above is an exemple how you get, set and save any config (that you just installed via .yml and from core).

**On .install or .module file**

```
  //Getting editable configs
  $module_cfg = \Drupal::configFactory()->getEditable('your.module.file');
  $settings = \Drupal::configFactory()->getEditable('any_core.settings');
  //Getting values
  $a_value = $settings->get('key_from_core');
  //Setting and save configs
  $module_cfg->set('any.key', $a_value)->save();
  $settings->set('key', 'new_value')->save();

```

From **hook\_install** docs:

> Implementations of this hook are by convention declared in the module's .install file.

For further information see ConfigFactory docs.

There is a module called Features that helps if you want keep on track of your configs. I'm currently using this module for code-driven development, maybe is this what you're looking for.

**Edit 1 - Replace entire config**

First of all, you need to provide which config you pretend to override.

**On my.custom.config.yml file**

```
# Make sure this config exists in your database
target: 'config.to.override'
... # all your data (CAUTION with 'dependencies')

```

**On .install file**

```
function module_install() {
  //Get your custom config
  $cfg = \Drupal::configFactory()->getEditable('my.custom.config');
  //Get config name to override
  $target = $cfg->get('target');
  //Get Config object
  $settings = \Drupal::configFactory()->getEditable($target);
  //Override all data that can be overridden
  $settings->setData($cfg->get())->save();
  //If you won't store any previous state, get rid of your custom config
  $cfg->delete();
}

```

This was tested in my development environment.

# Answer
> 4 votes
I leave here another example, in addition to **@Vagner's answer**, in case it is useful.

The scenario is as follows: *I would like to override addtoany's settings.*

The module's settings are located at `modules/contrib/addtoany/config/install/addtoany.settings.yml`.

In order to override them, create a custom module `foobar` and a file `modules/custom/foobar/config/install/foobar.addtoany.settings.yml`:

```
buttons_size: 32
additional_html: |
  <a class="a2a_button_facebook"></a>
  <a class="a2a_button_twitter"></a>
additional_css: ''
additional_js: ''
universal_button: none
custom_universal_button: ''
universal_button_placement: before
no_3p: false

```

In `modules/custom/foobar/foobar.install`, apply the new settings:

```
<?php

function foobar_install()
{
  // Get your custom config
  $cfg = \Drupal::configFactory()->getEditable('foobar.addtoany.settings');
  // Get Config object
  $settings = \Drupal::configFactory()->getEditable('addtoany.settings');
  // Override all data that can be overridden
  $settings->setData($cfg->get())->save();
  // Get rid of your custom config
  $cfg->delete();
}

```

# Answer
> 1 votes
> Apparently we need to define all entries, even the ones we don't want to change

Maybe this was the case, but currently I have just used the above example in 4 (thanks turdus-merula) to override just two of Devel modules settings. The others remain untouched.

\[edit: cannot add my comment directly to dxvargas's reply to which it relates\]

# Answer
> 1 votes
Inspired by @Vagner's, answer, I choose to read a directory of config files to be imported during installation. Call this from HOOK\_install(). This avoid having to install config and then delete it. You can also simply copy config files from the sync director to the install/override directory (and remove the uuid entry of course). If you have a number of config files, this might be easier.

```
use Drupal\Core\Config\FileStorage;
// (snip)
/**
 * Read all configuration from config/override and install.
 */
function _MODULE_override_config() {
  $path = drupal_get_path('module', 'MODULE') . '/config/override';
  $file = new FileStorage($path);
  foreach ($file->listAll() as $id) {
    $config_data = $file->read($id);
    $config = \Drupal::configFactory()->getEditable($id);
    $config->setData($config_data)->save();
  }
}

```

---
Tags: 8, configuration
---


# Question
Title: Missing bundle entity, entity type paragraphs_type from field_instance.yml file
I'm currently trying to migrate my D7 site to D8 and one of the things migrating is field\_collections to paragraphs. I have a field\_collection call "field\_sidebar\_callouts". I want to migrate that to paragraphs.

Everything is migrating correctly until it reaches to field\_instance.yml file. It throws an error call this:

> Missing bundle entity, entity type paragraphs\_type, entity id r\_callouts

Is the instance.yml file importing half the id? How come the entity id is only "r\_callouts" and not "field\_sidebar\_callouts".

Did my field\_instance.yml get auto-generated incorrectly?

Any help would be amazing!

Here's my instance file:

```
uuid: 295c39a9-1857-4d53-a342-92a16ae71223
langcode: en
status: true
dependencies: {  }
id: upgrade_d7_field_instance
class: Drupal\migrate_drupal\Plugin\migrate\FieldMigration
field_plugin_method: alterFieldInstanceMigration
cck_plugin_method: null
migration_tags:
 - 'Drupal 7'
 - Configuration
 migration_group: migrate_drupal_7
label: 'Field instance configuration'
source:
 plugin: d7_field_instance
 constants:
  status: true
process:
 type:
  -
  plugin: process_field
  source: type
  method: getFieldType
 entity_type:
  -
   plugin: get
   source: entity_type
  -
   plugin: static_map
   map:
    field_collection_item: paragraph
    paragraphs_item: paragraph
  bypass: true
field_name:
  -
   plugin: get
   source: field_name
bundle:
 -
  plugin: static_map
  source: bundle
  bypass: true
  map:
    comment_node_forum: comment_forum
-
  plugin: paragraphs_process_on_value
  source_value: entity_type
  expected_value: field_collection_item
  process:
    plugin: substr
    start: 6
label:
 -
  plugin: get
  source: label
description:
 -
  plugin: get
  source: description
required:
 -
  plugin: get
  source: required
status:
 -
  plugin: get
  source: constants/status
allowed_values:
 -
  plugin: sub_process
  source: allowed_vid
  process:
    -
      plugin: migration_lookup
      migration: upgrade_d7_taxonomy_vocabulary
      source: vid
settings:
  0:
   plugin: d7_field_instance_settings
   source:
    - settings
    - widget
    - field_definition
field_collection:
  plugin: field_collection_field_instance_settings
default_value_function:
 -
  plugin: get
  source: ''
default_value:
 -
  plugin: d7_field_instance_defaults
  source:
    - default_value
    - widget
translatable:
 -
  plugin: get
  source: translatable
settings/title:
 -
  plugin: static_map
  source: settings/title
  bypass: true
  map:
    disabled: 0
    optional: 1
    required: 2
destination:
 plugin: 'entity:field_config'
migration_dependencies:
 required:
  - upgrade_d7_field
optional:
  - upgrade_d7_node_type
  - upgrade_d7_comment_type
  - upgrade_d7_taxonomy_vocabulary
  - upgrade_d7_field_collection_type

```

# Answer
I believe you need to change the `expected_value: field_collection_item` to match your field\_collection\_items
> 0 votes

---
Tags: entities, migrations, paragraphs
---


# Question
Title: How can I add Taxonomy Term to a Node's Breadcrumb?
The Node has attached a single Term.

Current breadcrumbs rendered

```
[HOME] >> [NODE_TITLE]

```

Want to render like this.

```
[HOME] >> [TERM] >> [NODE_TITLE]

```

# Answer
Yes @No Sssweat is right. I think you need to built a custom module for this.
Add Taxonomy Term to a Node's Breadcrumb in Drupal 8
> 0 votes

# Answer
Themers who don't want to use a custom module to implement a BreadcrumbBuilder can change the breadcrumbs in a preprocess hook.

Example how you can add a link before the last link:

```
function mytheme_preprocess_breadcrumb(&$variables) {
  $breadcrumb = &$variables['breadcrumb'];
  $lastlink = array_pop($breadcrumb);
  array_push($breadcrumb, [
    'text' => 'New Link',
    'url' => '/newlink',
  ]);
  array_push($breadcrumb, $lastlink);
}

```

If you add a taxonomoy term from a node you would have to add both as cache tags and a cache context on the url to make this work.
> 5 votes

# Answer
We can implement custom breadcrumb either via `module` or via `HOOK_preprocess_breadcrumb`.

Via `HOOK_preprocess_breadcrumb`:

Add this in your `YOURTHEME.theme`

```
/**
 * Implements HOOK_preprocess_breadcrumb().
 */
function YOURTHEME_preprocess_breadcrumb(&$variables) {
  if (($node = \Drupal::routeMatch()->getParameter('node')) && $variables['breadcrumb']) {
    $breadcrumb = &$variables['breadcrumb'];
    if (!empty($node->field_tags->entity)) {
      $term_url = $node->field_tags->entity->toLink();
      $node_url = array_pop($breadcrumb);
      array_push($breadcrumb, $term_url);
      array_push($breadcrumb, $node_url);
      // Implementing Cache.
      $variables['#cache']['contexts'][] = "url.path";
      $variables['#cache']['tags'][] = "node:{$node->nid->value}";
    }
  }
}

```

Via `module`:

In `custom_breadcrumb.module` file

```
<?php

namespace Drupal\custom_breadcrumb;

use Drupal\Core\Breadcrumb\Breadcrumb;
use Drupal\Core\Breadcrumb\BreadcrumbBuilderInterface;
use Drupal\Core\Link;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\node\NodeInterface;

/**
 * Class Breadcrumbs.
 *
 * @package Drupal\custom_breadcrumb
 */
class Breadcrumbs implements BreadcrumbBuilderInterface {
  use StringTranslationTrait;

  /**
   * {@inheritDoc}
   */
  public function applies(RouteMatchInterface $route_match) {
    return $route_match->getRouteName() == 'entity.node.canonical' && $route_match->getParameter('node') instanceof NodeInterface;
  }

  /**
   * {@inheritDoc}
   */
  public function build(RouteMatchInterface $route_match) {
    $node = $route_match->getParameter('node');
    $breadcrumb = new Breadcrumb();

    // By setting a "cache context" to the "url", each requested URL gets it's
    // own cache. This way a single breadcrumb isn't cached for all pages on the
    // site.
    $breadcrumb->addCacheContexts(["url"]);

    // By adding "cache tags" for this specific node, the cache is invalidated
    // when the node is edited.
    $breadcrumb->addCacheTags(["node:{$node->nid->value}"]);

    // Add "Home" breadcrumb link.
    $breadcrumb->addLink(Link::createFromRoute($this->t('Home'), '<front>'));

    // Given we have a taxonomy term reference field named "field_tags" and that
    // field has data, add that term as a breadcrumb link.
    if (!empty($node->field_tags->entity)) {
      $breadcrumb->addLink($node->field_tags->entity->toLink());
    }
    return $breadcrumb;
  }

}

```

and then in `custom_breadcrumb.services.yml`

```
services:
  custom_breadcrumb.breadcrumbs:
    class: Drupal\custom_breadcrumb\Breadcrumbs
    tags:
      - { name: breadcrumb_builder, priority: 100 }

```

Both the ways are achievable, if your question is which one should be followed and which one should be referred as a **best practice**, refer https://drupal.stackexchange.com/a/238962/3808
> 5 votes

# Answer
A slightly more parametrized theme code example for non-node entities with taxonomy parents, made by combining Rishi Kulshreshtha's code with taxonomy parents addition by mfrosch

```
/**
 * Implements hook_system_breadcrumb_alter().
 */
function THEMENAME_preprocess_breadcrumb(array &$vars) {
  // proper taxonomy breadcrumbs for Commerce Products through field_category
  $entity_type = 'commerce_product'; // TODO: change or verify
  $taxonomy_field_name = 'field_category'; // TODO: change or verify

  if (($entity = \Drupal::routeMatch()->getParameter($entity_type)) && $vars['breadcrumb']) {
    $cache_tag = "{$entity_type}:{$entity->product_id->value}"; // TODO: change or verify

    $breadcrumb = &$vars['breadcrumb'];
    if (!empty($entity->$taxonomy_field_name->entity)) {
      $node_url = array_pop($breadcrumb);

      $term = $entity->$taxonomy_field_name->entity;
      $storage = \Drupal::service('entity_type.manager')
        ->getStorage('taxonomy_term');
      $parents = $storage->loadParents($term->id());
      if (!empty($parents)) {
        foreach ($parents as $index => $parent) {
          array_push($breadcrumb, $parent->toLink());
        }
      }
      array_push($breadcrumb, $term->toLink());

      array_push($breadcrumb, $node_url);

      // Implementing Cache.
      $vars['#cache']['contexts'][] = "url.path";
      $vars['#cache']['tags'][] = $cache_tag;
    }
  }
}

```
> 1 votes

# Answer
Taking a quick peek in contrib modules, as of this writting, there doesn't seem anything that you can use for D8.

Here is a creative quick and easy solution/suggestion:

With Views and bit of Rewrite Results/Template file + CSS you could create your own breadcrumbs view block.
> -1 votes

---
Tags: 8, breadcrumbs
---


# Question
Title: Defining module.links.action.yml with route parameters
How can I pass dynamically route parameters to module.links.action.yml?

**My code of module.links.action.yml:**

```
module.group_apply:
  route_name: module.group_apply
  title: 'Subscribe to group'
  weight: 0
  appears_on:
    - entity.node.canonical

```

**My code of module.routing.yml:**

```
module.group_apply:
  path: '/projects/{project}/usergroup/{group}/subscribe'
  defaults:
    _controller: '\Drupal\module\Controller\SubscriptionController::subscribe'
    _title: 'Apply'
  options:
    parameters:
      project:
        type: entity:node
      group:
        type: entity:node
  requirements:
    _permission: 'access content'

```

**My subscibe function (actually):**

```
public function subscribe(NodeInterface $project, NodeInterface $group) {
    return array(
        '#markup' => 'HERE WE GO!',
    );
}

```

# Answer
1、you can add class to process as follows：

2、you can debug in getRouteParameters function, localAction.php content as follows:
> 2 votes

# Answer
I was on the wrong track the whole time.

The right way is to use entity.node.canonical as route (/node/{node}) and using other variables from node itself in the subscribe function ($node).

Thank you @4k4 for your help.
> 0 votes

---
Tags: 8, routes, navigation
---


# Question
Title: How can I set up an a SQLite memory database to improve PHPUnit test speeds?
I'm trying to speed up a functional Drupal test. Given a test...

```
...
  public function the_front_page_loads_for_anonymous_users() {
    $this->config('system.site')
      ->set('page.front', '/node')
      ->save(TRUE);

    $this->drupalGet('<front>');

    $assert = $this->assertSession();
    $assert->pageTextContains('Welcome to Drupal');
    $assert->pageTextContains('No front page content has been created yet.');
  }

```

This test runs really slow against my database ... 2+ mins.

If I use a test sqlite database, it drops to around 1.6 mins `<env name="SIMPLETEST_DB" value="sqlite://localhost/logs/test.sqlite"/>`

If I use a in-memory database, `<env name="SIMPLETEST_DB" value="sqlite://localhost/:memory:"/>`, Drupal detects no database and runs `install.php`

How can I set up an `sqlite memory` database to improve test speeds?

# Answer
On Linux, we use sqlite://localhost/dev/shm/test.sqlite where /dev/shm is memory mapped
> 0 votes

---
Tags: testing
---


# Question
Title: Keep entity object after getTitle() method in render() method in a custom controller
I've setup my controller like this:

```
my_controller:
  path: '/controller/{id}'
  defaults:
    _controller: '\Drupal\Mymodule\Controller\MyController::Render'
    _title_callback: '\Drupal\Mymodule\Controller\MyController::getTitle'
  requirements:
    permission: 'access content'

```

Now, in my **MyController.php** I need to load an entity object (for which {id} is the id). Unfortunately, it seems I need to load my object twice. First, in my getTitle function because this is called first. Then again in my Render() function, which is called afterwards.

When I try to save the entity to my class as $this-\>entity It gets lost when the Render() function gets called. I tried to load via a constructor or create function, but these do not have access to the {id} slug in a proper manner.

What's the good practice way to make sure I need to load my entity object once for both functions?

# Answer
> When I try to save the entity to my class as $this-\>entity It gets lost when the Render() function gets called.

Use a service. Services are singletons and when the class resolver finds an existing service it loads the instance from the container and doesn't create a new class instance:

```
defaults:
  _controller: 'my_service:render'
  _title_callback: 'my_service:getTitle'

```

For good practice this is not really necessary in this case because entities are cached in memory automatically and loading an entity twice doesn't have a performance impact.

Good practice, though, would be to load the entity via route parameter upcasting:

```
foobar.view:
  path: '/foobar/{foobar_placeholder}'
  defaults:
    _controller: '\Drupal\foobar\Controller\Foobar::content'
    _title: 'Oh yeah foobar'
  options:
    parameters:
      foobar_placeholder:
        type: entity:foobar

```

Example from https://www.drupal.org/docs/8/api/routing-system/parameters-in-routes/parameter-upcasting-in-routes
> 2 votes

---
Tags: 8, page-controller
---


title: Deployment Issue with Heroku

text:
# Question
Title: Deployment Issue with Heroku
I have a Drupal project on heroku and it works fine, until a dyno restart. After that, the Css and Js on the Drupal site stop working. Whenever that happens, I have to do a flush cache to get the site working. From my understanding, flushing cache creates files that Drupal uses for Css and Js. Since the storage system on Heroku is ephemeral, after dyno every restart I lose that file. Thus, I am forced to do a cache flush to get that file again and make everything on the site work. Is there a way around this? Is there a way to change the folder location of the temporary file that is created?

# Answer
> 1 votes
I eventually got the site working by disabling caching. But better approach to this problem is, creating the site on your local instance first. You need to create and install Drupal on your local system. If you install it directly on Heroku, it creates some temporary file on Heroku, which Heroku discards after every dyno restart. Even settings.php loses all the changes made to it(during installation) after dyno restart. (I installed my site directly on Heroku, so I got through this issue by adding changes to settings.php manually)

Once you create the Drupal site on your local instance (using the GUI), you will have some files in sites/default/files, as well as some changes in settings.php (hash salt, database setting etc). Now, you can track all these files and push it to Heroku. The site should work fine, except you won't be able to store any public files, you will need S3 bucket for that. Hope this helps who encountered similar issue!

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


# Question
Title: Why isn't hook_node_access() invoked when a node is created?
The following code doesn't work.

```
function mymodule_node_access(\Drupal\node\NodeInterface $node, $op, \Drupal\Core\Session\AccountInterface $account) {
    $type = $node->getType();

  if ($type == 'application' && $op == 'create' && arg(3) != "" ) {
    print_r(arg(3));
    return AccessResult::neutral();
  }
  else {
    // ...
    return AccessResult::forbidden();
  }
}

```

Could you tell me what is wrong in the code?

# Answer
As documented in `hook_ENTITY_TYPE_access()`, `hook_node_access()` is only invoked when the users try to view, update, or delete a node. The documentation doesn't make it explicit, but when an entity is created, the invoked hooks are `hook_ENTITY_TYPE_create_access()` and `hook_entity_create_access()`.

With both `hook_ENTITY_TYPE_access()` and `hook_ENTITY_TYPE_create_access()`, a single hook implementation returning `AccessResult::forbidden()` is sufficient to block users from acting on the entity. If you are noticing users aren't allowed to take an action on an entity when you expect them to be able to take that action, that is one of the probably causes.

I assume the code shown in the question is part of the code inside the mymodule.module file, or that a module with that machine name is installed on the site. Differently, Drupal would not consider that function a hook, and it would not invoke it (which could be a reason to say *it doesn't work*).

As side note, `arg()` is implemented in Drupal 4.6.x, 4.7.x, 5.x, 6.x, and 7.x, but not 8.x.y, nor 9.x.y. (Click on *Same name and namespace in other branches* in the documentation page to see the list of Drupal versions for which that function is implemented.)

>

The code shown in the question should thrown an error about a call to a not existing function.
> 3 votes

# Answer
Seems `hook_node_access` is not longer called for the create operation. Use `hook_ENTITY_TYPE_create_access` instead.

See hook\_node\_access() no longer fires for the 'create' operation for background info and code samples on how to change your code.

---

Also `arg()` is deprecated.
> 2 votes

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


# Question
Title: The website encountered an unexpected error. Please try again later( Olivero subtheme)
Tried to make an Olivero subtheme. Followed drupal tutorials and after several unsuccessfull attempts ended in error "**The website encountered an unexpected error. Please try again later**" on both backend and frontend now I don't get the error anymore on the backend but I still can't access the frontend.

Error in drupal log looks like this

```
Drupal\Core\Asset\Exception\InvalidLibraryFileException: Invalid library definition in themes/mysubtheme/mysubtheme.libraries.yml: A colon cannot be used in an unquoted mapping value at line 1 (near "global-styling: version: 1.x "). in Drupal\Core\Asset\LibraryDiscoveryParser->parseLibraryInfo() (line 348 of /home/admin/web/mysite.com/public_html/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php).

```

mysubtheme.info.yml looks like this

```
type: theme
base theme: olivero
description: My custom theme based on the core Olivero theme. It's meant for customization.
package: Custom
libraries:
  - mysubtheme/css
  - mysubtheme/js

regions:
  header: Header
  primary_menu: 'Primary menu'
  secondary_menu: 'Secondary menu'
  hero: 'Hero (full width)'
  highlighted: Highlighted
  breadcrumb: Breadcrumb
  social: Social Bar
  content_above: Content Above
  content: Content
  sidebar: 'Sidebar'
  content_below: 'Content Below (Flex Layout)'
  footer_top: 'Footer Top (Flex Layout)'
  footer_bottom: 'Footer Bottom'

core: '8.x'
core_version_requirement: ^8 || ^9

```

and mysubtheme.libraries.yml like this

```
 version: VERSION
 css:
   theme:
     css/custom.css: {}

global-scripts:
 version: VERSION
 dependencies:
   - core/jquery
   - core/drupal
   - core/drupalSettings
 js:
     js/custom.js: {}

```

Thank you for any help.

# Answer
> 0 votes
As @Leigh wrote in a comment one of the cause of my problem is that, sadly, OLivero doesn't support yet subtheming.

---
Tags: theming
---


# Question
Title: Changing the layout of a Taxonomy Term Page
By default my taxonomy term page lists all articles using this term in 2-columns. I would like to change it to a 1-column layout.

**(1) I have created a custom display layout for the taxonomy group:**

**(2) And selected the one column layout:**

Still it doesn't work. Any other changes, like adding a field, do work though. What am I missing?

Note: I did clear the cache.

# Answer
> 0 votes
Thanks to @prkos, it turned out that the root of the problem was located inside the Bootstrap Sub-Theme.

Someone created a (hacky) template override for one specific content type in a generic manner. By renaming the file `views-view-unformatted.html.twig` to `views-view-unformatted--SOME-CONTENT.html.twig` it kept the override for the mentioned content item, but also made layouts of other, generic content types work as intended.

---
Tags: theming, taxonomy-terms
---


# Question
Title: Change the theme used for the user reset password page
Drupal 8 - I have the following issue:

The problem is that the password reset page uses the administrator theme, while I need it uses the default site theme.

# Answer
> 3 votes
You can use a `RouteSubscriber` to do that but it will also affect your user edit form and render it with the default site theme since it uses the same route name. The RouteSubscriber can't alter a route based on a query string parameter such as `pass-reset-token`

**yourmodule/yourmodule.services.yml**

```
services:
  yourmodule.routesubscriber:
    class: Drupal\yourmodule\Routing\YourmoduleRouteSubscriber
    tags:
      - { name: event_subscriber, priority: 1 }

```

**yourmodule/src/Routing/YourmoduleRouteSubscriber.php**

```
<?php

namespace Drupal\yourmodule\Routing;

use Drupal\Core\Routing\RouteSubscriberBase;
use Symfony\Component\Routing\RouteCollection;

/**
 * Custom route subscriber.
 */
class YourmoduleRouteSubscriber extends RouteSubscriberBase {

  /**
   * {@inheritdoc}
   */
  protected function alterRoutes(RouteCollection $collection) {
    if ($route = $collection->get('entity.user.edit_form')) {
      $options = $route->getOptions();
      $options['_custom_theme'] = 'yourthemename';
      $route->setOptions($options);
    }
  }

}

```

---
Tags: 8, theming
---


title: How to inject an object into a service?

text:
# Question
Title: How to inject an object into a service?
I need to do a couple of things:

1. Inject guzzle's httpclient into class A
2. Inject class A into my service

What I've tried so far:

1. ```
services:
  my_module.field_fetcher:
    class: Drupal\my_module\ClassB
    arguments: ['@my_module.obj', '@logger.factory', '@config.factory']

  my_module.obj:
    class: Drupal\my_module\ClassA
    arguments: ['@http.client']

```
2. ```
parameters:
  my_module.http_client.config:
    base_uri: 'http://myurl.com/'

services:
  my_module.http_client:
    factory: '@http_client_factory:fromOptions'
    arguments: ['%my_module.http_client.config%']

  my_module.obj:
    class: Drupal\my_module\ClassA
    arguments: ['@my_module.http_client']

  my_module.field_fetcher:
    class: Drupal\my_module\ClassB
    arguments: ['@my_module.obj', '@logger.factory', '@config.factory']

```

Simple versions of classes A and B look like this:

ClassA:

```
<?php

namespace Drupal\my_module;

use GuzzleHttp\ClientInterface;
use Psr\Http\Message\RequestInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

class A {

  /**
   * @var \GuzzleHttp\ClientInterface
   */
  private $httpClient;

  public function __construct(ClientInterface $httpClient) {
    $this->httpClient = $httpClient;
  }
}

```

ClassB:

```
<?php

namespace Drupal\my_module;

use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\node\NodeInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Psr\Log\LoggerInterface;
use Drupal\Core\Logger\LoggerChannelFactory;

class B implements BInterface {

  /**
   * @var \Drupal\my_module\A
   */
  private $a;

  /**
   * @var \Drupal\Core\Logger\LoggerChannelFactory
   */
  private $logger;

  public function __construct(A $a, LoggerChannelFactory $logger, ConfigFactoryInterface $config) {
    $this->a = $a;
    $this->logger = $logger;
  }

  public static function create(ContainerInterface $container) {
    return new static(
      A::create($container),
      $container->get('my_module.obj'),
      $container->get('logger.factory')->get('my_module'),
      $container->get('config.factory')
    );
  }
}

```

No matter what I try, I keep running into the same issue of drupal error logs telling me that "argument 1 passed to Drupal\my\_module\ClassB::\__construct() must be an instance of Drupal\my\_module\ClassA, string given"

**Edit:** Updated classes A and B to reflect changes suggested.

# Answer
> 3 votes
For this `my_module.services.yml` file:

```
services:
  my_module.obj:
    class: Drupal\my_module\ClassA
    arguments: ['@http.client']

```

You can discard the `create()` method from your `A` class, because you declared it as a service for which the arguments get resolved by the services YAML file parameters ie. `'@http_client'`:

```
class A implements AInterface {

  /**
   * @var \GuzzleHttp\ClientInterface
   */
  private $httpClient;

  /**
   * @param \GuzzleHttp\ClientInterface $http_client
   *   A Guzzle client object.
   */
  public function __construct(ClientInterface $http_client) {
    $this->httpClient = $http_client;
  }

```

> argument 1 passed to Drupal\my\_module\ClassB::\__construct() must be an instance of Drupal\my\_module\ClassA, string given

Fix this by correcting your `B` class `create()` method to pass your service `A` name being `'my_module.obj'`, which would then in turn correctly pass an instance to the constructor of class `B`:

```
class B implements ContainerInjectionInterface {

  /**
   * @var \Drupal\my_module\AInterface
   */
  private $a;

  /**
   * @var \Drupal\Core\Logger\LoggerChannelFactory
   */
  private $logger;

  /**
   * @param \Drupal\my_module\AInterface
   *   Your module A class.
   */
  public function __construct(AInterface $a, LoggerChannelFactory $logger, ConfigFactoryInterface $config) {
    $this->a = $a;
    $this->logger = $logger;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('my_module.obj'),
      $container->get('logger.factory')->get('my_module'),
      $container->get('config.factory')
    );
  }

```

---
Tags: dependency-injection, symfony-services
---


# Question
Title: How do I add a custom validation handler to an existing form/field?
How do I add a custom validation handler to an existing form (or form field) in Drupal 8?

I have a form that I haven't created. I want to add my own validation rules on some fields when the form is submitted.

For Drupal 7, Custom validation for a form? explains to implement `hook_form_alter()` and then add your validation handler\]\[1\] to the `$form['#validate']` array, but in Drupal 8 forms are classes. Validation is done through the `validateForm()` method and I don't know how to plug my code into that.

# Answer
> 22 votes
The `#validate` property is still used in Drupal 8. (With Adi's solution you will override the existing validator)

If you want to add your custom validator in addition to the default, you will have to add something like this in hook\_form\_FORM\_ID\_alter (or similar):

```
$form['#validate'][] = 'my_test_validate';

```

# Answer
> 40 votes
Berdir gave the correct answer, that a constraint is the correct way to go about adding validation to a field in Drupal 8. Here is an example.

In the example below, I will be working with a node of type `podcast`, that has the single value field `field_podcast_duration`. The value for this field needs to be formatted as HH:MM:SS (hours, minutes and seconds).

To create a constraint, two classes need to be added. The first is the constraint definition, and the second is the constraint validator. Both of these are plugins, in the namespace of `Drupal\[MODULENAME]\Plugin\Validation\Constraint`.

First, the constraint definition. Note that the plugin ID is given as 'PodcastDuration', in the annotation (comment) of the class. This will be used further down.

```
namespace Drupal\[MODULENAME]\Plugin\Validation\Constraint;

use Symfony\Component\Validator\Constraint;

/**
 * Checks that the submitted duration is of the format HH:MM:SS
 *
 * @Constraint(
 *   id = "PodcastDuration",
 *   label = @Translation("Podcast Duration", context = "Validation"),
 * )
 */
class PodcastDurationConstraint extends Constraint {

  // The message that will be shown if the format is incorrect.
  public $incorrectDurationFormat = 'The duration must be in the format HH:MM:SS or HHH:MM:SS. You provided %duration';
}

```

Next, we need to provide the constraint validator. This name of this class will be the class name from above, with `Validator` appended to it:

```
namespace Drupal\[MODULENAME]\Plugin\Validation\Constraint;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

/**
 * Validates the PodcastDuration constraint.
 */
class PodcastDurationConstraintValidator extends ConstraintValidator {

  /**
   * {@inheritdoc}
   */
  public function validate($items, Constraint $constraint) {
    // This is a single-item field so we only need to
    // validate the first item
    $item = $items->first();

    // Check that the value is in the format HH:MM:SS
    if ($item && !preg_match('/^[0-9]{1,2}:[0-5]{1}[0-9]{1}:[0-5]{1}[0-9]{1}$/', $item->value)) {
      // The value is an incorrect format, so we set a 'violation'
      // aka error. The key we use for the constraint is the key
      // we set in the constraint, in this case $incorrectDurationFormat.
      $this->context->addViolation($constraint->incorrectDurationFormat, ['%duration' => $item->value]);
    }
  }
}

```

Finally, we need to tell Drupal to use our constraint on `field_podcast_duration` on the `podcast` node type. We do this in `hook_entity_bundle_field_info_alter()`:

```
use Drupal\Core\Entity\EntityTypeInterface;

function HOOK_entity_bundle_field_info_alter(&$fields, EntityTypeInterface $entity_type, $bundle) {
  if (!empty($fields['field_podcast_duration'])) {
    $fields['field_podcast_duration']->addConstraint('PodcastDuration');
  }
}

```

See official docs at Defining Constraints (Validations) on Entities and/or Fields.

# Answer
> 22 votes
The correct way to do this for a content entity like node is to register it as a constraint.

See `forum_entity_bundle_field_info_alter()` and the corresponding ? `ForumLeaf` validation constraint (note that there are two classes needed).

That is a bit more complicated at first, but the advantage is that it is integrated into the validation API, so your validation isn't limited to the form system but can, for example, also work with nodes submitted through the REST API.

# Answer
> 14 votes
I want to add some more light on this matter. The adding of the validation is exactly the same as before: in hook\_form\_alter:

```
$form['#validate'][] = '_form_validation_number_title_validate';

```

The use of the values object inside of the $form\_state in the validate function is though a bit different. e.g.:

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

  if ($form_state->hasValue('title')) {
     $title = $form_state->getValue('title');

     if (!is_numeric($title[0]['value'])) {
        $form_state->setErrorByName('title', t('Your title should be number'));
     }

  }
}

```

So not with a direct access to the private variables object, but rather with a getter function.

for more info you can see a full example in my github: https://github.com/flesheater/drupal8\_modules\_experiments/blob/master/webham\_formvalidation/webham\_formvalidation.module

cheers!

# Answer
> 7 votes
It is very much the same as in D7. A complete example:

**mymodule.module**:

```
use Drupal\Core\Form\FormStateInterface;

/**
 * Implements hook_form_FORM_ID_alter() for the FORM_ID() form.
 */
function mymodule_form_FORM_ID_alter(&$form, FormStateInterface $form_state, $form_id) {
  $form['#validate'][] = '_mymodule_form_FORM_ID_validate';
}

/**
 * Validates submission values in the FORM_ID() form.
 */
function _mymodule_form_FORM_ID_validate(array &$form, FormStateInterface $form_state) {
  // Validation code here
}

```

# Answer
> 3 votes
In complement of these good answers I would add :

```
$form['#validate'][] = 'Drupal\your_custom_module_name\CustomClass::customValidate';

```

It is how to call a distant class method for a form validation. I think it's better then calling an above function in the module file like in the example given.

# Answer
> 1 votes
you can use the Clientside Validation module. Some more details about it (from its project page):

> ... adds clientside validation (aka "Ajax form validation") for all forms and webforms using jquery.validate. The included jquery.validate.js file is patched because we needed to be able to hide empty messages.

# Answer
> 0 votes
Surprisingly adding validation callbacks directly to `$form['#validate'][]` simply won't work in case of some forms. Some Drupal forms define their validation handler at **actions \> button** form element level.

Example of such form is `language_admin_edit_form` where validation handler can be added this way:

`$form['actions']['submit']['#validate'][] = 'callback'`

It is worth to dump and inspect `$form` array inside `HOOK_form_alter()` and verify button element level also.

---
Tags: 8, forms
---


# Question
Title: Unable to uninstall the Field Collection module
I want to remove field collection module in Drupal 8 as the module has been deprecated. When I try to uninstall after removing the fields from content type the option to uninstall is greyed out.

I get an error

> field\_collection: There is content for the entity type: Field Collection Item. `<a
>  href="/admin/modules/uninstall/entity/field_collection_item">Remove
>  field collection item entities</a>`.

# Answer
> 1 votes
I guess you solved this already, but if somebody else stumbels over this, here my 5 cent on how to get rid of field collection. I encountered the same issue as @nitnac23 and was only able to get it out via direct data base manipulation:

1. definitely make a DB backup this time (might save your website)
2. Remove all field collection fields from your entities
3. run the cron potentially multiple times (this cleanes up the entities - fingers\_crossed)
4. it is important, that you no longer have **fields pending deletion** as a reason for not beeing able to dissable fields collection (under `/admin/modules/uninstall/`) - if you still have it, try running the cron again (more infos here)
5. clear the contents of the database tables `field_collection_item` and `field_collection_item_revision` directly in the database
6. uninstall field collections now via `/admin/modules/uninstall/`
7. if you have still `field_deleted_*` tables in your DB, drop them (I had 12 before runing the cron and still 2 after unsintsalling the module)

That should do it hopefully :)

---
Tags: 8, entities, installation
---


title: AJAX submitted form redirection

text:
# Question
Title: AJAX submitted form redirection
I just found out that when I try to submit a form with AJAX, in that instance user\_login, the redirection doesn't work anymore. Is this normal? How can I make the redirection happen after the AJAX request comes back?

# Answer
> 2 votes
Like it has been said, there isn't really a reason to do a redirect and AJAX. If you however really want to do it, it is pretty simple.

Using jQuery it would look like this:

```
$.post(Drupal.settings.basePath + 'url/to/page', {post: 'params'}, function (data) {
  window.location = Drupal.settings.basePath + 'url/to/redirect/to';
});

```

The gist of it, is to set `window.location` to the url you want to redirect to, if you want to refresh the page you could do

```
 window.location = document.URL;

```

# Answer
> 3 votes
I had the same situation: ajax login/register form until the fields are correctly filled, and then redirect the user to the logged in section. This is what I used, and it works fine for me, in the ajax callback function:

```
ctools_include('ajax');
ctools_add_js('ajax-responder');

$commands[] = ctools_ajax_command_redirect('<front>');

return array('#type' => 'ajax', '#commands' => $commands);

```

the full function looks like this:

```
function ajax_signup_detailed_submit_callback($form, &$form_state)
{
  $commands = array();
  $messages = drupal_get_messages(NULL, FALSE);

  if (count($messages))
  {
    $commands[] = ajax_command_replace("#better-messages-wrapper", theme('status_messages'));
  }
  else
  {
    ctools_include('ajax');
    ctools_add_js('ajax-responder');
    $commands[] = ctools_ajax_command_redirect('<front>');
  }

  return array('#type' => 'ajax', '#commands' => $commands);
}

```

Hope this helps, Istvan

# Answer
> 1 votes
The purpose of AJAX is to submit the form in background, and update the content of the form without refreshing the full page. If a redirection would happen, then the page would be refreshed, and replaced with the content returned from the server, which is the opposite of what AJAX tries to do.

AJAX is used to update part of a page without to refresh the full page. A background request is made to the server, and the value returned is used to update part of the page.
For example, AJAX is used to update a list of items, or to updated the value shown by a form field basing on the value selected from another form field. Suppose you have a drop-down list that reports the list of USA states, and another drop-down list that lists all the counties for that state, AJAX would be used to update the list of the counties when the user changes the state from, for example, Iowa to New York.

# Answer
> 0 votes
I found that the way to do what silkAdmin wants to do is not to use Ajax at all. If your submit handler determines that the password is invalid, set $form\_state\['resubmit'\] to TRUE, and add a test in your form builder function that changes the text. This does reload the entire page, but there doesn't seem to be a way to avoid that.

---
Tags: forms, ajax
---


# Question
Title: Sorting Views result rows based on an array of node IDs
I have a View of `song` nodes, and each node has a programmatically calculated total number of points associated with it. (For background: `song` nodes are referenced in a custom `field_chart_items` field on a `chart` node, hence the `$chartHistory` node query seen in the hook below. The custom field includes a numeric Position that's entered on the `chart` node, and a numeric Points total that's hidden from view and calculated based on Position in a `chart_field_entity_presave()` hook.) I'm trying to sort the View's results by points, with highest points totals listed first.

In a `views_pre_render()` hook, I calculate the points total for each row and place it into an array, `$songAndPoints`, that contains the song's `nid` and points total. The array is sorted so that the song with the highest points total comes first – therefore, the order of the `nid`s in the array is the order in which I want my results to appear.

Can I programmatically reorder the `$view->result` array based on the array of `nid`s I'm getting? My attempt below, using a `uasort()` callback, doesn't work, but I'm not sure if or how I can do what I'm looking for (or if, perhaps, it needs to happen in a different hook).

```
<?php
/**
 * Implements hook_views_pre_render().
 */
function MODULE_views_pre_render(&$view) {
  if ($view->current_display === 'DISPLAYID'
    && $view->id() === 'VIEWID') {
      $entity_type_manager = \Drupal::entityTypeManager();
      $node_storage = $entity_type_manager->getStorage('node');

      foreach ($view->result as $key => $song) {
        $node_type = 'chart';
        $songNID = $song->nid;

        $chartHistory = $node_storage->getQuery()
          ->condition('type', $node_type)
          ->condition('field_chart_items', $songNID, 'IN')
          ->condition('status', 1)
          ->execute();

        if ($chartHistory) {
          foreach ($chartHistory as $chartNID) {
            // ...
            // Various calculations to get points total, $songPoints, for each song.
            // ...
          }
          $songAndPoints[$key] = ['points' => $songPoints, 'nid' => $songNID];

          // Sort based on point values.
          arsort($songAndPoints);

        } else {
          $songAndPoints[] = ['points' => 0, 'nid' => $songNID];
        }
      }

      kint($songAndPoints); // Array with original row number as key and two values, points and NID, sorted with highest points first. This is how I want to sort the results.

      uasort($view->result, "MODULE_sort_by_points_total");
  }
}

/**
 * Custom uasort() callback to sort view results by points totals.
 */
function MODULE_sort_by_points_total($left, $right) {
    $order = ['704', '712', '707', '713', '711', '709', '708', '883', '882', '715', '714', '710', '705']; // TEMPORARY: Hardcoded list of node IDs in order; should be replaced by something like array_column($songAndPoints, 'nid'), but hardcoded values don't work either.

    $flipped = array_flip($order);
    $leftPos = $flipped[$left]->nid;
    $rightPos = $flipped[$right]->nid;
    return $leftPos >= $rightPos;
    // via https://stackoverflow.com/questions/17324708/php-array-multisort-not-sorting-my-multidimensional-array-as-expected/17325584#17325584
}

```

# Answer
I got my answer via the Drupal Slack, but reposting it here for anyone who might come across this later, since that's not publicly searchable. It was more of a PHP issue than anything Drupal-specific.

Within the `uasort()` callback, the `$left` and `$right` arguments are objects of the `ResultRow` class, with `nid` available from them, so switching `$leftPos` and `$rightPos` to `$flipped[$left->nid]` and `$flipped[$right->nid]`, respectively, gets me access to the results' `nid`s.

```
/**
 * Custom uasort() callback to sort view results by points totals.
 */
function MODULE_sort_by_points_total($left, $right) {
    $order = ['704', '712', '707', '713', '711', '709', '708', '883', '882', '715', '714', '710', '705'];

    $flipped = array_flip($order);
    $leftPos = $flipped[$left->nid];
    $rightPos = $flipped[$right->nid];
    return $leftPos >= $rightPos;
}

```

Continuing on, I figured out that switching it to an anonymous function was what I needed to pass `$songAndPoints` to the `uasort()` function, as follows, instead of separating it:

```
$sortByPointsTotal = function($left, $right) use ($songAndPoints) {
    $order = array_column($songAndPoints, 'nid');

    $flipped = array_flip($order);
    $leftPos = $flipped[$left->nid];
    $rightPos = $flipped[$right->nid];
    return $leftPos >= $rightPos;
};

uasort($view->result, $sortByPointsTotal);

```
> 2 votes

---
Tags: 8, views, hooks
---


title: Drupal Docker Setup

text:
# Question
Title: Drupal Docker Setup
I currently have a codebase for Drupal using Drupal-VM vagrant box and VirtualBox. I would like to migrate to docker but I am unaware on how to integrate it with my existing code base.

Can anyone help me? I have followed instructions from Docker Hub - Drupal Install Steps and MySQL and Drupal Container to spin up mysql and Drupal images but how do I make it point to my pre-existing codebase?

##

##

---

Previous posts with more details, questions and background:

# Answer
You can mount host volumes, such as your application codebase, inside your container.

e.g with `docker-compose`:

```
drupal:
  volumes:
    # Mount application codebase
    # - ./project-directory:/container-directory
    - ./project/dir:/var/www/docroot

```

You can also mount a host volume for your mysql data, to preserve the DB across docker stack rebuild.

```
mysql:
  volumes:
    # Database on host
    # - /host-directory:/container-directory
    - /var/lib/my-project/mysql:/var/lib/mysql

```
> 1 votes

# Answer
You can do this in lando.

Basically, this is the workflow:

* Configure your `lando.yml` to get your site running locally and commit this to your repository. This will allow everybody to create a local dev environment as long as they have cloned the repo and have lando installed.
* Use lando to run the site locally, and continue to commit code/build your project in the same way that you were doing before.

Here are some notes from Acquia on setting up lando with BLT.
> 0 votes

---
Tags: 8
---


# Question
Title: Webform alter with ajax submit callback - field values are empty in callback
At this point I'm doubting if I'm doing it the right way, but I'm struggling with an issue:

I'm adding an Ajax callback to the form alter of a specific form:

```
function mymodulename_form_alter(&$form, &$form_state, $form_id) {
if ($form_id == 'webform_submission_matching_node_218_add_form') {
    $form['actions']['submit']['#ajax'] = array(
        'callback' => 'matching_api_call',
        //'event' => 'click',
        'effect' => 'fade',
        'speed' => 500,
        'wrapper' => 'block-matchingblock',
        'progress' => [
            'type' => 'throbber',
            'message' => t('Matching...'),
        ]);
    }
}

```

The callback works fine but when I call $form\_state-\>getValues(), I get an array with all my fields but they are simply empty or 0.

My callback function:

```
function matching_api_call(&$form, \Drupal\Core\Form\FormStateInterface $form_state) {
    // ajax debug
    $response = new AjaxResponse();
    $selector = '#block-matchingblock';
    $content = print_r($form_state->getValues(), true);
    $settings = [];

    $response->addCommand(new HtmlCommand($selector, $content, $settings));
    return $response;
}

```

My output:

```
Array(
    [field1] =>
    [field2] =>
    [field3] => 0
    [field4] => 0
    [submit] => Match
    [form_build_id] => {formbuildid}
    [form_token] => {formtoken}
    [form_id] => {form_id}
    [op] => Match
)

```

The entry is added in the backend so it does get submitted. Should I do something else because I'm using Ajax here?

Thanks in advance.

# Answer
> 1 votes
Someone guided me in the right direction. My Webform Confirmation setting was set to 'None'. After setting it to 'Inline', calling `$form_state->getValues()` finally returns the form values.

---
Tags: ajax, webforms
---


# Question
Title: How to display the user's preferred language in a User profile page
In a Drupal 8/9 site, I can select the User's preferred language.

In the "*Manage form display*" page (for user's fields), there are two rows which are about language:

* `Language settings` (settings = --no settings available--)
* `Language code` (settings = "language select" as the only option)

**Question 1** : What do these two options produce?

In the "*Manage display*" page, I can display only one item about the language : `Language code`

As a result, if I visit my user profile page, I can see:

> **Language code**: French

But if I change my preferred language in my user edit profile page into Dutch, there is no effect in my "User view" page: it is always "French"

ok, I can preprocess something and adapt the twig template to display my preferred language but this is not the answer I would like to have.

**Question 2**: I would like to understand this behavior because, as always in Drupal, I am sure there is a good reason for that.

# Answer
> 0 votes
I think I could answer myself to most of my questions:

1-The `Language code` field store the initial language of a user... it looks like it can't be changed after all. For my use case, it is an useless field.

2-The `Language settings` options display the **Preferred language** widget and the **Administration pages language** widget. I think that this last widget is there only if you check **Account administration pages language setting.** in `admin/config/regional/language/detection`

3-The most important part: How to display the preferred language of a user in the the display user page (`/user/xxx`)

You can do it with this hook:

```
function mymodule_entity_base_field_info_alter(&$fields, EntityTypeInterface $entity_type) {
  if ($entity_type->id() == "user") {
    $fields['preferred_langcode']->setDisplayConfigurable('view', TRUE);
  }
}

```

I really don't know why it is not a default... (don't hesitate to add any information on this point)

---
Tags: users, i18n-l10n
---


# Question
Title: DATABASE SYSTEM VERSION: The database server version 5.6.41-84.1 is less than the minimum required version 5.7.8
I am trying to run a Drupal Security Update, update.php, but receive an error like this:

DATABASE SYSTEM VERSION 5.6.41-84.1 The database server version 5.6.41-84.1 is less than the minimum required version 5.7.8. (See Screenshot)

My Drupal site version is 9.0.2.

Can anyone help me with this error? Thank you in advance.

# Answer
Your mySQL is out of date. Drupal 9 requires at least 5.7.8, as described in the Drupal database system requirements.

This is not a Drupal problem *per se*; you will need to update the version of MySQL you are using on your web host.
> 3 votes

---
Tags: 9
---


# Question
Title: How to delete message entities (message stack) of a special template depending on entity age
for the "Private Message" module, my Drupal 8 site uses the "Message" module (https://www.drupal.org/project/message) as substructure.

I would like to build a kind of notification center into the page, which should be possible to implement with the message stack (as I heard).

The trigger to generate such a message will probably be a custom module. The message module also offers a kind of "auto cleanup", but unfortunately as far as I have seen only for all messages and not per message template.

In principle I only want a notification center, which is triggered at certain events and which cleans itself depending on the message type (e.g. only the last 10 messages of a certain template or delete all messages of a certain template which are older than 10 days).

In general, I guess cleanup does not work, as it would probably also delete the "private messages".

Any hints.

# Answer
> 0 votes
It's possible to override the cleanup/auto delete settings in the message template configuration (even via UI) per template. Just visit the template configuration form.

---
Tags: 8, message-subscribe
---


# Question
Title: How to setup module: Referer to Entity Reference
i tried to use this in url:

```
site.com/node/add/material/?field_material_category=6

```

content type 'material' has entity field 'field\_material\_category'

number '6' is nid of node content type 'material\_category'

But this url link doesnt work at all, field is empty....

What i am doing wrong?

# Answer
If you want to pre-fill a field value on the add form with the query string, you can use the Prepopulate module.
> 3 votes

---
Tags: entities, 9
---


# Question
Title: Pre process a template that uses layout display
I want to preprocess a user account display. I want to manipulate a field value at display time. for example, i want to change: **field\_prefered\_color:** red
to :
**field\_prefered\_color:** red - Cool, that is used 5 times today.

If I don't use layout builder I can easily change that in

```
function mymodule_preprocess_user(&$variables) {
  $variables['content']['field_prefered_color'][0]['#context'][['value'] .= t(' - Cool, that is used @times times today,['@times' => $times]);
}

```

But when I use layout builder, where can I find field\_prefered\_color to manipulate its output?

# Answer
> 0 votes
It appears quite easy to achieve what I want: I needed to create a conditional field functionality. I know there is a module for that but at this time the module is not stable and not performing well with layout builder. As indicated by @CG Monroe the last called template is field.html.twig. If this is a user field the fully loaded user is available in:

```
$variables['elements']['#object']

```

So I could access all the user fields I needed to manipulate the field output in the preprocess function

```
function my_module_preprocess_field(&$variables) {
  $field = $variables['elements']['#object']->field_some_other_field->value;
  // now I can manipulate the output of the field being viewed
  // the manipulation is needed because of the value of "some-other-field"
  $variables['items'][0]['content']['#context']['value'] = ' ***  ****';
  $variables['items'][0]['attributes']->addClass('my-module-field-manipulated');
}

```

---
Tags: 8, layout-builder
---


# Question
Title: Is it possible to host private files on remote file server in Drupal 8?
I want to know, In drupal 8, is there any way to host all private files on remote file server separated from host server.

Files must be uploaded or removed from remote server directly from Drupal site. Is it possible?

# Answer
Yes, the private file system is just another folder on your server, configured in settings.php

For example, you could

1. Mount a separate storage volume there via NFS
2. Add another EBS volume (if AWS)
> 3 votes

---
Tags: files
---


title: How to convert a file into File Entity

text:
# Question
Title: How to convert a file into File Entity
I need to use file\_copy in a custom module in D8.

The function `file_copy` requires the first parameter to be a `File Entity`. Here is what I have tried but it doesn't work and returns an error:

**TypeError: Argument 1 passed to file\_copy() must be an instance of Drupal\file\FileInterface, instance of stdClass given**.

```
$file_path = drupal_realpath("public://Testttt58.png");
$file = (object) array(
            'uid' => 1,
            'uri' => $file_path,
            'filemime' => mime_content_type($file_path),
            'display' => 1,
            'filename' => "Testttt58.png"
);
$fileUpload = file_copy($file, "public://TestFolder", FILE_EXISTS_RENAME);

```

Here is the output of `kint($file);`

How can I solve this?

# Answer
> 3 votes
Just use something like this:

```
use Drupal\file\Entity\File;
$file = File::create([
  'uri' => $file_path,
  'filemime' => mime_content_type($file_path),
  'filename' => "Testttt58.png",
]);
$fileUpload = file_copy($file, "public://TestFolder", FILE_EXISTS_RENAME);

```

# Answer
> 2 votes
You can use `file_save_data` to save a file and create the managed file object.

e.g:

```
$filepath = 'public://Testttt58.png';
// Save the file, using the file contents in $data
$file = file_save_data($data, $filepath, FILE_EXISTS_REPLACE)

```

---
Tags: 8, entities, files
---


# Question
Title: Create dynamic text fields on form based on other entities
I've created an entity which has fields that users need to fill out. As part of that entity there is a reference field back to a content type 'food'.

The 'food' content type has it's own entity reference called 'sections'.

When a user selects a 'food', i want to dynamically add each 'section' as a title with a textarea box underneath which gets stored against the original entity.

Considered using paragraphs as the 'sections' but they need to be reusable on different 'food' nodes. Also checked the dynamic fields module but this doesn't look like it's well supported.

Fallback approach is going to be to programmatically create a field for each 'section' item as they are added, but with this we could end up with hundreds of fields.

Any ideas on how else this can be done programmatically?

# Answer
Paragraphs *is* what you want. What you are describing is Paragraphs' exact use case. We use Paragraphs as a staple of our platform because of its re-usability.

Assigning an existing Paragraph to an Entity Reference Revisions field on a node is as simple as:

```
// Note that the value will be a nested array, even if cardinality is 1.
$node->get('field_food')>setValue([
  [
    'target_id' => $paragraph->id(),
    'target_revision_id' => $paragraph->getRevisionId(),
  ],
]);
$node->save();

// Another example: assigning multiple references to a single field.
$node->get('field_myfield')>setValue([
  [
    'target_id' => $paragraph1->id(),
    'target_revision_id' => $paragraph1->getRevisionId(),
  ],
  [
    'target_id' => $paragraph2->id(),
    'target_revision_id' => $paragraph2->getRevisionId(),
  ],
  [
    'target_id' => $paragraph3->id(),
    'target_revision_id' => $paragraph3->getRevisionId(),
  ],
]);
$node->save();

```

If you need to generate a paragraph programmatically, that is also easy:

```
// Note that I'm using the DIC for demonstration's sake.
// Be sure to use dependency injection and other best practices in your project.
$storage = \Drupal::entityTypeManager()->getStorage('paragraph');
$paragraph = $storage->create([
  'type' => 'food',
  'title' => 'A title',
  'field_a' => 'a value',
]);
$paragraph->save();

```

You can then assign this newly created paragraph to an Entity Reference Revisions field using the method I mentioned above.
> 1 votes

---
Tags: 8, forms
---


# Question
Title: Add a local task tab for a content type only
Someone can help me ? I want to display a tab only when the content type is 'test'.

Here's my files.

*mymodule.routing.yml* :

```
mymodule.check_test:
  path: '/checktest/{node}'
  defaults:
    _controller: '\Drupal\mymodule\Controller\CheckTestController::content'
  requirements:
    _access: 'TRUE'

```

*mymodule.links.task.yml* :

```
mymodule.check_test:
    title: Display tests
    route_name: mymodule.check_test
    base_route: entity.node.canonical

```

My tab is displayed for every content, i don't know how to filter with my content type...

Thanks :).

***Edit*** : From mradcliffe's answer,

I've add a mymodule.services.yml :

```
services:
  access_check.test:
    class: Drupal\mymodule\Access\MyModuleTestAccess
    tags:
      - { name: access_check, applies_to: _access_test }

```

and a MyModuleTestAccess class with :

```
public function access(NodeInterface $node)
{
    return AccessResult::allowedIf($node->bundle() === 'test');
}

```

My edited mymodule.routing.yml :

```
mymodule.check_test:
  path: '/checktest/{node}'
  defaults:
    _controller: '\Drupal\mymodule\Controller\CheckTestController::content'
  requirements:
    _access_test: ''

```

# Answer
> 10 votes
You can use an access check to hide a route.

If the user that will view the tab has the same permission for adding a node of a given type, then simply adding `_node_add_access: 'node:MYNODETYPEHERE'` would be sufficient. However this is probably not the case.

Instead you can add `_custom_access` to the route requirements as a method on the controller class.

```
mymodule.check_test:
  path: '/checktest/{node}'
  defaults:
    _controller: '\Drupal\mymodule\Controller\CheckTestController::content'
  requirements:
    _custom_access: '\Drupal\mymodule\Controller\CheckTestController::checkAccess'
    # It is highly-recommended to always use the default entity access check for
    # an Entity as pointed out by @pwolanin below. Not doing so may lead to
    # undesirable results and potential information disclosure or access bypass
    # vulnerability.
    _entity_access: node.view

```

And then a corresponding method on the controller (see Access checking on routes for more details). Something like this might work for you (untested).

```
public function checkAccess($node) {
  return AccessResult::allowedif($node->bundle() === 'my_node_type');
}

```

**Update 2019.08.30**: Incorporated @pwolanin's answer into this one in case anyone misses and doesn't read its importance.

# Answer
> 2 votes
I'm using Drupal 8.1.2 and both the accepted answer and the answer provided in the edit to the question did not actually work for me and they gave this error:

```
RuntimeException: Callable "Drupal\mymodule\Controller\CheckTestController::checkAccess" requires a value for the "$node" argument. in Drupal\Component\Utility\ArgumentsResolver->handleUnresolvedArgument() (line 142 of /var/www/html/core/lib/Drupal/Component/Utility/ArgumentsResolver.php).

```

the problem is that with the entity.node.canonical route, the $node variable seems to not actually link to the node itself, but stays as the ID.

The code that worked for me for the checkAccess method in the controller is:

```
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Controller\ControllerBase;
use Drupal\node\Entity\Node;

class CheckTestController extends ControllerBase {

    ...

    public function checkAccess($node) {
        $actualNode = Node::load($node);
        return AccessResult::allowedIf($actualNode->bundle() === 'test');
    }
}

```

# Answer
> 2 votes
Also - the answer above is incomplete since it skips a check on access to the node itself. This is possibly a recipe for an access bypass vulnerability.

I'd think you'd want a route more like:

```
mymodule.check_test:
  path: '/checktest/{node}'
  defaults:
    _controller: '\Drupal\mymodule\Controller\CheckTestController::content'
  requirements:
    _custom_access: '\Drupal\mymodule\Controller\CheckTestController::checkAcess'
    _entity_access: node.view

```

# Answer
> 0 votes
Yes, it's unfortunate that this is the normal/best way to handle this. We did't think hard enough about this kind of use case when writing the local task code originally.

An alternative (which I have been considering recently) is to use `hook_menu_local_tasks_alter()` whose purpose is to "Alter local tasks displayed on the page before they are rendered. The downside is that someone could still visit the path and get an unexpected result.

This is a bit sub-optimal since it's out of the OO flow, and you'd have to worry about updating the cache metadata correctly.

# Answer
> 0 votes
The answer from @mradcliffe is largely correct... if you don't want to load the node then in your mymodule.routing.yml user the options to bring in the node object:

```
mymodule.check_test:
  path: '/checktest/{node}'
  requirements:
    _custom_access: '\Drupal\mymodule\Controller\CheckTestController::checkAccess'
    _entity_access: 'node.view'
  options:
    parameters:
      node:
        type: 'entity:node'

```

And then in your controller:

```
namespace Drupal\mymodule\Controller;

use Drupal\Core\Routing\Access\AccessInterface;
use Drupal\node\NodeInterface;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Access\AccessResult;

/**
 * Checks access for displaying time tab.
*/
class CheckAccess extends ControllerBase {

```

public function checkAccess(NodeInterface $node) { return AccessResult::allowedif($node-\>bundle() === 'my\_node\_type'); } }

This will bring in the node object properly so you don't have to load it in your access method and avoid the error mentioned above if you try to call bundle() on the node id.

---
Tags: 8, routes
---


# Question
Title: Writing PHP into views field template twig
I'm less familiar with D8, but I need to re-write a views field output using some PHP. I've made a custom field template HTML.twig file, but I'm not sure what I need to do to be able to run a PHP execution on my field to render it out as I want.

edit:

I am trying to run a function on the User ID as I have a module which hashes it before sending it to an external platform, however, now the client wants the understand which user is which, and the only way I can think to do this is by performing the same hashing code on the User ID in a format I can easily cross reference the user with their hashed output

I have a very basic view table showing only the User ID and email address, and I've managed to create a views field override using this page which has overwritten my field successfully. But now I want to run a command I'm going to copy from my contrib module, the below to be specific, so that I can work out which User ID relates to which hashed code

```
return Crypt::hmacBase64($uid, \Drupal::service('private_key')->get() . Settings::getHashSalt());

```

# Answer
> 0 votes
You can write Twig directly into your view with a Custom text field.

Using Twig as an entry point, you can use all of the Twig functionality and filters that ship with Drupal, as well as expanding on these with modules like Twig Tweak and Twig Field Value. You can also write your own Twig extensions, which are written in PHP. Here are two suitable tutorials:

---
Tags: 8, views
---