title: Query custom field on user table

text:
# Question
Title: Query custom field on user table
How do you query custom fields on the user table? If edit a user in the Admin panel, and hit the DEVEL tab, I see the field I added, 'field\_display\_name'.

In a node template php file, I want to replace the 'name' field with 'field\_display\_name'.

When I query, either using:

```
$result = db_select('users', 'u')
  ->fields('u')
  ->condition('name', 'bubba', '=')
  ->execute()
  ->fetchAssoc();

```

or

```
$rst = db_query("select * from {users} where name = :name", array(':name' => 'bubba',));

```

neither one of these return my custom field on the user table. (DPM does not show field\_display\_name)

So obviously, i'm missing something fundamental in my understanding of the data structure.

How do i return this added field by querying with uid or name to return and print the 'field\_display\_name' ?

# Answer
Entity fields are in their own separate table(s), they don't get attached to the base entity table.

You can use an `EntityFieldQuery` to get that data:

```
$query = new \EntityFieldQuery();
$query->entityCondition('entity_type', 'user')
  ->fieldCondition('field_display_name', 'value', 'bubba');

$results = $query->execute();
if (!empty($results['user'])) {
  $users = user_load_multiple(array_keys($results['user']));
}

```

See Where does Drupal 7 store custom user account fields? for a bit more info
> 2 votes

# Answer
Drupal 8:

```
$query = \Drupal::service('entity.query')
  ->get('user')
  ->condition('field_custom', $custom_value)
  $entity_ids = $query->execute();

```
> 0 votes

# Answer
Alternatively, you could use the entity type manager service.

```
/** @var \Drupal\Core\Entity\Query\QueryInterface $query */
$query = \Drupal::service('entity_type.manager')
  ->getStorage('user')
  ->getQuery();

$query->condition('field_custom', $custom_value)
$entityIds = $query->execute();

```

> Previous code only gives you the user IDs that fulfill the condition, then you need to do a call to 'user\_load\_multiple' function.

```
$users = [];
if (!empty($entityIds)) {
  $users = user_load_multiple(array_keys($entityIds));
}

```

For Drupal 8.7+ and Drupal 9, I strongly recommend using Dependency Injection where it is possible because of code standards and performance.
> 0 votes

---
Tags: users, forms
---


title: How do I disable the subject?

text:
# Question
Title: How do I disable the subject?
In Drupal 8 I visited admin/structure/comment/manage/comment/form-display and disabled the subject.

1- The subject field is gone, but the subject label for comments is still shown. Is there any option to hide that, or should I change the theme?

2- It looks like there used to be an *Allow comment title* setting for each content type. Has it been removed in Drupal 8, or is it just me who cannot find it?

3- How can I avoid an empty comment title is automatically filled with the first words taken from the comment?

# Answer
> 0 votes
I find the Automatic Entity Label module to do that.

After **making a backup of your Drupal database and folders**, require it with composer and enable it.

Now you will see a new 'Automatic label' tab in the comment type management, and by clicking 'Automatically generate the label and hide the label field' you will be able to use tokens to auto fill it.

---
Tags: 8, comments
---


# Question
Title: php.ini opcache path for multiple websites with shared code base
I have a D9 website set up already and I want to add another that shares the same code base. (This is on a shared hosting environment)

Below is an example my current php.ini settings for the opcache with 'MyWebSite1.com' as the initial website cache directory path. I want to have the two sites cached in different directories.

How do I specify the path in this php.ini set up for the second 'MyWebSite2.com' website? Or, does this cache directory contain generic php info that can be shared between multiple sites so that only one directory can be specified?

Thank you.

```
date.timezone = 'America/City'

zend_extension=opcache.so;
opcache.enable=1;
opcache.memory_consumption=32;
opcache.interned_strings_buffer=8;
opcache.max_accelerated_files=3000;
opcache.revalidate_freq=180;
opcache.fast_shutdown=0;
opcache.enable_cli=0;
opcache.revalidate_path=0;
opcache.validate_timestamps=2;
opcache.max_file_size=0;
opcache.file_cache=/AbsoluteDirectoryPath/sites/MyWebSite1.com/.opcache;
opcache.file_cache_only=1;

```

# Answer
> 0 votes
If I understand your question correctly, I believe you can use `ini_set()` in your `settings.php` files if your multisite required different PHP ini configurations.

Example 1a:

```
// @file docroot/sites/default/settings.php
ini_set('opcache.file_cache', '/path/to/opcache/default');

```

Example 1b:

```
// @file docroot/sites/my-other-site/settings.php
ini_set('opcache.file_cache', '/path/to/opcache/my-other-site');

```

# Answer
> 0 votes
So the reason I posted under Drupal is because the Drupal installation was throwing an opcache error. These technologies and systems are interconnected so this is in the interest of some Drupal users even though opcache may be a external technology. Drupal doesn't exist in a vacuum, I wish it did because it would probably be easier to manage.

Here is what I found, in case anybody else is having this issue (disclaimer: I'm not an expert on this item... just sharing what I found). I don't know how to put the opcache in memory/database, as suggested (sounds like a good idea) and my host, and Drupal error message, seemed to be wanting a location for this cache, so that's how I proceeded.

Due to some word choices in the directions I found (by host and Drupal), I was under the impression that the cache might be specific for each site (I'm running a multi-site shared code base Drupal install) But the cache seems to be just for any php on the system, so I put the opcache folder under the 'sites' folder in the Drupal directory structure and pointed to it there in my php.ini. So Drupal built a cache folder in there, with a very long number string name. The PHP status information, from the Drupal Status page, will indicate if the opcache is enabled and it's perimeters.

Another problem I had was, when a new cache was built the old ones lingered and ate up a file number limit I had. It seems to be safe to delete these opcache entries and free up space (a lot of space). The caches will rebuild with the current date. So it's safe to play around with this, this is just a cache of PHP code so the server doesn't have to re-run it each time (for efficiency). This (opcache) seems to be new for D8+, I don't recall this issue for prior Drupal versions.

I think it's important to remember that everybody situation is different and there is a reason people reach out for help here. The setup that works for some may not be the case for someone else, and these technologies and networks are getting more and more bloated, complex and tangly. I hope someone may find this useful if they happen to have a similar problem and find themselves here. Thanks for the replies!

---
Tags: caching, multi-sites, 9
---


# Question
Title: When using a grouping field in an HTML list, is there a way to determine the group/loop number of the current content being rendered?
I want to be able to determine what group number is currently being processed to that I can treat the output of the first group differently than subsequent groups.

Unlike rows, I do not see a way to find the current count of groups or loops through the view such that I could, for instance, do something like the following (i.e., classing group content by group iteration) -

```
<div class="item-list">
  <h3 class="group-1">{{ title }}</h3>
  <ul class="group-1">
    {% for row in rows %}
      <li{{ row.attributes }}>
        {{- row.content -}}
      </li>
    {% endfor %}
  </ul>
</div>
<div class="item-list">
  <h3 class="group-2">{{ title }}</h3>
  <ul class="group-2">
    {% for row in rows %}
      <li{{ row.attributes }}>
        {{- row.content -}}
      </li>
    {% endfor %}
  </ul>
</div>
...
<div class="item-list">
  <h3 class="group-n">{{ title }}</h3>
  <ul class="group-n">
    {% for row in rows %}
      <li{{ row.attributes }}>
        {{- row.content -}}
      </li>
    {% endfor %}
  </ul>
</div>

```

# Answer
I don't know of a way to get the group number from within the grouping (e.g. `views-view-list`) template, but I would look to do this split between two templates: `views-view` and `views-view-list`.

First, in the `views-view` template, e.g. `views-view--my-view-id.html.twig`.

```
{# ... etc ... #}
{# Loop through the rows, aka groups, and add a wrapper with index identifier. #}
{% for row in rows %}
  <div class="item-list group--{{ loop.index }}">
    {{ row }}
  </div>
{% endfor %}
{# ... etc ... #}

```

Second, create your `views-view-list` template, e.g. `views-view--my-view-id.html.twig` to build the content for each group:

```
<h3>{{ title }}</h3>
<ul>
  {% for row in rows %}
  <li{{ row.attributes }}>
      {{- row.content -}}
    </li>
  {% endfor %}
</ul>

```

Then you can target the contents of each group in css like:

```
.group--1 h3 { }
.group--1 ul { }
.group--2 h3 { }
.group--2 ul { }
.etc { }

```
> 0 votes

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


# Question
Title: How do I programmatically populate longitude and latitude fields when Geolocation used in content type
I am using the Geolocation module and I have created a custom content type (we'll call it Bookshop), which contains a field called location and is of type Geolocation.

I can already programmatically create the custom content type instance and programmatically populate the title field.

```
    $node=Node::create(
      'title'=>'Shop 1'
    );

    $node->save();

```

How would I go about populating the the Geolocation field content (e.g. the longitude and latitude fields in the Geolocation field)? e.g.

```
    $node=Node::create(
      'title'=>'Shop 1'
      'Geolocation field'=>array ('latitude'=>'1', 'longitude'=>'2.33'),
    );

```

An approach such as the one above does not appear to work?

# Answer
Pretty straight forward just had to change the field names to correspond with the field names used by Geolocation:

```
$node=Node::create(
  'type' => 'content type - machine name',
  'title' => 'Shop 1',
  'geolocation_field' => ['lat'=> 1, 'lng' => 2.33]
);
$node->save();

```
> 6 votes

# Answer
```
<?php
use Drupal\node\Entity\Node;

$node = Node::load($nid);
//set value for body field
$node->body->value = 'body';
$node->body->format = 'full_html';

//save value for geolocation field.
//field_geolocation will be your field machine name
$node->field_geolocation = ['lat'=> 12, 'lng' => 2.33];
//save to update node
$node->save();

```
> 0 votes

---
Tags: 8, nodes
---


# Question
Title: Cannot disable module "monitoring" after failed upgrade
I just updated to Drupal 8.8.1 (`composer update drupal/* --with-dependencies` now says I'm up to date, even though I know that 8.8.2 is actually the most recent). After doing this, I can use most of the site fine, but when I went to update the monitoring module, I get the error `The geoip PHP extension is not installed!` which I cannot install because it is obsolete. Now I believe the database is corrupt because the process would not complete the installation and when I try got to `https://.../admin/modules` I get the stack trace below. I have tried using drush to remove the monitoring module but when I do I get:

```
In PmCommands.php line 129:

  monitoring: There is content for the entity type: Monitoring sensor result. <a href="/admin/modules/uninstall/entity/monitoring_sensor_result">Remove monitoring sensor
   result entities</a>.

```

Do I really need to disable all of the monitors to uninstall and reinstall everything? Is there any way I can do it in one command? And is this even the problem? Thanks.

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

ArgumentCountError: Too few arguments to function Drupal\monitoring\Sensor\SensorManager::__construct(), 5 passed in /var/www/html/otherrealm.org/web/core/lib/Drupal/Component/DependencyInjection/Container.php on line 285 and exactly 6 expected in Drupal\monitoring\Sensor\SensorManager->__construct() (line 73 of modules/monitoring/src/Sensor/SensorManager.php).

Drupal\monitoring\Sensor\SensorManager->__construct(Object, Object, Object, Object, Object) (Line: 285)
Drupal\Component\DependencyInjection\Container->createService(Array, 'monitoring.sensor_manager') (Line: 173)
Drupal\Component\DependencyInjection\Container->get('monitoring.sensor_manager') (Line: 52)
Drupal\monitoring\Plugin\rest\resource\MonitoringSensorConfigResource::create(Object, Array, 'monitoring-sensor', Array) (Line: 21)
Drupal\Core\Plugin\Factory\ContainerFactory->createInstance('monitoring-sensor', Array) (Line: 83)
Drupal\Component\Plugin\PluginManagerBase->createInstance('monitoring-sensor', Array) (Line: 62)
Drupal\Core\Plugin\DefaultSingleLazyPluginCollection->initializePlugin('monitoring-sensor') (Line: 80)
Drupal\Component\Plugin\LazyPluginCollection->get('monitoring-sensor') (Line: 83)
Drupal\Core\Plugin\DefaultSingleLazyPluginCollection->setConfiguration(Array) (Line: 99)
Drupal\Core\Plugin\DefaultSingleLazyPluginCollection->addInstanceId('monitoring-sensor', Array) (Line: 55)
Drupal\Core\Plugin\DefaultSingleLazyPluginCollection->__construct(Object, 'monitoring-sensor', Array) (Line: 213)
Drupal\rest\Entity\RestResourceConfig->getPluginCollections() (Line: 118)
Drupal\rest\Entity\RestResourceConfig->getResourcePlugin() (Line: 59)
Drupal\rest\RestPermissions->permissions()
call_user_func(Array) (Line: 149)
Drupal\user\PermissionHandler->buildPermissionsYaml() (Line: 108)
Drupal\user\PermissionHandler->getPermissions() (Line: 119)
Drupal\user\PermissionHandler->moduleProvidesPermissions('action') (Line: 248)
Drupal\system\Form\ModulesListForm->buildRow(Array, Object, 'Drupal') (Line: 174)
Drupal\system\Form\ModulesListForm->buildForm(Array, Object)
call_user_func_array(Array, Array) (Line: 520)
Drupal\Core\Form\FormBuilder->retrieveForm('system_modules', Object) (Line: 277)
Drupal\Core\Form\FormBuilder->buildForm(Object, Object) (Line: 91)
Drupal\Core\Controller\FormController->getContentResult(Object, Object)
call_user_func_array(Array, Array) (Line: 123)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 573)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 124)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) (Line: 97)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 151)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 68)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 106)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 85)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 50)
Drupal\ban\BanMiddleware->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 52)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 694)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)

