# Question
Title: How can I hide search results until the user submits the exposed form?
I have a fairly straightforward view, which exposes a simple keyword filter to the user.

Currently, when I first land on the page containing this view, all records are displayed (*i.e.*, the search results are unfiltered).

How can I alter this behavior, so that no search results are displayed until the user has entered a keyword and submitted the form?

(I'm converting an old Drupal 7 site to Drupal 8. On the D7 site, the view does *not* show search results when I first land on the page. Is this a difference in behavior between the Views implementation in D7 and D8? I can't find anything in the D7 site to suggest that this difference in behavior is caused by a module.)

# Answer
You can change that under `Advanced` Views options (third column): `Exposed form style:`

After you choose `Input required`, you can adjust further options, including the text to display before any filters are active:

---

If you're using Better Exposed Filters module it has an option for it too:

> **Input required**
> Only display results after the user has selected a filter option.

---

It hasn't changed since D7, it works the same in D8 as it did in D7.
> 2 votes

---
Tags: views, 8
---


# Question
Title: Can not override template for specific view
I'm new to Drupal so this might be a noobish question. I have a view called 'Category' where all posts are listed that belongs to the chosen category.

I would like to override the **views-view-unformatted.html.twig** as well as the **views-view-field.html.twig** which is working fine for other views.

When I enable the twig debug mode I see this at the top of the page:

```
<!-- FILE NAME SUGGESTIONS:
   * html--taxonomy--term--31.html.twig
   * html--taxonomy--term--%.html.twig
   * html--taxonomy--term.html.twig
   * html--taxonomy.html.twig
   x html.html.twig
-->

```

So I thought templates with the name

```
views-view-unformatted--categories.html.twig
views-view-fields--categories.html.twig

```

would do the job. Or being even more specific:

```
views-view-unformatted--categories--block-1.html.twig
views-view-fields--categories--block-1.html.twig

```

But these templates aren't used. I have also tried to use 'taxonomy--term' for the template names with no success. There is also no file name suggestion for these templates.

Can anyone please tell me how I can get it working or hint me to the right direction?

# Answer
You either haven't rebuilt cache, or the page you're viewing isn't being generated by your `Categories` Views. It seems to be generated by the default `Taxonomy term` Views. Or you're viewing the wrong page :)

Views templates debug info is shown further down the source HTML, you won't find it at the top of the source page. Try looking below the main page heading in the source HTML, that's there the page views will start with their own templates.

This issue is also relevant:
Views file name suggestions often missing from Twig debugging

Especially the fifth comment there:
#5

Also:
\[PP-3\] Twig debug output does not display all suggestions when an array of theme hooks is passed to #theme

I haven't tried this module but it may be relevant:
Views Templates
> 0 votes

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


# Question
Title: Select order type and store with hook_form_alter()
In drupal commerce, I have 3 stores and 3 orders type When placing a manual order, i am first asked to choose the store and the order type ( which are entities), with **radio buttons**. With a select list, I know how to programmatically select one option, with the following code.

```
function reservation_form_commerce_order_add_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  $form['type']['widget']['#default_value'][0] = 'type_order_1';
  $form['store_id']['widget']['#default_value'][0]['#value'] = 1;
}

```

How do I do the same with the button?

# Answer
> 0 votes
You're overthinking it. As with most elements, you just need to set #default\_value on the main element definition itself. Here's working example code I tested in my own development environment:

```
/**
 * Implements hook_form_FORM_ID_alter().
 *
 * Sets default values on the order add form for the order type and store.
 */
function example_form_commerce_order_add_form_alter(&$form, $form_state) {
  $form['type']['#default_value'] = 'default';
  $form['store_id']['#default_value'] = 2;
}

```

Obviously you'll need to replace the values I've set with your own. : )

---
Tags: commerce
---


# Question
Title: How to get taxonomy tree with path auto token?
I'm using Path auto module to automatically set url of articles. Last part of url is node title and `[node:title]` works just fine. But url part before node title should follow taxonomy structure (tree) of tag used for tagging that article (taxonomy name: "structural\_category".

So i.e. if article is tagged with tag "Child" and that tag has parent tag called "Parent" then url of my article should be:

```
/parent/child/node-title

```

I can get only Child tag with tokens like this: `[node:field_structural_category:0]`, but I don't see the way to get Child's tag parent with token. With "Browse available tokens" I just can't drill any deeper than tag which is used directly for tagging the article.

For Drupal 7 I found that there is a solution with "join" keyword, something like:

```
[term:taxonomy_name:join:/]/[term:name]

```

What are the URL Alias pattern replacements for taxonomy parent terms when building up Node paths?

And I know that for Drupal 8 there should be something like:

```
[term:parent:url:path]/[term:name]

```

But when I try to save pattern like that I get an error "Path pattern is using the following invalid tokens:..."

When I use "Available tokens" helper tool I don't see this "term" at all?! All I see is:

There's no a word on "join", "parent" or any other similar token.

# Answer
Found it. Token should look like:

```
[node:field_structural_category:entity:parents]

```

It appeared (I think) after I changed reference field from multiple to accept only one value.

While it was accepting multiple values I could access first 3 elements, but not their parents. So this option is available only for single value fields. I see that lot of tokens are missing when tag reference field is set to accept multiple values. Bug or feature - can't say.
> 1 votes

---
Tags: 8, path-aliases, tokens
---


title: Overriding 'user.login.http' method

text:
# Question
Title: Overriding 'user.login.http' method
I am trying to override the core login method in `Drupal\user\Controller\UserAuthenticationController` by extending the UserAuthenticationController class so that I can inject custom data into the response object. I could achieve override by creating an Event subscriber service and using the alterRoutes method.

```
 public function login(Request $request) {
     $response_data = parent::login($request);

      return $response_data;

  }

```

However the response data is an object of type `Symfony\Component\HttpFoundation\Response` and there is absolutely no way to access the data. I would like to do the following but not able to modify the response object.

```
 public function login(Request $request) {
     $response_data = parent::login($request);
     $response_date = $this->fetchCustomdata($response_data);
     return $response_data;

  }

  private function fetchCustomdata($response_data) {
   // Do some work and return modified $response_dat
   return $reponse_data
 }

```

Is there any better way to inject custom data into the response parameters?

Note: The additional data I am trying to inject is additional fields i have added to the user profile like First Name, Email and other reference fields. It is required to deliver these along with the other default responses along with the default response on login.

Note: I tried copying the original method and modifying the data and it works but it goes against the good practice as we are trying to reduce duplication.

# Answer
> 0 votes
I figured out how to actually do this. We need to go to the class from which the object was instantiated and figured out any public getter and setter methods. This should be obvious for someone well versed with OOPs. Here is I managed to modify the response.

```
public function login(Request $request) {
  $response_data = parent::login($request);

  // We need to get data in the original response and there is actually a
  // a public method provided by the parent class getContent which we are using
  // below.
  $mydata = $response_data->getContent();

  // Original data is serialized so we need to decode it.
  $decoded_data = $this->serializer->decode($mydata, 'json');
  $uid = $decoded_data['current_user']['uid'];
  $user = $this->userStorage->load($uid);

  // custom function to process the user
  $mynewdata = $this->customfunction($user);

  // Adding to the original decoded response array and
  // then encoding again.
  $decoded_data += $mynewdata;
  $combined data = $this->serializer->encode($decoded_data, 'json');

  // Setting the content to the origina response object. Important!!!
  $response_data->setContent($encoded_sponsor_data);
  return $response_data;
}

```

---
Tags: 8
---


# Question
Title: Trigger a behavior from another module in Javascript?
The block\_ajax module defines a behavior in its module:

https://git.drupalcode.org/project/block\_ajax/-/blob/8.x-1.x/js/refresh\_ajax\_block\_command.js

I want to initiate this call every 60 seconds so the contents of the block can refresh if there is new data from my own script file.

I tried two ways.

The first way I tried was setting up a route for a simple controller that returned an AjaxResponse:

```
  public function execute() {
    $response = new AjaxResponse();
    $response->addCommand(new RefreshBlockAjaxCommand('.my_block'));
    return $response;
  }

```

