# Question
Title: Rendering a region for a theme programmatically
I am building a module that contains a route and a controller that only renders a specific theme region, without any surrounding HTML.

How can I load and render the region programmatically within the controller output method?

The region output from the controller contains one or more blocks and the entire region needs to be embedded on another site. The site will retrieve the markup using a custom route (e.g. example.com/partials/header or example.com/partials/footer).

I don't know which blocks are going to be in the region; the list of blocks in the region is not hard-coded in the module.

# Answer
Using the `block.repository` service you can get an instance of the BlockRepository class. You can then call the `getVisibleBlocksPerRegion` method on it which will return an associative array BlockInterface\[\]\[\] (first key is the region name, second key is the block ID).

You will probably need to change the active context if some of these blocks only appear certain conditions.
> 2 votes

# Answer
Coming back to this nearly five years later, because we now have to output an entire HTML (in our case, Smarty) template incl. assets that can be consumed by another service. Might be useful to someone, or myself when I google this in another five years.

We are rendering selected regions into a custom theme, that we then pass into an HTML render element.

We then call some hooks on the render element to allow modules to alter it.

We use the `HTMLResponse` class to process attachments and add them to the response.

We use `getContent()` on the response to get the final template and return it as text.

**Note:** the template becomes invalid when the processed asset URLs change! Drupal's absolute path URLs `/sites/default/...` work for use because we are using a reverse proxy, but they are easy to str\_replace in the rendered template.

```
<?php

namespace Drupal\my_module\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Render\HtmlResponse;
use Drupal\user\Entity\User;
use Symfony\Component\HttpFoundation\Response;

/**
 * Returns template.
 */
class MyController extends ControllerBase
{

    /**
     * Returns the template.
     */
    public function template()
    {
        $content = $this->generateTemplate();

        $response = new Response(
            $content,
            Response::HTTP_OK,
            [
                'Content-Type' => 'text/plain; charset=UTF-8',
                'X-Robots-Tag' => 'noindex, nofollow',
            ]
        );

        return $response;
    }

    /**
     * Generates and saves the Smarty template.
     *
     * @return string
     *   The rendered template.
     */
    private function generateTemplate()
    {
        // Switch to anon.
        /** @var \Drupal\Core\Session\AccountSwitcherInterface $account_switcher */
        $account_switcher = \Drupal::service('account_switcher');
        $account_switcher->switchTo(User::getAnonymousUser());

        // Create a theme that renders the required regions.
        $build = [
            '#theme' => 'regions_template',
            '#preheader' => $this->renderRegion('preheader'),
            '#header' => $this->renderRegion('header'),
            '#prefooter' => $this->renderRegion('prefooter'),
            '#footer' => $this->renderRegion('footer'),
        ];

        // Add the regions to a page.
        $html = [
            '#type' => 'html',
            'page' => [
                '#type' => 'page',
                'content' => $build,
            ],
        ];

        // Call some hooks.
        system_page_attachments($html['page']);
        \Drupal::service('module_handler')->alter('page_attachments', $html['page']);

        // Render the render array (this modifies it, as it is passed by ref).
        \Drupal::service('renderer')->renderRoot($html);

        // Use a response to process the attachments in the render array.
        $response = new HtmlResponse();
        $response->setContent($html);

        $response = \Drupal::service('html_response.attachments_processor')
            ->processAttachments($response);

        // Get the content from the response.
        $rendered = $response->getContent();

        // Switch back.
        $account_switcher->switchBack();

        return $rendered;
    }

    /**
     * @param string $region
     */
    private function renderRegion($region)
    {
        $build = [];
        foreach ($this->getBlocksInRegion($region) as $block) {
            $build[] = \Drupal::entityTypeManager()
                ->getViewBuilder('block')
                ->view($block);
        }
        return $build;
    }

    /**
     * @param string $region
     *
     * @return array
     */
    private function getBlocksInRegion($region)
    {
        return \Drupal::entityTypeManager()
            ->getStorage('block')
            ->loadByProperties([
                'status' => 1,
                'theme' => 'mytheme',
                'region' => $region,
            ]);
    }
}

```
> 2 votes

---
Tags: 8
---


# Question
Title: The "is-active" class is added to the main-menu links only when the site is accessed by an anonymous user
I use this simple template (menu--main.html.twig) to render the main menu I created.

```
<ul>
    {% for item in items %}
    <li>
        {{ link(item.title, item.url) }}
        {% if item.below is not empty %}
            <div class='submenu'>
                {% for subitem in item.below %}
                    {{ link(subitem.title, subitem.url) }}
                {% endfor %}
            </div>
        {% endif %}
    </li>
    {% endfor %}
</ul>

```

Drupal is nice enough to add an *is-active* class to the currently active link, which is good and worked fine for a bit.

Recently, it stopped working properly and I have no idea why. Currently it is only applying an *is-active* class to the menu links when I am not logged in. When I log in, there is only a menu link that gets that class applied to it when active.

The menu links are identical, apart title and destination on the *Edit Menu Link* menu, so I'm very confused.

Can anybody offer suggestions for things to try to help solve this problem?

# Answer
The problem was with JavaScript, at some point I overwrote the `html.html.twig` template in order to add a container div immediately after the body tag, which subsequently wrapped this line:

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

```

Moving this one line outside of my container div but still within the body tag fixed the issue.

This article was useful https://createdbycocoon.com/knowledge/drupal-8-js-errors-cannot-read-property-currentpath-undefined
> 0 votes

---
Tags: navigation, 9
---


# Question
Title: Fill filter between (min, max) field programmatically drupal
I have created the view. It displays all comments from a certain time period. So I need filter created date and between option, isn't it?

But also I need to get these MIN and MAX options from node: MIN - created node time and MAX - node\`s filed "to\_date".

So, How can I pass these parameters to view? Is here some solution?

**Edit:**

Case: I should create contest module(contest for most popular comments).

Process: Admin creates a node of type Contest. There he must specify contest "To date" and add the description. So in order to determine contest winners, I have created view, that must sort all comments by total views and filter by range date(node created and "To date" field) from node on which page view is displaying. I need to display this view under node: I do it in this way:

```
$page['content']['winners'] = array('#markup' => views_embed_view('contest_winners_one', 'block'));

```

But how to change view filter for every view instance?

# Answer
You should pass `nid` to views by contextual filter to restricts results to specified nodes, then for Comment Post Date filter I have two solution to pass your filter value programmatically to view filter

you can expose your `Post comment ( created)` filter and hide it by css( or in views template remove markups ) then in your code

**Notice:this code is example please dsm $view to precises filter machine name**

```
 $view = views_get_view($name);
  $view->set_display($display_id);

  $start = '2015-12-01 00:00:00';
  $end = '2015-12-31 00:00:00';
  $view->exposed_input['created'] = array('min' => $start, 'max' => $end);
  //$r = $view->get_exposed_input();
  //dsm($r);
  $view->pre_execute();
  $view->execute();
  $r = $view->result;

```

**another solution** is pass your values to filter (without expose them)

```
 $view = views_get_view($name);
  $view->set_display($display_id);
  $item = $view->get_item($display_id, 'filter', 'date_filter');
  //$item['value'] = array('value'=>'2015-01-01 00:00:00');
  $item['default_date'] = '2015-01-01 00:00:00';
  $item['default_to_date'] = '2015-12-01 00:00:00';
  $view->set_item($display_id, 'filter', 'date_filter', $item);
  $item = $view->get_item($display_id, 'filter', 'date_filter');
  $view->pre_execute();
  $view->execute();
  $r = $view->result;
  dsm($r);

```

I had the same requirement after some research found this issue and I resolved my problem.maybe help you too.
> 1 votes

# Answer
If the comments starting from the publication of the node are valid, you do not need a start date. You only need to make sure you load all comments for that single node and an end date.

Since your view lists comments, I suggest you start by adding a contextual filter for the `Comment: nid`. This limits all the comments to those on that specific node only. For this to work in your use case, you need to update views\_embed\_view to also send the node id along (all parameters after the second parameter are sent as arguments (contextual filters)):

```
views_embed_view('contest_winners_one', 'block', $nid);

```

Now the results are limited to those on this node only, you need to compare the post date. If the **To date** is formatted properly (Drupal supports multiple date formats and out of my head I do not know the right one, but my guess is that the date needs to be stored as a timestamp), you can do a field comparison.

For this you have to add the fields to compare to the *Fields* section of the View (if there is no option to add fields, you can force enable in the dialog you get when clicking `settings` behind **Format**. These are the `Comment: creation date` and the `Content: To date` fields. Display format does not matter and you can select `Exclude from display`.

Then in the **Filter** section add the `Field comparison` filter. Then make sure the `comment date` is smaller or equal to the `to date`.

If you fail to get the contextual filter working, you can also use this approach for the content creation date and the comment creation date, but without node filtering, comments would get mixed up if two contests run at the same time.

Additionally you can probably use Rules and the Rules scheduler sub-module to disable comments on the node once the to date is reached. Refer to How do I create a rule that closes comments on node after 30 days? for reference on how to achieve this. If the comments are closed on the correct date, you can safely show all comments as they could only have been created in the defined period. (You wouldn't need any filtering)
> 1 votes

# Answer
Took me a while to figure it out, so for D8/9:

Assuming the field you want to filter on is the "created" one.

```
$view = \Drupal\views\Views::getView($view_machine_name);
$view->setDisplay($display_name);
// Contextual filters.
$view->setArguments([$arg1, $arg2]);
// Get values for filter handler.
$values = $view->getHandler($display_name, 'filter', 'created')['value'];
// Set new values for created filter.
$view->setHandlerOption($display_name, 'filter', 'created', 'value', array_merge($values, [
  'min' => 'YYYY-MM-DD 00:00:00',
  'max' => 'YYYY-MM-DD 00:00:00',
]));
$view->execute();
$renderable_array = $view->render();