```

# Answer
> -1 votes
I have a similar problem for the visitors module. But nothing I do can fix it, as I cannot get to any of the /admin pages. If I try /update.php, it stops with an error that geoip is required. This is all happening after reinstalled the whole large, production website from backup of public\_html and backup of the database. I am baffled, does anyone know what to do?

---
Tags: drush, updating, composer
---


# Question
Title: How do I override an entity view controller?
I am trying to override the entity view controller for a commerce product view, so that I can redirect the user based on certain conditions.

I am trying to do this through the RouteSubscriber::alterRoutes implementation.

```
class RouteSubscriber extends RouteSubscriberBase {

  /**
   * {@inheritdoc}
   */
  protected function alterRoutes(RouteCollection $collection) {
    if ($route = $collection->get('entity.commerce_product.canonical')) {
      $route->addDefaults(['_controller' => '\Drupal\mymodule\Controller\ProductViewController::view']);
    }
  }

}

```

My custom controller is acknowledged, but I'm getting the following error:

> RuntimeException: Controller "Drupal\mymodule\Controller\ProductViewController::view()" requires that you provide a value for the "$\_entity" argument. Either the argument is nullable and no null value has been provided, no default value has been provided or because there is a non optional argument after this one. in Symfony\Component\HttpKernel\Controller\ArgumentResolver-\>getArguments() (line 78 of /var/www/html/vendor/symfony/http-kernel/Controller/ArgumentResolver.php).

My ProductViewController extends the Drupal\Core\Entity\Controller\EntityViewController.

```
class ProductViewController extends EntityViewController {

  public function view(EntityInterface $_entity, $view_mode = 'full')
  {
    return parent::view($_entity, $view_mode);
  }

}

```

Can anyone tell what additional route context parameters I need to add to get this working?

# Answer
I think you may be unsetting some things in your alterRoutes method doing it the way you are. (However, I can't tell if or why that's happening after looking at Route::addDefaults().)

I'm doing the same thing for a media entity's route. My alterRoutes method is a little different - I'm using Route::setDefault().

```
public function alterRoutes(RouteCollection $collection) {
  if ($route = $collection->get('entity.media.canonical')) {
    $route->setDefault('_controller', '\Drupal\my_module\Controller\MyController::view');
  }
}

```

Additionally, the variable names in your controller methods are important - they must match the variable name from the route definition. See the documentation for Using parameters in routes

> In most PHP code the name of the variable does not matter but here it does: **the name of the method argument must match the slug**. Conversely, if the method argument name matches the name of the slug, the parameter will be passed in, irrespective of the order of arguments.
> 0 votes

# Answer
I figured this out. The problem was the argument name. Once I changed $\_entity to $commerce\_product in the controller::view method it started working.

```
class ProductViewController extends EntityViewController {

  public function view(EntityInterface $commerce_product, $view_mode = 'full')
  {
    return parent::view($commerce_product, $view_mode);
  }

}

```

I figured this out by looking for other classes that extend EntityViewController and I found NodeViewController and the variable name was the only significant difference.

Such specific variable naming conventions is a bit *unconventional* imxp, but I believe I have seen this is other places in this Drupal 8.

Anyway, thanks for the assistance @sonfd and I hope this helps others.
> 0 votes

---
Tags: 8, commerce, routes
---


# Question
Title: Change date format "Authored on" for views with replacement pattern
In Druapl 8, how can i change the date format used in a view (see screen shot)

The view uses a replacement pattern `{{ created }} == Authored on`

and i don’t find where to modify the format. I’ve checked :

> configuration / regional and language / date and time formats

But i don’t know how to use the custom format with {{ created }} in the view.

Could it be done in admin without modify template file ?

# Answer
In Drupal 8, fields use the normal field formatters. In your list of Fields in the View, click on **Content: Authored on (Authored on)**. You can change the **Formatter** to what you want (same choices as **Manage Display** on the content type configuration). You can then configure other options, like the format.

If you already are using `{{ created }}` in the template, and you need it in a different format for a replacement pattern / token, then add **Content: Authored on (Authored on)** again to the list of **Fields**, but exclude it from display. Reorder things, so this appears before the field you need it as a token. Configure it as above. Then, where you need the token, you should have `{{ created_1 }}`, which is the duplicate you just made.
> 2 votes

# Answer
I havent try, but if you can use some twig maybe with something like that:

```
{{created|format_date("name_of_your_format")}}

```

Or

```
{{created.value|format_date("name_of_your_format")}}

```

maybe try to inspect that 'created' variable with a `{{dump(created)}}` Hope, it helps.
> 0 votes

# Answer
If you absolutely want a solution that involves replacement patterns, I've found that you need to use the raw value and run it through a conversion to UNIX time if you want to use a Drupal date format.

For example, I have a view of media that have an "Imported date" field (`field_date_imported`):

```
{{ field_date_imported__value | date("U") | format_date("medium") }}

```

I'm using this to add a "title" attribute to a span wrapping a "Time ago" date, so that the user can hover over the date to get the actual timestamp.
> 0 votes

---
Tags: 8, datetime
---


# Question
Title: How to display messages "properly" when using ajax submit?
Here is a simple form:

```
  public function buildForm(array $form, FormStateInterface $form_state)
  {
    $form['some_text'] = [
      '#type'  => 'textfield',
      '#title' => $this->t('TextValue'),
    ];
    $form['submit'] = [
      '#type'  => 'submit',
      '#value' => $this->t('Submit'),
    ];
    return $form;
  }

  public function validateForm(array &$form, FormStateInterface $form_state)
  {
    if ($form_state->getValue('some_text') != 'Awesome') {
      $form_state->setErrorByName('some_text', $this->t('Please enter "Awesome"'));
    }
  }

  public function submitForm(array &$form, FormStateInterface $form_state)
  {
    drupal_set_message($this->t('The form was submitted'));
    $form_state->setRedirectUrl(Url::fromRoute('<front>'));
  }

```

And it works as expected:
Case 1A: Submit with no entry gives this (error message in default message location):  Case 1B: Submit with "Awesome" in `TextValue` gives this (completion message in default message location and back to the front page of the site):  Now, I add some ajax on the submit button:

```
$form['submit'] = [
  '#type'  => 'submit',
  '#value' => $this->t('Submit'),
  '#ajax'  => [
    'wrapper'  => 'default_form_wrapper',
    'callback' => '::ajaxCallback',
    'progress' => [
      'type'    => 'throbber',
      'message' => $this->t('Be patient'),
    ],
  ],
];
$form['#prefix'] = '<div id="default_form_wrapper">';
$form['#suffix'] = '</div>';

```

and the corresponding callback:

```
  public function ajaxCallback(array &$form, FormStateInterface $form_state)
  {
    if ($form_state->hasAnyErrors()) {
      return $form;
    }
  }

```

And it works more or less as expected:
Case 2A: Submit with no entry gives this (almost OK, wrong location of the message):  Case 2B: Submit with "Awesome" in `TextValue` gives nothing (KO, no message and form is still displayed instead of front page).
And if I refresh the page in the browser, I get this:  As you can see, the location of the message area in case 2A is above form in `default_form_wrapper` (to be compared to the default message area location, a div with class="region region-highlighted"):

How can I make it work as I expect?

1. Have the message in the "default" area?
2. Have my `submitForm` work after all?

# Answer
> 1 votes
Finally, after hours digging Drupal Answers, I made it work this way.
My `ajaxCallback`:

```
$response = new AjaxResponse();
if ($form_state->hasAnyErrors()) {
  $messages = \Drupal::messenger()->deleteAll();
  $messages = [
    '#theme'        => 'status_messages',
    '#message_list' => $messages,
  ];
  $response->addCommand(new ReplaceCommand('#messages', ''));
  $response->addCommand(new AppendCommand('.region-highlighted', $messages));
}
else {
  $response->addCommand(new \Drupal\Core\Ajax\RedirectCommand(Url::fromRoute('<front>')->toString()));
  }
}
return $response;