Hitting the route with `Drupal.ajax` results in 'context.querySelectorAll is not a function', but it appears that the block *is* replaced (but missing the block wrapper around it, oddly enough, which probably won't work calling it over and over).

The second way is I tried to call it from the browser console with Javascript, but I can't figure out between this answer and the linked Javascript file at the top of the question what to call.

Trying to loop the element and attachBehaviors results in this:

# Answer
> 1 votes
Turned out to be a couple of things.

One, I was getting the querySelectorAll error because the Block being rendered was being rendered with a theme and custom template file, which was missing an outer div. The first tag it was seeing was a `<style>` tag, and breaking on that.

Second, the block\_ajax module seems buggy and not fit for refreshing on intervals.

I wound up removing the library that module attaches (from the original question), copying that, and attaching that to my block with two key changes:

Instead of `.replaceWith` I use `.html` to preserve the outer Block tags (or they get lost, and the next Ajax command will fail):

```
// Compose a new block content, replacing the old one
// with it.
var $newBlock = $(data.content);
$block.html($newBlock);

```

Then, I added this to the file, to initiate a check every 30 seconds with Ajax:

```
  // Check every 30 seconds if there is a notification.
  setInterval(refresh, 30000);

  function refresh() {
    Drupal.ajax({url: '/api/v1/auth/refresh'}).execute();
  }

```

Which uses the same service that the block does to read/check an external service for auth state and cookie updates.

Wanted to note that various forms of `Drupal.attachBehaviors(context, drupalSettings);` did not seem to do anything at all. Perhaps its something wrong in the block\_ajax module. It was not returning any errors, but also not refreshing the display.

# Answer
> 0 votes
> Hitting the route with Drupal.ajax results in 'context.querySelectorAll is not a function.

This happens when Drupal.attachBehaviors() is passed a jQuery object. It expects an HTML string. So if you are doing this:

```
var element = $(".some_element");
Drupal.attachBehaviors(element);

```

You change it to:

```
$(".some_element").each(function () {
  Drupal.attachBehaviors($(this).eq(0));
});

```

---
Tags: 8, javascript
---


# Question
Title: drush migrate:upgrade not behaving as expected
I'm working with the Migrate Tools modules for the first time. Specifically, I'm trying to use the Migrate Upgrade module to import users and roles from an old Drupal 7 site to a new, Drupal 8 rebuild of that site.

Per these instructions, I'm running this command to configure the migrations:

```
drush migrate:upgrade --legacy-db-url=mysql://olduser:password@localhost/oldschema --legacy-root=http://olddomain.test:8888 --configure-only

```

When I run `drush migrate:status upgrade_d7_user,upgrade_d7_user_role` immediately after that command, here's what I see:

```
----------------------------------------- ---------------------- -------- ------- ---------- ------------- ---------------
 Group                                     Migration ID           Status   Total   Imported   Unprocessed   Last Imported
----------------------------------------- ---------------------- -------- ------- ---------- ------------- ---------------
 Import from Drupal 7 (migrate_drupal_7)   upgrade_d7_user_role   Idle     4       4          0
 Import from Drupal 7 (migrate_drupal_7)   upgrade_d7_user        Idle     197     196        0
----------------------------------------- ---------------------- -------- ------- ---------- ------------- ---------------

```

This isn't what I expect to see. It looks like it has *already* imported all roles and all users (except for the admin user), and has none left to process. I expect to see *zero* imported at this point, since I used the `--configure-only` flag, and I haven't yet issued the Drush command to actually *run* the migrations.

Looking in the Drupal backend, I don't see that anything has actually been imported.

If I go ahead and run these commands:

```
drush migrate:import upgrade_d7_user_role
drush migrate:import upgrade_d7_user

```

...then I see:

```
[notice] Processed 0 items (0 created, 0 updated, 0 failed, 0 ignored) - done with 'upgrade_d7_user_role'
[notice] Processed 0 items (0 created, 0 updated, 0 failed, 0 ignored) - done with 'upgrade_d7_user'

```

It seems like the Migrate Tools *thinks* that the imports have already been completed – but they haven't.

Any ideas? Has anyone run into anything similar before?

I *have* been restoring the new (target) site's database from a snapshot periodically, because I'm learning the migration process as I go. So maybe that has hosed something up.

The very first time I ran `migrate:status`, I saw what I expected – some records queued, but none imported yet.

And the first time I ran `migrate:import`, it did import the records as expected.

So it seems like something about that previous import got "stuck" somewhere in the system. But I've taken increasingly drastic measures to burn my development site to the ground and rebuild from scratch – to no avail.

Is there perhaps something being cached by the Drush CLI itself?

Appreciate any suggestions. Thanks.

# Answer
> 2 votes
I figured it out!

I just needed to run `drush migrate:rollback`. That put Drupal back into a state where it understood that the migrations hadn't actually been run yet.

---
Tags: 8, migrations
---


# Question
Title: Is it possible to send a response from a service, but return something else?
I have a block that returns a render array. I would also like to set a cookie value as well in this process. Is it possible to set a cookie and also return a render array?

# Answer
> 0 votes
You can still use setcookie/setrawcookie in Drupal, if you are sending a response, you can use Symfony to set one:

```
$cookie = new Cookie('name', 'value', $expire, '/', 'domain', TRUE, TRUE, TRUE);
$response->headers->setCookie($cookie);

```

vs

```
setrawcookie('name', 'value', $expire, '/', 'domain', TRUE, TRUE);

```

Note that the internal Drupal function that writes a cookie adds a prefix that you probably don't want.

---
Tags: 8
---


# Question
Title: Can I still start a "stable" D8 project now that D9 is stable?
Trying to start a new Drupal 8 project today:

```
$ composer create-project --no-install drupal/recommended-project my-recommended-project

```

But this now installs Drupal 9.0.0 instead! :mindblown:

So I tried to manually require 8.9:

```
$ composer create-project --no-install drupal/recommended-project^8.9 my-recommended-project

```

But:

```
Could not find package drupal/recommended-project^8.9 with stability stable.

```

So it seems like I will need to install `^8.9@dev`

But then the whole project will be ... unstable?

What do you recommend?

# Answer
You are missing a `:`

This works: `composer create-project --no-install drupal/recommended-project:^8.9 my-recommended-project`
> 4 votes

---
Tags: 8, composer
---


# Question
Title: \Drupal::currentUser() returns information about the anonymous user, even though I am logged in
I'am trying to check whether a user is logged-in or not; with `\Drupal::currentUser()->id()` I am getting the user ID for the anonymous user (i.e. 0), even though I'm logged in.

How can I resolve this?

I'm just calling this function in the `.module` file, and it is not run from cron. I am using the following code.

```
use Drupal\Core\Session\UserSession;
use Drupal\Core\Session\AccountInterface;

$user = \Drupal::currentUser();
if ($user->isAuthenticated()) {
  echo 'logged-in';
}
else {
  echo 'guest';
}

```

# Answer
To determine if a user is logged-in (authenticated), it would be best to use:

`\Drupal::currentUser()->isAuthenticated()`
> 3 votes

# Answer
It seems you are running your code directly from your `.module` file and not inside a function. This way your code may not work because most services are likely to be not instantiated at the time the module files are included.

Try to run your code from a hook (e.g. hook\_entity\_view()) or use Devel module's *Execute PHP-Code* functionality (at */devel/php*).
> 3 votes

# Answer
Try this.

```
use Drupal\Core\Session\AccountInterface;

function mymodule_function() {
  $account = \Drupal::currentUser();
  if ($account->isAuthenticated()) {
    // User is logged in.
  }
}

```

Refer the below Link for more details

https://www.drupal.org/node/2017231
> 1 votes

# Answer
I encountered this kind of behaviour when using hook\_download\_file. However in my situation I had varnish to pass request to Drupal backend and I were downloading file through Drupal. Varnish checked that it's actually file and stripped out cookies that contains session info.
> 1 votes

# Answer
Try

```
\Drupal\user\Entity\User::load(\Drupal::currentUser()->id())->uid->value

```
> 0 votes

# Answer
For the sake of more robust and descriptive code, you can make use of the handy User::isAnonymous() method, e.g.

```
if (\Drupal::currentUser()->isAnonymous()) {
  // Anonymous user...
}

```

or

```
$user = \Drupal::currentUser();

if ($user->id() == 0) {
    // is visitor
}
else {
    // is logged
}

```
> 0 votes

# Answer
It appears that the code in the original post is not in any function, it's just in the global spec of whichever file it's in, so the current user probably hasn't been loaded yet.
> 0 votes

# Answer
I ran into the same issue in some code today. The code was in a controller and the controller was mapped to a route for a URL which was being accessed by users from emails.

The problem was that the URLs in the emails had http and the site was running on https. The site was also accessible via http and was not automatically redirecting to https.

So when the user comes to the site from the email he would be on http and the session would be an anonymous session.

Hope this helps somebody!
> 0 votes

---
Tags: users, 8
---


title: Hide/show a custom block

text:
# Question
Title: Hide/show a custom block
I have created a custom block of id `downloadourapp` and I would like to show/hide it base on certain statements.

I have create my custom module along with `.module` file where the code should be, however, I failed to find the right function to be used for that matter.

is `hook_block_view_alter` is the right function and how to hide or show this `downloadourapp` specific block.

# Answer
Plugin ID doesn't equal Block ID, example.

isForbidden is not a static function, need to use forbidden.

```
if ($block->id() == 'downloadourapp') {

    // If the user's phone is Android.
    if(preg_match("/(android)/i", $_SERVER["HTTP_USER_AGENT"])) {

    return AccessResult::forbidden()->addCacheableDependency($block);

    }
}

```
> 1 votes

# Answer
No, `hook_block_view_alter()` is not the hook you are looking for.

Try using `hook_block_access()` to control access to the block instead.

If you created your custom block programmatically, you can even control visibility directly from inside the block class via `blockAccess()`.
> 0 votes

---
Tags: 8, blocks
---


# Question
Title: How do I display real names instead of usernames for referenced users?
Here are the steps which I followed:

1. Added the user referenced field in the content type so one author can add multiple users who contributed in that content.
2. Using views i am showing the content and showing the users who contributed in this node.

My issue is that the view is showing the usernames of all the users. I want to convert those usernames to the Display name.

# Answer
As with most problems this one too can be solved in more than one way.

Probably the easiest, common, and "most Drupal" way is through using **View modes**.

## View modes

View modes are different ways of displaying entity content, depending on the context. Don't confuse them with Views module that is used for building lists of entities, they are completely different things.

An example of a View mode: you want the user profile page to show all user user fields, but in a lot of other places on the site you need the username and their geo-location, so you keep the `Default` User View mode for profiles, and create a new View mode where you only enable the username and geofield. Then activate the new user view mode in all places where you need to show the user with their geo-info.

In your case you have a User Reference field in Content Views and you want to change how the user info from that field is presented:

1. Create a new User View mode under People `Manage display` (`/admin/config/people/accounts/display`) \> `Custom display settings`
2. Enable the newly created View mode. After you enable it and `Save` the page will reaload and a new Drupal tab will appear named after your new View mode.
3. Visit the page of the newly created View mode (click on that tab) and adjust which user fields you want to show under that View. In your case that might be firstName and lastName, disable all others by dragging them down to the Disabled list (and Save).
4. Edit your Content Views (this is now the list of content you mention in your question, not the View modes), edit the User reference field and change the `View mode` option to the one you created in step 1.

Now your User reference field will show only the user fields you have enabled in the View mode on People account configuration.

You can use this View mode in other places too where you want any User data to display only as the Display names.

---

## Through Views

Alternatively, you can achieve the same result with Contextual filters within a Views Block Display to show only users referenced by the article you're currently viewing, and only showing that Block on the pages of that specific Content Type.
> 0 votes

---
Tags: views, 8
---


# Question
Title: Exposed Form: Send only selected filters
I have a view with several exposed filtears. The filters are of different types: checkboxes, taxonomy autocomplete and some jquery slider (I use Better Exposed Filters module).

The view shows all nodes of type A. Node type A has 15 field, each of which has a respective exposed filter within the view. Not all fields are mandatory which is why some nodes don't have value for all fields.

**My problem is this** (just an example to demonstrate):

* Field A1 is called 'Location' (taxonomy) -- this is a mandatory field
* Field A2 is called 'Retail purchasing power' (jquery slider with
min/max values) -- this field is not mandatory

Now, a user selects in the exposed filter for 'Location' let's say 'Florida'. The view will show all nodes with Florida that also have a value for 'Retail purchasing power', but not the nodes without a value for this field.

I can see that this is the expected behaviour but in my view I have a lot of filters and there are many nodes that don't have values for some fields. Some users only search for the 'location' and don't care too much about the other filters.Tthey don't see all location because they are filterd out.

Does somebody know a way to only send the filter values that have actively been selected by the user? The min/max values form the jquery sliders should only be considered when they are used.

# Answer
> 0 votes
I can confirm that on page load the option **jQuery UI slider** of the Better Exposed Filters module does apply the minimum value set in options.

The minimum value is displayed in the slider, so it's a visible cue that it will be displayed.

If you delete the number in the slider and then apply other filters, the slider filter will not be applied!

But the minimum value will still be visible in the slider on page reload (if you're not using Ajax in Views).

I couldn't find any similar issues so I created a new one: jQuery UI slider Exposed filter always applied

Add your test results/observations there.

---
Tags: views
---


# Question
Title: How to edit the id of a form element of a content type?
I have a content type with a text field that I need Javascript to do some work on (when in the content type add/edit form). I prefer to have Javascript identify the form element by it's id so I would like to set the id of the form element to something meaningful.

I've attempted to set the id in with a hook\_form\_alter() but to no success. If I kint() out the template with the form I do see the id being set in the kint() info however the actual form element html is unchanged. My hook\_form\_alter():

```
function hook_form_alter(&$form, FormStateInterface $form_state) {
  $form['field_element_name']['#id'] = 'element_name_id';
}

```

Is what I'm attempting possible and if so does anyone know how to do this? Or is there some completely different way of achieving this?

Thanks!

# Answer
I figured it out by digging through the kint() statement. Turns out the id is buried deeper in the $form array. Here is what worked for me:

```
function hook_form_alter(&$form, FormStateInterface $form_state) {
  $form['field_element_name']['widget']['0']['value']['#id'] = 'element_name_id';
}

```
> 0 votes

---
Tags: 8, forms, hooks
---


title: The "Modules" page doesn't load

text:
# Question
Title: The "Modules" page doesn't load
I am running a setup on Ubuntu and WSL (Windows Subsystem for Linux) with Nginx and PHP7.4.

Drupal 8 and Drupal 9 fresh installations load every page with no problem, except the page on /admin/modules.

On the error.log file I found this error.

> 2020/06/04 17:28:17 \[error\] 3610#3610: 1 upstream timed out (110: Connection timed out) while reading upstream, client: 127.0.0.1, server: d9.local, request: "GET /admin/modules HTTP/1.1", upstream: "fastcgi://unix:/run/php/php7.4-fpm.sock:", host: "d9.local:8080", referrer: "http://d9.local:8080/"

The Nginx configuration is the following.

```
server {
    server_name d9.local;
    root /var/www/d9.local/web; ## <-- Your only path $
    access_log /var/www/d9.local/logs/access.log;
    error_log /var/www/d9.local/logs/error.log;

    listen 8080;
    listen [::]:8080;

    location = /favicon.ico {
        log_not_found off;
        access_log off;
    }

    location = /robots.txt {
        allow all;
        log_not_found off;
        access_log off;
    }

    # Very rarely should these ever be accessed outside of your lan
    location ~* \.(txt|log)$ {
        allow 192.168.0.0/16;
        deny all;
    }

    location ~ \..*/.*\.php$ {
        return 403;
    }

    location ~ ^/sites/.*/private/ {
        return 403;
    }

    # Block access to "hidden" files and directories whose names begin with a
    # period. This includes directories used by version control systems such
    # as Subversion or Git to store control files.
    location ~ (^|/)\. {
        return 403;
    }

    location / {
        # try_files $uri @rewrite; # For Drupal <= 6
        try_files $uri /index.php?$query_string; # For Drupal >= 7
    }

    location @rewrite {
        rewrite ^/(.*)$ /index.php?q=$1;
    }

    # In Drupal 8, we must also match new paths where the '.php' appears in the middle,
    # such as update.php/selection. The rule we use is strict, and only allows this pattern
    # with the update.php front controller.  This allows legacy path aliases in the form of
    # blog/index.php/legacy-path to continue to route to Drupal nodes. If you do not have
    # any paths like that, then you might prefer to use a laxer rule, such as:
    #   location ~ \.php(/|$) {
    # The laxer rule will continue to work if Drupal uses this new URL pattern with front
    # controllers other than update.php in a future release.
    location ~ '\.php$|^/update.php' {
        fastcgi_split_path_info ^(.+?\.php)(|/.*)$;
        #NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
        include fastcgi_params;
        include snippets/fastcgi-php.conf;
        fastcgi_param SCRIPT_FILENAME $request_filename;
        fastcgi_intercept_errors on;
        fastcgi_pass unix:/run/php/php7.4-fpm.sock;
                fastcgi_read_timeout 60;
                fastcgi_keep_conn on;
                fastcgi_buffering off;
    }

    # Fighting with Styles? This little gem is amazing.
    # location ~ ^/sites/.*/files/imagecache/ { # For Drupal <= 6
    location ~ ^/sites/.*/files/styles/ { # For Drpal >= 7
        try_files $uri @rewrite;
    }

    location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
        expires max;
        log_not_found off;
    }
}

```

`Drupal 7` fresh install loads the modules page fine.

Note that page loads if you switch from Nginx to Apache. Do I cross post this to Server Fault? I just don't see it how this can be Nginx fault for not loading one specific page and people at Server Fault might not just get it or work with Drupal, I don't know what other kind of information to provide.

While the page loads, running `service php-fpm7.4 restart` immediately loads the complete page. I had this issue previously on all pages, which was solved reading the answer for Pages load only when you restart php-fpm, more with .gif images and previews. I am still stuck on the *Modules* page.

# Answer
Problem was WSL1, in PowerShell with admin rights `wsl -v -l`

```
  NAME            STATE           VERSION
* Ubuntu-18.04    Running         1

```

Convert your WSL1 installation to WSL2 `wsl --set-version Ubuntu-18.04 2`

Takes about 10 minutes to finish and needs more than 10GB of free space on the drive for the process.

More at https://scotch.io/bar-talk/trying-the-new-wsl-2-its-fast-windows-subsystem-for-linux
> 1 votes

---
Tags: debugging, performance, 9
---


# Question
Title: Is it possible to join dynamic tables (subqueries) using db_select()?
I've got a complex query I'm trying to convert to `db_select()`.

```
SELECT c.cid, c.pid, c.thread, count.replies, SUBSTRING(c.thread, 1, (LENGTH(c.thread) - 1)) as torder
FROM comment c
JOIN(
    SELECT count(*) as replies, SUBSTRING_INDEX(LEFT(thread, LENGTH(thread) -1 ), '.', 1) as torder
    FROM comment
    WHERE nid = 1
    GROUP BY torder
) as count
ON SUBSTRING_INDEX(LEFT(c.thread, LENGTH(c.thread) -1 ), '.', 1) = count.torder
WHERE c.nid = 1 ORDER BY count.replies DESC, torder ASC;

```

I'm not sure how join through a select statement, if it is possible, or if there is another alternative.

I don't need to return anything from the join (count.replies is only there for show) so maybe there is another option other than join.

I'm trying to select order by the top-level comment with the highest number of replies and it's children.

The result prints this for my test data:

```
+-----+-----+-----------------+---------+----------------+
| cid | pid | thread          | replies | torder         |
+-----+-----+-----------------+---------+----------------+
| 262 |   0 | 03/             |      11 | 03             |
| 269 | 262 | 03.00/          |      11 | 03.00          |
| 272 | 269 | 03.00.00/       |      11 | 03.00.00       |
| 270 | 262 | 03.01/          |      11 | 03.01          |
| 273 | 270 | 03.01.00/       |      11 | 03.01.00       |
| 275 | 273 | 03.01.00.00/    |      11 | 03.01.00.00    |
| 276 | 275 | 03.01.00.00.00/ |      11 | 03.01.00.00.00 |
| 280 | 275 | 03.01.00.00.01/ |      11 | 03.01.00.00.01 |
| 277 | 270 | 03.01.01/       |      11 | 03.01.01       |
| 278 | 270 | 03.01.02/       |      11 | 03.01.02       |
| 271 | 262 | 03.02/          |      11 | 03.02          |
| 264 |   0 | 04/             |       3 | 04             |
| 281 | 264 | 04.00/          |       3 | 04.00          |
| 282 | 264 | 04.01/          |       3 | 04.01          |
| 260 |   0 | 01/             |       2 | 01             |
| 279 | 260 | 01.00/          |       2 | 01.00          |
| 261 |   0 | 02/             |       2 | 02             |
| 274 | 261 | 02.00/          |       2 | 02.00          |
| 283 |   0 | 05/             |       1 | 05             |
+-----+-----+-----------------+---------+----------------+

```

The 'replies' number includes the top level comment which is OK because I'm only using this for ordering and includes all of the comments in a thread for each comment which is by design because I want to group all of the comments first by how many comments are in their group.

The SELECT in the join returns the number of replies for each top level comment:

```
+---------+----------+
| replies | torder   |
+---------+----------+
|       2 | 01       |
|       2 | 02       |
|      11 | 03       |
|       3 | 04       |
|       1 | 05       |
+---------+----------+

```

I can't to this using db\_query because I'm trying to overwrite the query in `comment_get_thread()` using `hook_query_TAG_alter()`.

I've tried using `$query->join()` but don't see where it is possible to put in an argument.

**EDIT:**

Thanks so much for your answers. Here is the db\_select translation of the sql query above if anyone is having trouble with this in the future:

```
$subquery = db_select('comment', 'c')
  ->fields('c', array('thread'))
  ->condition('c.nid', '1134');
$subquery->addExpression('COUNT(*)', 'replies');
$subquery->addExpression('SUBSTRING_INDEX(LEFT(c.thread, LENGTH(c.thread) -1 ), \'.\', 1)', 'toporder');
$subquery->groupBy('toporder');
$query = db_select('comment', 'c')
  ->fields('c', array('cid', 'pid'))
  ->condition('c.nid', '1134');
$query->addExpression('SUBSTRING(c.thread, 1, (LENGTH(c.thread) - 1))', 'torder');
$query->addJoin('', $subquery, 'count', 'SUBSTRING_INDEX(LEFT(c.thread, LENGTH(c.thread) -1 ), \'.\', 1) = count.toporder ');
$query->orderBy('count.replies', 'DESC');
$query->orderBy('torder', 'ASC');
$results = $query->execute()->fetchAll();

```

# Answer
Both db\_select and addJoin documentation says clearly that the table

> May be a string or another SelectQuery object. If a query object is passed, it will be used as a subselect.

So,

```
$sub_select = db_select('comment');
// Convert.
$select = db_select('comment')->addJoin($sub_select...

```
> 11 votes

# Answer
I think you're looking for addJoin() ... I could be wrong ... here's a small example of adding a join to a db\_select() from some random code I have ...

```
$query2 = db_select('dew_response', 'dr')->extend('TableSort')->orderByHeader($header);
$query2->addJoin('LEFT', 'dew_response_item', 'dri', 'dr.drid = dri.response_id');
$query2
  ->fields('dri', array('driid', 'item_id', 'response_id', 'answer'))
  ->fields('dr', array('drid'))
  ->condition('dri.survey_id', $survey_id, '=')
  ->condition('dri.response_id', $response_id, '=');
$result = $query2->execute();

```
> 3 votes

# Answer
Apply select query on the subquery result set.

```
  $sub_query = db_select('quiz_node_results', 'qnr');
  $sub_query->join('quiz_node_results_answers', 'qnra' , 'qnra.result_id =
  qnr.result_id');
  $sub_query->condition('qnra.is_correct', 0, '=');
  $sub_query->fields('qnr', ['nid', 'score']);
  $sub_query->fields('qnra', ['question_nid', 'result_id', 'is_correct']);

  $main = db_select($sub_query, 't1');
  $main->join('node', 'n', 'n.nid = t1.question_nid');
  $main->fields('n', ['title']);
  $main->fields('t1', ['question_nid']);
  $main->addExpression('COUNT(t1.is_correct)', 'ctr');
  $main->groupBy('t1.question_nid');
  $main->orderBy('ctr', 'DESC');

```
> 0 votes

---
Tags: database
---


# Question
Title: Maintaining libraries on a live site without Composer
I notice this question has been asked several times on here - and each time the answers always seem to involve using Composer one way or another! :-)

I get that one can get around shared hosting constraints by using Composer in their local dev environment and then uploading the lot, but what about maintaining libraries without Composer at all. Is it even possible?

I recall in D7 it was possible to manually download and maintain libraries in a nominated folder location. Is this still possible in D8?

# Answer
> 0 votes
Well, turns out it is possible, at least in terms of getting modules like Webform and Entity Print working. Both of these require libraries and many guides on installing them are emphatic that you MUST use composer for them to work.

I managed to get both of them working without using Composer:

Regular libraries such as those used by the Webform module can simply be extracted to the /Libraries folder. Simply create the directories specified in the admin/reports/status report after you instal the Webform module and put each library there.

Here is a great guide on manually installing dompdf (to use with modules like Entity Print) in the /Vendors directory: https://www.drupal.org/project/entity\_print/issues/3081358#comment-13667896.

So far, at least, not so hard after all...

---
Tags: 8, composer
---


title: Updating without Composer

text:
# Question
Title: Updating without Composer
I've previously used Drush to update my Drupal-installations. They are installed without using Composer, and currently on version 8.7.3. However, when I try to use Drush (drush v8.1.15, using drush up) to install the currently newest version the update fails when untarring the new core. When googling I see conflicting answers about what to do - among suggestions are Drush9, updating using composer (which I tested - does not work since the page is not installed using Composer) and others. What would be the simplest, least likely way to destroy the page while being able to update (with regards to security updates)?

# Answer
> 6 votes
The latest releases of Drupal 8 are "supported but not recommended" on Drush 8. Drush 8 is still necessary if you are not using Composer to build your site. Composer is recommended for all Drupal 8 sites because sooner or later you are likely to need a module that requires Composer. If your site does not yet need such a module, though, then it is possible to continue to use Drush 8 and the pm-update command.

A few months back drupal.org changed all of the URLs used to download Drupal images; in order to continue to use Drush 8, you need the latest version, which has been updated to use the new URL scheme. Please update to Drush 8.3.0, and you should be fine.

# Answer
> 0 votes
I am sure many expert users will consider this heretical advice. It may or may not work for you depending on your hosting arrangements.

I'm with a shared hosting provider using a cpanel interface. Their cpanel has the Softaculous installer.

I have found that I can simply update drupal core using their scripts in 1 click.

No drush. No Composer. No fuss.

Of course it does not update contrib modules (which can still be updated using the admin/modules/update interface) or libraries (which would need to be updated manually) but I have found this route way less stressful and complex with the relatively simple sites I am working with.

Pro developers of course need more sophisticated tools and more time efficient ways of updating multiple sites, and the manual route does take longer if you are updating multiple libraries.

I hope those developers so enamored with Composer don't kill off that functionality once they hear of this! (Please don't :-))