```
> 0 votes

---
Tags: views
---


# Question
Title: content types vs. paragraphes types + taxonomy
I have quite a complex content structure and found the paragraphs module (in combination with taxonomies) can be very powerful for creating complex compound fields and dynamically reusing existing content types.

Example: 1 content type "equipment" tagged with a term from a taxonomy "mobility devices" (terms: car, aircraft, bike...) and with different fields of paragraphs types representing the different attributes for each of the devices. This way I'd only use the car\_paragraphs\_field if the equipment is tagged as a car and leave the other paragraphs fields blank. This in contrast of having multiple different content types "car", "bike"...

I'm wondering whether this a reasonable approach in terms of later displaying data in views, storing data to the DB, internal Drupal complexity/load when having let's say 100 different paragraphs types and only using 1 for each new content (i.e. leaving many paragraphs types fields blank), instead of having one separate content type for each.

# Answer
Personally I don't think this is a good use case for paragraphs. I don't see any benefit of having only a single content (node) type, you are just moving comeplexity from nodes to paragraphs.

I think the key here is to carefully plan and reuse fields across entities. If your car equipment and your plane equipment both have a weight attribute, reuse the same field (or to be more precise: reuse the field storage), so e.g. you can use it to as filter in a shared view for both equipment types.
> 1 votes

# Answer
Nodes, taxonomy terms and paragraphs are all different types of entities. Each entity type has unique properties that make it better suited for different use cases and content types.

Here’s a breakdown of the most important Drupal terminology you need to know to structure your content:

**Node:** A page of content is a node, accessible via its own URL

**Taxonomy terms:** Used to categorize other content, taxonomy terms live in a hierarchy. They can be used to filter content and create unique landing pages.

**Paragraphs:** Content that lives within other content and doesn’t need a dedicated URL is a paragraph.

You can read more here : https://evolvingweb.ca/blog/structuring-content-drupal-8
> 0 votes

---
Tags: 8, nodes, taxonomy-terms, paragraphs
---


# Question
Title: Can't restore existing site (no route found for "GET /")
I have a site with Drupal 9.2.5 and the site was clobbered after installing WordPress in the web root.

I have a backup of the site database, and the sites/default/\* files, but I just can't get Drupal up and running again to restore it to the way it was.

I have tried installing again and placing the files back, but this doesn't work.

I have looked at the Drupal docs and searched for migrating or restoring a Drupal site, but nothing seems to be working out.

Once I create a new database, and import all data from the old one, update my settings and restore the folders and files, I get this error:

```
The website encountered an unexpected error. Please try again later.

Symfony\Component\HttpKernel\Exception\NotFoundHttpException: No route found for "GET /"
in Symfony\Component\HttpKernel\EventListener\RouterListener->onKernelRequest()
(line 136 of vendor/symfony/http-kernel/EventListener/RouterListener.php).

```

I am not sure what to do here: the issue is obviously with routing but I am stuck.

I can get to the install script, but it tells me Drupal is already installed, and to empty the database and start again (not what I want!)

I have tried the upgrade script, but I get an error:

```
The website encountered an unexpected error. Please try again later.
Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException: You have requested a
non-existent service "access_check.db_update". in
Symfony\Component\DependencyInjection\ContainerBuilder->getDefinition() (line 1032 of vendor/symfony/dependency-injection/ContainerBuilder.php).
Symfony\Component\DependencyInjection\ContainerBuilder->getDefinition('access_check.db_update') (Line: 600)
Symfony\Component\DependencyInjection\ContainerBuilder->doGet('access_check.db_update', 1) (Line: 558)
Symfony\Component\DependencyInjection\ContainerBuilder->get('access_check.db_update') (Line: 186)
Drupal\Core\Update\UpdateKernel->handleAccess(Object, Object) (Line: 101)
Drupal\Core\Update\UpdateKernel->handleRaw(Object) (Line: 75)
Drupal\Core\Update\UpdateKernel->handle(Object) (Line: 27)

```

This is very frustrating. I can't find any useful information on restoring an existing Drupal site and how to do this.

# Answer
> 1 votes
After restoration the database you need to reload cache. If drush is installed globally you can do it by executing this command from docroot `drush cr` . If drush is installed locally `../vendor/bin/drush cr`

If drush is not installed you need to Truncate cache tables from database. But it should be considered as last resort and not advisable.

```

TRUNCATE `cachetags`;
TRUNCATE `cache_bootstrap`;
TRUNCATE `cache_config`;
TRUNCATE `cache_container`;
TRUNCATE `cache_data`;
TRUNCATE `cache_default`;
TRUNCATE `cache_discovery`;
TRUNCATE `cache_dynamic_page_cache`;
TRUNCATE `cache_entity`;
TRUNCATE `cache_menu`;
TRUNCATE `cache_page`;
TRUNCATE `cache_render`;
TRUNCATE `cache_rest`;
TRUNCATE `cache_toolbar`;
TRUNCATE `cachetags`;
TRUNCATE `cache_bootstrap`;
TRUNCATE `cache_config`;
TRUNCATE `cache_container`;
TRUNCATE `cache_data`;
TRUNCATE `cache_default`;
TRUNCATE `cache_discovery`;
TRUNCATE `cache_dynamic_page_cache`;
TRUNCATE `cache_entity`;
TRUNCATE `cache_menu`;
TRUNCATE `cache_page`;
TRUNCATE `cache_render`;
TRUNCATE `cache_rest`;
TRUNCATE `cache_toolbar`;

```

---
Tags: database, 9, backups
---


# Question
Title: What are the steps for rebasing an issue fork of core to the latest code plus 'patch'?
It appears the current version of Drupal outside the issue fork needs to be added as a remote repository, but i'm getting tripped up on creating it as a branch i can rebase against.

Hoping the answer to this is a link to documentation, but https://www.drupal.org/docs/develop/git/using-git-to-contribute-to-drupal/rerolling-patches does not mention the issue fork workflow.

# Answer
This seems to do it, where '3029545' is the issue number which is forked, these steps are presumed to have happened first:

```
git clone git@git.drupal.org:issue/drupal-3029545.git
cd drupal-3029545

```

And now rebasing on most recent Drupal core:

```
git checkout 3029545-add-route-exists # check out the branch in development
git remote add drupal git@git.drupal.org:project/drupal.git
git fetch drupal
git rebase drupal/9.2.x # current core branch

```
> 1 votes

---
Tags: 9, version-control
---


# Question
Title: "The import is empty" errors validating config synchronization after core upgrade
After Drupal 9 upgrade, I can no longer use configuration synchronization to deploy configuration to Acquia Cloud environment:

```
 Import the listed configuration changes? (yes/no) [yes]:
 > >  [error]  Drupal\Core\Config\ConfigImporterException: There were errors validating the config synchronization.
> This import is empty and if applied would delete all of your configuration, so has been rejected. in Drupal\Core\Config\ConfigImporter->validate() (line 750 of /mnt/www/html/d9readiness/docroot/core/lib/Drupal/Core/Config/ConfigImporter.php).
>
> In ConfigImportCommands.php line 360:
>
>   The import failed due to the following reasons:
>   This import is empty and if applied would delete all of your configuration,
>    so has been rejected.
>
>

```

The configuration settings are the same ones that worked before the upgrade:

```
$ grep -Rn '../config/default' .
./docroot/sites/default/settings.php:258:// $config_directories['vcs'] = '../config/default';
./docroot/sites/default/settings.php:259:// $config_directories['sync'] = '../config/default';
./docroot/sites/default/settings.php:262:$settings['config_sync_directory'] = '../config/default';
./docroot/sites/default/settings.php:263:$settings['config_vcs_directory'] = '../config/default';

```

My suspicion is that Acquia is overriding my settings somewhere outside of my document root, but I can't quite find it.

Local environment is Lando with the new-ish `acquia` recipe, so perhaps there is some legacy config that comes with `acli` or something.

I'm hoping to install BLT 12 as soon as I deal with the last couple of weird errors in my local; maybe that will help me to fix the config sync issue since it comes with its own configuration overrides.

This may be related to the following error reported by the Upgrade Status module *before* Drupal 9 upgrade: https://www.drupal.org/project/upgrade\_status/issues/3229552#comment-14209685

**UPDATE:** *via Drupal Slack*

> **mcdruid** 6 hours ago
>
> > My suspicion is that Acquia is overriding my settings somewhere
>
> ...probably not answering your question directly, but you should be able to check any of the settings with e.g.
>
> ```
> $ drush ev 'print_r(\Drupal\Core\Site\Settings::get("config_sync_directory"));'
>
> ```

I tried this, and indeed it confirms that Acquia is using different configuration which is not in my `settings.php`.

Here is the output from running that command in my local and on Acquia Cloud:

```
$ lando drush ev 'print_r(\Drupal\Core\Site\Settings::get("config_sync_directory"));'
../config/default%

$ lando drush @dev ev 'print_r(\Drupal\Core\Site\Settings::get("config_sync_directory"));'
Enter passphrase for key '/var/www/.ssh/id_rsa':
/mnt/www/html/d9readiness/docroot/sites/default/files/config_315f86d0f57aa166d80058769033a13b1b4823d0/syncConnection to d9readiness.ssh.devcloud.acquia-sites.com closed.

$ lando drush @test ev 'print_r(\Drupal\Core\Site\Settings::get("config_sync_directory"));'
Enter passphrase for key '/var/www/.ssh/id_rsa':
/mnt/www/html/d9readiness/docroot/sites/default/files/config_72c878fc6029f4e12c65fa9d1ce2afd4c3a94575/syncConnection to d9readiness.ssh.devcloud.acquia-sites.com closed.

```

This proves that Acquia is overriding my configuration settings.

Just to verify this, I grepped for the Dev configuration directory in my local project and no results were returned:

```
$ grep -Rn 'sites/default/files/config_315f86d0f57aa166d80058769033a13b1b4823d0/sync' .
$

```

In case the public files directory path segment was provided by stream wrapper, variable expansion or string concatenation, I tried again with only the config identifier:

```
$ grep -Rn '315f86d0f57aa166d80058769033a13b1b4823d0' .
$

```

No results again. This config is coming from someplace weird for sure.

Could it be this `require` near the end of `settings.php`?

```
// On Acquia Cloud, this include file configures Drupal to use the correct
// database in each site environment (Dev, Stage, or Prod). To use this
// settings.php for development on your local workstation, set $db_url
// (Drupal 5 or 6) or $databases (Drupal 7 or 8) as described in comments above.
if (file_exists('/var/www/site-php')) {
  require('/var/www/site-php/d9readiness/d9readiness-settings.inc');
}

```

Note: This config is at least two years old. The project is really not called `d9readiness` (imagine it's called `client-project-name`).

# Answer
> 0 votes
Even though I never was able to figure out where the old D8 project config was coming from, I was able to resolve the problem by explicitly overriding the config at the very end of `settings.php`:

```
// Replace Acquia Dev Desktop settings (deprecated) with Acquia Cloud environment overrides.
// Note: This is for troubleshooting only; remove this code after configuring BLT 12.
if (isset($_ENV['AH_SITE_ENVIRONMENT'])) {
  switch ($_ENV['AH_SITE_ENVIRONMENT']) {
    case 'dev':
      // do something on dev
      $settings['config_sync_directory'] = '../config/default';
      $settings['config_vcs_directory'] = '../config/default';
      break;
    case 'test':
      // do something on staging
      $settings['config_sync_directory'] = '../config/default';
      $settings['config_vcs_directory'] = '../config/default';
      break;
    case 'prod':
      // do something on prod
      // Site Factory may require a different value depending
      // on site configuration
      $settings['config_sync_directory'] = '../config/default';
      $settings['config_vcs_directory'] = '../config/default';
      break;
    case 'ra':
      // do something on ra - necessary if a
      // Remote Administration environment is present
      $settings['config_sync_directory'] = '../config/default';
      $settings['config_vcs_directory'] = '../config/default';
      break;
    }
  }
  else {
  // do something for a non-Acquia-hosted application
  // (like a local dev install).
  $settings['config_sync_directory'] = '../config/default';
  $settings['config_vcs_directory'] = '../config/default';
}