```

and my `submitForm` is now empty!

Nota: `$response->addCommand(new ReplaceCommand('#messages', ''));` is here to have a new error message replacing a previous one (without this command, all the messages are displayed one after the other...).

---
Tags: 8, forms, ajax
---


# Question
Title: icon_map in PHP annotation instead of layouts.yml
I need to add an Icon to a layout added by a contrib module. But I see it is adding the layout via plugin PHP file instead of layouts.yml. The annotation looks like following

```
/**
 * A very advanced custom layout.
 *
 * @Layout(
 *   id = "lb_tabs_tabs",
 *   label = @Translation("Tabs"),
 *   category = @Translation("Effects"),
 *   path = "layouts/tabs",
 *   template = "lb-tabs-tabs",
 *   icon_map = ""
 * )
 */

```

I don't know how to represent the multidimensional array into this annotation form. When I tried simple `[['region', 'region']]` form it errored `[Syntax Error] Expected PlainValue, got '['` .

tried `@Array(@Array('region', 'region'))` as well but got

`Syntax Error] Expected Doctrine\Common\Annotations\DocLexer::T_CLOSE_PARENTHESIS, got '('` .

What is the correct way to add an icon\_map there?

Also tried adding `layouts.yml` and moving these values to yml and the layout option just disappeared as a whole\`.

# Answer
You can do this via the layout alter hook ( `hook_layout_alter(&$definitions)` ). The definitions variable is an array of all the defined layouts keyed by the layout machine name.

The value here is a `Drupal\Core\Layout\LayoutDefinition` object. This has a setIconMap method. You can pass this an array of arrays that define the icon.

E.g. if the yml format is:

```
- [top]
- [first, second]
- [bottom]

```

the value is something like:

```
$map = [
  ['top'],
  ['first', 'second'],
  ['bottom']
]

```
> 0 votes

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


# Question
Title: How to restrict access to specific php file to only athenticated users
I manually made a php file that has the ability to connect to the database and create table entries, it works fine, but now the problem is that if I leave it there, anyone will be able to access it to create entries.

So I want to restrict the access to that file to only authenticated users, I think this may be posible using the .htaccess file, but I don't know how just yet.

# Answer
> 3 votes
.htaccess won't help with this; Apache doesn't know what an authenticated Drupal user is, and there's no easy way to grant it that knowledge. Fortunately there's a much better option:

Create a route in a custom module, and execute your code in its controller. You can easily protect the route with permissions, or by role. Aside from the flexibility this gives you around access control, you can also refactor your custom DB code to use Drupal's database API, making your code more future-proof.

The other option, less desirable IMO for your requirements, is to bootstrap Drupal in your custom PHP file, and use the `current_user` service to determine whether the user has access to your script.

---
Tags: 8, security, .htaccess, domain-access
---


# Question
Title: Linking two different views for the same content type
I have a content type with around 50 fields with three groups A,B and C(grouped in views). I have a view which shows the new content added in table format(limited fields). I do not want the table to be huge so I have created another view - page containing 3 blocks( A- 10 fields, B- 20, C-20) which shows the content according to the group(A,B,C). Now the analysis result link has to redirect to the second view and show the correct content corresponding to the content added( nid to be the same), but all the links in every row of the table show the same result- the recent most view result. The link to content redirects correctly to the content but I want it to redirect it to the correct view result. I have to have a unique url for ever anaylsis result link. I prefer doing it the drupal way, so I tried adding relationship-to show results where nid is same, but it required an absolute value(like nid=5). I tried making the page path /{{nid}} too but it did not work. Please help me with the solution.

I followed the solution postyed by prkos. Here is the current progress:

# Answer
## Construct link in the first Views

You need to create the correct link in your first Views yourself.

You will need the ID field for that purpose since that is the information you need for filtering the second Views.

You don't want the ID show in that Field, we need to construct the link that has the ID in it so that it can be passed to the second View as an argument.

When you add the ID Field set its Formatter to **Unformatted** just to make sure you get plain number out of it.

Under `Rewrite results` select **Override the output of this field with custom text** and in the Text area enter the text you want as your link text, something like "More info about this/Analysis", otherwise the text will be the content ID number.

Again under `Rewrite results` select **Output this field as a custom link** and put the path of your second Views path with the token for your ID field. It will look something like this:

`/my-second-views-path/{{ nid }}`

You can check what your token is in the `Replacement patterns` a bit further down the page. You can also use the raw value token.

You can check your configuration is correct by hovering over the text (it should be a link) and seeing in the browser tooltip (usually bottom left of browser viewport) that the link has been constructed correctly.

## Add Contextual ID in the second Views

To make the second Views show only the one correct result when you click on the constructed link in a particular row in the first View you need to make it aware of that number in the link.

This is done by adding a Contextual ID filter in your second View. Contextual filters are under Advanced options, usually on the right in Views configuration.

Configure it with these settings:
`When the filter value is NOT available`
**Provide default value**
**Content ID from URL**
`When the filter value IS in the URL or a default is provided`
**Specify validation criteria**
Validator: **Content**
Content type **\[yourCT\]**
Set other options to what makes sense in your case.

You can test that the configuration is correct by entering a known content ID number into Views `Preview` field, it should show only the row with the content with that ID.

The `Path` of the second View should be `/my-second-views-path/%`. The % character there represents the input for the first Contextual filter (the only one in this particular case).

---

Final test is to visit the First View page and click on a link, it should take you to the second Views page and only show one result, the one with the corresponding ID number.
> 0 votes

---
Tags: 8, views, nodes
---


# Question
Title: Sending reminder Email if taxonomy term and webform submission term reference match
This is a tricky request and I cant get my head around it completely.

A restaurant delivers only to certain districts within town each day (on an irregular schedule). The webpage shows the next 7 days and for each days the districts for this day. That's up and running.

But people should be notified that the next day its their districts turn, so they dont forget to order (which they do at the moment).

I am thinking of a subscription form where visitors only have to leave their email adress and click their district. Like a newsletter subscription. They should NOT register into Drupal. There are several paths to choose from, but with everyone I tried there was one piece missing.

One could choose Mailchimp with the districts as groups or lists and have the subscribers per district there. But how would Mailchimp know that tomorrow district X will be served and it should send out the mailing.

Tried to get it done with a webform including a term reference to the districts (which are a taxonomy vocabulary), then using Rules to check the the upcoming days districts to the webform submissions term references with the same value. No luck so far.

Simplenews might be an option, but it seems it doesnt have the capability to ad a term reference field to subscribers.

Anyone having an idea, I am eager to listen to everyone.

thanks in advance

ps: all in Drupal 8

# Answer
> 0 votes
Assuming that each person is a representative for only one district, you basically have several different mailing lists-- one for each district.

So if you are using a mailing list like Mailchimp, you need to set up a different list for each district and then let people sign up to each list.

Doing this with a single list and filtering the list is going to get really complicated because what you actually seem to want to do is to send out emails per district, so in that case, each district should be its own list.

If you implement this another way within Drupal, it's the same-- create separate lists of people per district, and then your email sending logic should handle each district.

> But how would Mailchimp know that tomorrow district X will be served and it should send out the mailing.

In Mailchimp, you can set a list to send out an email once a week on a certain day of the week, etc. You could alternately configure Drupal to tell Mailchimp to send out the mails using the Mailchimp API, but that's a complex topic not suitable for a general answer to this question.

---
Tags: webforms, rules, emails
---


# Question
Title: Flag count is incrementing only after page reload
I have a views with like and unlike flag. When I click on like flag the count not increments. But when I reload the page, then only like's count will change. How can I solve this issue?

**Note**: I have already enabled ajax for my views.

# Answer
I had the same problem, and find how to solve it. The Views Flag Refresh module is only available for Drupal 7, but someone ported it to work on Drupal 8, here is the download link.

I find it in this issue comment by WalkingDexter.

In my case I need it to work on Drupal 9, so it is necessary to change a line in a file in the downloaded custom module as Akash\_Daimari explains in this comment.

The module would go in /modules/custom/

In the view you have to use Ajax and add the flag in 'Flag refresh' options.

As a note, in the View preview the count does not update, but on the page it does.
> 0 votes

---
Tags: 8, flags
---


title: How to post node tags using REST API?

text:
# Question
Title: How to post node tags using REST API?
There is no problem with a node creation with filled in title/body/custom text field fields using REST API. We just need to send a post request with the following body:

```
{
  "_links": {
    "type": {
          "href": "http://localhost/drupal/rest/type/node/page"
    }
  },
  "title": {"value": "Does it work?"},
  "body": {"value": "node body"},
  "field_test": {"value":"hello"}
}

```

Where "field\_test" is a plant text field.

But how to create a node with filled in tags field?

I've tried to post a node using the following post request body:

```
{
  "_links": {
    "type": {
          "href": "http://localhost/drupal/rest/type/node/page"
    }
  },
  "title": {"value": "Does it work?"},
  "body": {"value": "node body"},
  "field_tags": {"value":"tag1"}
}

```

It creates the node, but without tags ("field\_tabgs") value. Any help?

# Answer
> 1 votes
They are relations, so firstly you need to create the tags with **the taxonomy REST service**.

```
/taxonomy/term

```

You must take into account they are entities ( node and taxonomy\_term ) and the field\_tags field only stores the reference to the entity taxonomy\_term.

Once you have created it, you will have to add the tags in the following way in your node definition.

Don't forget change the **term\_id** ( in my case 1 ) and the **uuid** :

```
{
  "_links": {
    "type": {
      "href": "http://localhost/drupal/rest/type/node/page"
     }
  },
  "title": {"value": "Does it work?"},
  "body": {"value": "node body"},
  "_embedded": {
    "http://localhost/drupal/rest/relation/node/page/field_tags":
      [
        {
          "_links": {
          "self": {
            "href": "http://localhost/drupal/taxonomy/term/1?_format=hal_json"
          },
          "type": {
            "href": "http://localhost/drupal/rest/type/taxonomy_term/tags"
          }
        },
        "uuid": [
          {
            "value": "ff61ea71-2540-47fe-a4bb-384b12d4de47"
          }
        ],
       "lang": "en"
      }
    ]
  }
}