---
Tags: 8, drush, composer
---


title: Get path alias of node on presave

text:
# Question
Title: Get path alias of node on presave
I was trying to get the path alias using for nodes using the following code.

```
\Drupal::service('path.alias_manager')->getAliasByPath('/node/' . $nid);

```

It works for nodes that are already created, but it breaks when a new node is being added. I get the following error.

> Uncaught PHP Exception Symfony\Component\Routing\Exception\InvalidParameterException: "Parameter "node" for route "entity.node.canonical" must match "\d+" ("" given) to generate a corresponding URL.

Is there an alternative way to get the path alias for nodes that have not been saved yet?

# Answer
> 1 votes
Aliases are alternative paths to the node. They require the canonical path, so that there is a path to be an alternative of. The canonical path requires the Node ID (Entity ID) as node paths are /node/\[NODE ID\]. The Node ID doesn't exist until the node has been saved, as it comes from the database upon save. So the path does not exist until the node has been saved, meaning there is nothing to alias.

So the answer is that no, it's impossible to create an alias before a node has been saved, as the canonical path does not and cannot exist until the node has been saved.

# Answer
> 0 votes
Well, there "is" a "way"... But it would be very convoluted, error-prone and limited to specific use-case. So only try it if you really cannot wait until you got past the save...

It amounts to, basically, calling/injecting the pathauto.generator service (on 8.7, it may have changed name since 8.8) and the token service then...