```

I have set the same default config for all environments here just to get a basic config sync working again, but my intent is to remove this code after setting up BLT 12. (BLT has its own overrides in different locations, which I don't want to mess up by overriding here.)

---
Tags: configuration, 9, upgrading, acquia-cloud
---


# Question
Title: How to return Service Worker with custom HTTP header from custom module
I have a custom module providing a HTML5 Service Worker file under `/modules/custom/my_blocks/assets/js/service-worker.js`. Since the Service Worker is not located in the root of the Drupal server, I need to return the file with an additional `Service-Worker-Allowed` HTTP header.

How to do that within my module?

# Answer
To provide a dynamic file, you need to make a Controller with a method like:

```
 public function serve(Request $request) {
    $file_str = $file_system->realpath($module_handler->getModule('my_module')->getPath()) . '/assets/js/service-worker.js';

    if (file_exists($file_str)) {

      $response = new BinaryFileResponse($file_str, 200);
      $response->headers->set('Content-Type', 'application/javascript');
      // Allow same origin service worker.
      $response->headers->set('Service-Worker-Allowed', '/');

      return $response;
    }

    throw new NotFoundHttpException();
  }

```

And then define a route for it, where the path is not existing as a static file, like:

```
example.serviceworker:
  path: '/serviceworker'
  defaults:
    _controller: '\Drupal\my_module\Controller\ExampleController::serve'
  requirements:
    _permission: 'access content'

```

see - https://www.drupal.org/docs/drupal-apis/routing-system/introductory-drupal-8-routes-and-controllers-example.
> 4 votes

---
Tags: http-request
---


title: Drush and user permissions

text:
# Question
Title: Drush and user permissions
I see that my user is a member of the apache group. I added and confirmed via the following

```
$ sudo usermod -a -G apache `whoami`  # add my user to apache group
$ sudo chmod -R g+w .                 # permit group members to write
$ groups `whoami`                     # confirm I'm in the apache group

```

However, when I attempt to run a drush update core or even drush cron

```
$ drush cc all

unlink(sites/default/files/css/css_71ba7c25a8d3c47c68a8e05608ae525c.css):[warning]
Permission denied file.inc:482

```

And the CSS cache in this situation looks like

```
$ ll
total 1536
drwxrwxr-x.  2 apache apache  12288 Nov 26 10:12 .
drwxrwxr-x. 11 apache apache   4096 Nov 24 20:35 ..
-rw-rw-r--   1 apache apache 162269 Nov 26 10:06 css_00d5f4d7c5c92cd4f.css
-rw-rw-r--   1 apache apache 158090 Nov 26 10:02 css_0605989692a2119d305.css
-rw-rw-r--   1 apache apache 162269 Nov 26 10:02 css_0779dcac71ee9aa8e02d9e.css

```

I would assume that my user account, which has sudo access, should be a group member of apache (or www-data) and that the file tree should permit group write access. Any help or points in the right direction would be much appreciated.

# Answer
Though the other answer is informative, I now use the proper user permission as described in

***Securing file permissions and ownership***

Which opens with

> The server file system should be configured so that the web server (e.g. Apache) does not have permission to edit or write the files which it then executes. That is, all of your files should be 'read only' for the Apache process, and owned with write permissions by a separate user.
> 4 votes

# Answer
Arguably, a much more straightforward approach is to not muck with your user's group assignments at all and instead run drush as the web server user (ie: apache, www-data).

**Use sudo:**

```
sudo -u apache drush

```

or on debian/ubuntu:

```
sudo -u www-data drush

```

**Create a command alias:**

Then, to ensure that you always run drush like that, add an alias:

```
echo "alias drush='sudo -u apache drush'" >> ~/.bash_aliases

```

or on debian/ubuntu:

```
echo "alias drush='sudo -u www-data drush'" >> ~/.bash_aliases

```

Now when running any drush command, you'll be prompted for your password by sudo, and the command will run as the web server user. No more permissions problem reading and writing files.
> 15 votes

# Answer
When I ran drush as `www-data` drush was no longer available as my $PATH had changed.

As a workaround you can enter the whole path to drush.

E.g.

```
sudo -u www-data /home/vagrant/.composer/vendor/bin/drush status

```

To get the path of your drush you can run:

```
which drush

```

Which means you can also just run:

```
sudo -u www-data `which drush` status

```

which removes the need to hard code the path in the command.
> 1 votes

# Answer
Inside files folder

```
chown -R youruser:www-data .
find . -type d -exec chmod ug=rwx,o= '{}' \;
find . -type f -exec chmod ug=rw,o= '{}' \;

```

See: https://www.drupal.org/node/244924#linux-servers
> 0 votes

---
Tags: drush, files
---


# Question
Title: Render first element of a multivalued field
On my site I've an image field, multi value. I would like, on a custom view mode, to display only the first image. On the field formatter I don't have this option.

How should I do this? Directly from twig or I've to use a preprocess function?

\[EDIT\] I would to do this without using a custom node template :)

# Answer
> 4 votes
Then it's

```
{{ content.field_name[0] }}

```

> **Note**: If you need to print the label use `{{ content.field_name['#title'] }}` as `{{ content.field_name[0] }}` does not print the label.

# Answer
> 1 votes
There are now a couple of modules which look like they could help.

https://www.drupal.org/project/single\_image\_formatter

> This module provides formatters for Image, Media and Responsive image field, that displays only first value of multi-valued fields. It is useful, when you configure teasers display and don't need to show all images.

https://www.drupal.org/project/field\_formatter\_range

> The Field Formatter Range module provides the option to display only selected range of values for multivalued entity fields.

---
Tags: theming, 8
---


# Question
Title: Change required state by checking checkbox
I have an image field and a checkbox in my node edit form. I want the image field to be required when the checkbox is not checked. And I want the image field to not be required when the checkbox is checked.

How can I do this?

# Answer
> 1 votes
For image field use #states, this will be making a field required based on the checkbox clicked or not. Check here for more information

```
'#states' => array(
  'required' => array(
    :input[name="NAME OF THE FIELD"]' => array('value' => 'VALUE OF FIELD'),
  ),
),

```

---
Tags: 9
---


title: PHPUnit fails when logging in user

text:
# Question
Title: PHPUnit fails when logging in user
I've got a custom module and have the auto generated `LoadTest` but it is not working. This is a functional test.

```
  protected function setUp() {
    parent::setUp();
    $this->user = $this->drupalCreateUser(['administer site configuration']);
    $this->drupalLogin($this->user); // Breaks here
  }

  public function testLoad() {
    $this->drupalGet(Url::fromRoute('<front>'));
    $this->assertSession()->statusCodeEquals(200);
  }

```

Running this test returns :

```
1) Drupal\Tests\weekly_digest\Functional\LoadTest::testLoad
User <em class="placeholder">belwfS3e</em> successfully logged in.
Failed asserting that false is true.

/app/web/core/tests/Drupal/TestTools/PhpUnitCompatibility/PhpUnit7/TestCompatibilityTrait.php:18
/app/web/core/tests/Drupal/Tests/UiHelperTrait.php:254
/app/web/modules/custom/weekly_digest/tests/src/Functional/LoadTest.php:35

```

When I comment out the `drupalLogin` call the test succeeds.

The fail is on this line

```
$this->assertTrue($this->drupalUserIsLoggedIn($account), new FormattableMarkup('User %name successfully logged in.', ['%name' => $account->getAccountName()]));

```

And if you look at the error from above it's from the TestCompatibilityTrait which had some pretty wacky deprecation errors.

Here is my phpunit env

```
    <!-- Set error reporting to E_ALL. -->
    <ini name="error_reporting" value="32767"/>
    <!-- Do not limit the amount of memory tests take to run. -->
    <ini name="memory_limit" value="-1"/>

    <env name="SYMFONY_DEPRECATIONS_HELPER" value="disabled"/>

    <env name="SIMPLETEST_BASE_URL" value="http://changelog.lndo.site/"/>
    <env name="SIMPLETEST_DB" value="mysql://drupal8:drupal8@database/drupal8"/>

    <env name="BROWSERTEST_OUTPUT_DIRECTORY" value="web/sites/simpletest/browser_output"/>
    <env name="BROWSERTEST_OUTPUT_BASE_URL" value=""/>

    <!-- Example for changing the driver class for mink tests MINK_DRIVER_CLASS value: 'Drupal\FunctionalJavascriptTests\DrupalSelenium2Driver' -->
    <env name="MINK_DRIVER_CLASS" value=''/>
    <!-- Example for changing the driver args to mink tests MINK_DRIVER_ARGS value: '["http://127.0.0.1:8510"]' -->
    <env name="MINK_DRIVER_ARGS" value=''/>
    <!-- Example for changing the driver args to phantomjs tests MINK_DRIVER_ARGS_PHANTOMJS value: '["http://127.0.0.1:8510"]' -->
    <env name="MINK_DRIVER_ARGS_PHANTOMJS" value=''/>
    <!-- Example for changing the driver args to webdriver tests MINK_DRIVER_ARGS_WEBDRIVER value: '["chrome", { "chromeOptions": { "w3c": false } }, "http://localhost:4444/wd/hub"]' For using the Firefox browser, replace "chrome" with "firefox" -->
    <env name="MINK_DRIVER_ARGS_WEBDRIVER" value=''/>

```

This is using lando.
Why would I be getting these failures? It accesses the site just fine, it seems to be checking if the user is logged in that's causing the issue but I can't find out why.

# Answer
> 1 votes
I ran into this same behaviour, and found that while the `phpunit.xml` had `SIMPLETEST_BASE_URL` set to my site URL locally, in the Lando appserver the environment variable was set to `https://appserver_nginx`.

Even setting `SIMPLETEST_BASE_URL="http://appserver_nginx"` in a Lando `env_file` directive didn't resolve this.

When I used `lando ssh` into the appserver container and executed `phpunit web/modules/contrib/modulename`, I saw the same error. If I set the environment variable manually using `export SIMPLETEST_BASE_URL=http://appserver_nginx` then ran the tests again, the login step worked.

---

The eventual solution I used, from here, was to modify `phpunit.xml` to contain this line:

```
    <env name="SIMPLETEST_BASE_URL" value="http://appserver_nginx" force="true"/>

```