```

More information in the following link.

# Answer
> 0 votes
You can simply use

`"field_tags": {"target_id":"46"}` // where 46 is term id

---
Tags: 8
---


title: How to get list of cron tasks?

text:
# Question
Title: How to get list of cron tasks?
Drupal 6 possible noob question. Is there a way to get a list of cron tasks from the Drupal 6 Admin? I am a themer for the site. The original dev is long gone. Everyone complains of slowness and 500.shtml errors. I looked in the log and noticed that these are most often associated with a cron task that runs hourly. But I can't see what those jobs are. Once I get the list is there also a way to disable unneeded tasks from within Drupal?

I'm running Windows on my client machine. I don't have DRUSH.

Thanks In Advance

# Answer
If you don't have Elysia Cron installed, and from a purely debugging standpoint, if you want or need to see what module's cron is running, as well as how long it is taking to run, you can **TEMPORARILY** edit `includes/common.inc`'s `drupal_cron_run()` function like so...

```
// Iterate through the modules calling their cron handlers (if any):
// module_invoke_all('cron'); // watchdog how long each hook takes now...

$details='';
foreach (module_implements('cron') as $module) {
  $start=microtime(TRUE);
  $function = $module . '_cron';
  $function();
  $finish=microtime(TRUE);
  $duration=$finish - $start;
  $details.='<pre>' . $module . ': ' . $duration . ' seconds</pre>';
}

// Record cron time
variable_set('cron_last', time());
watchdog('cron', 'Cron run completed.' . $details, array(), WATCHDOG_NOTICE); // . in $details here :)

```

eg, comment out the `module_invoke_all()` and instead loop through via `module_implements()` and log how long each individual cron run takes.
> 3 votes

# Answer
Or simple use

```
drush ev 'var_dump(module_implements("cron"))'

```

For list the cron job that exists.
> 8 votes

# Answer
For Drupal 8/9, you can simply use the following command:

```
drush php-eval 'var_dump(\Drupal::moduleHandler()->getImplementations("cron"))'

```
> 5 votes

---
Tags: cron
---


# Question
Title: Views filter group "or" operator not working
I'm having an issue with the "or" operator in a view acting like an "and" operator (at least, I think that's what it's doing).

The view is meant to display articles with either "Primary Feature" checked, or one of the "Secondary Feature" options selected. The "Secondary Feature" is a list of radio options with three values: Secondary Feature 1, Secondary Feature 2, Secondary Feature 3. I've tried setting up the view a couple ways, first with a single "Secondary Feature" filter using the "is one of" operator with all three values selected (first screenshot), and second with three "Secondary Feature" filters, each using the "is one of" operator with only one value selected (second screenshot).

There are only four articles these filters apply to, one with each type of feature selected (1 Primary Feature, 1 Secondary Feature 1, 1 Secondary Feature 2, and 1 Secondary Feature 3).

From the Googling I've done it seems that checking "reduce duplicates" fixes this issue for some folks but it doesn't here. When I check "reduce duplicates" on the Primary Feature and Secondary Feature filters, it displays the article with "Primary Feature" checked, but none of the articles with "Secondary Feature" checked.

Any ideas on how to fix this?

**Edited to add:** This is on Drupal 7.

# Answer
> 0 votes
I got this working — I had to check "distinct" under Advanced \> Query Settings, uncheck "reduce duplicates" for the Primary Feature filter, check "reduce duplicates" for the Secondary Feature filter (set up as a single filter using the "is one of" operator with all three values selected), and clear the cache. Now it's working fine.

---
Tags: views
---


# Question
Title: Use entity reference to target revisions of an an entity
I'm building a custom entity `document` which supports revisions. Revisions are seen as versions of the document (v1.1, v1.2, ...), the title field is revisionable as well. Then there is a custom entity `customer`, which needs to accept documents. On creation of a customer, I need to point out which revision of the document is suitable for this customer.

I have an **entity reference field** on the customer to target a document. However, I'm not achieving to target revisions of a document.

I tried **entity reference display** in views (with a view that supports revisions) but I'm not able to select it in the field settings (no eligible view found). Probably because I can only select 'Document' as target type and not 'Document revisions'.

I tried **entity reference revisions** module but gave me the same results. This module just keeps track of changes in parent vs child revisions (I guess).

**I would expect document revisions being available in the settings above!**

Any suggestions on how to do this properly, am I missing something? I want to make use of core as much as possible for this one.

**Update**: I ended up creating a custom field plugin to get the required solution.

# Answer
> -1 votes
Revisions are stored in a separate db table from content. Views module makes you choose the base table for the query to the database when you're creating a new View (it's commonly called Views type: Content, User, Media, Taxonomy terms).

The easiest way to allow an Entity Reference Field to choose a particular Revision of a Content item is to **build the list of Content Revisions items, and not a list of Content items**.

Create a new Views entirely but this time choose `Content revisions` under **Show**, and not `Content` (you can't change that from within your existing Content type Views).

Your aim it to have a separate revision in each Views row, because when you're using that list within an ER Field each Views row becomes one checkbox/radio button to select when you're creating a new node.

Revisions can be grouped by their original content ID, Title or something else in common, but I'm not sure if the Entity Reference Views Display type supports that, I expect it doesn't and it won't affect it, you'll still get a plain list of all Revisions and you need to make sure yourself what to output and how to style it to make the options clear. There are probably ways on how to improve the ER Display output in Field widgets but that is out of scope of this question.

---

I haven't tries this, but usually when listing content referenced through ERs you need to add a Relationship to get any other info than an ID of the referenced entity. You'd need a Relationship to get that info. In your case if you start with Content Views type I expect you'd have to make sure to have each Revision is in a separate row (after you make them appear in results by adding a Relationship, and you'd probably need to list only the Revision info to make them appear in separate rows). I know it's possible to create the reverse ER Views through the forward list Views this way, but haven't tried it with Revisons, maybe the same logic applies.

Anyway, go with the Content Revisions Views type as explained above ;)

---
Tags: entities, 9
---


# Question
Title: How can I output the absolute URL as link text for internal links on link fields?
When using a link field without a link text and just with the URL, Drupal 8/9 outputs the relative path as the link text for internal links. How can I change that to either output the absolute URL or (even better) use the title from the entity in the link as the link text?

I am using the "Separate link text and URL" formatter provided by Drupal core.

# Answer
Inspired by Link field title from entity/route, I created a preprocess function.

```
/**
 * Prepares variables for link fields.
 */
function mytheme_preprocess_field__node__field_links(&$variables) {
  /* If it's an internal link and there was no link title provided by the editor,
then use the entity label as the link text.*/
  $i = 0;
  foreach ($variables['element']['#items'] as &$item) {
    if($item->getUrl()->isRouted()) {
      $parameters = $item->getUrl()->getRouteParameters();
      if (!empty($parameters)) {
        foreach ($parameters as $entity_type => $id) {
          if ($entity = Drupal::entityTypeManager()
            ->getStorage($entity_type)
            ->load($id)) {
            $variables['items'][$i]['content']['#url_title'] = Link::fromTextAndUrl($entity->label(), $entity->toURL())
              ->toString();
            break;
          }
        }
      }
    }
    $i++;
  }
}

```
> 1 votes

# Answer
Alternatively to the code answer already posted, which is probably preferable because of better performance you could use Views to change the output of the Link Field.

1. Hide the Link Field completely (drag to the Disabled area).
2. Create Views with Block Display listing Content where you have the Link Field, set it to output Fields.
3. Add the Title and the Link fields.
4. Make sure the Title Field is set to `Exclude from display` and DON'T output as link to content!

This way you will get the Title text to later act as link text.
5. Change the Link Field configuration under **Rewrite results**: in **Override the output of this field with custom text** Text area put the token for the node Title, usually something like `{{ title }}`. (You can lookup available tokens further down the Field settings page under **Replacement patterns**)
6. more under **Rewrite results**: `Output this field as a custom link` enter something like `{{ field_link_uri }}` into the **Link path** field and check the **Use absolute path** option.

At this point you have a list of Links from all nodes.
7. To make only the relevant Link appear in the Block add the Contextual filter for Content **ID** and provide default ID from URL (standard config you can find in other questions).

This filters the results to the Link from only the node you're currently viewing. Enter the node ID into Views Preview field to test the Contextual is working correctly, at least in Views context.
8. Now that the Link in Views is constructed place the Block into a theme Region, make it Visible only on your Content pages, and set the Contextual ID from URL option.

You should now have the modified Link show up on node pages.
> 0 votes

---
Tags: theming, 9
---


title: Disable Inline Form Errors

text:
# Question
Title: Disable Inline Form Errors
I'm encountering the bug described at "Login form error message is redundant and does not make sense". In short, if a user enters invalid credentials once, an inline error message appears on the user login page. When the user enters valid credentials and successfully logs in, the user sees an error message at the top of the screen (e.g., "1 error has been found: username"), but that is no longer correct.

According to this blog post one can disable inline form errors for a particular form by adding `$form['#disable_inline_form_errors'] = TRUE;` to the form definition, and I have seen that code snippet elsewhere, too. But I can't find any instructions for implementing it. Does anyone have an example?

# Answer
The core issue you linked to has a patch that is apparently working, so it may be easier to patch with Composer instead of adding code to a custom module.

But, if you want to use the `$form['#disable_inline_form_errors'] = TRUE;`, this is what you can do:

First, create a custom module. You need to follow the instructions on the first four pages:

* Getting Started - Background & Prerequisites
* Prepare a Module skeleton
* Naming and placing your Drupal module
* Let Drupal know about your module with an .info.yml file

Then, in the `MYMODULE.module` file, add this code:

```
/**
 * Customize the user login form.
 */
function MYMODULE_form_user_login_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  $form['#disable_inline_form_errors'] = TRUE;
}

```

What this code does is use `hook_form_alter` to target the user login form. Lots of Drupal's form behaviors can be customized in this way.

You then need to go to the module administration page and enable your custom module.
> 1 votes

---
Tags: 8, entities, status-messages
---


# Question
Title: How do I serve up a themed 500 error response page?
Has anyone developed a custom themed page for 500 errors on a Drupal 8 site? There is no maintenance offline template equivalent, and core out of the box simply delivers an unstyled stack trace. We've been toying around with a solution in .htaccess, or by hooking into Symfony's exception events.

Anyone had success with either of these approaches?

# Answer
> 7 votes
You may create custom exception subscriber as it is shown below.

Notice that I did not use Drupal theming engine to render the error page. Uncaught exception indicates that something really wrong has happened on a site. There is a great chance that some Drupal services are not available so rendering error page may fail as well.

Also keep in mind that exception subscriber won't catch fatal PHP errors because they are handled differently.

*src/EventSubscriber/ExceptionSubscriber.php*

```
<?php