a) Requesting the appropriate pathauto configuration for your current entity with $pathautoGenerator-\>getPatternByEntity (unless I'm mistaken, you have an $entity in pre\_save, and this method does not care that you have an id or not, it just needs to query entitytype and bundle).

b) Recreating the string that corresponds to alias by reading that config then using the appropriate fields values to reconstruct (or if easier for you using $tokenService-\>replace with $string being the pattern, $data being \['node' =\> $yourNode\]).

If obviously won't work if you're actually using in your pattern any metadata that is yet to be filled on pre-save (which means on a brand new entity, at least nid, vid and uuid).

Honestly I feel that this would be a "glorified hack" (with "raw hack" being writing everything without even trying to rely on pattern configuration XD).

So I'd use it *only until* I found better way to go or managed to get rid of that "need to get alias before entity is saved" (like put a big @todo / @fixme "refactor or remove ASAP").

If this is a common need for you in your whole site, you may question whether best for later maintenance/evolution is... \- keeping using Pathauto or... \- "building up custom alias generator/manager".

Hope that helps. :)

---
Tags: 8, nodes, path-aliases
---


# Question
Title: How do I install without having these errors?
So far, Drupal Commerce is the best module for e-commerce on Drupal. But now Drupal 9.0.0 was released, and when I want to install Drupal Commerce on Drupal 9, both way is out of luck.

Both way I mean, **installing Drupal Commerce** via **Drupal Console** or **Ludwigh Module**. Here is the official documentation on how to install Drupal Commerce: https://docs.drupalcommerce.org/commerce2/developer-guide/install-update/installation

**On Existing Site**

**1. First method, Drupal Console:** error when try to install it via composer with command:

```
$ composer require drupal/console:~1.0 --prefer-dist --optimize-autoloader

```

It will produce a long error message.