And to execute PHPUnit in Lando with this tooling:

```
tooling:
  phpunit:
    service: appserver
    cmd: "php /app/vendor/bin/phpunit -c /app/phpunit.xml"

```

Related:

---
Tags: 8, testing
---


# Question
Title: How can I write a unit test for a custom field formatter?
I'm working on a project where we need to have code coverage using phpunit. I have a public method that includes this code:

```
  /**
   * {@inheritdoc}
   */
  public function viewElements(FieldItemListInterface $items, $langcode) {
    $elements = [];

    foreach ($items as $delta => $item) {
      $elements[$delta] = $this->viewValue($item);
    }

    return $elements;
  }

```

and dependent private method:

```
  /**
   * Generate the output appropriate for one field item.
   *
   * @param \Drupal\Core\Field\FieldItemInterface $item
   *   One field item.
   *
   * @return string
   *   The textual output generated.
   */
  protected function viewValue(FieldItemInterface $item) {
    $frequency = $item->getValue();
    return [
      '#theme' => 'frequency',
      '#frequency' => $this->switchWeights($frequency['value']),
      '#limit' => 5,
    ];
  }

```

I am trying to cover with unit test the parent method to make sure that it works as suspected. Here my code with no items provided to field to be formatted just covered with abstract class mock:

```
/**
 * Simple test to cover FrequencyFieldFormatter class.
 *
 * @group my_custom_module_name
 */
class FrequencyFieldFormatterTest extends UnitTestCase {

  /**
   * Test viewElements function.
   */
  public function testviewElements() {

    /** @var \Drupal\Core\Field\FieldItemList|\PHPUnit\Framework\MockObject\MockObject $field_list */
    $field_list = $this
      ->getMockBuilder(FieldItemListInterface::class)
      ->getMockForAbstractClass();

    $resultElements = FrequencyFieldFormatter::viewElements($field_list, 'und');
    $this->assertEmpty($resultElements);
  }

}

```

When i trying to change assertion to make sure that items field\_items processed to be rendered with custom theme but i am facing difficulty when instead providing a mock for abstract class which is specified as interface i providing a mock for real class \Drupal\Core\Field\FieldItemList:

```
$field_list = $this
      ->getMockBuilder(\Drupal\Core\Field\FieldItemList::class)
      ->getMock();

```

I know that the error i am getting in this case is related to not initialized container for this stack:

```
There was 1 error:

1) Drupal\Test\my_custom_module_name\Unit\FrequencyFieldFormatterTest::testviewElements
ArgumentCountError: Too few arguments to function Drupal\Core\TypedData\TypedData::__construct(), 0 passed in /Users/username/Sites/drupal-site-09/code/vendor/phpunit/phpunit/src/Framework/MockObject/Generator.php on line 607 and at least 1 expected

```

Then i tried to initialize container to make it works but i do not know how to do it properly.

May somebody help me?

# Answer
FieldFormatters do not profit from unit tests as they are too much abstracted away from the typical usage scenario, so I would advise against creating them for formatters.

In case you have a really large implementation, you might consider extracting those aspects into methods or classes and have these unit tested based on a more restrictive API than just the `FieldItemListInterface`.

And as you have noticed, you need to mock away too many services and the parts of the eco system.

To ensure your formatter will actually work, these questions should be answered by a test:

* Is the formatter plugin picked up by the system?
* Does the renderer produce what you expect you are producing?
* Is the caching layer going to get the correct cacheability meta data?
* Are variants of the data you expect via `$field_items` covered: empty field, single field, multiple fields?

Pretty much all formatters in Core and the usual modules opt for an integration test based on `KernelTestBase`.

`.../modules/custom/src/Plugin/Field/FieldFormatter/CustomFormatter.php`

```
<?php
namespace Drupal\custom\Plugin\Field\FieldFormatter;

/**
 * @FieldFormatter(
 *   id = "custom_datetime",
 *   label = @Translation("Custom Date & Time"),
 *   field_types = {
 *     "datetime"
 *   }
 * )
 */
class CustomFormatter extends FormatterBase implements ContainerFactoryPluginInterface {
  /**
   * {@inheritdoc}
   */
  public function viewElements(FieldItemListInterface $items, $langcode) {
    return [
      '#markup' => $this->t('Completed'),
    ];
  }

}

```

`.../modules/custom/tests/src/Kernel/CustomFormatterTest.php`

```
<?php

namespace Drupal\Tests\custom\Kernel;

use Drupal\Component\Render\MarkupInterface;
use Drupal\field\Entity\FieldConfig;
use Drupal\KernelTests\Core\Entity\EntityKernelTestBase;
use Drupal\field\Entity\FieldStorageConfig;

/**
 * Tests the date time formatters functionality.
 *
 * @group custom
 */
class CustomFormatterTest extends EntityKernelTestBase {

  /**
   * The entity type used in this test.
   *
   * @var string
   */
  protected $entityType = 'entity_test';

  /**
   * The bundle used in this test.
   *
   * @var string
   */
  protected $bundle = 'entity_test';

  /**
   * Modules to enable.
   *
   * @var array
   */
  public static $modules = ['datetime', 'language', 'custom'];

  /**
   * {@inheritdoc}
   */
  protected function setUp() {
    parent::setUp();

    FieldStorageConfig::create([
      'field_name' => 'field_under_test',
      'entity_type' => $this->entityType,
      'type' => 'datetime',
      'settings' => [],
    ])->save();
    FieldConfig::create([
      'entity_type' => $this->entityType,
      'bundle' => $this->bundle,
      'field_name' => 'field_under_test',
      'label' => 'Field label',
    ])->save();
  }

  protected function createAndRenderFieldData(array $field_data): MarkupInterface {
    // Create the entity to be referenced.
    $entity = $this->container->get('entity_type.manager')
      ->getStorage($this->entityType)
      ->create(['name' => $this->randomMachineName()]);
    $entity->field_under_test = $field_data;
    $entity->save();
    $build = $entity->get('field_under_test')->view(['type' => 'custom_datetime']);
    return \Drupal::service('renderer')->renderRoot($build);
  }

  /**
   * Tests the formatter's output with a date in the past.
   */
  public function testFormatterWithDateInThePast() {
    // Verify the text field formatter's render array.
    $result = $this->createAndRenderFieldData(['value' => '2021-01-01T12:00:00']);
    $this->assertEqual($result, "Completed");
  }

}

```
> 3 votes

---
Tags: 8, testing
---


# Question
Title: Paragraphs removed from graphql schema if not anywhere in content, which causes error for union type
I'm making a headless Drupal site with Gatsby using paragraphs. I'm experienced with Drupal but relatively new with gatsby/graphql.

The issue I'm running into is that if our database does not actually have any instances of a paragraph, then it generates the schema without that (i guess it generates a minimal schema based on what exists, not what types are actually possible) and it errors out because it's not an allowed type in the schema when it gets to that paragraph in my graphql union type.

I'm getting around this currently by making sure there's a node with content with all the possible paragraphs (or referenced nodes for entity reference fields). Everything works then, but this is a bad solution, especially for a site that'll eventually be handed off to a client. I feel like there's gotta be a way to make them optional in graphql or not break the build if one paragraph doesn't exist in content.

I know I can customize the schema, but some content types have 10-20 possible paragraphs and that'd just get insane if I had to manually maintain the schema when it's so close to what I need automatically.

Any help would be greatly appreciated. Thanks!

# Answer
This may help: https://medium.com/@Zepro/contentful-reference-fields-with-gatsby-js-graphql-9f14ed90bdf9

Just wrap your GraphQL fragments into a Node-type.
> 1 votes

---
Tags: 8, javascript, paragraphs
---


# Question
Title: Custom field formatter with blob, value always empty
I have the following custom field:

```
/**
 * Plugin implementation of the 'price_table' field type.
 *
 * @FieldType(
 *   id = "price_table",
 *   default_widget = "price_table_widget",
 *   default_formatter = "price_table_formatter",
 * )
 */
class PriceTable extends FieldItemBase {

  public static function mainPropertyName(): string {
    return 'value';
  }

  public static function schema(FieldStorageDefinitionInterface $field_definition): array {
    return [
      'columns' => [
        'value' => [
          'type' => 'blob',
          'size' => 'big',
          'serialize' => TRUE,
        ],
      ],
    ];
  }

  public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition): array {
    $properties['value'] = MapDataDefinition::create()
      ->setLabel(t('Table data'));

    return $properties;
  }

  public function setValue($values, $notify = TRUE) {
    if (isset($values) && !empty($values['table'])) {
      $values['value'] = $values['table'];
      unset($values['table']);
      parent::setValue($values, $notify);
    }
  }

  public function isEmpty(): bool {
    try {
      $value = $this->get('value')->getValue();
      dpm($value); //<<<
      return !is_array($value) || empty($value);
    } catch (MissingDataException | InvalidArgumentException $e) {
      return FALSE;
    }
  }

}

```

with the appropriate widget (using a table form element) and formatter present. The editing goes fine, the serialized data gets stored into the database record of my entity. However, when it comes to the formatter, it displays nothing because `isEmpty()` above always gets an empty value and returns `FALSE`. The blob gets stored all right (thanks to `setValue()` above) but it isn't retrieved by the field.

What am I missing here?

# Answer
Never mind... :-)

```
public function isEmpty(): bool {
  try {
    $value = $this->getValue();

```

That simple.
> 0 votes

---
Tags: 8
---


# Question
Title: How to alter routes defined in route_callbacks?
Usually I alter static routes in routes subscriber:

```
  protected function alterRoutes(RouteCollection $collection) {
    $route = $collection->get('gutenberg.media.load_media');
    if ($route) {
      $route->setDefault('_controller', '\Drupal\gutenberg_adv\Controller\MediaController::loadMedia');
    }
  }

```

However I this does not work for routes defined in routes\_callback, so this does not work for search route for example:

```
$route = $collection->get('search.view_node_search');
if ($route) {
  $route->setDefault('_controller',
      '\Drupal\wi_misc\Controller\SearchController::view');
}

```

So how to alter search route controller?

# Answer
Try to change the weight of the execution of the `alterRoutes` function. You can override the `getSubscribedEvents` function:

```
public static function getSubscribedEvents(): array
{
    return [
        RoutingEvents::ALTER => [
            'onAlterRoutes', 1
        ],
    ];
}

```

Notice that i call `onAlterRoutes` instead of `alterRoutes`. This is because in the parent class this is a wrapper for the called function:

```
public static function getSubscribedEvents() {
    $events[RoutingEvents::ALTER] = 'onAlterRoutes';
    return $events;
}

```

The higher your number (= weight) is, the earlier it gets executed (or the other way around). I would try with some high and some low numbers and check the result.