namespace Drupal\example\EventSubscriber;

use Drupal\Core\EventSubscriber\DefaultExceptionSubscriber;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\KernelEvents;

/**
 * Last-chance handler for exceptions.
 *
 * This handler will catch any exceptions not caught elsewhere and send a themed
 * error page as a response.
 */
class ExceptionSubscriber extends DefaultExceptionSubscriber {

  /**
   * {@inheritdoc}
   */
  protected function onHtml(GetResponseForExceptionEvent $event) {
    if ($this->getErrorLevel() == ERROR_REPORTING_DISPLAY_VERBOSE) {
      parent::onHtml($event);
    }
    else {
      $content = file_get_contents(DRUPAL_ROOT . '/../500-error.html');
      $response = new Response($content, 500);
      $event->setResponse($response);
    }
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    // Catch the exception just before default exeception subscriber.
    // @see Drupal\Core\EventSubscriber\DefaultExceptionSubscriber::getSubscribedEvents()
    $events[KernelEvents::EXCEPTION][] = ['onException', -255];
    return $events;
  }

}

```

*services.yml*

```
services:
  example.exception_subscribtr:
    class: Drupal\example\EventSubscriber\ExceptionSubscriber
    arguments: ['@serializer', '%serializer.formats%']

    tags:
      - { name: event_subscriber }

```

Note that you need to have error reporting set to something other than verbose for this to work (unless you alter the code above). This can either be controlled in the CMS here: /admin/config/development/logging or it may be overridden in your settings.php file. For example, you might need to set

```
$config['system.logging']['error_level'] = 'hide';

```

Also note, that if your file\_get\_contents throws a fatal error, you will get the standard error for uncaught exceptions: "The website encountered an unexpected error. Please try again later."

Here's two ways you can trigger a 500 error for testing:

```
use Symfony\Component\HttpKernel\Exception\HttpException;

throw new HttpException(500);

```

or

```
/** @var \Drupal\Core\Template\TwigEnvironment $environment */
$environment = \Drupal::service('twig');
$environment->loadTemplate('this-template-does-not-exist.html.twig')->render([]);

```

# Answer
> 0 votes
Here is a newer version of @ya.tecks answer with the same logic but different classes and more uptodate with latest versions of Drupal.

```
<?php

namespace Drupal\example\EventSubscriber;

use Drupal\Core\EventSubscriber\HttpExceptionSubscriberBase;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;

/**
 * Last-chance handler for exceptions.
 *
 * This handler will catch any exceptions not caught elsewhere and send a themed
 * error page as a response.
 */
class ExceptionSubscriber extends HttpExceptionSubscriberBase {

  /**
   * {@inheritdoc}
   */
  protected static function getPriority() {
    // A very low priority so that custom handlers are almost certain to fire
    // before it, even if someone forgets to set a priority.
    return 1;
  }

  /**
   * {@inheritdoc}
   */
  protected function getHandledFormats() {
    return [
      'html',
    ];
  }

  /**
   * The default 500 content.
   *
   * @param \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event
   *   The event to process.
   */
  public function on500(GetResponseForExceptionEvent $event) {
    $content = file_get_contents(DRUPAL_ROOT . '/../500-error.html');
    $response = new Response($content, 500);
    $event->setResponse($response);
  }

  /**
   * Handles errors for this subscriber.
   *
   * @param \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event
   *   The event to process.
   */
  public function onException(GetResponseForExceptionEvent $event) {
    $exception = $event->getException();
    // Make the exception available for example when rendering a block.
    if (preg_match('/5[0-9][0-9]/', $exception->getStatusCode())) {
      $method = 'on' . $exception->getStatusCode();

      if (method_exists($this, $method)) {
        $this->$method($event);
      }

      if (!method_exists($this, $method)) {
        $this->on500($event);
      }
    }
  }

}

```

---
Tags: theming, 8, maintenance-mode
---


# Question
Title: How do I include special characters in a path alias?
I'm trying to add a path alias for a node, /student-&-courses/maths, but in the URL it is displayed as www.testone.com/student-%26-courses/maths.

I unchecked the *Generate automatic URL alias* option manually set the path alias without adding a pattern. I enabled the *Reduce strings to letters and numbers* and *Transliterate prior to creating alias* options in the settings, but it doesn't have any effect: The special characters are not encoded in ASCII format.

How can I fix this so the URL contains special characters?

# Answer
The ampersand (`&`) is a reserved character in URLs because it is usually input as part of the query string. Some more info.

Most special characters can be used in URLs with the settings you described in your question, but `&` is an exception. Either just live with `%26` as the encoding or rewrite the title to not use the `&` symbol, which is reserved.

This is not a Pauthauto problem; it's a URL problem.
> 2 votes

# Answer
As others have said, `&` is a reserved character with special meaning in urls.

There are a couple options to remove or replace ampersand rather than have it be rewritten to `%26` with the pathauto module. **Note that these options only apply to aliases that are auto-generated**, i.e. when the content has "Generate an automatic URL alias" checked.

The module's settings page (at /admin/config/search/path/settings) has options to remove punctuation or replace punctuation with the default separator. (These options are hidden in the collapsed *Punctuation* section near the bottom of the form.)

Additionally, *pathauto* provides an api hook to alter the alias yourself:

```
/**
 * Alter Pathauto-generated aliases before saving.
 *
 * @param string $alias
 *   The automatic alias after token replacement and strings cleaned.
 * @param array $context
 *   An associative array of additional options, with the following elements:
 *   - 'module': The module or entity type being aliased.
 *   - 'op': A string with the operation being performed on the object being
 *     aliased. Can be either 'insert', 'update', 'return', or 'bulkupdate'.
 *   - 'source': A string of the source path for the alias (e.g. 'node/1').
 *     This can be altered by reference.
 *   - 'data': An array of keyed objects to pass to token_replace().
 *   - 'type': The sub-type or bundle of the object being aliased.
 *   - 'language': A string of the language code for the alias (e.g. 'en').
 *     This can be altered by reference.
 *   - 'pattern': A string of the pattern used for aliasing the object.
 */
function hook_pathauto_alias_alter(&$alias, array &$context) { }

```

For example, you could use this hook to replace the `&` with `and`, but you must first set Ampersand to *No action (do not replace)* in the pathauto punctuation settings mentioned above.

```
/**
 * Replace `&` with `and` in generated url paths.
 *
 * Implements hook_pathauto_alias_alter().
 */
function MYMODULE_pathauto_alias_alter(&$alias, array &$context) {
  $alias = str_replace("&", "and", $alias);
}

```
> 2 votes

---
Tags: path-aliases
---


# Question
Title: How to get fields definitions of a vocabulary in drupal 8/9?
I needed the field list related a vocabulary item.I was able to list the fields related to a content type by using like this:

```
\Drupal::entityManager()->getFieldDefinitions('node', 'article');

```

But I can't find a way for the vocabulary items.

# Answer
`\Drupal::entityManager()` is deprecated, instead you should use `\Drupal::entityTypeManager`. From the docs:

> Deprecated in Drupal 8.0.0 and will be removed before Drupal 9.0.0. Use \Drupal::entityTypeManager() instead in most cases. If the needed method is not on \Drupal\Core\Entity\EntityTypeManagerInterface, see the deprecated \Drupal\Core\Entity\EntityManager to find the correct interface or service.

This is especially relevant here as the `getFieldDefinitions()` method has moved to a different service, `entity_field.manager`.

With all of this said, you can use the same method to get taxonomy term fields as any other bundle. As documented in this related answer:

```
$entity_type_id = 'taxonomy_term';
$bundle = 'article_tags';

// Load the field definitions for any bundle.
$my_bundle_fields = \Drupal::service('entity_field.manager')
  ->getFieldDefinitions($entity_type_id, $bundle);

```
> 0 votes

---
Tags: entities, taxonomy-terms
---


# Question
Title: How do I clear cache using an SQL query?
After a module update, my site has become unusable, and only shows a php error message. I tried circumventing the problem with `drush cc`, but that didn't help.

Also tried with a custom php script but that has issues finding my `DRUPAL_ROOT`

I just want to clear the cache tables from Drupal 7 directly on the mysql server, but I'm unsure which tables should be cleared for that and especially which I should not clear.

Do I just need to clear all the `[SITE-PREFIX_]cache*` tables?

# Answer
> 6 votes
Any well written module that has a cache, should prefix it with cache, meaning that the answer to your question is "Yes".

In the odd event that a module caches data somewhere else, you can check your modules for implementations of hook\_flush\_caches, and see what they remove.

# Answer
> 34 votes
Yes, you can simply clear (`TRUNCATE`) all `cache*` tables.

This worked well for me:

```
TRUNCATE TABLE cache;
TRUNCATE TABLE cache_block;
TRUNCATE TABLE cache_bootstrap;
TRUNCATE TABLE cache_field;
TRUNCATE TABLE cache_filter;
TRUNCATE TABLE cache_form;
TRUNCATE TABLE cache_image;
TRUNCATE TABLE cache_menu;
TRUNCATE TABLE cache_page;
TRUNCATE TABLE cache_path;
TRUNCATE TABLE cache_token;
TRUNCATE TABLE cache_update;

```

If you use drush, run `drush sql-cli` and paste the above in there.

These commands might not clear all cache tables of your specific site but it can help fix some errors. Afterwards you can try `drush cc all` to clear the rest.

# Answer
> 15 votes
To clear all cache tables run this command in your server terminal.

```
# Truncate cache tables in MySQL regardless of the active cache backend
echo "SHOW TABLES LIKE 'cache%'" | $(drush sql-connect) | tail -n +2 | xargs -L1 -I% echo "TRUNCATE TABLE %;" | $(drush sql-connect) -v

```

this will loop through all cache tables and truncate them in one command.

# Answer
> 4 votes
For me (Drupal 9.1.3) - works below:

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

```

After TRUNCATE this tables clear browser's history. That's all.

# Answer
> 3 votes
You can either TRUNCATE/DELETE each table separately which starts from `cache_` like:

```
DELETE FROM cache;
DELETE FROM cache_block;

```

and so on (check via `drush sqlq "SHOW TABLES LIKE 'cache_%'"`).

Or generate query with list of tables and pass into drush to truncate them, e.g.:

```
echo "SHOW TABLES LIKE 'cache%'" | $(drush sql-connect) | tail -n +2 | xargs -L1 -I% echo "DELETE FROM %;" | $(drush sql-connect) -v

```

or:

```
echo "SELECT CONCAT('DELETE FROM ', GROUP_CONCAT(TABLE_NAME SEPARATOR ';DELETE FROM ') , ' cache;' ) AS statement FROM information_schema.TABLES WHERE TABLE_NAME LIKE 'cache_%'" | drush sqlc --extra=--skip-column-names | drush sqlc

```

### Memcache

If you're using memcached, you also need to flush the caches there, e.g. (Bash syntax):

```
echo flush_all > /dev/tcp/127.0.0.1/11211

```

# Answer
> 1 votes
`drush cr` and/or `drush cc all` is supposed to clear all caches, but indeed some cache tables do not get cleared. The following (simplified) command does truncate all caches:

```
drush sql-query "SHOW TABLES LIKE 'cache%'" | while read table; do drush sql-query "TRUNCATE $table"; done;

```

# Answer
> 0 votes
Or, you can import you mysql dump with already truncated `cache*` tables:

```
gunzip -c ~/database.sql.gz | grep -v 'INSERT INTO `cache'| mysql --user=root drupal

```

# Answer
> 0 votes
JFR in this article an other flexible pattern-based solution is offered in a form of raw SQL-query, but was not working for me as good as Mohammad's: https://thebarton.org/clear-drupal-cache-sql-query/

---
Tags: caching
---


# Question
Title: Getting current user ID in a custom block
I have a custom block where I need to use `[current-user:uid]` in just one text. In Drupal 7, I would have used `PHP input filter`. How can I do this in Drupal 8?

# Answer
You may use twig bamboo or a preprocess function where you load the current user.

```
function hook_preprocess_HOOK(&$variables) {
  $vars['user'] = \Drupal\user\Entity\User::load(\Drupal::currentUser()->id());}

```
> 0 votes

---
Tags: 8, blocks
---


# Question
Title: How do I list all names of the same group type?
For a Group type (Birds), I tried to create a View in Drupal 9 to list all groups of that type, but I end up getting a group title entry for every node, for example this list.

* Birds groups
    + Hawks
    + Hawks
    + Hawks
    + Jays
    + Jays

I want it to be a group oriented list, and not group member oriented.

* Birds groups
    + Hawks
    + Jays

I'm only a view (an unformatted list) with group relationships. Groups aren't tied to users in any way.

What I tried to do is editing a view that shows nodes and change it to show groups by playing around with relationships from the *Advanced* settings section.

# Answer
If your goal is to show groups, create a view that displays them.

Create a new view from /admin/structure/views/add - in *View settings*, *Show* **Group** *of type* **Birds**.

>
> 1 votes

---
Tags: views, 9, group
---


# Question
Title: Replace placeholder in custom block with preprocess hook
This is the first time I'm using the preprocees hook, apologies in advance.

I added a **placeholder**, `{{user-uid}}`, in a custom block body field, `<a href="advisor/{{user-uid}}">Advisor Page</a></h5>`.

My code is very simple, I have this hook theme.

```
    function boostrap_kampuster_preprocess_block(&$variables) {
        if (isset($variables['content']['#block_content'])) {
            $content = $variables['content']['#block_content'];

            /** custom block ID is 4 **/
            if( method_exists($content,'id') && $content->id() == '4') {

                $body = $variables['content']['body'][0]['#text'];

                $vars['user'] = \Drupal\user\Entity\User::load(\Drupal::currentUser()->id());
                $body=str_replace('{{user-uid}}',$vars['user'],$body);
            }
        }
    }

```

I am not getting any errors but the function is not doing what it is supposed to do and replace `{{user-uid}}` with logged in user's ID either.

FYI, I cleared caches several times.

# Answer
Recommend using @4k4's answer instead.

There are a few issues here:

1. You're setting your `$body` variable, but not setting the change in your `$variables` array. You can fix this by using a reference, update with `$body = &$variables['content']['body'][0]['#text'];`
2. You're replacing with the user object rather than the user id. You can't insert an object into the middle of a string. You can get the id of the current users with just `\Drupal::currentUser()->id()`.
3. I'd recommend not setting the current user to `$vars['user']` in a preprocess function when you're using `$variables` as the accepted parameter. It's pretty common to use `$vars` as a shorthand in a preprocess `$variables` function and randomly setting `$vars['user']` here is definitely going to cause confusion for anyone reading this in the future.
4. I'd also recommend not using `{{ VARIABLE }}` as a custom placeholder since D8 templates use twig and that is twig syntax. For the same reasons you wouldn't use `<?php echo $VARIABLE; ?>` as your custom placeholder.

Your code updated:

```
function boostrap_kampuster_preprocess_block(&$variables) {
  if (isset($variables['content']['#block_content'])) {
    $content = $variables['content']['#block_content'];

    /** custom block ID is 4 **/
    if( method_exists($content,'id') && $content->id() == '4') {
      // These lines updated.
      $body = &$variables['content']['body'][0]['#text'];
      $body = str_replace('{{user-uid}}', \Drupal::currentUser()->id(), $body);
      // As 4k4 pointed out - you must set a cache context or this won't work as expected.
      $variables['#cache']['contexts'][] = 'user';
    }
  }
}

```
> 1 votes

# Answer
In addition to @sonfd answer you also need to consider caching. The easiest way would be to add a cache context:

```
$variables['#cache']['contexts'][] = 'user';

```

But then the database needs to store a cached version for each user.

Better for performance would be to postpone replacing the placeholder by attaching a lazy builder to the render array:

```
function mytheme_preprocess_block(&$variables) {
  $variables['#attached']['placeholders']['{{user-uid}}'] = [
    '#lazy_builder' => ['_mytheme_replace_uid', []],
  ];
}

```

which then returns the markup of the user UID:

```
function _mytheme_replace_uid() {
  return [
    '#markup' => \Drupal::currentUser()->id(),
    '#cache' => ['contexts' => ['user']],
  ];
}

```

**Drupal 9**

Drupal 9 requires using only trusted callbacks. So define a class implementing TrustedCallbackInterface or RenderCallbackInterface:

*mytheme/src/MythemeLazyBuilders.php:*

```
<?php

namespace Drupal\mytheme;

use Drupal\Core\Render\Element\RenderCallbackInterface;

class MythemeLazyBuilders implements RenderCallbackInterface {

  public static function replaceUid() {
    return [
      '#markup' => \Drupal::currentUser()->id(),
      '#cache' => ['contexts' => ['user']],
    ];
  }

}

```

and add it to the render array:

```
function mytheme_preprocess_block(&$variables) {
  $variables['#attached']['placeholders']['{{user-uid}}'] = [
    '#lazy_builder' => ['\Drupal\mytheme\MythemeLazyBuilders::replaceUid', []],
  ];
}

```
> 4 votes

---
Tags: 8, hooks
---


# Question
Title: How can I display the values returned from an external API under a form?
I have created a custom module that pulls in data from an external API. Users select a few values on a form; submitting the form makes a call to the external API. The module then displays the data, which has been filtered by the values entered from users.

I have been able to show the returned data with `\Drupal::messenger()->addMessage()`, but this doesn't seem the right method. I've found a few other suggestions, but I can't get any of them to work. They are for older Drupal versions.

I'd like to be able to display the formatted results under the form, on the same page.

How can I achieve this in Drupal 9?

# Answer
It's not much different from what done with Drupal 7; the difference is the involved classes (which weren't implemented in Drupal 7) and the used methods.

* The submission handler stores the values obtained from the external API and sets the form to be rebuilt
* The form builder verifies the values set by the submission handler are set and shows them

In the case of a class extending the `FormBase` class this means:

* `submitForm()` calls `$form_state->setValue()` to set the value obtained from the external API
* `submitForm()` calls `$form_state->setRebuild()` to tell Drupal the form needs to be rebuilt
* `buildForm()` uses `$form_state->hasValue()` to check the value has been set and `$form_state->getValue()` to get that value

As for showing the returned value, it's sufficient to use a form element similar to the following one.

```
$form['api_value'] = [
  '#type' => 'markup',
  '#markup' => $api_result,
];

```

As side note, the `$key` value passed to `$form_state->setValue()` should not be a value already used for a form element. Differently, `$form_state->setValue()` would set the value submitted for that form element.
> 1 votes

---
Tags: 9
---


# Question
Title: How to pass a field value from a parent node to its entity referenced children nodes when saving the parent node form
Drupal 8

Here is the scenario

I have a Company \> Department \> Employee… in that hierarchy.

Companies are already created previously.

On the Department node add form, there is an entity reference field to reference a Company. On that same Department node form, there is another Entity Reference field that leverages Inline Entity Form to add + reference Employee nodes on the fly. These Employee nodes also have a Company entity reference field.

The goal is to pass the Company field value from the Department node to the referenced Employee nodes when the Department form is saved.

I figure this may be accomplished with the Business rules module, and/or a hook form alter. Tried both without any traction. Any tips?

# Answer
One option is to use hook\_ENTITY\_TYPE\_update() and hook\_ENTITY\_TYPE\_insert().

```
// Top of .module
use Drupal\node\NodeInterface;

function MYMODULE_node_update(NodeInterface $node) {
  _MYMODULE_set_department_employee_company($node);
}

function MYMODULE_node_insert(NodeInterface $node) {
  _MYMODULE_set_department_employee_company($node);
}

function _MYMODULE_set_department_employee_company(NodeInterface $node) {
  if ($node->bundle() == 'department') {
    $dept_company_id = $node->DEPARTMENT_COMPANY_FIELD->target_id;
    foreach ($node->DEPARTMENT_EMPLOYEE_FIELD->referencedEntities() as $employee) {
      // Only update the employee company if it's different.
      if ($employee->EMPLOYEE_COMPANY_FIELD->target_id !== $dept_company_id) {
        $employee->EMPLOYEE_COMPANY_FIELD->target_id = $dept_company_id;
        $employee->save();
      }
    }
  }
}

```
> 1 votes

---
Tags: 8, forms
---


# Question
Title: Image Files Uploaded via REST got Temporary status - Cannot be refereced by Media Image
Drupal 8.9.11

Image File Uploaded via REST gets "status - Temporary" while setting explicitly "status" case to True server error 403 (code in python)

```
   "status": [
      {
        "value": True
      }
   ],

```

The sever returns code 403, an exception:

```
Status: 403, Message: {"message":"Access denied on creating field \u0027status\u0027."}

```

The error on the server: $ vendor/bin/drush watchdog-show

```
access denied Warning Path: /themag_dp8/entity/file?_format=hal_json.
   Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException: Access denied on creating
   field 'status'. in Drupal\rest\Plugin\rest\resou