```
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

Problem 1
- drupal/console 1.9.4 requires drupal/console-core 1.9.4 -> satisfiable by drupal/console-core[1.9.4].
- Conclusion: don't install drupal/console-core 1.9.4
- drupal/console 1.9.3 requires drupal/console-core 1.9.3 -> satisfiable by drupal/console-core[1.9.3].
- Conclusion: don't install drupal/console-core 1.9.3
- drupal/console 1.9.2 requires drupal/console-core 1.9.2 -> satisfiable by drupal/console-core[1.9.2].
- Conclusion: don't install drupal/console-core 1.9.2
- drupal/console 1.9.1 requires drupal/console-core 1.9.1 -> satisfiable by drupal/console-core[1.9.1].
- Conclusion: don't install drupal/console-core 1.9.1
- drupal/console v1.9.0 requires drupal/console-core 1.9.0 -> satisfiable by drupal/console-core[v1.9.0].
- Conclusion: don't install drupal/console-core v1.9.0
- drupal/console 1.8.0 requires drupal/console-core 1.8.0 -> satisfiable by drupal/console-core[1.8.0].
- Conclusion: don't install drupal/console-core 1.8.0
- drupal/console 1.7.0 requires drupal/console-core 1.7.0 -> satisfiable by drupal/console-core[1.7.0].
- Conclusion: don't install drupal/console-core 1.7.0
- drupal/console 1.6.1 requires drupal/console-core 1.6.1 -> satisfiable by drupal/console-core[1.6.1].
- Conclusion: don't install drupal/console-core 1.6.1
- drupal/console 1.6.0 requires drupal/console-core 1.6.0 -> satisfiable by drupal/console-core[1.6.0].
- Conclusion: don't install drupal/console-core 1.6.0
- drupal/console 1.5.0 requires drupal/console-core 1.5.0 -> satisfiable by drupal/console-core[1.5.0].
- Conclusion: don't install drupal/console-core 1.5.0
- drupal/console 1.4.0 requires drupal/console-core 1.4.0 -> satisfiable by drupal/console-core[1.4.0].
- Conclusion: don't install drupal/console-core 1.4.0
- drupal/console 1.3.2 requires drupal/console-core 1.3.2 -> satisfiable by drupal/console-core[1.3.2].
- Conclusion: don't install drupal/console-core 1.3.2
- drupal/console 1.3.1 requires drupal/console-core 1.3.1 -> satisfiable by drupal/console-core[1.3.1].
- Conclusion: don't install drupal/console-core 1.3.1
- drupal/console 1.3.0 requires drupal/console-core 1.3.0 -> satisfiable by drupal/console-core[1.3.0].
- Conclusion: don't install drupal/console-core 1.3.0
- drupal/console 1.2.0 requires drupal/console-core 1.2.0 -> satisfiable by drupal/console-core[1.2.0].
- Conclusion: don't install drupal/console-core 1.2.0
- drupal/console 1.1.1 requires drupal/console-core 1.1.1 -> satisfiable by drupal/console-core[1.1.1].
- Conclusion: don't install drupal/console-core 1.1.1
- drupal/console 1.1.0 requires drupal/console-core 1.1.0 -> satisfiable by drupal/console-core[1.1.0].
- Conclusion: don't install drupal/console-core 1.1.0
- drupal/console 1.0.2 requires drupal/console-core 1.0.2 -> satisfiable by drupal/console-core[1.0.2].
- Conclusion: don't install drupal/console-core 1.0.2
- drupal/console 1.0.1 requires drupal/console-core 1.0.1 -> satisfiable by drupal/console-core[1.0.1].
- Conclusion: don't install drupal/console-core 1.0.1
- drupal/console 1.0.0 requires drupal/console-core 1.0.0 -> satisfiable by drupal/console-core[1.0.0].
- Conclusion: don't install drupal/console-core 1.0.0
- drupal/console 1.0.0-rc26 requires drupal/console-core 1.0.0-rc26 -> satisfiable by drupal/console-core[1.0.0-rc26].
- Conclusion: don't install drupal/console-core 1.0.0-rc26
- drupal/console 1.0.0-rc15 requires doctrine/collections 1.3.0 -> satisfiable by doctrine/collections[v1.3.0].
- drupal/console 1.0.0-rc16 requires doctrine/collections 1.3.0 -> satisfiable by doctrine/collections[v1.3.0].
- drupal/console 1.0.0-rc23 requires doctrine/collections 1.3.* -> satisfiable by doctrine/collections[v1.3.0].
- drupal/console 1.0.0-rc24 requires doctrine/collections 1.3.* -> satisfiable by doctrine/collections[v1.3.0].
- drupal/console 1.0.0-rc25 requires doctrine/collections 1.3.* -> satisfiable by doctrine/collections[v1.3.0].
- Conclusion: don't install doctrine/collections v1.3.0
- Conclusion: don't install drupal/console 1.0.0-rc22
- Conclusion: don't install drupal/console 1.0.0-rc21
- Conclusion: don't install drupal/console 1.0.0-rc20
- Conclusion: don't install drupal/console 1.0.0-rc19
- Conclusion: don't install drupal/console 1.0.0-rc18
- Conclusion: don't install drupal/console 1.0.0-rc17
- Conclusion: don't install drupal/console 1.0.0-rc14
- Conclusion: don't install drupal/console 1.0.0-rc13
- Conclusion: don't install drupal/console 1.0.0-rc12
- Conclusion: don't install drupal/console 1.0.0-rc11
- Conclusion: don't install drupal/console 1.0.0-rc10
- Conclusion: don't install drupal/console 1.0.0-rc9
- Conclusion: don't install drupal/console 1.0.0-rc8
- Conclusion: don't install drupal/console 1.0.0-rc7
- Conclusion: don't install drupal/console 1.0.0-rc6
- Conclusion: don't install drupal/console 1.0.0-rc5
- Conclusion: don't install drupal/console 1.0.0-rc4
- Conclusion: don't install drupal/console 1.0.0-rc3
- Conclusion: don't install drupal/console 1.0.0-rc2
- Conclusion: don't install drupal/console 1.0.0-rc1
- Conclusion: don't install drupal/console 1.0.0-beta5
- Conclusion: don't install drupal/console 1.0.0-beta4
- Conclusion: don't install drupal/console 1.0.0-beta3
- Conclusion: don't install drupal/console 1.0.0-beta2
- Conclusion: don't install drupal/console 1.0.0-beta1
- Conclusion: don't install drupal/console 1.0.0-alpha2
- Conclusion: remove symfony/console v4.4.9
- Installation request for doctrine/collections (locked at 1.6.5) -> satisfiable by doctrine/collections[1.6.5].
- Installation request for doctrine/annotations (locked at 1.10.3) -> satisfiable by doctrine/annotations[1.10.3].
- Installation request for drupal/console ~1.0 -> satisfiable by drupal/console[1.0.0, 1.0.0-alpha1, 1.0.0-alpha2, 1.0.0-beta1, 1.0.0-beta2, 1.0.0-beta3, 1.0.0-beta4, 1.0.0-beta5, 1.0.0-rc1, 1.0.0-rc10, 1.0.0-rc11, 1.0.0-rc12, 1.0.0-rc13, 1.0.0-rc14, 1.0.0-rc15, 1.0.0-rc16, 1.0.0-rc17, 1.0.0-rc18, 1.0.0-rc19, 1.0.0-rc2, 1.0.0-rc20, 1.0.0-rc21, 1.0.0-rc22, 1.0.0-rc23, 1.0.0-rc24, 1.0.0-rc25, 1.0.0-rc26, 1.0.0-rc3, 1.0.0-rc4, 1.0.0-rc5, 1.0.0-rc6, 1.0.0-rc7, 1.0.0-rc8, 1.0.0-rc9, 1.0.1, 1.0.2, 1.1.0, 1.1.1, 1.2.0, 1.3.0, 1.3.1, 1.3.2, 1.4.0, 1.5.0, 1.6.0, 1.6.1, 1.7.0, 1.8.0, 1.9.1, 1.9.2, 1.9.3, 1.9.4, v1.9.0].
- Conclusion: don't install symfony/console v4.4.9
- drupal/console 1.0.0-alpha1 requires symfony/event-dispatcher ~2.8 -> satisfiable by symfony/event-dispatcher[2.8.x-dev, v2.8.0, v2.8.0-BETA1, v2.8.1, v2.8.10, v2.8.11, v2.8.12, v2.8.13, v2.8.14, v2.8.15, v2.8.16, v2.8.17, v2.8.18, v2.8.19, v2.8.2, v2.8.20, v2.8.21, v2.8.22, v2.8.23, v2.8.24, v2.8.25, v2.8.26, v2.8.27, v2.8.28, v2.8.29, v2.8.3, v2.8.30, v2.8.31, v2.8.32, v2.8.33, v2.8.34, v2.8.35, v2.8.36, v2.8.37, v2.8.38, v2.8.39, v2.8.4, v2.8.40, v2.8.41, v2.8.42, v2.8.43, v2.8.44, v2.8.45, v2.8.46, v2.8.47, v2.8.48, v2.8.49, v2.8.5, v2.8.50, v2.8.52, v2.8.6, v2.8.7, v2.8.8, v2.8.9].
- symfony/event-dispatcher 2.8.x-dev conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.0 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.0-BETA1 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.1 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.10 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.11 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.12 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.13 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.14 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.15 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.16 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.17 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.18 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.19 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.2 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.20 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.21 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.22 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.23 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.24 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.25 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.26 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.27 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.28 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.29 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.3 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.30 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.31 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.32 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.33 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.34 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.35 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.36 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.37 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.38 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.39 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.4 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.40 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.41 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.42 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.43 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.44 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.45 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.46 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.47 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.48 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.49 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.5 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.50 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.52 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.6 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.7 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.8 conflicts with symfony/console[v4.4.9].
- symfony/event-dispatcher v2.8.9 conflicts with symfony/console[v4.4.9].
- Installation request for symfony/console (locked at v4.4.9) -> satisfiable by symfony/console[v4.4.9].

Installation failed, reverting ./composer.json to its original content.

```

After searching for solution, I know the error on installing Drupal Console is because it is not supporting Symfony 4 yet (Drupal 9 use Symfony version 4). Any help on this?

**2. Second method, Ludwig module**: This way simply doesn't work due to Ludwig module only supporting Drupal 8. https://www.drupal.org/project/ludwig

**On New Site** Alternatively, when installing using New Site also producing error when browsing:

```
[Fri Jun 05 23:24:21.842746 2020] [php7:notice] [pid 7092:tid 1560] [client 127.0.0.1:63807] TypeError: Argument 1 passed to Symfony\\Component\\HttpFoundation\\ParameterBag::replace() must be of the type array, null given, called in C:\\xampp\\htdocs\\mystore\\web\\core\\lib\\Drupal\\Core\\Routing\\RouteProvider.php on line 171 in C:\\xampp\\htdocs\\mystore\\vendor\\symfony\\http-foundation\\ParameterBag.php on line 59 #0 C:\\xampp\\htdocs\\mystore\\web\\core\\lib\\Drupal\\Core\\Routing\\RouteProvider.php(171): Symfony\\Component\\HttpFoundation\\ParameterBag->replace(NULL)\n#1 C:\\xampp\\htdocs\\mystore\\web\\core\\lib\\Drupal\\Core\\Routing\\Router.php(239): Drupal\\Core\\Routing\\RouteProvider->getRouteCollectionForRequest(Object(Symfony\\Component\\HttpFoundation\\Request))\n#2 C:\\xampp\\htdocs\\mystore\\web\\core\\lib\\Drupal\\Core\\Routing\\Router.php(123): Drupal\\Core\\Routing\\Router->getInitialRouteCollection(Object(Symfony\\Component\\HttpFoundation\\Request))\n#3 C:\\xampp\\htdocs\\mystore\\web\\core\\lib\\Drupal\\Core\\Routing\\AccessAwareRouter.php(92): Drupal\\Core\\Routing\\Router->matchRequest(Object(Symfony\\Component\\HttpFoundation\\Request))\n#4 C:\\xampp\\htdocs\\mystore\\vendor\\symfony\\http-kernel\\EventListener\\RouterListener.php(113): Drupal\\Core\\Routing\\AccessAwareRouter->matchRequest(Object(Symfony\\Component\\HttpFoundation\\Request))\n#5 [internal function]: Symfony\\Component\\HttpKernel\\EventListener\\RouterListener->onKernelRequest(Object(Symfony\\Component\\HttpKernel\\Event\\GetResponseEvent), 'kernel.request', Object(Drupal\\Component\\EventDispatcher\\ContainerAwareEventDispatcher))\n#6 C:\\xampp\\htdocs\\mystore\\web\\core\\lib\\Drupal\\Component\\EventDispatcher\\ContainerAwareEventDispatcher.php(111): call_user_func(Array, Object(Symfony\\Component\\HttpKernel\\Event\\GetResponseEvent), 'kernel.request', Object(Drupal\\Component\\EventDispatcher\\ContainerAwareEventDispatcher))\n#7 C:\\xampp\\htdocs\\mystore\\vendor\\symfony\\http-kernel\\HttpKernel.php(127): Drupal\\Component\\EventDispatcher\\ContainerAwareEventDispatcher->dispatch('kernel.request', Object(Symfony\\Component\\HttpKernel\\Event\\GetResponseEvent))\n#8 C:\\xampp\\htdocs\\mystore\\vendor\\symfony\\http-kernel\\HttpKernel.php(68): Symfony\\Component\\HttpKernel\\HttpKernel->handleRaw(Object(Symfony\\Component\\HttpFoundation\\Request), 1)\n#9 C:\\xampp\\htdocs\\mystore\\web\\core\\lib\\Drupal\\Core\\StackMiddleware\\Session.php(57): Symfony\\Component\\HttpKernel\\HttpKernel->handle(Object(Symfony\\Component\\HttpFoundation\\Request), 1, true)\n#10 C:\\xampp\\htdocs\\mystore\\web\\core\\lib\\Drupal\\Core\\StackMiddleware\\KernelPreHandle.php(47): Drupal\\Core\\StackMiddleware\\Session->handle(Object(Symfony\\Component\\HttpFoundation\\Request), 1, true)\n#11 C:\\xampp\\htdocs\\mystore\\web\\core\\modules\\page_cache\\src\\StackMiddleware\\PageCache.php(106): Drupal\\Core\\StackMiddleware\\KernelPreHandle->handle(Object(Symfony\\Component\\HttpFoundation\\Request), 1, true)\n#12 C:\\xampp\\htdocs\\mystore\\web\\core\\modules\\page_cache\\src\\StackMiddleware\\PageCache.php(85): Drupal\\page_cache\\StackMiddleware\\PageCache->pass(Object(Symfony\\Component\\HttpFoundation\\Request), 1, true)\n#13 C:\\xampp\\htdocs\\mystore\\web\\core\\lib\\Drupal\\Core\\StackMiddleware\\ReverseProxyMiddleware.php(47): Drupal\\page_cache\\StackMiddleware\\PageCache->handle(Object(Symfony\\Component\\HttpFoundation\\Request), 1, true)\n#14 C:\\xampp\\htdocs\\mystore\\web\\core\\lib\\Drupal\\Core\\StackMiddleware\\NegotiationMiddleware.php(52): Drupal\\Core\\StackMiddleware\\ReverseProxyMiddleware->handle(Object(Symfony\\Component\\HttpFoundation\\Request), 1, true)\n#15 C:\\xampp\\htdocs\\mystore\\vendor\\stack\\builder\\src\\Stack\\StackedHttpKernel.php(23): Drupal\\Core\\StackMiddleware\\NegotiationMiddleware->handle(Object(Symfony\\Component\\HttpFoundation\\Request), 1, true)\n#16 C:\\xampp\\htdocs\\mystore\\web\\core\\lib\\Drupal\\Core\\DrupalKernel.php(708): Stack\\StackedHttpKernel->handle(Object(Symfony\\Component\\HttpFoundation\\Request), 1, true)\n#17 C:\\xampp\\htdocs\\mystore\\web\\index.php(19): Drupal\\Core\\DrupalKernel->handle(Object(Symfony\\Component\\HttpFoundation\\Request))\n#18 {main}

```