I have never tried it with this specific eventbut i used this method to solve other problems with events in some `RouteSubscriber`.

If you use drush to clear your cache (which you should after changing code in a `RouteSubscriber`) then you can also use `var_dump($route);` to ensure your route does exist and is loaded correctly. The dump will get displayed in the cmd.
> -1 votes

---
Tags: routes, 9, event-subscribers
---


# Question
Title: How do I alter a view and add/change the form action in Entity View Attachment (eva) with table format?
I have 2 related content types (*Order* and *Proposals*). In the *Order Detail* page, I attach the proposals for that order using EVA with table format.

>

I want to add an action button (vote) in EVA output (orange colored box buttons), so that when it's clicked, it updates the *Vote* field in the corresponding proposal node. I don't know where to start.

I've tried using `hook_view_pre_render()` but I can't find the corresponding object because the `dpm()` breaks the site.

This is the code I am using.

```
function mymodule_views_pre_render(\Drupal\views\ViewExecutable $view) {
  if ($view->id() == 'order_proposal_list') {
    $results = $view->result;
    dpm($view); // This breaks the site.
    ddm($view); // This outputs 300000 and more lines in drupal_debug.txt.
  }
}

```

Somehow, I can get that field value using this code, but it's still not enough.

```
function mymodule_preprocess_views_view_field(&$variables)  {
  $view = $variables['view'];
  if ($view->id() == 'order_quotation_list') {
    if ($variables['field']->field == 'edit_node') {
      dpm($variables['output']);
    }
  }
}

```

# Answer
> 0 votes
It's too late to change field plugins at this stage. You have to configure them in the View.

You could create a custom field handler plugin providing the button link and make it available in Views via hook\_views\_data().

On a higher level of the Entity API entities define operations. You can add your own in hook\_entity\_operation() or alter them in the corresponding alter hook. To use them in a View add the field *Operation Links*. The existing core operations edit/delete are only displayed for users who have access.

On a lower level, directly adding the HTML markup of the button to the field, use the rewrite input box of the Views field UI. See How can I theme individual fields in a row?

---
Tags: 8, views
---


title: Create a path to node/add in twig

text:
# Question
Title: Create a path to node/add in twig
Can I use the path() function in twig to create a link to a non-node entity add form. Taking the group module as an example, if I want to create a link to the 'group/add' page in twig can I use something like:

```
{{ path('entity.group.add') }}

```

I know that the above does not work, neither does

```
{{ path('group.add') }}

```

Not sure if there is a way to do this with the various twig functions that create links.

# Answer
> 6 votes
According to According to Functions - In Twig Templates just Try

```
{{ path('node.add', {'node_type' : 'yourcontenttypename'}) }}

```

as the example for article content type

```
{{ path('node.add', {'node_type' : 'article'}) }}

```

**Update** Try

```
{{ path('entity.group.add_form', {'group_type' : 'yourgrouptype' }) }}

```

# Answer
> 0 votes
If anyone looking for 'add feed' path in twig.

```
{{ path('entity.feeds_feed.add_form', {'feeds_feed_type' : '<FEED_NAME>' }) }}"

```

---
Tags: theming, 8, routes
---


# Question
Title: How can I programmatically delete a field value?
Using Entity API, I know how to get a value or to set a value :

```
$nid = $entity->id();
$node = \Drupal::entityTypeManager()->getStorage('node')->load($nid);
...
$nom = strtoupper($node->get('field_nom')->value);
$node->set('field_nom', $nom);
$node->save();

```

But is there a possibility to delete a value of this field?

I tried to directly delete the value in the database

```
$query =\Drupal::database()->delete('node__field_nom');
$query->condition('field_nom', $nom);
$query->execute();

```

But since the value is cached, the node have to reload twice to see the result on the screen (an empty field)

# Answer
> 5 votes
The field content is a field item list and normally you would need to include a single value also in an array. The fact that you can set a scalar like in your example is due to extra code in the Field API detecting the scalar and transferring it to a field item list with a single value. To delete the field you can't set an empty scalar, though, because this would be interpreted as a single field item with that empty value.

So to delete the entire field content set an empty array:

```
$node->set('field_nom', []);

```

---

BTW you can get the entire field content:

```
$values = $node->get('field_nom')->getValue();

```

Change the array $values and set it again:

```
$node->set('field_nom', $values);

```

---
Tags: entities
---


# Question
Title: How do I programmatically create an order without deleting a profile?
I followed Orders to write the following code.

```
$order = \Drupal\commerce_order\Entity\Order::create([
  'type' => 'custom_order_type',
  'state' => 'draft',
  'mail' => 'user@example.com',
  'uid' => 1,
  'ip_address' => '127.0.0.1',
  'order_number' => '6',
  'billing_profile' => $profile,
  'store_id' => $store->id(),
  'order_items' => [$order_item],
  'placed' => time(),
]);

```

`$profile` is a user profile.

I then programmatically change the order status to *place* with `$order->getState()->applyTransitionById('place');`.

The order is placed and everything looks fine, except that the user addressbook becomes empty. I think I miss a step.

Is there a way to preserve the addressbook while placing the order?

# Answer
The profile is not being deleted - it's just becoming "owned" by the order. This occurs in `Order::preSave()` where the profile uid is set to 0. This ensures that a customer will not be able to use the addressbook interface to edit a profile referenced by an order. For more background on how the addressbook in Commerce 2.x works with respect to profile copying, please see may article:

https://www.centarro.io/blog/understanding-drupal-commerce-2x-address-book

The solution is for you to create a copy of the profile yourself, set its uid to 0, and reference that profile from your order instead of the original one.
> 3 votes

---
Tags: commerce
---


title: Show two content types in same view

text:
# Question
Title: Show two content types in same view
Drupal 8 newb here,

I have two basic types I need to show in my front page: There’s a “Restaurants” content type and a “Chefs” content type.

These are shown in my site like this:

The types are unrelated, I just need to show them in the same page as featured.

I’ve found documentation on how to make blocks and views but nothing about mixed content, which seems to me like a common use case.

Thanks in advance.

# Answer
You don't need to use blocks: You can create a view with a page and an attachment. First from admin/structure/views/add, you create a view for content, selecting the content type to show and selecting *Create a page*.

>

Click on `Save and edit`. On the next page, which shows the view settings, click on the `+ Add` button and select *Attachment*.

>

The next page will show the settings for the attachment.

>

The attachment shows nodes for the same content type the *Page* view does. The first step is changing that. Click on the *Content: Content type* in the filtering criteria.

>

On the top, change *For* from *All displays* to *This attachment (override)*, select the content type to show. Click on `Apply (this display)`.

The attachment still need to be attached to the *Page* view. On  *Attach to: Not defined* click on *Not defined*.

>

On the dialog box, select *Page* and click on `Apply`.

>

If you want the attachment to appear after the main content, change from *Attachment position: Before* to Attachment position: After\*. Then, click on `Save` to save the settings.

The view needs to be styled better (for example, selecting *Grid* as format instead of *Unformatted list*), but it shows two different content types on the same page.
> 2 votes

---
Tags: views, nodes, blocks
---


# Question
Title: How target specific version of fork based merge request (MR) patch
I'm upgrading the core from `9.1.7` to `9.2.5`, however there's a patch I don't how to upgrade.

This is the relative issue. The file `2897638-48.patch` is currently used. The patch's work meanwhile proceed and was integrated in the "fork based merge request (MR)" system.

I opened a issue in the past on the general use of the MR system, read this one and the documentation of Drupal site, so at least I know how to get the latest patch file. However it doesn't aplly, because I suppose it has been target for the `9.3` version.

Reading the commits' list I'd like to try to install the patch at the commit `eaa43b0c10c6fff8595d72d23c0f40a028bf0a71` ("Cleanup leftover."), because it looks to me it's the last one before the switch to the 9.3 branch.

However I don't know if and how I can get the .patch file of that specific revision.

# Answer
> 3 votes
There's more than one way to apply a one-off patch to a Composer-based PHP project. The classic way is to use `cweagans/composer-patches`, which is the way you have learned.

This article explains in detail how to use Composer Patches to patch Drupal core.

You may be able to use this method to apply this patch, which is the approach recommended by @catch in this comment, by including this in your `composer.json`:

```
    "extra": {
      "enable-patching": true,
        "patches": {
          "drupal/core": {
            "Allow Views exposed sort identifiers to be configured": "https://git.drupalcode.org/project/drupal/-/merge_requests/54.diff"
          }

```

As @catch mentions:

> @Giuseppe87 you can use https://git.drupalcode.org/project/drupal/-/merge\_requests/54.diff \- although to get a stable patch to apply, it's best to download this to a /patches directory in your codebase, and then add the local patch path to composer.

To follow these instructions, open a Terminal and `cd` to the project root directory of your Drupal 9.2 project, then execute the following commands:

```
$ mkdir patches
$ cd patches
$ wget https://git.drupalcode.org/project/drupal/-/merge_requests/54.diff
$ mv 54.diff configure-views-exposed-sort-identifiers.patch

```

To use the local patch file in your project rather than the remotely-hosted patch on Drupal.org, your `composer.json` would look like this:

```
    "extra": {
      "enable-patching": true,
        "patches": {
          "drupal/core": {
            "Allow Views exposed sort identifiers to be configured": "patches/configure-views-exposed-sort-identifiers.patch"
          }

```

Using a local file is considered the best practice here, since it has some advantages over using a remote file. It's both more secure and more efficient.

There's another, relatively new, method to apply patches by opening up an Issue Fork and my initial answer recommended that method, but it's not necessary here.

**EDIT:** After reading your comments below, it looks like your problem is that !54 was never applied to the 9.2 branch before rebasing.

Going back to the MR on GitHub, you can roll back the last two commits by choosing "Version 9" of the MR:

But even then, the target is set to 9.3 and it's not clear how to change it using the web-based UI.

You'll need to follow the Git Instructions to clone Drupal core to a local development environment:

```
$ git clone https://git.drupalcode.org/project/drupal.git
$ cd drupal

```

Then, go back to your Issue Queue and look at the instructions to check out the branch for an Issue Fork:

```
$ git remote add drupal-2897638 git@git.drupal.org:issue/drupal-2897638.git
$ git fetch drupal-2897638

```

Also check out the 9.2.x branch:

```
$ git checkout -b '9.2.x' --track drupal-2897638/'9.2.x'

```

Now, you want to generate a diff between the state of the project at commit `eaa43b0c` and the `9.2.x` branch:

```
$ git checkout eaa43b0c
$ git diff drupal-2897638/9.2.x > configure-views-exposed-sort-identifiers.patch

```

This will generate a patch between the commit you have identified and the 9.2.x branch.

However, this may still not be what you want. The patch generated by this method is more than 230,000 lines of code:

```
$ wc -l configure-views-exposed-sort-identifiers.patch
230134 configure-views-exposed-sort-identifiers.patch

```

It's possible that the git commit you have identified was always based on the 9.3.x branch. It seems that there is more work to be done in order to recreate the essential work for this patch and apply it cleanly to the 9.x branch.

It's difficult to say for sure, because `eaa43b0c` is already 93,000 lines of code ahead of the 9.3.x branch:

```
$  git diff 9.3.x |wc -l
93794

```

It's easy to take for granted how much work people put in to this open source software that we all rely on. If you require the functionality supplied by this patch, the easiest way to get it will be to upgrade your Drupal project to the 9.3.x branch a bit sooner than you'd have preferred to do so. Then the patch will apply cleanly, and you won't need to understand those 93,000 lines of code.

One last note -- the diff generated by Merge Request 54 is less than 1000 lines of code:

```
$ wc -l 54.diff
936 54.diff

```

You might be able to check out the 9.x branch and apply each of those 936 changes by hand in order to generate the patchfile in your local. It would still be a lot of work, but maybe less work than some of the other options.

This is not a common situation; most Composer Patches are smaller than this monster by orders of magnitude.

Good luck!

---
Tags: composer, 9, version-control, community-official-site
---


# Question
Title: How to use #states with a container element?
I come from read this Using the Drupal 7 Form API states system to create conditions between form elements and I'm able to use the #states with an input element like the title (textfield element), the problem is that if I try to use a container element the #states doesn't works.

This code works:

```
$form['field_courriels_des_autres']['#states']['disabled']['input[name="title"]']['filled'] = TRUE;

```

This code doesn' works:

```
$form['field_preciser']['#states']['enabled']['select[name="field_salle"]']['value'] = 'other';

```

I think that the problem is that the `field_salle` is a container.

# Answer
> 1 votes
As it's been mentioned, the `#states` property doesn't work for fieldsets, containers. You need some JS here, e.g:

**The form**

```
$form['promo_code_trigger'] = [
  '#type' => 'container',
  '#attributes' => ['id' => ['promo-code-add-el']],
  'data' => [
    '#markup' => t('Add promotional code'),
  ]
];

$form['promo_code_wrapper'] = [
  '#type' => 'container',
  '#attributes' => [
    'id' => ['promo-code-add-el-triggered'],
    'class' => ['hidden'],
  ],
];

```

**JS**

```
$("#promo-code-add-el").on("click", function (e) {
  $('#' + e.target.id + "-triggered").toggleClass('hidden');
  $('#' + e.target.id).toggleClass('active');
});

```

# Answer
> 3 votes
States indeed doesn't work with containers yet, because containers don't have necessary wrapper classes (`.js-form-item` or `.js-form-wrapper`). However you can do a workaround to get `#states` API to work with containers. Here is working code example from Drupal 9:

```
$form['container'] = [
  '#prefix' => '<div class="js-form-wrapper">',
  '#suffix' => '</div>',
  '#type' => 'container',
  '#states' => [
    'visible' => [
      ':input[name="field_name"]' => ['value' => 'your_conditional_value_here'],
    ],
  ],
];

```

---
Tags: 7, javascript
---


# Question
Title: How do I make JavaScript behavior run on every page load?
I don't know how to run my Drupal.behaviours.mybehaviour on every page load.

Here's my code example that run only once, when I load the page is no longer run my code, how can I change that from once to run on every page load:

```
       Drupal.behaviors.searchFilter = {
            attach: function (context) {
               once('searchFilter', 'html', context).forEach( function () {
                   console.log("function run");
               });
            }
       }

```

# Answer
I found, you have to attach your library using the `hook_page_attachments` This hook will attach your library on every page, so it will run on page load.

Then you can execute your js script like the following:

```
 Drupal.behaviors.searchFilter = {
            attach: function (context) {
                console.log("function run");
            }
       }

```
> 0 votes

---
Tags: 8, javascript
---


# Question
Title: How can I implement sign in with Google / Apple for a decoupled site?
I have a decoupled Drupal site that uses JSON:API to serve an Ionic React app.

I'm currently using the JWT (JSON Web Token Authentication module to enable users to register and log in (alongside the Get JWT on Login module) to the app/Drupal site.

I have used the Email Registration module so that users only need to provide an email address and password to log in, so the sign-up form is very simple.

Now, I want to integrate "sign in with Google" and "sign in with Apple" functionality to make it easier for users on Android and iOS.

Requirements

# Answer
> 1 votes
At this time, it doesn't seem like a ready-made solution is available yet for Drupal 9.

**Solution: OpenID Connect**

One solution is to use the OpenID Connect module with the Simple OAuth module or the OAuth2 Server module. These modules do similar things but OAuth2 Server is less opinionated/more complex to set up.

OpenID Connect module provides support for Google out of the box; Apple support needs to be written, but work is ongoing here.

**Solution: Social Auth**

The Social Auth family of modules provides both Google and Apple submodules; however, the Social Auth Decoupled module does not have a Drupal 9 release, and it is looking for a new maintainer.

At a minimum, Social Auth Decoupled and Social Auth Google API would need to be updated for Drupal 9, and a `Social Auth Sign in with Apple` module would need to be written.

So, **Social Auth** is good if you don't need decoupled login, but if you do need decoupled, you will be writing a lot of code on your own.

---
Tags: authentication-authorization
---


# Question
Title: PHPUNIT is running successfully on local but giving error on acquia-pipleine
When I am running the .vendor/bin/phpunit it is not giving any error. o/p:

Testing . 1 / 1 (100%)

Time: 00:00.014, Memory: 14.00 MB

OK (1 test, 1 assertion)

When I am running the same on acquia-pipeline's build it is giving the below error.

Executing step test.

* ./vendor/bin/phpunit docroot/modules/custom

PHPUnit 9.5.9 by Sebastian Bergmann and contributors.

No tests executed!

Remaining direct deprecation notices (4)

1x: The "Drupal\Component\EventDispatcher\Event" class extends "Symfony\Component\EventDispatcher\Event" that is deprecated since Symfony 4.3, use "Symfony\Contracts\EventDispatcher\Event" instead.

```
1x in DeprecationErrorHandler::shutdown from Symfony\Bridge\PhpUnit

```

1x: The "PHPUnit\TextUI\DefaultResultPrinter" class is considered internal This class is not covered by the backward compatibility promise for PHPUnit. It may change without further notice. You should not use it from "Drupal\Tests\Listeners\HtmlOutputPrinter". 1x in DeprecationErrorHandler::shutdown from Symfony\Bridge\PhpUnit

1x: The "Drupal\Tests\Listeners\DrupalListener" class implements "PHPUnit\Framework\TestListener" that is deprecated Use the `TestHook` interfaces instead. 1x in DeprecationErrorHandler::shutdown from Symfony\Bridge\PhpUnit

1x: The "Drupal\Tests\Listeners\DrupalListener" class uses "PHPUnit\Framework\TestListenerDefaultImplementation" that is deprecated The `TestListener` interface is deprecated. 1x in DeprecationErrorHandler::shutdown from Symfony\Bridge\PhpUnit

Can you help me to figure out the problem?

# Answer
From the creator of PHPUnit:

> By default, PHPUnit's command-line test runner exits with shell exit code 0 when the use of a deprecated feature is reported. This shell exit code is used to indicate that no error occurred. This information is used by continuous integration environments, for instance, to decide whether or not the build was successful. If you want your build to fail because the tests use deprecated functionality from PHPUnit, configure failOnWarning="true" in phpunit.xml. This instructs PHPUnit to exit with shell exit code 1 when deprecated assertions are used.

So in your phpunit.xml file, change the `failOnWarning` flag to false:

```
<phpunit bootstrap="tests/bootstrap.php" colors="true"
         beStrictAboutTestsThatDoNotTestAnything="true"
         beStrictAboutOutputDuringTests="true"
         beStrictAboutChangesToGlobalState="true"
         failOnWarning="false"
         printerClass="\Drupal\Tests\Listeners\HtmlOutputPrinter"
         cacheResult="false">

```

You need to provide a custom phpunit.xml file that only tests your custom module or theme and set the appropriate flags. Then tell PHPUnit to use that file instead of the one shipped with Drupal core.

In mine, I have also added:

```
    <!-- To disable deprecation testing completely uncomment the next line. -->
    <env name="SYMFONY_DEPRECATIONS_HELPER" value="weak"/>

```

I never have tests fail because of deprecation notices.

Configure PHPUnit
> 3 votes

---
Tags: 9, testing
---


# Question
Title: hook_mail_alter() doesn't remove the Return-Path, Sender, and Reply-To headers
I want to remove the *Return-Path*, *Sender*, and *Reply-To* headers from the sent emails. I am trying to achieve this using the following code, but the headers aren't removed from the email.

```
function mymodule_mail_alter(&$message) {
  unset($message['headers']['Return-Path']);
  unset($message['headers']['Sender']);
  unset($message['headers']['Reply-To']);
}

```

We are using default PHP mailer of Drupal 8 and the SMTP module . We are trying to fire the Test Mail via the SMTP module after entering credentials. But it seems we are not able to modify the headers from `hook_mail_alter()`.

What am I doing wrong?

# Answer
> 1 votes
The SMTP module always sets certain headers which cannot be unset. See the following lines from `Drupal\smtp\Plugin\Mail\SMTPMailSystem`:

```
$headers['Sender'] = $from;
$headers['Return-Path'] = $from;
$headers['Reply-To'] = $from;

```

This is to make it compatible with Drupal core which does the same from what I can tell.

For more control, you can use the module PHPMailer SMTP instead which explicitly unsets the `Return-Path` header to comply with RFC 5321.

It also makes no assumptions about which extra headers should be present (beyond the required ones) and only sets them if they are added elsewhere.

The following would work if the case of the headers match:

```
function mymodule_mail_alter(&$message) {
  unset($message['headers']['Sender']);
  unset($message['headers']['Reply-To']);
}

```

Alternatively, the following would unset headers regardless of case:

```
function mymodule_mail_alter(&$message) {
  $message['headers'] = array_change_key_case($message['headers']);
  unset($message['headers']['sender']);
  unset($message['headers']['reply-to']);
}

```

**Disclaimer:** I am the author of PHPMailer SMTP.

# Answer
> 2 votes
Removing the values from `$message['headers']` isn't sufficient, as the plugin used to send emails could also use `$message['Return-Path']`, `$message['Sender']`, or `$message['Reply-To']` value to build the email headers. The class that is used as default plugin to send emails, `PhpMail` uses the following code, but other plugins could use different code.