```

If I'll not specify "status = true" The next REST call to Create Media fails to reference it due to its temporary status.

```
   payload = {
        "name": {
            "value": name
        },
        "field_image": [
            {
                "target_id": file_id
            }
        ],
        "field_description": [
            {
                "value": description
            },
        ],
        "bundle": [
            {
                "target_id": "image"
            }
        ],
        "_links": {
            "type": {
                "href": oauth.base_url + REST_TYPE_MEDIA_IMAGE
            },
            oauth.base_url + "/rest/relation/media/image/thumbnail": [
                {
                    "href": oauth.base_url + "/file/%d" % file_id + FORMAT_HAL_JSON
                }
            ],
            oauth.base_url + "/rest/relation/media/image/field_image": [
                {
                    "href": oauth.base_url + "/file/%d" % file_id + FORMAT_HAL_JSON
                }
            ]
        }
    }

```

```
Status: 422, Message: {"message":"Unprocessable Entity: validation failed.\nfield_image.0.target_id:
This entity (file: 119) cannot be referenced.\n"}

```

Server error: $ vendor/bin/drush watchdog-show

```
access denied Warning
    Path: /themag_dp8/entity/paragraph?_format=hal_json.
    Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException:  in
    Drupal\Core\Routing\AccessAwareRouter->checkAccess() (line 120 of
php           Error
    Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException: Unprocessable Entity:
    validation failed.
    field_image.0.target_id: This entity (file: 119) cannot be referenced.
    in

```

When I manually, via web site admin (https://drupal8.site/admin/content/files), change the file status to "Permanent", this Create Media REST call succeeds to create a new media/image entity.

Seems the Rest user missing some security allowances, but which one? Did anybody succeed to create a node consisting of the teaser image, paragraph video and so?

Sure I'm not the first who attack this issue, where the relevant documentation, working code examples?

# Answer
> 0 votes
The solution I found so far is to fix a Drupal module code:

modules\contrib\file\_entity\src\Normalizer\FileEntityNormalizer.php on line 48 add:

```
$entity->setPermanent();

```

*See:*

# Answer
> 0 votes
You can upload images and create media without the File Entity module and any module fixes.

*Try this:*

New "file\_upload" REST resource plugin: allows file uploads of any size, creates File entities

In your case, the request would be like this:

```
POST /file/upload/media/image/field_media_image?_format=hal_json HTTP/1.1
Content-Type: application/octet-stream
Content-Disposition: file; filename="filename.jpg"

[… binary file data …]

```

And request to create media /entity/media?\_format=hal\_json:

```
{
    "_links": {
        "type": {
            "href": "YOUR_SITE/rest/type/media/image"
        }
    },
    "name": [
        {
            "value": "Image.jpg"
        }
    ],
    "field_media_image": [
        {
            "target_id": YOUR_ID
        }
    ]
}

```

It's works fine.

---
Tags: media, files, 8
---


# Question
Title: How do I create a block in a module that can be referenced via an entity reference field?
I'd like to be able to reference my programmed block as a field in a paragraphs.

I've

* Generated a module with drupal console - drupal generate:module
* Used the template for a block from the example module. Only has Plugin/Block/MyBlock.php

I create a new field in my paragraph

* Field type Reference
* choose other

How do I get the block to be able to be embedded in this way?

# Answer
> 4 votes
To achieve this you may use the Block field:
From module description:

> **Use Cases**
> Add blocks to a node's sidebar.
> Add blocks to paragraph.
> Create a carousel of content and configurable blocks.

1. install and enable the module
2. Create a new field of type **Block(plugin)** in your paragraph type
3. In case you want only your custom block to be referenced in the field settings uncheck all other blocks in the **AVAILABLE BLOCKS** config like this for my **Hello block** for exemple
4. now you can reference your block in the paragraph.

---
Tags: blocks, paragraphs, plugins
---


# Question
Title: Check if the connection to the database is available
I have 2 databases, the first one with Drupal and the second one with external data. In a controller I want to read data from that second database and display it.

As the external database can be available or not, **is there any method to check if the connection is available or not**?

My code is working, but if the DB is not available (or unset) I get the following error:

> Drupal\Core\Database\ConnectionNotDefinedException: The specified database connection is not defined: schedules in Drupal\Core\Database\Database::openConnection() (line 364 of core/lib/Drupal/Core/Database/Database.php).

Code:

```
abstract class AbstractSchedulesRepository {

  /**
   * Schedules repository target.
   */
  public const SCHEDULES_REPOSITORY_TARGET_DATABASE = 'default';

  /**
   * Schedules repository key.
   */
  public const SCHEDULES_REPOSITORY_KEY_DATABASE = 'schedules';

  /**
   * Drupal\schedules\Repository\SchedulesCache definition.
   *
   * @var \Drupal\schedules\Cache\SchedulesCache
   */
  protected $schedulesCache;

  /**
   * Drupal\Core\Language\LanguageManager definition.
   *
   * @var \Drupal\Core\Language\LanguageManager
   */
  protected $languageManager;

  /**
   * Drupal\Core\Database\Connection definition.
   *
   * @var \Drupal\Core\Database\Connection
   */
  protected $connection;

  /**
   * Constructor.
   *
   * @param \Drupal\schedules\Cache\SchedulesCache $schedulesCache
   *   Schedules cache.
   * @param \Drupal\Core\Language\LanguageManager $languageManager
   *   Language manager.
   */
  public function __construct(SchedulesCache $schedulesCache, LanguageManager $languageManager) {
    $this->schedulesCache  = $schedulesCache;
    $this->languageManager = $languageManager;
    $this->connection      = Database::getConnection(self::SCHEDULES_REPOSITORY_TARGET_DATABASE, self::SCHEDULES_REPOSITORY_KEY_DATABASE);
  }

```

# Answer
> 2 votes
> is there any method to check if the connection is available or not?

If you mean class method, then no, because it wouldn’t be necessary. You can simply catch the exception, which will tell you immediately that the connection was not successful:

```
try {
  // Code using a database connection
} catch (ConnectionNotDefinedException $e) {
  // No database for you
}

```

---
Tags: 8, database
---


# Question
Title: Custom field validator comparing original and new values
In my validator, I need to compare the new field value, that was submitted by the user, with the old value. How can I get the original value?

So far, I have this:

```
class CompareNewOldValuesValidator extends ConstraintValidator {

  public function validate($item, Constraint $constraint) {

    if (empty($item->getValue())) {
      return;
    }
    $value_new = $item->getValue()[0]['value'];

    /** @var ContentEntityInterface $entity */
    $entity = $item->getEntity();
    if (!$entity->isNew()) {
      $value_original = '???';
    }
  }
}

```

I need to get the field value that was filled in the form before the user changed it, no matter if it is the active version or a draft or an old revision.

# Answer
Normally the original entity is stored in the entity object before the user input is applied. If not, you can get it via the loaded revision id, which is preserved when an entity is loaded to keep it save from changes:

```
if (isset($entity->original)) {
  $original = $entity->original;
}
else {
  $original = \Drupal::entityTypeManager()
    ->getStorage($entity->getEntityTypeId())
    ->loadRevision($entity->getLoadedRevisionId());
}

$value_original = $original->{$item->getFieldDefinition()->getName()}->value;

```
> 5 votes

# Answer
I got the old value. I'll share my solution.

```
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityRepositoryInterface;

class CompareNewOldValuesValidator extends ConstraintValidator {

  public function validate($item, Constraint $constraint) {

    if (empty($item->getValue())) {
      return;
    }
    $value_new = $item->getValue()[0]['value'];

    /** @var ContentEntityInterface $entity */
    $entity = $item->getEntity();
    if (!$entity->isNew()) {
      $entity_old = $this->entityRepository->loadEntityByConfigTarget($entity->getEntityTypeId(), $entity->getConfigTarget());
      $value_old = $entity_old->get($item->getName())->value;
    }
  }
}

```
> 2 votes

---
Tags: 8, forms
---


# Question
Title: Issue installing module via composer. - "package is fixed"
I've installed Drupal via Composer as well as 2 other modules and everything seemed ok. But now I tried installing Nodeaccess and get the following error message in console:

```
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Root composer.json requires drupal/nodeaccess ^1.0 -> satisfiable by drupal/nodeaccess[1.0.0].
    - drupal/nodeaccess 1.0.0 requires drupal/core ^8 -> found drupal/core[8.0.0, ..., 8.9.13] but the package is fixed to 9.1.4 (lock file version) by a partial update and that version does not match. Make sure you list it as an argument for the update command.

Use the option --with-all-dependencies (-W) to allow upgrades, downgrades and removals for packages currently locked to specific versions.

Installation failed, reverting ./composer.json and ./composer.lock to their original content.

```

and I don't know how to proceed. Any clues? T.I.A.

# Answer
Ok, right answer was given by @Clive as Nodeacces module is not yet announced as ready for Drupal 9 (despite being worked out https://www.drupal.org/project/nodeaccess/issues/3130778). So I believe (I'm not sure because I can't understand the composer error message) that's the reason for the error message I got.

Sorry for posting an inappropriate question, and thank you for the comments.
> 0 votes

---
Tags: composer, 9
---


title: Webform and TypeForm

text:
# Question
Title: Webform and TypeForm
How would I add an image to a Drupal Webform?

# Answer
> 2 votes
The trick to including anything in a Webform is to use the "Advanced HTML/Text" element, which allows you to utilize Drupal's Text Format functionality to embed any media, including videos.

---
Tags: webforms
---


# Question
Title: Cannot get form_state storage or protected form values to work
I am building a form using formBuilder. I have tried two methods to store values across form submit/validate for usage in ajax callbacks, but have been unsuccessful in either.

The first method, was to store a value in $form\_state-\>set('name','value'); and retreiving it in the form submit/validate handler. That returned an empty result.

The second method was to store a variable on the class itself `protected $image_deltas = 0;` and then when the ajax form submit/validation is triggered, $this-\>image\_deltas++; However, when I do this, it still does not work.

The following is the code I am using.

```
$form['images'] = [
  '#type' => 'container',
  '#id' => 'images',
];

dpm($this->image_deltas);

for ($i=0;$i<=$this->image_deltas;$i++) {
  $form['images'][$i]['image'] = [
    '#type' => 'textfield',
    '#title' => t('Image Path:'),
  ];
}

$form['add_another'] = [
  '#type' => 'button',
  '#value' => t('Add Another Image'),
  '#ajax' => [
    'callback' => [$this, 'addAnotherImage'],
    'wrapper' => 'images',
  ],
  '#submit' => [$this, 'addAnotherImageSubmit'],
  '#limit_validation_errors' => [],
];

```

The form submission handler is the following.

```
public function addAnotherImageSubmit(&$form, FormStateInterface $form_state) {
  $this->image_deltas++;
  $form_state->setRebuild();
}

```

The AJAX callback is the following one.

```
public function addAnotherImage(&$form, FormStateInterface $form_state) {
  return $form['images'];
}

```

When I submit the form, `dpm()` prints *0* every time. The same thing happens if I use `$form_state->set('image_deltas')` and `$form_state->get('image_deltas')`.

# Answer
This:

```
'#submit' => [$this, 'addAnotherImageSubmit'],

```

Should be this:

```
'#submit' => [[$this, 'addAnotherImageSubmit']],

```

Submit handlers are only called for #type `submit` and not #type `button`, so you'll need to change the type.

You will also need to use $form\_state-\>set(), rather than a property on the class. This is because the form class is re-instantiated for each iteration (build, validate, submit), and therefore values stored in the properties of the form class will not persist. $form\_state-\>set() persists values, as these are stored in the database, and are repopulated for each instance of the form class (as long as you call $form\_state-\>setRebuild() as you have done).
> 1 votes

---
Tags: 8, forms
---


title: Seeing PHP info twice in status report

text:
# Question
Title: Seeing PHP info twice in status report
On the status report page of a drupal site we run with 7.78, the PHP version number gets reported twice. We have only setup 1 PHP instance in IIS with version 7.3.24.

How do I correct this to pull from the right PHP instance.

# Answer
This is perfectly normal.

Every module you have enabled declares its own set of requirements. In your case, it seems that one module requires a version of PHP greater than the Drupal 7 default minimum PHP version of 5.2.4. Because of this, you will see two entries in the status report:

The first entry shows you what version of PHP you are using. This is always present.

The second entry shows you a status message from one of your enabled modules. This also shows you the version of PHP you are using, but in a slightly different format. This is only present if you have a module that checks the PHP version in `hook_requirements()`.

If you want to find out which module you are using requires a non-standard PHP version, search your modules directory for `hook_requirements`. This is usually found in the `<modulename>.install` file for the module.

You will commonly see multiple entries for a variety of things. In my experience, the most common (in Drupal 7) is for cURL support - many modules require cURL, so you may see two, three, four or even more lines in the status report that tell you cURL is enabled. Again, perfectly normal.
> 1 votes

---
Tags: 7, status-messages
---


# Question
Title: How can I use one of the pre-set email texts for user registration in a custom module
At /admin/config/people/accounts, there are several stock email messages set.

How can I use one of these when I am sending emails from a custom module?

The text that's being used in "Welcome (new user created by administrator)" is all that I need, plus there's the bonus that our client can edit this email in the future if they want to.

I can send the message easily enough using:

```
$params = [
   'title' => "My Title",
   'subject' => "An Account Has Been Created for you",
   'message' => Html::escape("Some text here")
 ];

$result = $mailManager->mail($module, $key, $to, $language_code, $params, NULL, true);

```

Is there a variable somewhere to get the pre-entered text?

# Answer
I guess this should be possible via configuration API. Look for the suitable entry where the message body is saved, call it via the service to put it into a variable. Then you can do additional coding with the string variable. More information you can find here: Configuration override system in the docs
> 0 votes

# Answer
All emails in Drupal are uniquely identified by their sending module and key. In the case of the welcome message for admin-created users, the sending module is `user` and the key is `register_admin_created`. This is all you need. The subject and the message body is defined by the sending module and you don't need access to it in order to send the message.

If you want to send this message from your own module, the correct way to do it is: `\Drupal::service('plugin.manager.mail')->mail('user', 'register_admin_created', $to, $langcode);` where `$to` is a string containing the email address of the recipient, and `$langcode` is a RFC 5646 language code. There are also a few optional parameters you can pass to `mail()`. See the MailManager::mail() API documentation for more information about how to use `mail()` and what the arguments mean.

Also note that if you are calling `mail()` from object-oriented code, you really should inject the `plugin.manager.mail` service instead of using the static `\Drupal` call shown above. But explaining that is outside the scope of this question.
> 0 votes

# Answer
Thanks for the guidance on this @dercheffe. I found what I needed in the config file user.mail.yml and was able to pull the strings outs as an array with :

`$config_txt = \Drupal::config('user.mail')->get('register_admin_created');`

However, I had the problem of how to replace the user and site variables in the strings from the config file.

Long story short, I didn't even need that config information.

The answer was to just use the Drupal function

`_user_mail_notify('register_admin_created', $newuser);`

The email is sent out based on the text in the configuration to our new user.
> -1 votes

---
Tags: 8, emails
---


# Question
Title: Check if the user has read a node, if so give access to the next
Is there a module which can check if an user has read a node? For example, I have this node:

1. Node order 1
2. Node order 2 (locked)
3. Node order 3 (locked)
4. Node order 4 (locked)

If the user read 'node order 1' or marked as read with a button, he has access to 'node order 2'. If 'node order 2' has marked as read, he has access to 'node order 3'.

It's all user based. It's similar to an e-learning structure, but I don't like heavy modules like: course or opigno for just this functionality.

Can I do something like this with rules or an other lightweight module? I saw the flag module, but I don't know if it possible to do something like this with that module?

# Answer
I'd say you can use hook\_ENTITY\_TYPE\_view to store the uid and the nid of the user into a custom table. That would solve the easy part, I believe.

You'd may start by something similar to

```
function yourmodule_node_view(array &$build, \Drupal\Core\Entity\EntityInterface $entity,
        \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display, $view_mode) {

  $bundle = $entity->bundle();
  if($bundle == 'your_content_type') {
    $uid = \Drupal::currentUser()->id(); // get current user's ID
    $nid = $entity->get('nid');
    [...] // insert into custom table, etc
  }
}

```

For the long-term, complex solution regarding performance, that's a huge discussion. If your node list is just a simple queue that unlocks next node if previous has been read, then maybe storing just the current nid would work for you. If you need the history per user, then, as mentioned, some different solutions could do the trick. Other approach could be to do database sharding, for instance creating 1 table per node so table\_read\_nid\_1 would just contain the users who actually have read this node and can unlock the second. table\_read\_nid\_2 would contain the next and so on. Don't be afraid of sharding, lots of big companies use it daily! :)
> 0 votes

---
Tags: 8
---


title: image 404 error (via JSON:API)

text:
# Question
Title: image 404 error (via JSON:API)
My 'gatsby develop' command fails as image files (coming from Drupal 8) are returning a 404 error - I don't understand why (this is new)

== Details: ==

JSON:API (which Gatsby uses to build the site), uses this URL: https://dev-tuckel.pantheonsite.io/jsonapi/file/file

it provides this image URL:

https://dev-tuckel.pantheonsite.io/sites/default/files/2020-08/mckenzie%20falls.jpg

Which returns a 404. There are at least 3 other images that are returning a 404 error - this is strange.

== Investigation: ==

In: content\> Files: the file is 165.17 KB, which is strange, as I ussually upload higher quality images.

it also says it has 1 "use count", however the "entity" field is empty (again, not usual)

I cleared the Admin \> Performance cache (thinking it's may a thumbnail / cache file error).

The site is hosted in the free dev tier of pantheon.

Prior: I was not working on Drupal at the time of failure, I was working on Gatsby code.

If you have any ideas, it would really help because I'm stumped.

# Answer
I was able to delete the files via JSON:API (thank god that exists) using Postman.

The FIDs were: 1,2,8,9 - indicating that the files were very early on in the development of the site. I think they may have belonged to article content types that were recently removed (and therefor orphaned) - however I was still able to build the gatsby sites after this.

However, I think it was straight after I deleted the .cache folder from the Gatsby build that I had this issue, so it's possible that I had the images cached, they were then orphaned (during deletion of the 'article' content type.). Although I would have expected that Drupal would have done appropriate deletion of files and records when removing a content type.
> 1 votes

---
Tags: 8
---


# Question
Title: Is there a hook that could manipulate the list of field items before the field is built?
I am currently porting a custom field module from Drupal 7 to 8. The field (Topic Access) has 3 select fields, typically about 10 to 20 items per field, and uses a custom widget. When the form is loaded, I typically insert several "inherited" items to the field before displaying it. When saving, only the items that vary from the inherited ones are actually saved to the database.

In Drupal 7, I used `hook_field_load()` to add these "inherited" items to the form. As explained on Dynamic/Virtual field values using computed field property classes, that hook has been removed from Drupal 8 in favor of computed field properties.

I can't see an elegant way to manipulate the list of items. I could use `hook_form_alter()` on the forms that contain the field to update `$form['field_topic_access']['widget']`. However, it would end up duplicating code from the widget and have to specifically pick out the fields by name.

Is there a hook that could manipulate the list of field items before the field is built?

# Answer
> 0 votes
What about `hook_entity_prepare_form()`? This simple example loaded an extra item into the form.

```
function mymodule_entity_prepare_form($entity, $operation, $form_state){
  if ($entity->bundle() == 'domain_groups') {
    $items = $entity->get('field_topic_access')->getValue();
    //just a hardcoded item for test purposes
    $demo_item=['topic_tid'=>'74','available_to_group'=>'1', 'publish_to_group'=>'0'];
    $items[] = $demo_item;
    $entity->set('field_topic_access', $items);
  }
}

```

There may be a more elegant solution but I could use this hook to show my inherited items and `hook_entity_presave()` to remove inherited values before saving.

---
Tags: entities, forms
---


# Question
Title: How to union two views and pass on arguments
I want to union two views and pass on arguments from the first to the second view. Below is what I have so far. Not sure, if this is working. At least the bit to pass on arguments is still missing. Any ideas what I should put in the code?

```
use Drupal\views\Views;
use Drupal\views\ViewExecutable;

/**
 * Implements hook_views_pre_execute().
 */
function mymodule_views_pre_execute(ViewExecutable $view) {
  if ($view->id() == 'music_by_year' && $view->current_display = 'block_2') {

    $view_by_author = Views::getView('music_by_author');
    $view_by_author->setDisplay('block_1');
    $view_by_author->build();

    $query_by_author = $view_by_author->build_info['query'];

    $query_by_year = &$view->build_info['query'];
    $query_by_year->union($query_by_author);
  }
}

```

# Answer
> 2 votes
What you can do is to load and execute the $view\_by\_author view as you are doing but passing the by\_year arguments/contextual as this:

```
$arguments = [$view_by_year->build_info['parameter_you_need']];

$view_by_author = Views::getView('music_by_author');
$view_by_author->setArguments($arguments);
$view_by_author->setDisplay('block_1');
$view_by_author->preExecute();
$view_by_author->execute(); // or build, etc

```

I believe something like this would work for you.

Also, there is a module called Views Field View that might do what you are trying to do.

---
Tags: 8
---