**Has anyone had any way to successfully install Drupal Commerce on Drupal 9?**

# Answer
> 2 votes
This doesn't look like a question of Drupal Commerce compatibility at all ... all your error messages are from Drupal Console, which is not a requirement for Drupal Commerce. Just use Composer to fetch the module and then drush or the Drupal UI to install it.

---
Tags: commerce, console, 9
---


# Question
Title: Libraries shared by more than one installation?
I am working with several Drupal 8 installs On a shared hosting environment.
I've got them up and running and they are looking great thanks to the MoreThanThemes themes I'm using. I'm at the stage of adding modules that require libraries.

It would be great if I could simply maintain libraries in a folder like */Home/\[accountname\]/Libraries* outside of the Drupal root folder. In this way several installs could rely on a common set of libraries, and these wouldn't have to be maintained per site (as would be the case if they were stored in */Home/\[accountname\]/\[sitefolder\]/Libraries* for example).

An equivalent would be storing private files in a folder like */Home/\[accountname\]/Files*.

Would this be possible?

I know that many are very strong advocates for using Composer, but I am interested in answers that do not require using that tool.

# Answer
> 2 votes
Sometimes different module versions use different library versions. For example an upgrade for a module comes with supporting the next library version.

AFAICT if you're after simplifying your maintenance, and the sites you're hosting are similar in their features, it makes sense to also set the modules to also be shared.

That is, the entire Drupal installation. This is called a multisite installation and I've been satisfied with that type of a solution when having a cluster of smallish Drupal sites that use the same modules (and libraries) but different themes.

Multisite Drupal

This way you only maintain one Drupal folder on your host (or at least one Drupal for more than one site, you can still have more Drupal folders for more sites if you like, independent of the multisite one).

Each site has its own database.

Advantages are that when you need to update the modules or core you do it only once on that folder, but don't forget to perfom database updates on all the sites that use that Drupal folder, so they will all have to be in Maintenance mode at the same time.

The downside is that when you need to update, you **have to** do them all.

Each site usually has a special theme, so themes are placed under the specific sites' folder, not under themes/ where the shared themes are.

You can still have individual sites use a special module that you don't want on other sites in the "cluster", just put it under the site's folder and not in the general one.

Libraries will be shared across all sites, but if the modules used across the sites are also of the same version, you win because you've simplified your maintenance.

To clarify, you don't need to enable all the same modules for all sites within a multisite "cluster". The enabled modules don't even need to overlap! One site can use modules a, b, and c, and the other site can use modules d, e, and f. It's only about keeping the versions the same across the sites to simplify the maintenance.

---
Tags: 8
---


title: Custom redirect to an url with "+"

text:
# Question
Title: Custom redirect to an url with "+"
I use search api module and a view of products. If I put the search text block and I do a search, It redirect to an url like this: `<my domain>?search_api_fulltext=word1+word2+word3&sort_by=title_1&sort_order=ASC`

Where all search words are separated by a plus sign ("+"). I have my custom search block and I want to redirect to the same url in the submit function of the form. This is my code:

```
public function submitForm(array &$form, FormStateInterface $form_state) {

if (!empty($form_state->getValue('textBox'))) {
  $text = str_replace(' ', '+', $form_state->getValue('textBox'));
  $option = [
    'query' => ['search_api_fulltext' => $text,
                'sort_by'=>'search_api_relevance',
                'sort_order'=>'ASC'],
  ];
  $url = Url::fromUri('internal:/shop', $option);
  $form_state->setRedirectUrl($url);
}
return;

```

}

But it redirect to `<my domain>?search_api_fulltext=word1%2Bword2&sort_by=title_1&sort_order=ASC`, where plus signs are replaced with %2B, and then, the search is incorrect. How could I avoid this replacement?

# Answer
> 1 votes
The URL you're building is taking the query (e.g. `"word1 word2 word3"`) and replacing it with literal `"+"` chars for spaces. Hence, the `%2B` encoding in the string.

You don't need to parse/encode `$form_state->getValue('textBox')`. Per the documentation of `Url::fromUri()` for the `$options` param:

> * 'query': An array of query key/value-pairs (**without any URL-encoding**) to append to the URL.

`$options['query']` expects its key/value pairs to have the literal strings.

You needn't worry about `+`/`%20` encoding differences. They are different ways to encode the space character. (the `+` is an older space-encoding spec which you can do if absolutely needed, see `rawurlencode`, `urlencode`, & `http_build_query` in the PHP docs).

---
Tags: 8, forms, search
---


# Question
Title: Is it a good practice to declare drush as a dependency of a contrib module?
Is it a good practice to put `"drush/drush": "^9 || ^10"` in the `required` section of the composer.json of a contrib module if drush is actually its only interface?

I'm maintaining a contrib module, that can be operated only by using `drush`, but as far I saw in other similar modules (like: https://www.drupal.org/project/data\_fixtures ) - drush doesn't appear in the composer's dependencies. Is there any reason for that other than maybe "crowd psychology"?

I'm just considering putting drush as explicit composer dependency of my contrib module.

# Answer
> 4 votes
If the module doesn't do anything when Drush isn't installed, for example because it's only implementing Drush commands, adding Drush as dependency in composer.json is perfectly fine.

I don't see any reason for not adding it in the composer.json dependencies. Probably, the users who don't add it as dependency for their modules think that most users download the module from the project page on drupal.org and the dependencies on composer.json wouldn't stop them from installing the module.

I would rather add the dependency from Drush in the composer.json file, in the same way I would add a dependency from a module the Standard profile installs, in the .info.yml file of a module I develop.
Eventually, I would add a `hook_requirements()` implementation that doesn't allow users to install the module when Drush isn't present, for the users who install the module from the user interface or using the project archive downloaded from drupal.org.

---
Tags: 8
---


# Question
Title: Is it safe to delete the /module folder?
I see that the /module folder still exists and a /module/contrib folder has the updated module folders in it.

>

* `composer update` has updated the site to **8.9**
* `composer update` will not update any of the modules still shown in /modules (webform for example)
* When running `composer update`, Composer reports installing *Webform 8.5.16*, but it doesn't in fact install it and the site still reports *Webform 8.x-5.4-beta1*
    + Many other modules are also not updating
    + The modules in /module are the old versions, while the newer versions are in /module/contrib
    + Drupal think the modules are in the old path (for example, /module/webform)

What is the safest way to fix the problem? Delete folders in /module folder other than contrib and rerun composer update?

I have already executed the following commands.

1. `composer composerize`
2. `composer cc`
3. `composer self-update`
4. `sudo rm -Rf composer.lock vendor/`
5. `composer update`

# Answer
> 2 votes
Yes, you should be able to delete the versions of the modules directly under /modules, and clear cache; in theory that should be enough to get the system to re-register the same modules from their new locations.

Take a backup of the files and database first, and if you want to play it safe, delete one module folder at a time, running `drush cr` and checking that the version Drupal now sees is correct after each deletion.

It's probably wise to run `drush updb` after this, in case any of module versions have incremented and there are updates.

---
Tags: 8, composer
---


# Question
Title: How do I import configuration without getting these errors?
I am using `drush cim` and `drush cex` for importing and exporting the configuration between environments.

At this moment, local and develop are working OK, but I am getting an error on stage.

This is the error.

> The import failed due to the following reasons:
> This config does not have system.site, rejected
> UUID source site does not match current site.
>
> Config core.extension does not exists.

But actually both of them exists. I have already ran `drupal config.override` and set the UUID on system.site, but I am still getting those errors.

I have also tried `drush cr`.

The system site has the same UUID as local. It's the same file.

# Answer
> 0 votes
I have fixed the issue using config suite module: install this module and it will assign the uuid for those enviroments so you don't need to worry to set up manually.

---
Tags: 8, importing-exporting
---


title: How to make form field read only?

text:
# Question
Title: How to make form field read only?
I want prevent any user from being able to change the value of a field, yet I want to display its value.

How can I achieve this?

# Answer
This can be done via hook\_form\_alter

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

   if($form_id == 'user_register_form') {
      $form['field_name']['widget'][0]['value']['#attributes']['readonly'] = 'readonly';
   }

}

```

Add some css:

```
input:read-only {
  background-color: #ddd !important;
}

```

# Result:
> 9 votes

# Answer
And Just as a Reference, another solution is using the #disabled attribute:

```
function mymodule_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'user_register_form') {
    $form['field_name']['#disabled'] = TRUE;
  }
}

```
> 11 votes

---
Tags: 8, forms
---


# Question
Title: Where does the profile name on the Status Report come from?
When I click on *Reports \> Status report*, the *Install profile* field says *Snrub (snrub-"1.1)* (with exactly one double quote). Where is this value defined?

# Answer
> 2 votes
When the status report is rendered, profile info is retrieved from `drupal_get_profile()` (by referencing the `install_profile` var) as well as `system_get_info()` to retrieve all the metadata properties (by referencing the `system` data table)

# Answer
> 2 votes
The installation profile name given in the status report is output from `system_requirements()`, which uses the following code. (Note that code outputs the installation profile name and, between parentheses, the profile name returned from `drupal_get_profile()` and its version. It's not the installation profile name that contains the installation profile version.)

```
// Display the currently active installation profile, if the site
// is not running the default installation profile.
$profile = drupal_get_profile();
if ($profile != 'standard') {
  $info = system_get_info('module', $profile);
  $requirements['install_profile'] = array(
    'title' => $t('Install profile'),
    'value' => $t('%profile_name (%profile-%version)', array(
      '%profile_name' => $info['name'],
      '%profile' => $profile,
      '%version' => $info['version'],
    )),
    'severity' => REQUIREMENT_INFO,
    'weight' => -9,
  );
}

```

In other places, Drupal shows the distribution name, which is returned from `drupal_install_profile_distribution_name()`.

```
  // During installation, the profile information is stored in the global
  // installation state (it might not be saved anywhere yet).
  if (drupal_installation_attempted()) {
    global $install_state;
    return $install_state['profile_info']['distribution_name'];
  }
  else {
    $profile = drupal_get_profile();
    $info = system_get_info('module', $profile);
    return $info['distribution_name'];
  }
}

```

In both the case, that information is found in the .info file used from the installation profile / distribution. For example, the .info file for the Panopoly distribution contains the following lines.

```
name = Panopoly
distribution_name = Panopoly
description = A magical framework for building Drupal products based on the Panels module
core = 7.x
exclusive = 1