```
$site_mail = $this->configFactory->get('system.site')->get('mail');
$additional_headers = isset($message['Return-Path']) && ($site_mail === $message['Return-Path'] || static::_isShellSafe($message['Return-Path'])) ? '-f' . $message['Return-Path'] : '';
$mail_result = @mail($message['to'], $mail_subject, $mail_body, $mail_headers, $additional_headers);

```

Since the email plugin is used to send the email after the `hook_mail_alter()` implementations are invoked, and since the email plugin can add one of those headers to its discretion, there isn't any warranty the email is sent without those headers. Assuming the email plugin adds only those headers when `$message` or `$message['headers']` contains a value for them, the following code should work.

```
function mymodule_mail_alter(&$message) {
  unset($message['Return-Path']);
  unset($message['Sender']);
  unset($message['Reply-To']);
  unset($message['headers']['Return-Path']);
  unset($message['headers']['Sender']);
  unset($message['headers']['Reply-To']);
}

```

# Answer
> -1 votes
Use function hook\_mail($key, &$message, $params) instead. Also, you would need additional $key I believe to distinguish for which functionality is the mail being sent.

Then this hook would be triggered when sending the mail manually:

```
$send = true;
$mailManager = \Drupal::service('plugin.manager.mail');
$result = $mailManager->mail($module, $key, $to, $langcode, $params, null, $send);

```

I would suggest using Swiftmailer, it omits all of the manual work.

---
Tags: 8, hooks, emails
---


# Question
Title: How to make work Restfull /user/register?_format=hal_json
I am trying to access. All required modules are included, rights granted. so does not work. */user/register?\_format=hal\_json*

I get a message:

```
{"message":"Not acceptable format: hal_json"}

```

In RestUi settings, hal\_json format is enabled.

And in the log:

```
Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException: Not acceptable format: hal_json in Drupal\Core\EventSubscriber\RenderArrayNonHtmlSubscriber->onRespond() (line 30 of .../web/core/lib/Drupal/Core/EventSubscriber/RenderArrayNonHtmlSubscriber.php).

```

Drupal 9.0 and Drupal 8.8.4

# Answer
> 1 votes
please add at header:

```
 Content-Type : application/hal+json

```

# Answer
> 0 votes
Did you check, maybe JSON data from the frontend doesn't cover inside of `JSON.stringify(...)` and you try to send regular data which not serialized for sending?

I advice to make sure you stringify data before sending:

`const data = {"some":"value"} JSON.stringify(data)`

---
Tags: 8
---


# Question
Title: How to differentiate two different node creation/edit pages
I have 2 views, each one with a type of node (Products and Users). I want to add a unique class in each node create/edit pages, but i can't find any difference between the two, the only way i found is with the title of the page but that is not a good solution, because if the title changes it will stop working.

***I'm using the preprocess\_html hook***

I tried with the route of the two pages but it's the same.

```
$route = \Drupal::routeMatch()->getRouteName();
/* Output:
/* Products edit page -> $route = entity.node.edit_form
/* Users edit page -> $route = entity.node.edit_form
/*
/* In the node creation pages it's the same too
*/

```

Is there any way to find a difference in code from two node creation/edit pages?

This is the code i used to add classes to the same pages but now i need to add more specific classes like ***users\_creation\_page*** and ***products\_creation\_pages***

```
$route = \Drupal::routeMatch()->getRouteName();

  //Adding unique class to creation, edit and delete pages
  if (str_contains($route, 'add') || str_contains($route, 'create')) {
    $variables['attributes']['class'][] = 'action-nodes-page';
  }
  elseif (str_contains($route, 'edit')) {
    $variables['attributes']['class'][] = 'action-nodes-page';
  }
  elseif (str_contains($route, 'delete')) {
    $variables['attributes']['class'][] = 'node-delete-page';
  }

```

# Answer
> 2 votes
Are you asking how to preprocess node type specific?

```
use \Drupal\node\Entity\Node;

// #### implements hook_preprocess_html() ####

function yourmodule_preprocess_html(&$variables) {

switch ( $variables['node']->getType() ) {

// ## node-type: products ##
case 'products':

  ...

break;

// ## node-type: users ##
case 'users':

  ...

break;

default:

  ...

}

}

```

---
Tags: 8, nodes
---


# Question
Title: How to get the number of pages in a view template?
I'm trying to get the number of total "pager" pages with a view by using the **views-mini-pager.html.twig**. Here is my code so far...

```
{% if items.previous or items.next %}
<nav class="pagination" role="navigation">
            {% if items.previous %}
                {% if items.current %}
                    {% trans %}
                    <span class="page-number">Page {{ items.current }}</span>
                    {% endtrans %}
                {% endif %}
                    <a class="newer-posts" href="{{ items.previous.href }}"><span aria-hidden="true">←</span>{{ items.previous.text|default('‹‹'|t) }}</a>
            {% endif %}
            {% if items.next %}
                {% if items.current %}
                    {% if items.previous %}
                    {% else %}
                        {% trans %}
                        <span class="page-number">Page {{ items.current }}</span>
                        {% endtrans %}
                    {% endif %}
                {% endif %}
                <a class="older-posts" href="{{ items.next.href }}">{{ items.next.text|default('››'|t) }}<span aria-hidden="true">→</span></a>
            {% endif %}
    </nav>
{% endif %}

```

I want to have something like this

And currently, I can only get the current number page which ends up like this ...

I have searched for the variables inside of **views-mini-pager.html.twig** and I have not found the number of pages.

My question is...

* How can I get the number of pages total? So I can display it at **views-mini-pager.html.twig**
    + For instance, if I view is divided into three pages I want to display "Page 1 of 3"

# Answer
> 4 votes
Mini Pager doesn't give you that information. It's designed to not execute a count query. It just knows that there's at least one additional result (because it actually queries 21 if you show 21).

# Answer
> 4 votes
This is also an option:

```
/**
 * Implements hook_preprocess_HOOK().
 */
function MYTHEME_preprocess_pager(array &$vars) {
    $element = $vars['pager']['#element'];
    $pager_manager = \Drupal::service('pager.manager');
    $pager = $pager_manager->getPager($element);
    $vars['pager_max'] = $pager->getTotalPages();
}

```

Found this option here: https://api.drupal.org/api/drupal/core%21includes%21theme.inc/function/template\_preprocess\_pager/9.0.x

# Answer
> 3 votes
Berdir is right: the full pager needs to be used. Three steps are involved to get the output you wanted:

1. Switch the Views pager type to the `full` pager
2. Implement a `hook_preprocess_pager()` function

```
/**
 * Implements hook_preprocess_HOOK().
 */
function MYTHEME_preprocess_pager(array &$variables) {
  // @see globals.api.php
  global $pager_total;
  $element = $variables['pager']['#element'];
  // Get the max page number for the current pager.
  $variables['pager_max'] = $pager_total[$element];
}

```
3. Override the default pager template

Put something like this in `pager.html.twig`:

```
{#
/**
 * @file
 * Theme override to display a pager.
 *
 * @see template_preprocess_pager()
 */
#}
{% if items %}
  <nav class="pager" role="navigation" aria-labelledby="pagination-heading">
    <h4 id="pagination-heading" class="visually-hidden">{{ 'Pagination'|t }}</h4>
    <ul class="pager__items js-pager__items">
      {# Print previous item if we are not on the first page. #}
      {% if items.previous %}
        <li class="pager__item pager__item--previous">
          <a href="{{ items.previous.href }}" title="{{ 'Go to previous page'|t }}" rel="prev"{{ items.previous.attributes|without('href', 'title', 'rel') }}>
            <span class="visually-hidden">{{ 'Previous page'|t }}</span>
            <span aria-hidden="true">{{ items.previous.text|default('‹ Previous'|t) }}</span>
          </a>
        </li>
      {% endif %}
      {# Now generate the actual pager piece. #}
      {% for key, item in items.pages %}
        {% if current == key %}
          <li class="pager__item is-active">
            {% trans %}
              Page {{ current }} of {{ pager_max }}
            {% endtrans %}
          </li>
        {% endif %}
      {% endfor %}
      {# Print next item if we are not on the last page. #}
      {% if items.next %}
        <li class="pager__item pager__item--next">
          <a href="{{ items.next.href }}" title="{{ 'Go to next page'|t }}" rel="next"{{ items.next.attributes|without('href', 'title', 'rel') }}>
            <span class="visually-hidden">{{ 'Next page'|t }}</span>
            <span aria-hidden="true">{{ items.next.text|default('Next ›'|t) }}</span>
          </a>
        </li>
      {% endif %}
    </ul>
  </nav>
{% endif %}

```

The template is based on the template provided by Classy theme. It's inside the `{% trans %}` block where the magic happens.

# Answer
> 1 votes
Drupal 9 has a service that provides the pager data. Use the following in a preprocess to get the total number of pages:

```
$total_pages = \Drupal::service('pager.manager')->getPager()->getTotalPages();

```

# Answer
> -1 votes
In Drupal 9, you can put this line in pager.html.twig:

```
Page {{ current }} of {{ items.pages|length }}

```

Twig lets you output the length of the Twig array as a number of items in the array. This equals the total number of pages.

The `$pager_total` global variable mentioned earlier is no longer available in Drupal 9.

Make sure you change your view settings to use a full pager. You can further modify pager.html.twig so that it looks like a mini pager by removing stuff you don't need.

No preprocess functions needed.

---
Tags: theming, 8
---


# Question
Title: Dynamic nid for drupal_field twig tweak function
I have a field\_slides paragraph field on my home page, on drupal 9.1.3. It is for rendering a carousel. I want to iterate over the elements of the paragraph field (eg the slides with title, description and button fields). I'm using drupal\_field twig tweak function for the sake of translability. I have tried something like the following :

```
  {%  for slide in element['#items'] %}
     <div class="carousel-item {% if loop.index0 == 0 %}active{% endif %}">
     <img class="d-block w-100" src="{{ file_url(slide.entity.field_illustration[0].entity.fileuri) }}" alt="First slide">
     <div class="carousel-caption d-md-block w-50">
     <h5 class="carousel-title" onload="animateCarouselTitle(ev)">{{ drupal_field('field_titre', 'node', {{ slide.entity.nid }}) }}</h5>
     <p class="carousel-bouton">{{ drupal_field('field_bouton', 'node', {{ slide.entity.nid }}) }}</p>
     <p>{{ drupal_field('field_corps', 'node', {{ slide.entity.nid }}) }}</p>
     </div>
     </div>
   {% endfor %}

```

Any idea on how to dynamically get the nid of the paragraph entity in the `drupal_field` function?

# Answer
> 0 votes
Try taking away the curly brackets from around {{ slide.entity.nid }} so it's:

```
{{ drupal_field('field_corps', 'node', slide.entity.id) }}

```

---
Tags: theming, 9
---