; Drupal Core
dependencies[] = block
dependencies[] = menu
dependencies[] = image
dependencies[] = list
dependencies[] = number
dependencies[] = options
dependencies[] = path
dependencies[] = taxonomy
dependencies[] = search
dependencies[] = shortcut
dependencies[] = field
dependencies[] = field_ui
dependencies[] = file
dependencies[] = dblog
dependencies[] = update

; Panopoly Foundation
dependencies[] = panopoly_core
dependencies[] = panopoly_images
dependencies[] = panopoly_theme
dependencies[] = panopoly_magic
dependencies[] = panopoly_widgets
dependencies[] = panopoly_admin
dependencies[] = panopoly_users

; Panopoly Toolset
dependencies[] = panopoly_pages
dependencies[] = panopoly_search
dependencies[] = panopoly_wysiwyg

; Panopoly Recommended - Admin & UI
dependencies[] = navbar
dependencies[] = breakpoints
dependencies[] = backports
dependencies[] = simplified_menu_admin
dependencies[] = save_draft
dependencies[] = module_filter
dependencies[] = date_popup_authored
dependencies[] = views_ui

; Panopoly Recommended - Other
dependencies[] = devel
dependencies[] = distro_update
dependencies[] = uuid
dependencies[] = apps

```

If you are searching which file you need to edit to remove the double-quote character shown in the installation profile version, that is the .info file of the installation profile / distribution you used to install Drupal. Check the values given for the `version` key. The installation profile / distribution is using a wrong value for the version. (Actually, a distribution hosted on Drupal.org should not add the `version` key in its .info file, since that is automatically added from the packaging scripts running on Drupal.org. On Drupal.org, there isn't any *Snrub* distribution; I take it's a custom distribution hosted somewhere else, or build specifically for the site you are maintaining/developing.)

---
Tags: 7, installation-profiles
---


# Question
Title: Do I have to validate() user entity saved programmatically?
I have a custom module saving user accounts from a customer API.

For this I use the \Drupal\user\Entity\User::create method, and I initialise the user account with the code above:

```
  /**
   * Save a Drupal user using `mail`.
   *
   * @param array $data
   *   The User data to save.
   *
   * @return bool|int
   *   Result: SAVED_NEW or FALSE.
   */
  public static function saveUser(array $data) {
    // Only if user exists on API
    if (empty($data['mail'])) {
      return FALSE;
    }
    // Create the user
    $email = $data['mail'];
    $user = \Drupal\user\Entity\User::create();
    $lang = \Drupal::languageManager()->getCurrentLanguage()->getId();

    // The Basics
    $user->setEmail($email);
    $user->setUsername($email);
    $user->set("init", $email);
    $user->set("langcode", $lang);
    $user->set("preferred_langcode", $lang);
    $user->set("preferred_admin_langcode", $lang);
    $user->enforceIsNew();
    $user->setPassword(user_password());
    $user->activate();

    // Save user.
    return $user->save();
  }

```

I like to look for a good way of doing things and to read about getting D9 ready for my modules. When it is necessary, I also inspect the core code to see the available methods and how core modules are made to inspire me.

I found this interesting topic about Entity Validation API, where it speaks about using validation on entities. I also found that user object has methods to know if a validation is necessary and to validate, and the preSave method will throw an exception if the validation is necessary and not done.

All the examples and code snippet I found on internet about creating a user programmatically never use any kind of validation, and I wonder if this is something new or if it is just not really necessary for my case.

As I said, I save data from a remote API, and I do not manage the quality of the email address I use as email and username. I also do not verify if those values already exist.

Should I add something like this ?

```
// Entity validation
if ($user->isValidationRequired()) {
  $violations = $user->validate();
  if (count($violations)) {
    \Drupal::messenger()->addError($violations[0]->getMessage());
    return FALSE;
  }
}

```

# Answer
> 3 votes
If you want to first verify the user you programmatically created passes validation, which means (for example) that its username and emails are unique, you can check if there are validation violations. You don't need to fist call `isValidationRequired()` as that method returns the value set with `setValidationRequired()`, which is called only from `ContentEntityForm::buildEntity()` and `ContentEntityForm::validateForm()`. (In other words, if the entity isn't created via its entity form, `isValidationRequired()` will return `FALSE`.)

```
$violations = $user->validate();
if (count($violations)) {
  // The user account didn't pass the validation.
}

```

Note also that you can pass to `User::create()` an array containing the values to assign to the user fields, instead of calling each setter as your code does.

You could also create the user account with `\Drupal::entityTypeManager()->getStorage('user')->create($values)`, where `$values` is the same array accepted by `User::create()`.

---
Tags: 8, users
---


# Question
Title: Why is my form_token missing when i'm not logged as admin?
I'm in charge of multiple Drupal 8 website and with some of them, the hidden field form\_token is non-existent when I'm using the website anonymously.

Everything works fine when I'm logged in.

I'm sure everything was working before the quarantine but I didn't check **before updating to 8.8.6**

I tried deleting the custom twig templates of the webform and I checked my theme.theme

**webform version is 8.x-5.13** for some and 8.x-5.16 for others.

# Answer
> 0 votes
The problem comes from the antibot module.

For some reason that I don't know, when I am not logged in, the module considers that I do not have javascrip enabled and overrides the form\_token field which is required to submit the form.

---
Tags: 8, webforms
---


# Question
Title: Ordering in a query gives "call to an undefined function"
I am using Drupal 8 and I am trying to order my query like so:

```
 $query = db_query("SELECT * FROM `heritage_source_info`WHERE text_id = :textid AND format = :format ORDER BY type ASC", [':textid' => $textid, ':format' => 'text'])->orderBy('FIELD(type,moolam,translation,commentary)');

$available_sources_text = $query->fetchAll();

```

But it says call to an undefined function orderBy(). Could you help me with the correct syntax?

# Answer
> 0 votes
The object returned from `db_query()` is an instance of a class implementing `StatementInterface`, which doesn't have any `orderBy()` method. Since you are using a SQL string, you can order the result adding an `ORDER BY` clause.

As side note, instead of `db_query()`, which is deprecated and it's going to be removed from Drupal 9, the code should use `\Drupal::database()->query()`.

The alternative is using `\Drupal::database()->select()`. In this case, the object returned, which implements `SelectInterface`, has a `orderBy()` method.

---
Tags: 8, database
---


# Question
Title: Add CSS class to fieldset div element without extending the template
I only want to add a class to the inside the `fieldset` from `fieldset.html.twig`. It's a bit overkill to extend the template for just to add a class.

How can I achieve this with a preprocess function?

```
function mytheme_preprocess_fieldset(&$variables) {
// $variables['children']['attributes']['class'][] = 'mb-4';
}

```

# Answer
> 1 votes
Under a fieldsets 'Advanced' settings tab, you can add custom attributes to the fieldset.

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


# Question
Title: How to get user data/authenticate with bearer token - Simple OAuth - Decoupled
I am working on a single page application using NUXT and Drupal 8 as headless CMS. for user authentication token I am using Simple OAuth Drupal 8 module. Everything is working fine. I am getting the access token when I send request to this API `https://website.com/oauth/token` as you can see below.

What I want now is to authenticate the user using this token. How will I get the user detail every time I refresh the page using this response? Is there any API where we send the access token with the bearer .

Excuse me Please if I am using the wrong terms I am new to Decoupled.

But as you know setting up JWT for authentication. we send two requests. 1 request to get the token and another request to get the user using that token as mention in this tutorial.

I don't know if I made my point clear. I am totally lost here.

Thanks

# Answer
> 0 votes
I'm not familiar with the Nuxtjs framework discussed in the tutorial you linked to, but basically once you have the access\_token the user should be authenticated in Drupal. It should be enough that you on each request set an `Authorization` header that contains that access token, as described in the tutorial:

```
this.$axios.setHeader('Authorization', 'Bearer ' + resp.data.access_token)

```

Drupal will then read the Authorization header value and authenticate/authorize the user based on the Drupal role that the user has assigned to itself. So provided you have the REST endpoints for user information active you should be able to make a GET request to `/user/{user}` and get the logged in user information.

You can try this out using curl or Postman by manually adding the header to the request:

```
Authorization: Bearer HereGoesTheValueOfTheAccessToken

```

A curl example:

```
curl --request GET \
  --url https://mydrupaldomain.com/user/123 \
  --header 'authorization: Bearer HereGoesTheValueOfTheAccessToken'

```

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


# Question
Title: Where and when in the User login workflow is the last Access time timestamp set?
I am trying to understand when exactly the last access time is set in the Drupal user login workflow. I did notice that the following method is probably what is used to set the timestamp

```
  public function setLastLoginTime($timestamp) {
    $this->get('login')->value = $timestamp;
    return $this;
  }

```

However, I could only find the declaration but not the method call in the codebase and it has proven difficult to track it. It seems quite surprising it is not called anywhere. I am thinking that there should be a direct write to the field 'access'.

P.S The reason I am trying to get the value is to determine what all nodes are created after the user had last accessed the site.

# Answer
Simply scan the codebase for `setLastLoginTime` and you'll see that there's actually only one single place where this function gets called. And that is `user_login_finalize`.

> ```
> /**
>  * Finalizes the login process and logs in a user.
>  *
>  * The function logs in the user, records a watchdog message about the new
>  * session, saves the login timestamp, calls hook_user_login(), and generates a
>  * new session.
>  *
>  * The current user is replaced with the passed in account.
>  *
>  * @param \Drupal\user\UserInterface $account
>  *   The account to log in.
>  *
>  * @see hook_user_login()
>  */
> function user_login_finalize(UserInterface $account) {
>
> ```

And when does `user_login_finalize` get called? Scan the codebase again. And you'll see that there are some few places only. For example in the submit handler of the user login form, in the submit handler of the user register form, or for example also in the `install_finished` handler when you after a successful interactive site installation (in the browser) get logged in as user 1.

---

Following the input from @4k4 there must be differentiated between the **last login time** and the **last access time**. Both are base fields of the user entity. The login time gets stored on every login finalize (see above) and the access time (the one you can see in the users View in the LAST ACCESS column at /admin/people) **gets renewed every 180 seconds**. This happens in an event subscriber which gets triggered on every request/response cycle – the `UserRequestSubscriber`.

The last access time then can be retrieved from `User::getLastAccessedTime`. I maintain a small module to calculate online, absent and offline states of a user with exactly that method: https://git.drupalcode.org/project/user\_online\_status/-/blob/8.x-1.0/src/StatusService.php#L83.
> 4 votes

---
Tags: 8, users
---


# Question
Title: I'm getting a page not found error when trying to visit my custom form
This is the form that I created using Drupal 8:

```
namespace \Drupal\lookup\Form\lookupForm;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;

class lookupform extends FormBase
{
    /**
     * {@inheritdoc}
     */
    public function getFormId()
    {
        return 'lookup_form';
    }

    /**
     * {@inheritdoc}
     */
    public function buildForm(array $form, FormStateInterface $form_state)
    {
        $form['Username'] = [
            '#type' => 'textfield',
            '#title' => t('ULM Username'),
        ];

        $form['actions']['submit'] = [
          '#type' => 'submit',
          '#value' => $this->t('Save'),
          '#button_type' => 'primary',
        ];

        return $form;
    }

    /**
     * {@inheritdoc}
     */
    public function submitForm(&$form, FormStateInterface $form_state)
    {

    }

}

```

**Routing file:**

```
user.form:
 path: '/lookupForm'
 defaults:
   _title: 'Lookup User Autocomplete'
   _form: '\Drupal\lookup\Form\lookupForm'
 requirements:
   _permission: 'access content'

```

**Info file:**

```
name: Form
description: This is a form.
core: 8.x
package: Custom
type: module

```

I am getting a page not found error. What could be the issue?

# Answer
Problem 1: Incorrect namespace. The class name should not be included in the namespace. Your namespace should be:

`Drupal\lookup\Form`

Problem 2: The name of your class is not the same name as the routing file (capitalization).

Class name: `lookupform`

Routing file: `_form: '\Drupal\lookup\Form\lookupForm'`

(Capital F)

Problem 3 (credit: laymannx) - you're visiting the wrong path. Should be visiting `/lookupform` (after fixing the above problems).
> 3 votes

---
Tags: 8, forms, routes
---


# Question
Title: Why cannot I choose MySQL as database type in the installation page?
I downloaded the Drupal archive and extracted it on the dedicated server. In cPanel, I created a MySQL database, but when I try to install Drupal, in the *Database configuration* page, I can only choose between PostgreSQL and SQLite as database type; I cannot choose MySQL.

>

Why did it happen? How do I fix it?

# Answer
1. Create a **info.php** file and upload it to your server :

```
 php_info()

```
2. upload the file to your server is docroot then visit the URL **http://youdomain.com/info.php**
3. search for **pdo\_mysql** and it should be enabled if it does not exist contact the server admin and tell him to enable the **pdo\_mysql** (https://serverfault.com/questions/471282/how-enable-pdo-mysql) :

> in your case I think you have just the **pgsql** and **SQLite** PDO enabled
> 2 votes

---
Tags: database, installation
---


# Question
Title: Create nodes from a JSON file uploaded in a form by an user
I've got this form:

```
 $form['import_json'] = [
      '#type' => 'file',
      '#description' => $this->t('Allowed extensions: json'),
      '#title' => $this->t('Import your JSON\'s file.'),
    ];

    $form['submit'] = [
      '#type' => 'submit',
      '#value' => $this->t('Import'),
    ];

```

I have to use `'#type' => 'file'` because AFAIK managed\_file doesn't allow json file and file is the only type left.

I need to be able to get the uploaded file when the user submit the form to be able to convert the JSON's data to create nodes of a certain type.

My function is already created and it looks like this:

```
protected function createActualite(string $json)
  {

    $jsonstring = json_decode($json, TRUE);

    foreach ($jsonstring as $field) {
      $node = Node::create([
        'type' => 'import_content', // Machine name de notre content type 'actualité'
        'title' => $field['titre'],
        'body' => $field['body'],
      ]);
      $node->save();
    }
  }

```

The problem is that I can't find a way to properly get the uploaded file, I tried the same way that we do with managed\_file

```
$file = File::load($field['import_json']);
        $file->setPermanent();
        $file->save();

```

but it doesn't work, also this (which is 10yo) doesn't do the trick either gist

If someone can lead me to arrive to save this file or to any doc, I would greatly appreciate.

# Answer
Ok I made it works, first I get the file's path using the solution given here

and then once I got the path, I'm reading the file using

```
$file = file_get_contents($file_path);

```

then calling my function createActualite($file); and it creates all the nodes up to the content of the JSON as expected.
> 0 votes

---
Tags: forms, files, 8
---


# Question
Title: How can I remove unwanted CSS found in the parent theme?
I'm working on a sub-theme of Bootstrap Barrio, which includes a `table.css` stylesheet. I don't want this stylesheet from the parent theme to be included in my sub-theme.

How do I **eliminate** a CSS file from sub-theme's parent?

# Answer
You can override it by adding a blank file with the same name in your theme (or you can add your own contents). Or, you can remove it altogether with libraries exclude: https://www.drupal.org/docs/theming-drupal/adding-stylesheets-css-and-javascript-js-to-a-drupal-theme#override-extend
> 5 votes

---
Tags: 8, theming
---


# Question
Title: Memory efficient way to load large entity set for data export
I'm working on an Excel exporting feature in a Drupal 8 site.

Obviously, I can load all entites of certain type like this:

```
$user = \Drupal::currentUser();

$entity_query = \Drupal::service('entity.query')->get('some_type');
$entity_query->sort('created', 'DESC');

$ids = $entity_query->execute();
$entites = $this->storage->loadMultiple($ids);

foreach ($entities as $entity) {
    // build some Excel row with the entity information
    // ...
}

```

But if you're doing this on a large entity set, you'll be running out of memory very soon. I think the reason why Drupal would run out of memory is the extensive caching involves in the entity query and loading process.

Is there a more memory-efficient way to load an indefinite size of entity set without running out of memory?

(Note: Let's pretend the Excel library is very clever and do not take up memory. That's another issue for another day.)

# Answer
> 2 votes
> Batches allow heavy processing to be spread out over several page requests, ensuring that the processing does not get interrupted because of a PHP timeout, while allowing the user to receive feedback on the progress of the ongoing operations. It also can reduce out of memory situations.
>
> <sub>Source: Example: Batch API </sub>

You need to use the Batch API. There is no official docs for D8, but you can look at the batch\_example module and the CSV Import module.

Good conceptual read, Drupal 8 Batch Processing but a bad code example.

# Answer
> 2 votes
To reduce the memory footprint you can load single entities and then use resetCache():

```
$ids = $entity_query->execute();

foreach ($ids as $id) {
  $entity = $this->storage->load($id);
  // build some Excel row with the entity information
  // ...
  // release entity from memory
  $storage->resetCache([$id]);
}

```

---
Tags: 8, entities, importing-exporting
---


# Question
Title: Altering (adding) field value when is unknown
I have three content types (A,B,C). A and B have *title*, *author*, and *field\_version* (a custom field), while C doesn't have *field\_version*. Let's assume I have a method that gets the version value from a node. (The `$node` parameter is an entity object.)

```
function getLatestVersion($node) {
   $version = $node->get('field_version'); //for A, B is OK, but for C - field_version is unknown
}

```

How can I check the field exists for the node passed as argument without comparing the node type with an hard-coded list?

# Answer
> 2 votes
For nodes, like for every content entity, you can use code similar to the following one to check if a Field API field(*) exists.

```
if ($node->hasField('field_version')) {
  // The node has that field; access it with $node->hasField('field_version').
}

```

A more generic code that would work for either Field API fields or non-field properties would be similar to the following one.

```
if (isset($node->field_version)) {
  // The node has that field/property; access it with $node->field_version.
}

```

* I am using the terminology used in a comment for code in `ContentEntityBase::__isset()`.

```
// "Official" Field API fields are always set. For non-field properties,
// check the internal values.
return $this->hasField($name) ? TRUE : isset($this->values[$name]);

```

---
Tags: nodes
---


# Question
Title: How do I add multiple images in JSON to meet Google's schema.org requirements?
The Google guidelines for article on schema.org state:

> For best results, provide multiple high-resolution images (minimum of 300,000 pixels when multiplying width and height) with the following aspect ratios: 16x9, 4x3, and 1x1.

How do I do this in Drupal?

# Answer
This takes a little while to set up but is pretty straightforward.

1. Download and install the Image Widget Crop and Schema.org Metatag modules.
2. Go to `admin/config/media/crop` and create three crop types: 1x1, 4x3, and 16x9. Set the aspect ratios to 1:1, 4:3, and 16:9, and set a *hard limit* of height 696 and width 696 for all three as stated in Google's documentation.
3. Go to `admin/config/media/image-styles` and create three image styles, 1x1, 4x3, and 16x9, and each should use the effect **Manual crop** pointing to the *crop type* you created in step #2.
4. Go to `/admin/structure/media` and find your image type. Go to **Manage form display** and use the crop widget. Require all three crops.
5. Go to `/admin/config/search/metatag/` and choose the content that includes the images.
6. For Schema.org Article, scroll down to **Image** and choose *ImageObject*. Enter the URLs as tokens.

For example, if your image styles are:

* `hero_16x9`
* `hero_4x3`
* `hero_1x1`

And your node contains an entity reference to the image you want to use in `field_ref_media_hero`, then you can enter the URLs separated by commas like this:

`[node:field_ref_media_hero:entity:field_media_image:hero_16x9:url], [node:field_ref_media_hero:entity:field_media_image:hero_4x3:url], [node:field_ref_media_hero:entity:field_media_image:hero_1x1:url]`
> 1 votes

---
Tags: media, meta-tags
---


title: How can I manually upgrade my site?

text:
# Question
Title: How can I manually upgrade my site?
I have updated my core to 8.9.0, all modules are Drupal 9 compatible and now I want to upgrade to Drupal 9.0.0. I always did my updates completely manually via FTP/web (swap core/vendor/root files, no SSH/drush/composer).

But for 8 to 9 drupal.org has only instructions using drush or composer, unlike the update instructions for Drupal 8 which had an instruction for how to do it manually.

Upgrading from Drupal 8 to Drupal 9 (or higher) https://www.drupal.org/docs/upgrading-drupal/upgrading-from-drupal-8-to-drupal-9-or-higher

Is there no way to upgrade manually, without SSH/Drush/Composer?

# Answer
> 4 votes
Yes you can. But it needs a little bit of effort beforehand.

You need to have a composerized and version tracked local copy of your site on your computer. All the updating with Composer will happen there then. Look around a bit for Drupal+composerize, there are a few options out already to composerize your site.

From now on, after upgrading/updating your local site with Composer you upload the updated dependencies (the vendor/ directory, the core/ directory, all contrib directories, all libraries directories etc. but also updated scaffolding files like the robots.txt file, the development.services file etc.) to your host via (S)FTP for example and then access your live site's /update.php URL to trigger pending database updates.

As your local site should be version tracked now via Git for example you'll always see which files exactly got updated. For that you may need to adjust the default .gitignore files a bit to only ignore files with sensitive information like the settings.php file. But everything else (the vendor/ directory, the core/ directory, the contrib directories etc.) should better be version tracked to identify changes more easily. When you are done `git add .` everything and `git commit -m "Update project."` and `git push` to some private repo somewhere before you update your project the next time.

---

Ah look, there's still one alternative. Although what's been described above should be the recommended way you can follow the guide on Update core manually which tells you that you could Download Drupal zip and then upload certain contents of it to your host replacing the vendor/ and the core/ directory and some scaffolding files. This guide applies for Drupal 9 as well.

---
Tags: upgrading, 9
---