# Question
Title: How to make the float field accept decimal values?
I am using Drupal 7 and have a float field. It is used to enter prices.

Most of prices I enter have decimals (e.g. 101.82, 99.88). Some of the prices are negative values (e.g. -55.52, -1009.88).

Sometimes when I enter a decimal value, Drupal will remove the decimal value. (E.g. 101.82 will become 101.00). Other times, it will keep the decimal value.

There doesn't seem to be any rhyme or reason as to why it keeps the decimal values for some fields and omits it for other fields.

How can I ensure that it always keeps the decimal value?

# Answer
> 1 votes
Your float values are working correctly. It is important to understand when to use a float and when to use a decimal type field. In your situation, **using a decimal field seems to be the best solution**. Check out these two wiki pages which break down how you would use these in Drupal.

Float

> Floating point is something that confuses a lot of people. Floating point numbers are essentially numbers stored in scientific notation, almost the same thing that we learned in math class in school...Floats and Doubles are used to store estimated values. The numbers they store can only be accurate to a certain precision.

Decimal (Numeric)

> It allows you to specify the precision and scale of a number...use DECIMAL data type to store exact numeric values, where we do not want any rounding off, but exact and accurate values.

**How to convert the field**

In order to accomplish this you will need to create a simple module and activate it in Drupal. Start off by following steps 1-4 of this Drupal wiki page. After that is done, follow these steps:

1. Copy the new \****.module file you created in steps 3-4 and change the extension to \****.install so you now have two files, both with just `<?php` at the beginning.
2. Inside of the \****.install file, you need to add an update function that Drupal can run.
3. Once you have that function, you would place the code from this answer inside.
4. You will want to adjust the variables in the script to match your configuration ie; `$field`, `precision`, `scale`, `not null`.
5. Backup your database, and be ready to revert back to the backup if things go wrong.
6. Activate the new module, which I suggest you do from the command line via `drush en your_module_name`.

If your website is not too large, you can get away with this, but if it is big, you will have to explore your options because eventually PHP will timeout.

# Answer
> 0 votes
Ryan Hartman's answer is the best to use. However, here is an alternative just in case that answer doesn’t work.

1. Make a back up of your database.
2. Export your database from phpmyadmin. Before exporting, you might want to sort tables by size and then empty all the cache tables if they are too big. You can also empty search\_index.
3. Open the software in an application that can read large database files such as BBedit. Sublime doesn’t seem to cope with the size.
4. Search for “`number_float`” (ensure grep is off)
5. You will find results like this: `(23, 'field_name’, 'number_float', 'number', 1, 'field_sql_storage', 'field_sql_storage', ….)`
6. Replace the `'number_float'` bit with `'number_decimal'`,
7. Repeat steps 3-5 for all instances of “`number_float`”.
8. Now search for “`float`
9. You will find multi line entries that begin with: `CREATE TABLE field_data_field_name(` In the multiple lines, they will have a line like this: `field_name float DEFAULT NULL`
10. Replace the word float with `‘decimal(10,2)’`.
11. Repeat steps 8 to 10 for all instances of “`float`”. However, when searching you will come across entries that don’t make references to fields, such as `search_index` and `search total`. Do not changes these.
12. Save the file and import into Phpmyadmin. Check in Drupal to see if all is okay.

Tip: Before exporting in step 2, go to Drupal and create a dummy field that uses decimal. (Give it a name that it is easy to search for such as `aaaaa`). Fill it with some dummy entries within Drupal. Then when you export your database, you can study how Drupal handles decimal fields, so you will know how best to change your float fields in the database.

---
Tags: 7, entities
---


# Question
Title: Programmatically remove content from a group
In order to add a node to any group in Drupal 8, I use the following code.

```
$group->addContent($node, 'group_node:article');

```

Now, for removing content from a group, I have tried `$group->removeContent($node, 'group_node:article');` and `$group->removeContent($node);` without success. All I obtained is the following error message.

> Error: Call to undefined method Drupal\group\Entity\Group::removeContent() in Drupal\my\_valetop\_extras\Plugin\WebformHandler\CustomWebformHandler-\>submitForm()

Finally, I have managed to remove content from a group using this code.

```
$type = 'group_node:' . $node->getType();
$current_node = $group->getContent($type, ['entity_id' => $node_id]);
$content = array_values($current_node)[0];
$content->delete();

```

But believe I can remove a single node from a group with a simple line of code.

How can I achieve it?

# Answer
> 1 votes
I believe that function was overlooked by the developers. In the issues queue for the Group module, which is what your error message refers to, I can see that the inverse of `addMember()`, `removeMember()`, was added later in the project's life. It seems reasonable to suppose that the inverse of `addContent()` was also overlooked, with the only difference being that it has remained unimplemented to this day.

There are no functions with names hinting at content-removing behaviour evident in the module's GroupInterface definition, so I recommend opening a new issue with the project to let them know about the gap.

# Answer
> 0 votes
This was my approach for programmatically adding and removing a node from a group on update. A `removeContent()` function would be helpful. However for my situation, I had to check if the entity was in the Group anyways, which gave me the GroupContent object that I could delete to remove the entity from the group.

```
/**
 * Implements hook_ENTITY_TYPE_update().
 */
function hook_node_update(EntityInterface $entity) {
    ...
    if (!empty($group = Group::load(1))) {
      $type = 'group_node:' . $entity->getType();
      $group_content = false;
      // Search for this entity in the group.
      $group_content_search = $group->getContent($type, ['entity_id' => $entity->id()]);
      if (!empty($group_content_search)) {
        $group_content = reset($group_content_search);
      }

      // Add entity to group.
      $group->addContent($entity, $type);

      ...

      // Remove entity from group.
      if (!empty($group_content)) {
        $group_content->delete();
      }
    }
    ...

```

---
Tags: 8, nodes, group
---


# Question
Title: Is there any way to revert the changes done by "drush cim"?
I usually take backup of the entire database before importing new configurations, but this time I didn't and now I need to double check something with old version of database. Is it possible to just revert the changes done by `drush cim`?

I am using Drupal 8.

Googling for this specific situation didn't give me any solution.

# Answer
No, you can't revert `drush cim` without a backup (or alternate config export) of some sort. If you don't have a backup, you're out of luck.

One safety measure to prevent this kind of problem is to write a script that backs up your database and then calls `drush cim`. Then, only run the script to do a config import, and you can ensure you have always made a backup first.
> 0 votes

---
Tags: drush, configuration, importing-exporting
---


# Question
Title: Problem removing field collection module
We recently migrated successfully in our drupal 8 instance from field collection module (latest alpha) to paragraphs. Now I am trying to remove the field collection module from our drupal instance, but it cant be removed as it is "used in the field field\_collection\_item.field\_sprechzeiten\_zeitraum" (see screenshot from uninstall view).

When I try to delete this field `field_sprechzeiten_zeitraum`, the following error message is displayed:

`Drupal\Core\Database\DatabaseExceptionWrapper: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'druco_stage.field_collection_item__field_sprechzeiten_zeitraum' doesn't exist: SELECT 'entity_id' FROM {field_collection_item__field_sprechzeiten_zeitraum} WHERE 'bundle' = 'field_sprechzeiten'; Array ( ) in field_collection_field_config_predelete() (line 95 of modules/contrib/field_collection/field_collection.module).`

It looks like somebody had tried to delete this earlier and something went wrong, as the database entry was deleted but not all the other references or the entry was not created in the first place.

As I am no drupal dev and just administrating this site, I am quite clueless, how to deal with it. I just want the field\_collection module to be gone, has anyone an idea how to solve this problem?

# Answer
I solved the problem by creating a new table as suggested by hotwebmatter. It was quite easy because i could use the structure of other field collection fields and just rename the value field. The structure looked like this:

```
field_collection_item__field_sprechzeiten_zeitraum: table
+ columns
    bundle: varchar(128)
    deleted: tinyint(4) NN
    entity_id: int(10) NN
    revision_id: int(10)
    langcode: varchar(32) NN
    delta: int(10) NN
    field_sprechzeiten_zeitraum_value: varchar(255)
+ indices
    bundle: index (bundle) type btree
    revision_id: index (revision_id) type btree
+ keys
    #1: PK (entity_id, deleted, langcode, delta)

```

After creating this I purged the field collection entities (there was a link in the uninstall section) and removed the remaining fields in my content types. The checkbox to uninstall the module was still disabled, so I deleted every table in the database containing field\_deleted\_data and field\_deleted\_revision. This didn't help, so I searched in the config table for the line with the name core.extension. Here I deserialized the data, removed the part with field collection, and serialized it again.

In between I always run the cron job and purged the caches. The checkbox to uninstall was still disabled, and by chance I saw that field collection checkbox in the module install section was not checked anymore. I checked it and tried to install it. It started and I was then forwarded to the module install section. the field collection was still unchecked and when I examined the uninstall tab it was finally gone.

This was gruelling, but with a happy end.
> 1 votes

# Answer
Do you have any old database backups? You could spin up a copy of the site in a local development environment and restore an old version of the database to see whether the missing tables can be recreated, allowing you to remove the `field_collection` module.

Generally, it is a bad idea to make such changes directly in the database (which is likely what someone did to create the problem in the first place) but you may be able to create an empty table with the same structure by analyzing the table in the old backup:

```
DESCRIBE field_collection_item__field_sprechzeiten_zeitraum;

```

Armed with this information, you may be able to create a matching table structure in the production database -- again, working in a local copy rather than on the production server.

If no suitable backups are available, you may be able to use the `field_collection` module to add the `field_collection_item__field_sprechzeiten_zeitraum` to the `field_sprechzeiten` bundle. (You won't be able to recreate the field contents this way, but you are just trying to delete it anyway.)

Once the missing table exists (even if it is empty) you may be able to remove the field without error and uninstall the module. Good luck.
> 1 votes

---
Tags: 8, entities
---


# Question
Title: Details wanted for "Mismatched entity and/or field definitions" message on custom field
I have developed a custom Drupal field.

All works fine. We are already using the field in production for a year. But the status report for exactly this field says:

> Mismatched entity and/or field definitions

I would like to get rid of that message. It gives me a bad feeling about the reliability of my Drupal installation.

I could write an update hook if I knew in detail what is wrong.

How can I find out what exactly does not match?

# Answer
OK, if this happened in production you probably had a code change in FieldItemInterface::schema().

The most detailed information you get is from

```
\Drupal::entityDefinitionUpdateManager()->getChangeList()

```

returning a list of entity fields affected and the status 1,2 or 3. If your field is listed with 2 (DEFINITION\_UPDATED) then check your code history for schema changes. If you don't have a code history you could check the current state of the database table(s). If you don't see the changes then install the module on a fresh site and compare the created tables.
> 3 votes

---
Tags: entities, debugging
---