# Question
Title: How do I find out which what fields are available?
I'm looking to access the values of the fields in `postSave()`.

```
public function postSave(WebformSubmissionInterface $webform_submission, $update = TRUE) {
  //what's in $webform_submission? can I use it to get field data that was saved/submitted?
}

```

How do I get which fields are available from `$webform_submission`? How do I access them?

I have a field whose machine name is \*feedback\_type. I need to access its properties from that function.

**UPDATE**

So essentially what I'm wondering is, is there a way to see the structure of the $webform\_submission variable? so that I can retrieve the data that the user submitted? I'd prefer to be able to do a print of it whether that's to a file/log/etc. doesn't matter I'd just like to know the structure of the $message\_submission and its fields.

# Answer
> 0 votes
Might depend a little on what you're trying to do with those fields (get info/set info/adjust info), but here are a couple of things you could try:

**CustomHandler.php**

For submission data:

```
/**
 * {@inheritdoc}
 */
public function postSave(WebformSubmissionInterface $webform_submission, $update = TRUE) {

  // Get the submitted webform data.
  $data = $webform_submission->getData();

  // Get specific submission value.
  $myFieldValue = $data['field_name']
}

```

For webform field values (e.g. type = radios):

```
/**
 * {@inheritdoc}
 */
public function postSave(WebformSubmissionInterface $webform_submission, $update = TRUE) {

  // Get the webform fields (which will contain properties/attributes/values/etc.).
  $elements = $webform_submission->getWebform()->getElementsDecoded();

  // Get field values.
  $fieldType = $elements['field_name']['#type'];
  $fieldTitle = $elements['field_name']['#title'];
  $fieldFirstOption = $elements['field_name']['#options'];['option_one'] // If you need the selected value that will be in ->getData(), or in ['#return_value'] key.

  // Get webform owner (not anonymous).
  $webformOwner = $webform_submission->getWebform()->getOwner();

  // Get owner values.
  $displayName = $webformOwner->getDisplayName();
  $userName = $webformOwner->getUsername();
  $userEmail = $webformOwner->getEmail();

  // And to set data values:
  $data = $webform_submission->getData();
  $data['myNewValue'] = $myNewValue;
  $webform_submission->setData($data);

  // If you need to find some other available methods, try:
  kint($webform_submission->getWebform());
}

```

Fields on the webform, e.g. `feedback_type`, `your_email`, `first_name` will be available inside the method `->getElementsDecoded()`.

---
Tags: 8, webforms
---


title: Can't place a custom block

text:
# Question
Title: Can't place a custom block
After adding a block file to src/Plugin/Block I can't add the block on the Block Layout admin page. When I filter by block name I can see it, but then when I try to place it I can't get to the configure block screen (pressing the 'Place block' button produces no effect). I do not get any errors.

What could be the reason for such a behaviour?

The block file contents:

```
    <?php

namespace Drupal\Core\Block\BlockBase;
use Drupal\Core\Link;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Provides a block with a link to start the toru.
 *
 * @Block(
 *    id = "iai_tour_link",
 *    admin_label = @Translation("Link for the IAI Product Guide tour"),
 *    category = @Translation("Links"),
 *    context = {
 *       "node" = @ContextDefinition(
 *         "entity:node",
 *          label = @Translation("Current Node")
 *        )
 *     }
 *   )
 */
class TourLinkBlock extends BlockBase implements ContainerFactoryPluginInterface{
    /**
     * The current user.
     *
     * @var \Drupal\Core\Session\AccountInterface;
     *
     */
    protected $currentUser;

    /**
     * Constructs an TourLinkBlock object.
     *
     * @param array $configuration
     * A configuration array containing information about the plugin instance.
     * @param string $plugin_id
     * The plugin_id for the plugin instance.
     * @param mixed $plugin_definition
     * The plugin implementation definition.
     */
    public function __construct(array $configuration, $plugin_id, $plugin_definition, AccountInterface $current_user){
        parent::__construct($configuration, $plugin_id, $plugin_definition);
        $this->currentUser = $current_user;
    }

    /**
     * {@inheritdoc}
     */
    public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition){
        return new static(
            $configuration,
            $plugin_id,
            $plugin_definition,
            $container->get('current_user')
        );
    }

    public function build(){

        $node = $this->getContextValue('node');
        if ($this->currentUser->hasPermission('access tour') && $node->getType() == 'book'){
            $url = Url::fromRoute('<current>', array(), array('query' => array('tour' => 1)));
            $build['tour_link']= [
                '#type' => 'markup',
                '#markup' => Link::fromTextAndUrl(t('Take the tour!'), $url)->toString(),
            ];
            $build['#attached']['library'][] = 'tour/tour';
            return $build;
        }
    }
}

```

# Answer
> 1 votes
Fix the namespaces:

delete: namespace Drupal\Core\Block\BlockBase;

add: namespace Drupal\MY\_COOL\_MODULE\Plugin\Block; use Drupal\Core\Block\BlockBase;

---
Tags: 8, blocks, plugins
---


# Question
Title: Google Analytics module is not tracking site search
I have a site that is using the Google Analytics (GA) module. It's happily tracking data to GA. However, I can't seem to get Site Search working.

The site uses Apache Solr. A search results page for the query "test" is: /sitesearch/test

1. I've enabled "Track internal search" in the Google Analytics module config page
2. I've enabled "Site search Tracking" in GA
3. I've set the query parameter to "sitesearch" in GA
4. I've unchecked "Strip query parameters out of URL" in GA
5. I've confirmed that if I manually hit this URL, it pings a track in GA: /sitesearch/test?sitesearch=test (Any URL on the site with ?sitesearch=test works.)

I'm out of ideas. What could be causing this to fail?

# Answer
> 1 votes
The problem is that Google Analytics only supports site search tracking if the path is "search/something", not "sitesearch" as we use on my client's site.

Line 138ish from googleanalytics.module:

```
if (module_exists('search') && variable_get('googleanalytics_site_search', FALSE) && arg(0) == 'search' && $keys = search_get_keys()) {
  $url_custom = '(window.googleanalytics_search_results) ? ' . drupal_to_js(url('search/'. arg(1), array('query' => 'search='. drupal_urlencode($keys)))) . ' : ' . drupal_to_js(url('search/'. arg(1), array('query' => 'search=no-results:'. drupal_urlencode($keys) .'&cat=no-results')));
}

```

# Answer
> 0 votes
looks like query param changed to "keys" so that should be updated in the GA interface

---
Tags: 6, search, google-analytics
---


# Question
Title: How do I retrieve a menu using its link?
Let say I have a menu item with these attributes

```
'title' => 'Menu Title',
'link' => ['uri' => 'internal:/taxonomy/term/1217'],
'menu_name' => 'my-menu',
'expanded' => TRUE,

```

I can find all the menus by their title, e.g.,

```
 $menu_links = \Drupal::entityTypeManager()->getStorage('menu_link_content')
                ->loadByProperties(['title' => 'Menu Title']);

if ($menu_link = reset($menu_links)) {
// Get the pid of the first menu
    $menu_pid = $menu_link->getPluginId();
}

```

Then I tried to retrieve menu by the link property, and I couldn't. I tried:

```
 $menu_links = \Drupal::entityTypeManager()->getStorage('menu_link_content')
                ->loadByProperties(['link' => array('uri' => 'internal:/taxonomy/term/1217')]);

 $menu_links = \Drupal::entityTypeManager()->getStorage('menu_link_content')
                ->loadByProperties(['link' => ['uri' => 'internal:/taxonomy/term/1217']]);

 $menu_links = \Drupal::entityTypeManager()->getStorage('menu_link_content')
                ->loadByProperties(['uri' => 'internal:/taxonomy/term/1217']);

```

None of them worked.

# Answer
Try the property `link.uri`:

```
$menu_links = \Drupal::entityTypeManager()->getStorage('menu_link_content')
  ->loadByProperties(['link.uri' => 'internal:' . $path]);

```
> 5 votes

# Answer
This worked for me:

```
$link = 'entity:node/' . $node->id();
$menulinks = \Drupal::service('entity.manager')->getStorage('menu_link_content')
    ->loadByProperties(['link.uri' => $link]);

```

So I think you should try `'entity:'` instead of `'internal:'`
> 0 votes

---
Tags: 8, navigation
---


# Question
Title: Do private properties persist between submissions on multi-step form?
I'm creating a 3-step (3-page) form in Drupal 8. One property I use for all three pages is $continue - which triggers an exit process (redirect) if an error condition is encountered, or allows the process to continue through all three pages. Also, there is a node created during submitForm() in step 1, and the node id is needed in steps 2 and 3.

I'm struggling with exactly how to pass data of that nature through the multiple steps. Initially, the form is built, and properties can be initialized in the constructor. But after the user submits the form, that's an entirely new request, right? So doesn't the form class have to be instantiated again before the submitForm() method is invoked? If so, it doesn't seem like properties could persist from buildForm() to submitForm() and back to the buildForm() for step 2?

In Drupal 7, I had to save all values I wanted to persist into $form\_state. Do I still need to do the same in Drupal 8?

# Answer
Yes, do the same in D8, use $form\_state. There is one caveat though. The form object and form state doesn't persist for the original form build. This was removed in the early stages of Drupal 8, because the form cache table was growing too fast. Since then forms are only cached after the first rebuild.

Normally this isn't a problem. If you store for example the form step in $form\_state and it is initialized again with 1, but you have a form action triggered incrementing it to 2, your form then can use the cached $form\_state to move back and forth.

This doesn't work however for data no longer available in later rebuilds. In this case use a hidden form value which will be cached together with the rendered form. Add the correct cache metadata for this value so that the rendered form can be invalidated when the value is changed.
> 0 votes

---
Tags: forms
---


# Question
Title: Does "hook_ENTITY_TYPE_load" have performance advantages over "hook_entity_load"?
I googled *Drupal 8 `hook_ENTITY_TYPE_load` faster than `hook_entity_load`*, but got no information on the question.

I was told that putting an entity type in the hook name is faster than putting an `if` statement for the entity type inside `hook_entity_load()`. This makes sense to me, but I want to make sure.

I also have a subscription to drupalize.me and couldn't find anything that supports the possibility of `hook_ENTITY_TYPE_load()` being faster than `hook_entity_load()`. In fact, it tells me to use `hook_entity_storage_load()` for that purpose.

# Answer
> 0 votes
There is no difference in the overhead. The only difference is that one is called earlier than the other. I can't remember which off the top of my head though.

# Answer
> 4 votes
The only difference is that `hook_entity_load()` is invoked for every entity loaded, while `hook_ENTITY_TPE_load()` is invoked for every entity for which the entity type is *ENTITY\_TYPE*.
If a module implemented `hook_entity_load()` only to handle a specific entity type, or a group of entity types, but not every entity type, its `hook_entity_load()` implementation would need to check which entity is being loaded, but since the second argument passed to the hook (`$entity_type_id`) is the entity type, checking that isn't time consuming nor a performance issue.

As for using `hook_entity_load()` or `hook_entity_storage_load()`, the second hook is invoked for content entities (not configuration entities) with a storage handler that saves the data in the database. In the other cases, including entities loaded from the entity cache, only `hook_entity_load()` is invoked.

---
Tags: 8, entities
---


# Question
Title: How to display data without html on ajax call?
How to display only content on ajax hit without html markup?

what i am trying to do i have to show data on button click in profile dashboard(custom page) ,for this i have created controller file .

```
class OutstandingPaymentPending extends ControllerBase {
  // callback for learning portal access
  public function GetPendingPayment() {
    /* TO DO
     * Making api dynamic via configuration
     */
    global $base_url;
    $user_id = \Drupal::currentUser()->id();
    $psid = '';
    $psid_request = \Drupal::request()->get('ds');
    if (!empty($psid_request)) {
      $psid = $psid_request;
    }
    else {
      $psid = get_psid_by_user_id($user_id);
    }
    // Get outstanding data from api
    $url = OUT_STANDING_API . '?PSID=' . $psid;
    //$url = OUT_STANDING_API . '?PSID=00002449846';
    $access_token = API_ACCESS_TOKEN;
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('AccessToken:' . $access_token));
    $response = curl_exec($ch);
    $err = curl_error($ch);
    curl_close($ch);
    $rows = array();
    $result = json_decode($response);

    $result = trim($result, '"');
    if (trim($result) == 'No data found') {
      $rows = array();
    } else {
        $outstanding_result = json_decode($result);
         $course_count = 1;
        $rows = [];
        if (!empty($outstanding_result)) {
        foreach ($outstanding_result as $key => $value) {
          //if ($outstanding_result->ResponseCode != 401) {
          $rows[] = array('course_name' => $outstanding_result[$key]->CRSNAME,
            'course_validity' => $outstanding_result[$key]->VALIDITY,
            'course_type' => $outstanding_result[$key]->COURSETYPE,
            'course_installment_date' => $outstanding_result[$key]->INSTDT,
            'course_total_outstanding' => $outstanding_result[$key]->TOTALOUTSTANDINSTAMT,
          );
          //}
        }
      }
    }

    return array(
      '#theme' => 'pending_installment_template',
      '#installment' => $rows
    );
  }
  }

```

My ajax code is:

```
//ajax for showing installment payment pending block on click
$(document).on('click', '#gettoptracks', function (e) {
    e.preventDefault();
    $.ajax({
        url: "/outstanding-payment-left",
        context: document.body,
        success: function (data) {
            $("#show-pending-payment").html(data);

        }
    });
    // your statements;
});

```

On clicking ajax based button its rendering entire page along with data with all html, so js files and css rendering two times in same page .

how i can show only data instead of entire page html which is rendering on page.html.twig?

# Answer
> 1 votes
I have done this in a custom controller before. You don't want to return a render array, because Drupal will take the default action.

Instead, you want to render it to HTML (string) and return that back. Something like this:

```
$rendered = $this->renderer->renderRoot($build_array);
$response = new Response();
$response->setContent($rendered);
return $response;

```

As far as the Javascript, here is a generic example using fetch (in a twig file):

```
  <script>
    fetch("{{ auth_url }}", { credentials: "include" })
      .then(
        function(response) {
          if (response.status !== 200) {
            console.log('Looks like there was a problem. Status Code: ' + response.status);
            return;
          }

          response.text().then(function(data) {
            document.getElementById("authorize-banner").innerHTML = data;
          });
        }
      )
      .catch(function(err) {
        console.log('Fetch Error :-S', err);
      });
  </script>

  <div id="authorize-banner"></div>

```

You also likely don't want to cache the render array either. You can also greatly simplify the API fetch code by using Guzzle (Client) instead of curl.

---
Tags: 8, ajax
---


# Question
Title: Load a CSS file only for anonymous users visiting the front page
I want to load a CSS file only for the front page, and only for users who didn't log in. Both conditions should be met; in the other cases, the CSS file should not be added to the page.

How do I achieve this in a preprocess function?

# Answer
While using a preprocess function can also solve this, here is the template file approach.

Copy template file page.html.twig and rename the copy to page--front.html.twig

Assuming you have already defined a library for your .css file.

In page--front.html.twig add

```
{% if not logged_in %}
    {{ attach_library('theme_name/library-name') }}
{% endif %}

```
> 4 votes

# Answer
There are two steps to this:

1. Creating a library that references the CSS file
2. Attaching that library to the front page

Let's assume your module is named `example`, and the css file is 'example/css/example\_front\_page.css\`. First, the libraries file needs to be created, declaring the CSS file.

example.libraries.yml:

```
front_page:
  css:
    theme:
      css/example_front_page.css: {}

```

Read more: https://www.drupal.org/docs/8/creating-custom-modules/adding-stylesheets-css-and-javascript-js-to-a-drupal-8-module

Next, you can implement hook\_page\_attachments to attach the library:

```
function example_page_attachments(array &$attachments) {

  // Check if on front page.
  if ( \Drupal::service('path.matcher')->isFrontPage() && \Drupal::currentUser()->isAnonymous()) {
    // This is the front page, so the library is attached.
    $attachments['#attached']['library'][] = 'example/front_page';
  }
}

```
> 4 votes

---
Tags: 8, theming
---


# Question
Title: Check if there are any elements with a certain class in the form array of unknown depth
I'm new to Drupal and still have to figure out a lot. This might also be just a general programming question.

I wrote a module that has some js-libraries which should be attached to forms on different conditions. For one of those libraries, I want to add it in case the form array has an element with the class "remove-button", which could be at any depth.

I searched for different recursive approaches, but it doesn't work somehow. I was able to attach the library without a condition so it attaches to all forms, so the problem lies within my recursive function.

Snippet from hook\_form\_alter in my .module file:

```
function my_module_form_alter(&$form, \Drupal\Core\Form\FormStateInterface &$form_state, $form_id)
{
  // remove-button
  $hasRemoveButton = containsClass($form, 'remove-button');
  if ($hasRemoveButton) {
    $form['#attached']['library'][] = 'my_module/remove-button';
  }
}

```

Recursive search function (last code I tried):

```
/**
 * Search a class in $form.
 */
function containsClass($array, $class)
{
  if (!is_array($array)) {
    return false;
  }
  if (isset($array['class']) && in_array($class, $array['class'])) {
    return true;
  }
  foreach ($array as $subarray) {
    containsClass($subarray, $class);
  }
}

```

Anyone an idea how this can be achieved? Maybe with a different approach than a recursion?

# Answer
You can try this for your recursive function.

```
function containsClass($array, $class) {
  if (is_array($array)) {
    if (in_array($class, $array['class'])) {
      return true;
    }

    foreach ($array as $element) {
      if (containsClass($element, $class)) {
        return TRUE;
      }
    }
  }

  return FALSE;
}

```

The problem with your function was that it's not returning the result of containsClass() when it's called recursively. However, you only want to return the value if it's TRUE, which is why I added the conditional to check that. Finally, after all items have been looped through, if no TRUE value is found, FALSE should be returned.
> 0 votes

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


title: How do I implement a sub-module?

text:
# Question
Title: How do I implement a sub-module?
I can't find anywhere documentation on how to create a sub-module inside a module in Drupal 8. I have created a custom module for translations I am trying to enable as sub-module.

In the main module, can I simply create a *sub\_modules* folder and place my sub-module, including the submodule.info.yml file and the translations folder? I'm guessing I have to add something into my mainmodule.info.yml file but I have not found anything to help me.

# Answer
Drupal doesn't have the concept of sub-modules. It just happens that it looks for modules in the directories where it expects to find modules, recursively. For example, if you install the CAPTCHA module, Drupal will find also the Image CAPTCHA module, and allow you to install it.

Drupal will not install it automatically, nor will it handle it differently from any other module. This means, for example, that the module still needs to declare its dependency from the CAPTCHA module, if it requires it, which is what the *Image CAPTCHA* module does in its image\_captcha.info.yml file.

```
name: Image CAPTCHA
type: module
description: Provides an image based CAPTCHA.
package: Spam control
core: 8.x
dependencies:
  - captcha
configure: admin/config/people/captcha/image_captcha

```

Usually, developers put any "sub-module" in the *modules* directory, but this is not required from Drupal, nor is it followed by every developer.
> 5 votes

---
Tags: 8
---


# Question
Title: How can I override or alter a module's help text?
I am trying to override or alter Layout Builder's default help text. Is is possible to do this? If so, how?

I have added some help text in a hook\_help() function in a custom module but I can only get it to add to Layout Builder's help text. I can't find a way to override the default text.

# Answer
I don't recall doing exactly this, but I think you can use a `hook_module_implements_alter()` for this:

```
function MYMODULE_module_implements_alter(&$implementations, $hook) {
  if ($hook === 'help') {
    unset($implementations['layout_builder']);
  }
}

```

This should disable `layout_builder_help()`, and then just yours will run. A `hook_help_alter()` would be nice, but I don't recall ever seeing an issue for it.
> 2 votes

---
Tags: 8
---


# Question
Title: Get interface translation LID (Locale Id?) using source string value
I'm using **User interface translation** in English to override system strings like Drupal 7's **String Overrides** module did. Works great. However, in my custom module, as I edit strings that run through the t() function, the **Source string** table in **User interface translation** is filling up with unused strings.

I'm writing a simple function to delete unwanted source strings one-by-one. The post at http://www.drupal8.ovh/en/tutoriels/89/delete-a-source-string-and-target-translations-drupal-8 provides code for deleting a translation once you know the LID (Locale Id?), which it suggests you get by inspecting the HTML of the displayed **User interface translation** page.

Question: Is there a way to look up the LID for a source string using the text of the source string?

I've read many posts, but don't see any that suggest how to do this.

# Answer
> 2 votes
OK: Figured it out through trial and error. Here's the code:

```
$db = \Drupal::database();

$query = $db->select('locales_source', 'ls')->
    condition('source', $source_string)->
    fields('ls', ['lid'])->
    range(0, 1);

$lid = $query->execute()->fetchField();

```

UPDATE: Found a cleaner way. Here's the code:

```
$storage = \Drupal::service('locale.storage');
$string = $storage->findString(['source' => $source_string]);

if (!is_null($string)) {
  $lid = $string->lid;
}

```

I'm using this now in a custom module. Seems to be working well.

---
Tags: 8, i18n-l10n
---


# Question
Title: How to display parent term name of a term located in a paragraph?
I have a vocabulary for employees, which has a paragraph field. In this paragraph entity, I have two fields. One for date and one for the job title. The hierarchy goes like: company \> department \> job title. I've created a view where I list all employees and what I want to accomplish is not to show what their job title is. I want to display in which department they work.

Any help is appreciated.

# Answer
1st you have to make relation with the field who reference to taxonomies after that youhave to make another relation with your paragraph field to get the job title
> -1 votes

---
Tags: views, taxonomy-terms, paragraphs
---


# Question
Title: Modify "head-placeholder" in html.html.twig
that's the first time I approach to Drupal or a CMS more generally but I've been working since years as FE dev.

I'm creating a theme based on a template created from scratch for the Italian Public Administration(PA) in such way to define a standard for the PA websites.

This is the template project

So I have to fully rely over the CSS and JS files provided by the theme, and can't use a base theme.

I'm struggling to understand how to change the content of the `head-placehoder` and the `title` one in the `html.html.twig` file

```
  <head>
    <head-placeholder token="{{ placeholder_token }}">
    <title>{{ head_title|safe_join(' | ') }}</title>
    <css-placeholder token="{{ placeholder_token }}">
    <js-placeholder token="{{ placeholder_token }}">
  </head>

```

# Answer
> 1 votes
For those who came here by Google, if you want to change the meta tags or other things injected by `head-placeholder`, you can use `hook_page_attachments_alter()`. Here is an example where I have removed the meta tag for Generator in Drupal 8. This meta tag:

```
<meta name="Generator" content="Drupal 8 (https://www.drupal.org)">

```

In your your\_theme.theme, here is the code:

```
function your_theme_page_attachments_alter(array &$attachments) {
   foreach ($attachments["#attached"]["html_head"] as $key => $attachment) {
     if ('meta' === $attachment[0]["#tag"] &&
         !empty($attachment[0]["#attributes"]["name"]) &&
         'Generator' === $attachment[0]["#attributes"]["name"]) {

            unset($attachments["#attached"]["html_head"]["$key"]);
     }
   }
}

```

If you want to know about `header-placholder` and how the rendering is happening, read the accepted answer for this post What is placeholder\_token in html.html.twig for?

# Answer
> 0 votes
I suggest you look at https://www.drupal.org/docs/8/theming-drupal-8/adding-stylesheets-css-and-javascript-js-to-a-drupal-8-theme, which provides pretty good documentation on how to add CSS in a theme.

If you don't extend from a theme then you technically extend from a special theme called "stable". You should get almost no default CSS then, at least from core modules. Unless that really results in a problem, in which case there are some options to override it (documented above), I wouldn't worry about that.

---
Tags: theming, 8
---


title: Create a user and auto login

text:
# Question
Title: Create a user and auto login
I use `user_save()` to create a new user in a custom module. If the function returns `TRUE`, is it possible to auto login the user?

**EDIT**

I've done some more searching and found the `user_authenticate()`

This is the code I have so far:

```
$user_info = array(
  'name' => $sessdata['username'],
  'pass' => user_password(),
  'mail' => $sessdata['username'],
  'init' => $sessdata['username'],
  'status' => 1,
  'roles' => array(DRUPAL_AUTHENTICATED_RID => TRUE),
                    'access' => time(),
                    );
  $save = user_save($account,$user_info);

  if($save) {
    $loggedin = user_authenticate($save->name, $save->pass);

    if($loggedin) {
      echo "logged in";
    } else {
      echo "damn";
    }
  }

```

Well it saves the user but it doesn't logins him.

# Answer
Actually, `user_save()` returns a user object, not `TRUE`. If it doesn't return `FALSE`, then the function was successful and you can use the returned object to log in that user.

For example, supposing that `$user` is the user object returned from `user_save()`, you can use the following code to replace the currently logged in user with that user (the code is for Drupal 7).

```
drupal_save_session(FALSE);
$original_user = $GLOBALS['user'];
$GLOBALS['user'] = $user;

// Do what you need.

$GLOBALS['user'] = $original_user;
drupal_save_session(TRUE);

```

The code can be used to do some actions impersonating another user, or when a user follows a link reported him in an email, which allows the user to log in. In the latter case, the last two lines should be removed from the code executed.

Without setting the value of `$GLOBAL['user']`, there isn't any way to let Drupal think a user is logged in.

`user_authenticate()` is not working because you are not passing the password for that account. In fact, Drupal doesn't save the password in any places; it saves the hash of the password, but that is not what user\_authenticate() needs, as reported from its documentation page:

> ### Parameters
>
> $name User name to authenticate.
>
> $password A plain-text password, such as trimmed text from form values.
>
> ### Return value
>
> The user's uid on success, or FALSE on failure to authenticate.

The function passed its `$password` parameter to user\_check\_password(), which execute the following code:

```
  if (substr($account->pass, 0, 2) == 'U$') {
    // This may be an updated password from user_update_7000(). Such hashes
    // have 'U' added as the first character and need an extra md5().
    $stored_hash = substr($account->pass, 1);
    $password = md5($password);
  }
  else {
    $stored_hash = $account->pass;
  }

  $type = substr($stored_hash, 0, 3);
  switch ($type) {
    case '$S$':
      // A normal Drupal 7 password using sha512.
      $hash = _password_crypt('sha512', $password, $stored_hash);
      break;
    case '$H$':
      // phpBB3 uses "$H$" for the same thing as "$P$".
    case '$P$':
      // A phpass password generated using md5.  This is an
      // imported password or from an earlier Drupal version.
      $hash = _password_crypt('md5', $password, $stored_hash);
      break;
    default:
      return FALSE;
  }
  return ($hash && $stored_hash == $hash);

```

As you see, `$account->pass` is used as stored hash of the password, while you are passing that value as password.
> 3 votes

# Answer
To login a user do

```
global $user;
$user = $save;

```
> 1 votes

# Answer
The function you're looking for is `user_login_finalize`. This takes the current value of `$GLOBALS['user']` and sets that user as the logged in user.

To create and log in a user, try the following:

```
// Operate on the global $user variable so it is available to
// user_login_finalize() when called.
global $user;

// Create a user. The password is set to a random 10-digit
// as generated by user_password().
$user_info = array(
  'name' => 'USERNAME',
  'pass' => user_password(),
  'roles' => array(
    DRUPAL_AUTHENTICATED_RID => TRUE,
  ),
  'mail' => 'E-MAIL ADDRESS',
  'init' => 'E-MAIL ADDRESS',
  'status' => 1,
  'access' => REQUEST_TIME,
  'timezone' => NULL,
);

// Add the 'ROLE_NAME' role
$rid = array_search('ROLE_NAME', user_roles());
$user_info['roles'][$rid] = TRUE;

// Set a value for FIELD_NAME
$user_info['FIELD_NAME'][LANGUAGE_NONE][0] = array('value' => '…');

// Set the $GLOBALS['user'] to the newly created user account
$user = user_save(NULL, $user_info);

// Finalize user login (modify $_SESSION, set login time in db)
user_login_finalize();

```
> 0 votes

# Answer
Just add following code in validation function:

```
$form_state['uid'] = user_authenticate($form_state['values']['name'], $form_state['values']['pass']);

```

Submit function (user\_login\_submit) will automatically log in user.
> 0 votes

# Answer
none of the above worked for me

instead i did the following:

```
if($save){
  $uid = user_authenticate($username , $password);
  // do not need to hash the password
  $user = user_load($uid);
  $form_state = array();
  $form_state['uid'] = $uid;
  user_login_submit(array(), $form_state);
}

```
> 0 votes

---
Tags: users
---


# Question
Title: hook_preprocess_paragraph is not invoked
function my\_module\_preprocess\_paragraph\__Paragraphname(&$variables) { var\_dump("Inside para hook"); }

This hook function is not working. Are there any dependencies in there?

# Answer
Hooks are working in Drupal. This situation happens all the time.

Usually :

* Check for a typo in the function name.
* Check the file name in which you placed the hook function. Depending on weither you're in a module or a theme, it should be `module_machine_name.module` or `module_machine_name.theme`
* Check the page type you're checking on. In my tests, this hook is not called on page types that does not reference a paragraph entity field reference.
* Hooks are cached, so you must empty the cache after creating a new hook.
> 1 votes

---
Tags: hooks
---


title: How do I add a user to a group?

text:
# Question
Title: How do I add a user to a group?
I am using the Drupal 7 version of the Group module. I found this Drupal 8 code which adds a user to a group, and I can't find anything similar for Drupal 7.

```
use Drupal\Core\Entity\ContentEntityBase;
$account = \Drupal\user\Entity\User::load('uid');
$group = \Drupal\group\Entity\Group::load($group_id);
$group->addMember($account);
$group->save();

```

What is the equivalent Drupal 7 code?

I tried using the following code, but it throws an error.

```
<?php
$account = user_load($uid);
$group = entity_load_single('group', 1);
$group->addMember($account);
$group->save();
?>

```

The error is the following one.

> Object of class stdClass could not be converted to int in Group-\>addMember()

# Answer
> 1 votes
For D7 its

```
$account = user_load($uid);
$group = group_load($group_id);
$group->addMember($account->uid, array('joined_on' => REQUEST_TIME));

```

To delete

```
$group->removeMember($account->uid);

```

To request

```
$group->addMember($account->uid, array('status' => 'requested', 'requested_on' => REQUEST_TIME));

```

To block:

```
foreach (group_membership_load_by_user($account->uid) as $group_membership) {
  $block_gid = // some code to get the Group ID that you want the ...
               // ... the block to take place in.
  $gid = $group_membership->gid;
  if ($gid == $block_gid) {
    global $user;
    if ($group_membership->status != 'blocked') {
      $group_membership->blocked_status = $group_membership->status;
      $group_membership->status = 'blocked';
      $group_membership->blocked_on = REQUEST_TIME;
      $group_membership->blocked_by = $user->uid;
      $group_membership->save();
    }
}

```

To Unblock:

```
foreach (group_membership_load_by_user($account->uid) as $group_membership) {
    $unblock_gid = // some code to get the Group ID that you want the ...
                  // ... the unblock to take place in.
    $gid = $group_membership->gid;
    if ($gid == $unblock_gid) {
      if ($group_membership->status == 'blocked') {
        $group_membership->status = $group_membership->blocked_status;
        $group_membership->blocked_status = '';
        $group_membership->blocked_on = NULL;
        $group_membership->blocked_by = NULL;
        $group_membership->save();
      }
    }
}

```

---
Tags: 7, group
---


# Question
Title: How to install latest stable Drupal version from drupal/recommended-project branch?
I've forked drupal/recommended-project and run `composer install` from the default branch (`8.8.x`), it installed the latest dev version (8.8.6-dev). There's also a tag 8.8.5 (latest stable as of now) which has the same `composer.json` with the exception of these lines:

```
    "require-dev": {
        "drupal/core-dev": "^8.8"
    },

```

I've deleted these lines in branch `8.8.x` hoping this would install the latest stable version but it installed the dev version anyway. I don't want to use tags because I forked the upstream and have my own changes.

How can I install the latest stable version of Drupal from the default branch (`8.8.x`)?

# Answer
Instead of forking and running `composer install`, you should run `composer create-project drupal/recommended-project <project_root_dir>`. This will install the latest stable version of Drupal and you can of course add this to your version control system (don't forget to exclude all files that you don't have to track in your VCS).

When you use the `composer.lock` file from the GitHub repository directly, Composer installs the software versions as defined in the lock file (in this case the development versions).
> 2 votes

# Answer
I use a different one, drupal-composer/drupal-project and it installs the latest stable version.

> **Note:** That as of Drupal 8.8.0 drupal-composer/drupal-project has been **deprecated** as an "official" source.
>
> **Note 2:** But the project it self is not deprecated **drupal-composer/drupal-project has \[not\] been deprecated**

If you look at its composer.json

Under require it has

```
"require": {
    "drupal/core": "^8.8.0",
},
"require-dev": {
    "drupal/core-dev": "^8.8.0"
},

```

while yours doesn't; thus, this is why yours fetches the dev version.
> 2 votes

---
Tags: composer
---


title: Trying TDD with PHPUnit

text:
# Question
Title: Trying TDD with PHPUnit
I'm trying out the built in test driven development method in Drupal 8 but I'm running in to a problem..

I'm getting the following errors when trying to run `./core/vendor/bin/phpunit --list-groups ./modules/` in my cli:

> PHP Fatal error: Class 'Drupal\Tests\UnitTestCase' not found in /Applications/MAMP/htdocs/drupal/modules/custom\_cookie\_compliance/ tests/CustomCookieComplianceTest.php on line 10
>
> Fatal error: Class 'Drupal\Tests\UnitTestCase' not found in /Applications/MAMP/htdocs/drupal/modules/custom\_cookie\_compliance/tests/ CustomCookieComplianceTest.php on line 10

I have created a module folder called custom\_cookie\_compliance in my modules folder. In turn I have a custom\_cookie\_compliance.info.yml file containing the following.

```
 name: Custom Cookie Compliance
 description: Displays a cookie compliance information window at the top of the website.
 core: 8.x
 type: module

```

I also have a *tests* folder containing a *src* folder which then contains a CustomCookieComplianceTest.php file with the following code.

```
<?php
namespace Drupal\custom_cookie_compliance\Tests;

use Drupal\Tests\UnitTestCase;

/**
 * @group cookie
 */

class CustomCookieComplianceTest extends UnitTestCase {
  public function testSetCookies() {
    if (!isset($cookie_set)) {
      $cookie_set = TRUE;
    }

    $this->assertTrue($cookie_set);
  }
}

```

I have written the code by following this guide.

I understand it can't find the `UnitTestCase` class, but the guide says that is should work, so why isn't it?

# Answer
> 12 votes
My guess is that you're not including the phpunit.xml.dist file, which sits in the core folder.

Either run tests from there (./vendor/bin/phpunit ../modules/your\_module) or specify that file with `-c`.

You can also provide your own phpunit.xml.dist file (see the Payment module as an example); then you can run PHPUnit from your module folder.

# Answer
> 0 votes
I ran into the same issue today and noticed that I was using an older version of PHP Unit. After upgrading to the latest, the tests worked.

---
Tags: testing
---


# Question
Title: How can I uncheck a required checkbox on the edit page for a given content type?
I have a "required" checkbox (single on-off boolean field) which users must check to agree to the rules of the site when they post a node of a certain content type. When users edit nodes of this content type, I would like to reset the checkbox to force them to check it again.

How can I do this in Drupal 7?

# Answer
Implement hook\_form\_FORM\_ID\_alter() such that it clears the `#default_value` property of the widget:

```
function mymodule_form_node_form_alter(&$form, &$form_state, $form_id) {
  $node_type = 'example_type'; // TODO: change to the desired node type
  $field = 'field_example';    // TODO: change to the name of the field

  $node = $form['#node'];
  if ($node->type == $node_type) {
    $language = $form[$field]['#language'];
    $form[$field][$language]['#default_value'] = 0;
  }
}

```
> 2 votes

# Answer
I can't comment on the other answer, but you can set a default value of an empty array (not 0 or FALSE to avoid a PHP warning):

```
$form[$field][$language]['#default_value'] = array();

```

See https://www.drupal.org/project/drupal/issues/3009881#comment-13407511

I would also add a condition to only set this default value on a node/add form, because #default\_value will override any existing checked box and blank it out again on an edit form. I used:

```
if (!isset($node->nid) || isset($node->is_new)) {
  $form['field_mycheckbox'][LANGUAGE_NONE]['#default_value'] = array();
}

```
> 0 votes

---
Tags: forms
---


# Question
Title: Form #after_build is not working for PHP 7x
I'm using #after\_build in one of my custom module form like follows

```
  $form['profile_image'] = array (
    '#type' => 'managed_file',
     '#after_build' => array("change_pic"),
  );

```

and the function is

```
function change_pic($element, &$form_state, $form) {
  if($form_state['values']['profile_image']['fid'] != 0){
    // my code goes here..
    return $element;
  }
}

```

It's working fine in PHP 5x version. but throws the following error in PHP 7x version.

> ArgumentCountError: Too few arguments to function change\_pic(), 2 passed How can we handle this in PHP 7?

Any inputs would be helpful.

# Answer
There are only 2 args to an after build method, the element and the form state.

Just remove the extra one and it’ll work:

```
function change_pic($element, &$form_state)

```
> 1 votes

# Answer
Clive's answer to use only those 2 arguments is correct; but this is also wrong on your code:

```
 $form['profile_image'] = array (
    '#type' => 'managed_file',
     '#after_build' => array("change_pic"),
  );

```

this will wipe out any other after builds added by other modules. You should add like this:

```
 $form['profile_image']['#after_build'][] = 'change_pic';

```
> 0 votes

---
Tags: 7, forms
---


# Question
Title: Node values not retrieving properly in .theme and Twig files
I created a content type and have a couple of fields: a heading, links, and images. After creating a node out that content type, I want to pull parts of the node into my homepage. And for that, I used the following in my .themename.theme.

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

function amarula_preprocess_page(&$variables) {

    $nid = 62;
    $node = \Drupal::entityTypeManager()->getStorage('node')->load($nid);

    $variables['field_vanilla_heading'] = $node->field_vanilla_heading->value;
    $variables['field_vanilla_main_content'] = $node->field_vanilla_main_content->value;
    $variables['field_vanilla_home_link'] = $node->field_vanilla_home_link->value;
    $variables['field_vanilla_home_thumbnail'] = $node->field_vanilla_home_thumbnail->value;
}

```

I get the value of the field\_vanilla\_heading in my page--front.html.twig

```
<h1>{{ field_vanilla_heading }}</h1>

```

But, the rest of the fields are giving problems.

For the main content {{ field\_vanilla\_main\_content }}, which is long text with summary, I am seeing all the HTML in the page. How can I escape this in twig?

For the rest of the fields, kint tells me that they are null, which is not true:

```
{{ kint(field_vanilla_home_link) }}
{{ kint(field_vanilla_home_thumbnail) }}

```

Below is the list of all the field settings:

I can already get the node ID. But how can I get all the values of the node accordingly?

# Answer
> 0 votes
not sure if you still need an answer, but the problem is how you want to retrieve the values from the fields. I get confused all the time, so I usually check out what the column name in the database is of the value I want to get from the field.

Links:

```
$node->field_vanilla_home_link->uri;
$node->field_vanilla_home_link->title;

```

Images are a bit more complicated, maybe there are more ways, but this is how I usually do it:

```
$entity = $node->field_vanilla_home_thumbnail->entity;
    if ($entity) {
      $variables['field_vanilla_home_thumbnail'] = $entity->getFileUri();
    }

```

OR with this you could load different image styles (don't forget to import ImageStyle class):

```
ImageStyle::load('thumbnail')->buildUrl($entity->getFileUri());

```

For the image alt:

```
$node->field_vanilla_home_thumbnail->alt

```

And I guess you know how to use those values in twig to print links and images (just basic html) :)

Edit: For your problem with your long text with summary, you can filter the markups with "raw":

```
{{ field_vanilla_main_content | raw }}

```

---
Tags: 8, theming
---


# Question
Title: Store custom messages displayed by \Drupal::messenger()->addMessage() in the database
In a custom module, I have the following code:

```
\Drupal::messenger()->addMessage(t("Email changed to %email.", ['%email' => $new_email]));

```

I issue more than a dozen different messages in this way.

I want a way to store these messages in the database with a way to list them and edit them, assign an ID or keyword to each message, and then do the equivalent of

```
\Drupal::messenger()->addMessage(message_id, parameters);

```

I'm sure I can accomplish this by creating a "message" content type with keyword and message fields, adding a message node for each message, and then writing a function in my custom module that loads a node by keyword, inserts any variables, and then calls \Drupal::messenger()-\>addMessage() to display it. I could also create a View to list all messages for editing purposes. But it seems like there should be a better way that doesn't involve adding messages to the content of the site.

Is there a module or a built-in Drupal facility that does this?

My reading hasn't uncovered anything that looks like it will do these things. I realize Interface translation will support some of what I'm looking for, but don't know that it can be used with \Drupal::messenger()-\>addMessage().

# Answer
The suggestions by @Taggart Jensen, @NoSssweat, and @Jaypan to use custom entity types are clearly good ones, given my original question. As I began working on a solution using custom entities, it dawned on me that I could use the t() function and **User interface translation** (which I already use for string overrides) to do what I want.

My goal:

Make it easy for editors to change the wording of messages displayed by our custom `rsc` module. Stop unwittingly adding a new entry to the interface translation table each time I change a message in my module code.

My solution:

I created a simple helper function in my `rsc` module to display messages by passing a *key* to addMessage() instead of an actual message:

```
function rsc_message($key, $args=[])
{
  \Drupal::messenger()->addMessage(t('rsc-' . $key, $args));
}

```

I realize this isn't especially brilliant, but I wanted a way to consistently prepend `rsc-` to each key. An example of a call to this function is:

```
rsc_message('option-expired',
[
  '@option' => $option,
  '@date' => date("F j", $expireTime),
  '@time' => date("g:i a", $expireTime)
]);

```

The corresponding entry in **User interface translation** (once the key gets added to the translation table and once I enter the "translation" shown below) will be:

```
rsc-option-expired | The option <strong>@option</strong> expired on @date at @time.

```

Passing a key to `rsc_message` rather than a displayable message turns **User interface translation** into a string manager. It's easy to find my keys using **String contains** in the manager because they all begin with `rsc-`.

Goodnesses of using this approach:

* I don't have much extra code to maintain.
* Editors modify our custom `rsc` module strings using the same manager they use for other strings.
* All of my message strings (25 or so of them) can be viewed at the same time.
* I don't create a new entry in the translation table every time I change a string in my `rsc` module code. The *key* stays the same; we just change the translation via the manager.
* I can directly include HTML tags in the translation, so I don't have to fuss with the @var, %var, !var t() function stuff.
* I can export the translations for bulk editing or reuse.

Badnesses of this approach:

* A *key* isn't added to the translation table until the message for that key gets displayed. Sometimes getting a particular error message to be displayed can be a challenge.
* I can't enter a translation into the table for a key until the key is there.

To overcome the badnesses, I created a quick-and-dirty *string-manager* feature in my custom `rsc` module as page `string-manager`. It allows me to add strings to the table, remove strings from the table, and test strings in the table to make sure they work right. Here's the code.

In modules/custom/rsc/rsc.routing.yml

```
rsc.stringManager:

  path: '/string-manager/{key}/{p1}/{p2}/{p3}/{p4}/{p5}'
  defaults:
    _controller: 'Drupal\rsc\Controller\rscController::stringManager'
    _title: 'String Manager'
    p1: ''
    p2: ''
    p3: ''
    p4: ''
    p5: ''
  requirements:
    _role: 'administrator'

```

In modules/custom/rsc/src/Controller/rscController.php

```
namespace Drupal\rsc\Controller;

use Drupal\Core\Controller\ControllerBase;

class rscController extends ControllerBase
{
  public function stringManager($key, $p1, $p2, $p3, $p4, $p5)
  {
    require_once DRUPAL_ROOT . '/modules/custom/rsc/rsc_string_manager.php';

    return
    [
      '#markup' => rsc_string_manager($key, $p1, $p2, $p3, $p4, $p5)
    ];
  }
}

```

In modules/custom/rsc/rsc\_string\_manager.php

```
function rsc_string_manager($key, $p1, $p2, $p3, $p4, $p5)
{
  // Avoid accidental add or delete of non-rsc strings.
  // Prepend ! to a key to override this safety measure.

  if (strpos($key, '!') === 0) {
    $key = substr($key, 1);
  }
  else if (strpos($key, 'rsc-') !== 0) {
    return "Prefix $key with rsc- or use ! to override";
  }

  // Note: '++' in the query string gets converted to '  '

  if (strpos($key, '  ') == strlen($key)-2) {
    $key = rtrim($key, ' ');
    $action = 'add';
  }
  else if (strpos($key, '--') == strlen($key)-2) {
    $key = rtrim($key, '-');
    $action = 'delete';
  }
  else {
    $action = 'check';
  }

  $storage = \Drupal::service('locale.storage');
  $string = $storage->findString(['source' => $key]);

  if ($action == 'add') {
    if (!is_null($string)) {
      return "$key -- ALREADY EXISTS";
    }
    $string = new \Drupal\locale\SourceString();
    $string->setString($key);
    $string->setStorage($storage);
    $string->save();
    return "$key -- ADDED";
  }
  else {
    if (is_null($string)) {
      return "$key -- NOT FOUND";
    }
    if ($action == 'delete') {
      $string->delete();
      return "$key -- DELETED";
    }
    else { // ($action == 'check')
      $mask = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_';
      $args = [$p1, $p2, $p3, $p4, $p5];
      $trans = t($key);
      $params = [];

       // Find placeholders in the "translated" string and match arguments
       // to them in their order in the url. We use only @ placeholders
       // because we can use bold, italics, etc. in the translated string.

      $i = 0;
      $p = 0;
      while ($i < count($args) && $args[$i] && ($p = strpos($trans, '@', $p)) !== false) {
        $q = strspn($trans, $mask, $p+1);
        $params[substr($trans, $p, $q+1)] = $args[$i];
        $p += $q;
        $i++;
      }
      return t($key, $params);
    }
  }
}

```

Usage:

* key++ (add a key)
* key-- (remove a key)
* key/p1/p2/... (check a translation)

Example:

* mysite.com/string-manager/rsc-option-expired++ (add)
* mysite.com/string-manager/rsc-option-expired (check)
* mysite.com/string-manager/rsc-option-expired/retry/April 1/2:30 pm (check w/parameters)
* mysite.com/string-manager/rsc-option-expired-- (delete)

Add the key (line 1 above). The displayed text is:

```
rsc-option-expired -- ADDED

```

Go to **User interface translation**, search for strings containing "rsc-", and find the newly added string. The string table contains:

```
rsc-option-expired | <no translation yet>

```

In the **Translation for English** column, paste in:

```
The option <strong>@option</strong> expired on @date at @time.

```

Now, the string table contains:

```
rsc-option-expired | The option <strong>@option</strong> expired on @date at @time.

```

Check the translation with no parameters (line 2 above). The displayed text is:

```
The option @option expired on @date at @time.

```

Check the translation with parameters (line 3 above). The displayed text is:

```
The option retry expired on April 1 at 2:30 pm.

```

Delete the key (line 4 above). The displayed text is:

```
rsc-option-expired -- DELETED

```

Now the string is gone from the table.

This utility has been quite useful to me as I've added messages to my custom `rsc` module. When I add a new message key, I use the utility to immediately add it to the translation table. Then I immediately add the translation (which editors will, no doubt, change later--who likes the way developers say things?)

Maybe this utility won't be useful to anyone but me; however, it took me a good while to figure out how to manipulate the translation string table properly, so maybe bits of the code will help someone.

P.S. By using ! before a key or by removing the `rsc-` requirement in the code, you can use this utility to manipulate *any* string in the translation table (as long as it doesn't contain slashes).
> 0 votes

# Answer
The first thing to determine is whether you need your messages to be content or configuration. Content is (usually not) migrated between environments. It is created on an environment, and is unique to that environment. So your development environment may have one set of messages used for testing, and your production environment has another set of messages, used live.

Configuration on the other hand is migrated between environments. So you would create the messages on one environment, and when configuration is exported from that environment, the existing messages would be included in that export.

You probably want content entities.

How to create a new content entity type: https://www.drupal.org/docs/8/api/entity-api/creating-a-content-entity-type-in-drupal-8

How to create a new configuration entity type: https://www.drupal.org/docs/8/api/configuration-api/creating-a-configuration-entity-type-in-drupal-8

If you create a new content entity type, give the entity two fields, `message_key` and `message_value`. You will then load the entity as follows:

```
$entity = \Drupal::entityTypeManager()->getStorage('my_entity_type_id')->loadByProperties([
  'message_key' => $message_key,
]);

$message_value = NULL;
if ($entity) {
  $message_value = $entity->get('message_value')->value;
}

```

If you create a configuration entity, the ID of the entity will be the message key, and the entity only needs one more field for message value. The code above would be adjusted slightly:

```
$entity = \Drupal::entityTypeManager()->getStorage('my_entity_type_id')->loadByProperties([
  'id' => $message_key,
]);

$message_value = NULL;
if ($entity) {
  $message_value = $entity->get('message_value')->value;
}

```

The entity type you choose will become the storage mechanism for your messages, which you can then recover with the above methodology. Don't run `$message_value` through the `t()` function, as variables should not be run through that function, and translations of the message values are handled as translations of the entity, rather than the `t()` function.
> 2 votes

# Answer
You could do it with Entity Construction Kit (ECK)

This allows you to create a custom entity and add fields to it just like a Node content type, but without having revisions, a title, an author, and some other bloat that comes by default with nodes if you don't want them.

Here is a D8 tutorial of it.

Unfortunately, the D8 version does create a view route, while in the D7 version this was optional, but you can take away permission to view it.
> 1 votes

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


# Question
Title: How to temporarily replace Drupal with static HTML pages?
I'm a JavaScript dev with no Drupal experience.

I'm working with a church to redesign their Drupal site after their dev moved on without leaving any notes/documentation/etc. In the meantime, I'd like to put up a few static html pages in place of the Drupal site, without getting rid of all the Drupal data.

Can I just "turn off" Drupal, so that routes that are now currently powered by Drupal (ie: `church.org/worship`) will instead render the static file version (ie: `church.org/worship/index.html`)?

Is leveraging Drupal's "maintenance mode" a possible solution? I found this article, https://drupalden.co.uk/static-maintenance-page-replace-drupals-default-maintenance-mode-page, on replacing the default maintenance page, but what about other routes too?

# Answer
Drupal only kicks in when a file does not exist. So if you create HTML files at the same path where a Drupal page existed, the HTML file will be shown, and Drupal will not be instantiated.

Example: You have a path named /node/4.

If you create a folder in your webroot named 'node', and a file named 4, it will be picked up instead of Drupal being instantiated, even if Drupal exists in the webroot. You may need to do some work to set the headers of the file as text/html though, since there is no file extension on the file to tell the processor that it's an HTML file.
> 2 votes

---
Tags: theming, routes
---


title: How should I replace jQuery UI dialog?

text:
# Question
Title: How should I replace jQuery UI dialog?
I try to use jQuery UI dialog.
Based on this, I put this in a node:

```
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script>
    $( function() {
      $( "#dialog" ).dialog();
    } );
</script>
<div id="dialog" title="Basic dialog">
    <p>
        This is the default dialog which is useful for displaying information. The dialog window can be moved, resized and closed with the 'x' icon.
    </p>
</div>
<p>
    Some stuff...
</p>

```

And it works! The popup window shows up automatically when the node is displayed.
But I noticed that jQuery is deprecated in Drupal 8.
So, how should I do the same thing in a more "Drupal" way?

\[EDIT\] Making progress...
@leymannx Using the 1rst example of Ajax Dialog Boxes page you provided, I get this working (see the screen capture).
My next step: how to have the dialog box displayed automatically when the page is reached without having to click the link?

# Answer
> 4 votes
**jQuery hasn't been deprecated**. Some unused jQuery UI components have been deprecated in 8.8 and will be removed in Drupal 9.0. `core/jquery.ui.dialog` is not among them.

Nonetheless there's the new Dialog API. For that you have to require the `core/drupal.dialog` library or the `core/drupal.dialog.ajax` library for more advanced stuff. Some examples can be found in the docs on Ajax Dialog Boxes. The following sample requires the `core/drupal.dialog.ajax` library.

> This link opens /node/1 in a modal dialog box:
>
> ```
> <a class="use-ajax"
>     data-dialog-options="{"width":400}"
>     data-dialog-type="modal"
>     href="/node/1">
>     First node displayed in modal dialog.
> </a>
>
> ```

What you currently do in your code sample hasn't much to do with Drupal at all. To do it the Drupal way check the docs on adding JS/CSS to your module or theme first. You could attach the library simply to your theme or directly to all nodes of a given type for example.

---
Tags: 8, javascript
---


# Question
Title: Entity reference field search by custom field
In my setup, a user can own more entities of a specific content type but the ownership is stored in the entity. The user entity does not 'know' anything about this. I know without context it seems weird but in my case, it made more sense like this instead of having an entity reference field on the user.

Now I'm trying to build an Entity Reference Display for a view so that for certain autocomplete fields I can search for users by either their name or the title of the entities they own. I created a view before that showed all the users and all of their entities so I was hoping I can reuse that field here but it seems like if I set the entity reference field to search by this field as well it just adds this view field's id to the query as if it was a user's field and it gives (of course) column not found SQL exception.

I've also tried to add a join with a view query alter hook but I could not figure out how to get the text entered by the user as that seems to be neither in exposed\_raw nor in args.

Any ideas?

**Edit:**

Here is how my relationship is set up:

Entity -\> Field referencing a paragraph that describes the ownership -\> field referencing a user

And here is what I tried based on @stevekeiretsu's comment:

* I set up a relation to paragraphs that have that field referencing a user
* Then I added another relation to content that has that field referencing this paragraph.
* Then I added the Title field of content to the view

The problem is that it still does not show anything. If I set the relations to required I have no results.

# Answer
> 0 votes
Ok, I found the issue:

```
SELECT
users_field_data.created AS users_field_data_created,
users_field_data.uid AS uid,
field_member_users_field_data.id AS field_member_users_field_data_id,
field_number_ownership_paragraphs_item_field_data.nid AS field_number_ownership_paragraphs_item_field_data_nid
FROM
    users_field_data as users_field_data
    LEFT JOIN paragraph__field_member as paragraph__field_member
        ON
        users_field_data.uid = paragraph__field_member.field_member_target_id AND
        paragraph__field_member.deleted = '0'

LEFT JOIN paragraphs_item_field_data as field_member_users_field_data
    ON
    paragraph__field_member.entity_id = field_member_users_field_data.id

LEFT JOIN node__field_number_ownership as field_member_users_field_data__node__field_number_ownership
    ON
    /** HERE **/
    field_member_users_field_data.id = field_member_users_field_data__node__field_number_ownership.field_number_ownership_target_revision_id AND
    field_member_users_field_data__node__field_number_ownership.deleted = '0'

LEFT JOIN node_field_data as field_number_ownership_paragraphs_item_field_data
    ON
    /** AND HERE **/
    field_member_users_field_data__node__field_number_ownership.entity_id = field_number_ownership_paragraphs_item_field_data.vid

INNER JOIN
    user__roles as user__roles ON users_field_data.uid = user__roles.entity_id   AND user__roles.deleted = '0'
WHERE (user__roles.roles_target_id = 'member')
ORDER BY users_field_data_created DESC
LIMIT 11 OFFSET 0

```

This is the SQL generated by the View. As you can see it is using entity\_id against vid and id against target\_revision\_id in the joins. This may be a bug or my lack of some fundametal drupal stuff. Please let me know if that is the case: Until then, I came up wiht this query alter to solve this problem:

```
function aci_ssp_views_query_alter(ViewExecutable $view, QueryPluginBase $query) {
    // Ifs view id is what i'm looking for
    $tables = $query->getTableQueue();

    $tbl1 = 'field_member_users_field_data__node__field_number_ownership';
    $tables[$tbl1]['join']->leftField = 'revision_id';
    $tables[$tbl1]['join']->configuration['left_field'] = 'revision_id';

    $tbl2 = "field_number_ownership_paragraphs_item_field_data";
    $tables[$tbl2]['join']->field = 'nid';
    $tables[$tbl2]['join']->configuration['field'] = 'nid';
}

```

---
Tags: views, 8
---


# Question
Title: How can I get a list of all my site's module and themes?
I want to get the list of current modules and themes and modify them on Drupal 9, previously in Drupal 8,7 I used the following functions to get and save them but it seems they are depricated on Drupal 9.

```
 system_get_info(), _system_rebuild_module_data()

```

what is equivalent to these functions in Drupal 9 and how can get/update data about the module/themes in Drupal 9?

# Answer
Simply check the deprecation notice on `system_get_info`

> ### Deprecated
>
> in drupal:8.8.0 and is removed from drupal:9.0.0. Use `\Drupal::service('extension.list.$type')->getExtensionInfo()` or `\Drupal::service('extension.list.$type')->getAllInstalledInfo()` instead.

and the change record on `_system_rebuild_module_data()` and co. are replaced by services to give you all available modules and themes

> ```
> // If you want to just get all extensions without rebuilding.
> $module_list = \Drupal::service('extension.list.module')->getList();
>
> ```
> 2 votes

# Answer
The change records tell you all you need to know ...

https://www.drupal.org/list-changes/drupal/published?keywords\_description=system\_get\_info&to\_branch=&version=&created\_op=%3E%3D&created%5Bvalue%5D=&created%5Bmin%5D=&created%5Bmax%5D=
> 2 votes

---
Tags: 9
---


# Question
Title: How can you hide "Your search yielded no results." when no keywords have been entered on the search page?
On the core default search page located at `/search/node`, if you visit this URI the page displays "Your search yielded no results." It displays this message whether keywords have been entered that truly have no search results, as well as when no keywords have been entered. It is odd to be presenting "Your search yielded no results." to users when they have yet to actually search for anything.

What's the most appropriate way to remove this message *when no keywords have been entered*?

# Answer
First find out how this string got there in the first place. Simply search your codebase for the exact string `Your search yielded no results.`. In a Vanilla Drupal you'll find only 6 occurrences of this string. 5 of them in tests, and only one in a controller, the SearchController.

Looking into the SearchController you'll see that this string is part of a render array. Keyed as `'#empty'` and themed with `'#theme' => ['item_list__search_results__' . $plugin->getPluginId(), 'item_list__search_results'],`. This means you can target that pretty easily with a preprocess function. Let's go for `item_list__search_results` since you don't know of any plugin yet.

In your theme or module implement `hook_preprocess_HOOK`. Replace `hook` with your theme or module machine name and `HOOK` with the `'#theme'` key from earlier.

Now find out if any search query has been entered at all via if `\Drupal::request()->query->has('keys')`, and for safety let's also check if there's an `'empty'` key in the `$variables` and then unset it. If you want you can tighten the condition now also on the plugin you'll find in `$variables['context']['plugin']`.

```
/**
 * Implements hook_preprocess_HOOK().
 */
function MYMODULE/MYTHEME_preprocess_item_list__search_results(&$variables) {
  // ksm($variables);
  if (!\Drupal::request()->query->has('keys') && isset($variables['empty'])) {
    unset($variables['empty']);
  }
}

```

**Hint:** Use the Devel sub-module Kint and its debugging function `ksm()` to have you any variable pretty-printed in the messages block of your site for easy debugging.
> 3 votes

---
Tags: 8, search
---


# Question
Title: Need help with taxonomy term creating a users view
I have a taxonomy field in the user registration form called location, I have a view listing all location terms (taxonomy terms).

I'm having trouble linking the terms to a view (containing the users info based on the location term), when the taxonomy term is clicked in a list of all terms, to display users that have the taxonomy term (with the same location). By default the taxonomy term view is set to display content and I'm having trouble changing that to display users.

# Answer
> 1 votes
You can create a View or Views with pages to accomplish this. The presentation of nodes connected to a taxonomy term on its display page is baked into Drupal separately from Views, I think. I'm not positive about that; I never use it. I'm more likely to go around it for reasons similar to what you're describing.

One page can easily present a list of of your location taxonomy terms. I would use a field-based view, and show the name of the term from the list. Uncheck the box that has the field link to the term directly, and instead check the box for the field to function as a custom link (under "Rewrite Results"), put in some URL that will include the location name, *e.g.*, `/user-location/{{ term_name }}`. Scroll further down and you'll see "Replacement Patterns". Use what seems appropriate there.

The other page may be field-based or entity-based dependent on your specific needs. It keys off users, and makes use of a contextual filter. That contextual filter is the location term name taken from the URL. The page URL will use the one you set in the first page. Thus this page will present user info filtered by the location term.

---
Tags: views, 8, taxonomy-terms
---


# Question
Title: Email Notification to Store Owner When Order Complete
During early development I had it working so the store owner would get an email when an order was completed. I just realized this isn't working anymore. Where are the settings related to this? Is it supposed to use the store's email, or something else?

# Answer
> 1 votes
You didn't mention the versions so I assume you are using Drupal 8 with Commerce 2.

You can use Commerce Reaction module as it allows you to select the Commerce event and have a reaction when it is dispatched.

It provides a plugin to send HTML, and twig template emails with nice integration with the Token module.

---
Tags: 8, commerce
---


# Question
Title: How to get the "field" value of config entity, with bundles, that is defined in a bundle while creating content
I am creating a custom entity (WebsiteType) with bundles (Website), where I want to define a URL, among other configurations, that all content in a given bundle should inherit.

I created the fields in the config entity type and managed to show and save these fields while creating a new bundle. Nevertheless, I couldn't manage to get these values in HOOK\_entity\_presave.

here is a sample of the code:

src/Entity/WebsiteType

Notation:

```
 *   entity_keys = {
 *     "id" = "id",
 *     "label" = "label",
 *     "uuid" = "uuid",
 *     "service_endpoint_url" = "service_endpoint_url",

```

Class:

```
class WebsiteType extends ConfigEntityBundleBase implements WebsiteTypeInterface {
  /**
   * The Website type Service Endpoint URL.
   *
   * @var string
   */
  protected $service_endpoint_url;

}

 /**
   * {@inheritdoc}
   */
  public function getServiceUrl() {
    return $this->service_endpoint_url;
  }

```

WebsiteTypeForm:

```
public function form(array $form, FormStateInterface $form_state) {
  $form = parent::form($form, $form_state);

  $website_type = $this->entity;

  $form['endpoint_settings']['service_endpoint_url'] = [
    '#type' => 'textfield',
    '#title' => $this->t('Argir Endpoint URL'),
    '#maxlength' => 255,
    '#description' => $this->t("The location of your service."),
    '#required' => TRUE,
    '#default_value' => $website_type->getServiceUrl(),
    '#attributes' => [
      'placeholder' => $this->t('https://XXXXX.com'),
    ],
  ];
}

```

WebsiteTypeInterface:

```
interface WebsiteTypeInterface extends ConfigEntityInterface {

  public function getServiceUrl();
}

```

I followed the documentation of Drupal of Entity API

Checked the answer here: enter link description here

also went through this outstanding tutorial: enter link description here

Tried to work with EntityTypeManager

All of that with no luck. Any advice is highly appreciated.

# Answer
> 2 votes
While creating content, HOOK\_entity\_presave() is called for the content entity and you can access only content fields. One of these content entity fields is a reference field to the bundle config entity, usually named `bundle`. Use this field to get the config entity via the magic property `entity` and get the config field value via the method you have defined in `WebsiteTypeInterface`:

```
$url = $entity->bundle->entity->getServiceUrl();

```

A more generic way when you don't know the bundle field name or the code should work for all entity types:

```
$bundle_field_name = $entity->getEntityType()->getKey('bundle');
if (!empty($bundle_field_name)) {
  $bundle_config = $entity->get($bundle_field_name)->entity;
  if ($bundle_config instanceof \Drupal\mymodule\Entity\WebsiteTypeInterface) {
    $url = $bundle_config->getServiceUrl();
  }
}

```

---
Tags: 8
---


title: Unicode Library

text:
# Question
Title: Unicode Library
I am currently having "Requirements problem" with Drupal. When I 'Verify requirements' at the start, I get an issue of not being able to continue.

> **Unicode library**
>
> **Multibyte string input conversion in PHP is active and must be disabled. Check the php.ini mbstring.http\_input setting. Please refer to the PHP mbstring documentation for more information.**

The Unicode library is the issue.

# Answer
Disable multibyte string input conversion either

in your **php.ini** (and reload Apache):

```
mbstring.http_input = pass
mbstring.http_output = pass

```

OR in your **.htaccess** (which already should be there by default, so maybe only your .htaccess is missing):

```
php_value mbstring.http_input pass
php_value mbstring.http_output pass

```

OR in your **settings.php**:

```
ini_set('mbstring.http_input', 'pass');
ini_set('mbstring.http_output', 'pass');

```
> 1 votes

---
Tags: files
---


title: Composer cannot delete .editorconfig

text:
# Question
Title: Composer cannot delete .editorconfig
I'm trying to install a third-party library in Drupal 8 by doing 'composer update'. I get this:

I have made it seemingly impossible for it not to be able to delete .editorconfig:

But I still get the same error. What should I try next?

# Answer
> 0 votes
From https://superuser.com/questions/373115/why-cant-i-delete-a-file-where-i-have-group-write-permissions-on

* File deletion is based on directory perms, not file perms (\*).

That said, check the directory `/var/www/html/drupal_2020` permissions.

---
Tags: composer
---


# Question
Title: How to insert value to user entity custom field while creating new account?
I am trying to insert a value into a custom field(`field_custom_referral`) which is created in the backend.When a user creating a account in our application, this particular custom field should be updated with custom value. Can anyone help me out here.

I tried below code in .module file but not working out:

```
function module_user_insert(Drupal\Core\Entity\EntityTypeInterface $entity) {
  $entity->set('field_custom_referral', '3');
  $entity->save();
}

```

Any suggestion will be appreciated.

# Answer
The `hook_ENTITY_TYPE_insert` in case of entity user expecting `Drupal\user\UserInterface` instance not `Drupal\Core\Entity\EntityTypeInterface`

change your hook to:

```
/**
 * Implements hook_ENTITY_TYPE_insert().
 */
function MYMODULE_user_insert(Drupal\user\UserInterface $user) {
  $user->set('field_custom_referral', '3');
  $user->save();
}

```
> 1 votes

---
Tags: 8, users
---


# Question
Title: How to programmatically set node alias on node save
I need to set a special path alias for nodes created by users in the `template.php` file of my theme. the pathauto module is enabled. I already tried the solutions that are given in the following links

1. Create path alias programatically when node is created
2. How To Set Node Path/Alias Programatically
3. Programmatically set path alias

But none of them worked. Here is a few codes I tried but I failed.

```
function THEME_nodeapi(&$node, $op, $a3=NULL, $a4=NULL){
    if($node->type == "image"){
        switch ($op){
            case "insert":
                $default_node_path = 'node/'.$node->nid;
                $alternate_url = "SOME SPECIAL PATH";
                path_set_alias($default_node_path, $alternate_url, 0, '');
                break;
        }
    }
}

```

or this one

```
function THEME_insert($node){
    $path = "SOME SPECIAL PATH";
    $node->path = array('alias' => $path, 'pathauto' => FALSE);
}

function THEME_node_insert($node){
    $path = "SOME SPECIAL PATH";
    $node->path = array('alias' => $path, 'pathauto' => FALSE);
}

```

or

```
function THEME_nodeapi(&$node, $op, $a3=NULL, $a4=NULL){
    if($node->type == "image"){
        switch ($op){
            case "insert":
                $node->path = t("SOME SPECIAL PATH");
                break;
        }
    }
}

```

How can I do set path alias programmatically ?

---

**UPDATE**

I tried this code that recommended by @Ajit S and it didn't work again

```
<?php
    function THEME_node_insert($node){
        $alias = "arar/".$node->nid;
        $lang_code = "en";
        $path = array(
          'source' => "node/{$node->nid}",
          'alias' => $alias,  // Any alias that you want to set.
          'language' => $lang_code,  // Optional, if you are working on a multilingual site.
        );
        path_save($path);
    }

```

# Answer
> 2 votes
Use hook\_insert

```
/**
 * Implements hook_insert().
 */
function mymodule_insert($node) {
    // Set the URL alias
    if (empty($node->path['alias'])) {
        $node->path['alias'] = 'slug/' . $node->nid;
    }
}

```

if url has no alias then we can create it

```
if( urlAlias == '' )
path_set_alias($default_node_path, $alternate_url, 0, '');

```

# Answer
> 6 votes
Path alias could be set using the path module in the core. Just call `path_save` the following from a function (or hook) of your choice. In your case I'd recommend you to implement the following code in `hook_node_insert`, because it is called after a node has been saved, and the node will have a valid nid.

```
// Assuming you have a $node object already.
$path = array(
  'source' => "node/{$node->nid}",
  'alias' => $alias,  // Any alias that you want to set.
  'language' => $lang_code,  // Optional, if you are working on a multilingual site.
);
path_save($path);

```

If you have global redirect set, the node page will be redirected to the alias.

# Answer
> 6 votes
None of the hook\_nodeapi implementations will work, that hook was removed in Drupal 7.

Your other attempts are failing because you're trying to implement the hooks in a theme - themes can implement theme hooks, hook\_theme, and alter hooks only.

Move your code to a module, and you'll have better luck.

# Answer
> 1 votes
I know this is an old post, but I just discovered a great way to do this for a Drupal 7 site:

1. In `hook_node_presave`, set `$node->path['pathauto']` equal to 0 if `$node->original` is not yet set (that is, if this is a node insert and not a node update). This prevents an automatic alias from being applied if one normally would.
2. In `hook_node_insert', create the new path using`path\_save`and make sure the source is`node/nid\`.

Here is an example for a custom module called `mymodule` assuming you want this for all new `mytype` nodes with a 'my\_field`value not equal to`1`, and that you want to customize the alias as`mycustomalias/my\_field/nid\`:

```
function mymodule_node_presave($node) {
  // Add any conditions that determine whether this node needs a custom alias.
  if (
    $node->type == 'mytype' &&
    !isset($node->original) &&
    isset($node->field_my_field['und'][0]['value']) &&
    $node->field_my_field['und'][0]['value'] != 1
  ) {
    $node->path['pathauto'] == 0;
  }
}

function mymodule_node_insert($node) {
  // Add the same conditions as you had in mymodule_node_presave, except you don't need to check for $node->original.
  if (
    $node->type == 'mytype' &&
    isset($node->field_my_field['und'][0]['value']) &&
    $node->field_my_field['und'][0]['value'] != 1
  ) {
    // Create a $new_path array that contains the source of your node and the custom alias you want.
    $new_path = [
      'source' => 'node/' . $node->nid,
      'alias' => 'mycustomalias/' . $node->field_my_field['und'][0]['value'] . '/' . $node->nid],
    ];
    // Save the path. By using the variable above rather than putting the array into the function call, you avoid PHP errors.
    path_save($new_path);
  }
}

```

---
Tags: 7, nodes, hooks, path-aliases
---


title: Geocoder and KML files

text:
# Question
Title: Geocoder and KML files
I am using Drupal 8 and I am trying to display a map of a Geofield field, using Leaflet. This part works as expected when I manually enter coordinates into the Geofield.

But problem comes with the geocoding part : I set up a File field to store a KML file. When the Geofield is told to geocode from the KML file field, each time I create or modify a content, two messages are shown :

* a warning about the fact the file "cannot be geocoded",
* an error saying that Drupal "could not find geo data in file" xxx.

Checking the Drupal log adds an interesting information : there is a php warning with a huge message starting with :

> Warning : exif\_read\_data(test.kml): File not supported in Drupal\geocoder\Geocoder\Provider\File-\>geocode()

The problem may come from the Geocoder plugin I use for the Geofield geocoding : I can select several plugins in the field management section, all of them apparently dealing with address geocoding, except a "File" plugin. I tried to check only this latter, or all, with the same failing result.

I thought the 'File" Geocoder plugin would be able to deal with KML, GPX... but it may be only for pictures shot containing exif data. Is there a specific plugin for KML files ? And what is the way to make it appear in the Geofield management ?

Anyway, I have tried for hours to find a solution, without any success for any file types (KML, GPX...).

Any help would be greatly appreciated.

Regards,

Remi.

# Answer
I had a similar problem but not with leaflet. It seems the geocoder could not parse kml files with polygons, only points. I had some railroad routes that worked fine on google earth but not in drupal 8. I redrew the routes that were "single lines" and it worked fine.
> 0 votes

---
Tags: 8, entities
---


# Question
Title: Installed Module crash my site. How do I bring my site back up by uninstalling a module
I installed a module but it crashed my site and I can't get to the administrator backend anymore. How do I disable this module to bring the site back up?

# Answer
> 1 votes
In Drupal 8, try to removing the module from your module folder and run http://YOURSITENAME/update.php

or

Removing module via Database \- In Drupal 8 it is a bit hard to remove a module.

I think the best way is to use Drush.

```
drush pm-uninstall module-name (machine-name)

```

---
Tags: installation
---


# Question
Title: Is it possible to bypass the local filesystem completely using an alternative filesystem?
I'm using a cloud hosting provider to host a Drupal site (7 moving to 8) with a huge amount of static file assets. The host charges a lot for file space.

Is there a way to bypass the local filesystem entirely using a third-party file storage system? Success stories most welcome!

# Answer
> 0 votes
Google drive field \- Have never tried it. But it should do the job.

S3 file storrage \- This is for amazon file-storage.

---
Tags: 7, files, cdn
---


# Question
Title: How to have a dialog box displayed automatically when a page is reached without having to click the link?
Using Dialog API and advice from @leymannx, I added this link to a node (node99):

```
<a class="use-ajax" data-dialog-options="{"width":600}" data-dialog-type="modal" href="/node/27">Last minute information</a>

```

and it works fine: when clicked, the dialog box shows up!

Now, I'd like to have the dialog box displayed automatically when the node is reached without having to click the link.
@No Sssweat suggested to `make jQuery to click the link for you on page load $(".use-ajax").click();`

After some errors (`$ is not a function`), I finally used this:

```
(function ($) {
  $('.use-ajax').trigger("click");
})(jQuery);

```

It works but not as expected: the node 27 (the link has `href="/node/27"`) is displayed instead of node99, not in a modal over node99.
What am I missing?

# Answer
> 1 votes
Your JS needs to be formatted like this:

```
(function ($, Drupal) {
  Drupal.behaviors.myThemeBehavior = {
    attach: function (context, settings) {
      $('.use-ajax', context).once('auto-open').each(function () {
        $(this).click();
      });
    }
  };
})(jQuery, Drupal);

```

Your library needs to be defined like this:

```
example:
  js:
    js/example.js: {}
  dependencies:
    - core/jquery #Just ot be save
    - core/drupal.dialog.ajax #Required for dialogs

```

---
Tags: 8, modal-dialogs
---


# Question
Title: How to show last login time and user email to all authenticated users?
I have created a view for user profile page. I also want to show the user's current email address and last login time. It is working fine for admin but email and last login time is not visible to authenticated user on front end. I have granted the View User Information permission to authenticated users but no success after that too. Is it a permission issue or something else ? What I am missing ?

# Answer
EDIT:

I set up a test View myself and confirmed the issue you reported. Upon some search, I see this is intended behaviour.

There is a thread discussing it here: https://www.drupal.org/project/drupal/issues/2799049

The thread has a very simply Core patch to resolve the issue that could be applied. Or, there's also information on using hook\_entity\_field\_access() to grant field-level access to User fields.

https://www.drupal.org/project/drupal/issues/2773645

\************************ORIGINAL INFO\***************************

From what you've said, it seems like it should work as you'd expect.

One thing you can try is checking the "Disable SQL rewriting" checkbox in your View. This will bypass ALL permission checking for the View. It is located in the Query Options setting in the Advanced section of your View config.

If checking this works then you'll know that,at least, the issue is permissions related.
> 1 votes

# Answer
You have to give "Administer users" permission to view the email and last login details of any user.

Note: This permission needs to be given for trusted user.
> 0 votes

---
Tags: views, 8, users
---


# Question
Title: Creating a drupal-composer/drupal-project gave me an outdated version of core
When I ran

```
composer create-project drupal-composer/drupal-project:8.x-dev mysite --no-interaction

```

it installed `drupal/core:8.8.0-alpha1`. Then to see what was wrong, I ran

```
composer prohibits drupal/core:8.8.5

```

and the output was

```
drupal/core-dev 8.8.0-alpha1 requires drupal/core (self.version)
drupal/core 8.8.5 requires zendframework/zend-diactoros (^1.8)
drupal-composer/drupal-project dev-master does not require  zendframework/zend-diactoros (but 1.7.2 is installed)

```

What should I do next to get the most recent stable version? Was I supposed to run `composer create-project drupal-composer/drupal=project:8.8.5`?

# Answer
Installed Drupal using this instead: composer create-project Drupal/recommended-project mysite and everything is current and correct.
> 1 votes

---
Tags: installation, composer
---


# Question
Title: How do I use PathMatcher::matchPath() for a wildcard path?
I am trying to use `PathMatcher::matchPath()` to match a string of paths using a wildcard pattern.

I'd like to match any path containing `/topic*` so if the path matches, I'd like to add a body class for pages that have `/topic`, `/topic/foo`, `/topic/bar`, etc..

The code I am using is the following.

```
function mytheme_preprocess_html(array &$vars) {
  // Define the current path.
  $current_path = \Drupal::service('path.current')->getPath();
  // Define the pattern using a string.
  $patterns = "/topic/*";
  // If the path matches the pattern.
  if (\Drupal::service('path.matcher')->matchPath($current_path, $patterns)) {
    $vars['attributes']['class'][] = 'is-topic';
  }
}

```

The code doesn't work to match this pattern so no class is added when I am on any of these pages.

My Xdebug info is as follows for the page that has the path `topic/review-procedures`

```
$current_path = /node/62
$path_alias = topic/review-procedures

```

Note that some pages with `/topic/` in the path will not be nodes however, that is why I am trying to do the path matching.

Am I correctly using `PathMatcher::matchPath()`?

# Answer
In your sample you were comparing the internal path (/node/123) with a path alias pattern (/topic/\*). This won't work. You need to do the matching with the path alias instead.

```
/**
 * Implements template_preprocess_html().
 */
function MYTHEME_preprocess_html(&$variables) {
  $current_path = \Drupal::service('path.current')->getPath();
  $current_alias = \Drupal::service('path.alias_manager')->getAliasByPath($current_path);
  if (\Drupal::service('path.matcher')->matchPath($current_alias, '/topic/*')) {
    $variables['attributes']['class'][] = 'is-topic';
  }
}

```

You could achieve the same by exploding the current request URI and then see if the first key is `topic`.

```
/**
 * Implements template_preprocess_html().
 */
function MYTHEME_preprocess_html(&$variables) {
  $request_uri = ltrim(\Drupal::request()->getRequestUri(), '/');
  $args = explode('/', $request_uri);
  if (isset($args[0]) && $args[0] === 'topic') {
    $variables['attributes']['class'][] = 'is-topic';
  }
}

```
> 5 votes

---
Tags: 8, theming
---


# Question
Title: How can I add JavaScript only on the front page?
I created a custom Theme: filhos\_do\_porto using Bartik as a subtheme and I would like to add JS code only to the Front Page.

Can someone help me? (I didn’t find anything specific of D8 clear enough for someone new in Drupal)

# Answer
> 5 votes
One way, in your `mytheme.theme` file:

```
/**
 * Implements hook_page_attachments_alter().
 */
function mytheme_page_attachments_alter(&$attachments) {
  if (\Drupal::service('path.matcher')->isFrontPage()) {
    $attachments['#attached']['library'][] = 'mytheme/library-name';
  }
}

```

This points to an entry in your `mytheme.libraries.yml` file which list out what file(s) to load.

# Answer
> 1 votes
You can use another trick if you have a twig file for the front page then use this code below the twig file. Generally, the front page twig file name is -

> page--front.html.twig

```
{{ attach_library('themename/library-name') }}

```

---
Tags: 8, javascript
---


# Question
Title: jQuery once callback function is not called
I'm struggling with the **once** function. The once callback function is not called. I'm trying to use like this:

```
(function ($, Drupal){
  Drupal.behaviors.my_module = {
    attach: function (context, settings) {
      console.log('this runs');

      $('.my_selector', document).once('special-mark', function() {
        console.log('this never called');
      });

      console.log('this also called');
    }
  }
})(jQuery, Drupal);

```

In the library file I use the following:

```
dependencies:
  - core/jquery
  - core/jquery.once
  - core/drupal

```

There's no a single error in the console. It's just simply not called the callback... How can I make it work?

Drupal: 8.8.4
jQuery: 3.4.1

# Answer
> 2 votes
jQuery `once` doesn't take a callback as a second parameter. You need to loop over the returned list of elements and apply a callback using one of the standard methods like `each`:

```
$('.my_selector', document).once('special-mark').each(function() {
  console.log('this will be called');
});

```

---
Tags: 8, javascript
---


# Question
Title: Functional tests report constants are undefined, even if the constant is set in the test or phpunit.xml
I have unit and kernel tests that check for the existence of secrets (via `define`) in a settings.secrets.php file in my local site (Acquia Cloud convention). This file is not committed to the repo, stored in the database or exported.

When writing a functional test, I ran into an issue (which sounds similar to this one). If I tried to put `define` in my test file, I would just get an error and test failure saying the constant is undefined.

I came up with this, overriding `prepareSettings()` to write to the settings file generated for functional tests:

```
  /**
   * {@inheritdoc}
   */
  protected function prepareSettings() {
    parent::prepareSettings();
    $directory = DRUPAL_ROOT . '/' . $this->siteDirectory;
    copy(DRUPAL_ROOT . '/sites/example.secrets.settings.php', $directory . '/secrets.settings.php');
    $append_line = 'include_once dirname(__FILE__) . \'/secrets.settings.php\';';
    file_put_contents($directory . '/settings.php', $append_line, FILE_APPEND);
  }

```

The file that is copied just contains `define` statements with fake values.

Is this a valid approach to fixing this problem in a functional test, or did I miss something else and don't need the above code?

**Update**:

The code in the question only works for Functional tests as they have that method. Lower level kernel and unit tests have no access to that.

Instead, I found that you can add constants to phpunit.xml and then the tests have them defined:

```
    <php>
        <const name="MYMODULE_API_URL" value="https://api.myproject.localhost"/>
        <const name="MYMODULE_API_KEY" value="123456789"/>
        <!-- Set error reporting to E_ALL. -->
        <ini name="error_reporting" value="32767"/>

```

There appears to be one exception though - BrowserTests that have calls to `drupalGet` can still throw `Use of undefined constant` exception and fail the test. I can't figure that part out. I also tried using a testing profile that does not enable page or dynamic cache - same result. For now I had to comment out the drupalGet calls until I figure it out later.

However by adding it to phpunit.xml, you cannot do it in `prepareSettings` or you get a 'constant already defined'. So it appears that it is aware of the existing of this value.

Why do non BrowserTests not adhere to constants that are set either in code or in phpunit.xml, but any other tests do?

**Update 2**:

Here is the code in the test. The lines in the first loop for `drupalGet` will fail with the error, but curiously, the last block passes just fine:

```
    foreach ($permitted as $account) {
      $this->drupalLogin($account);

      foreach ($this->entity_types as $entity_type) {
        $this->drupalGet('node/' . $entity_type['nid'] . '/edit');

        if ($entity_type['response'] === 200) {
          $this->assertLinkByHref('/node/' . $entity_type['nid'] . '/update');
          $this->assertLinkByHref('/node/' . $entity_type['nid'] . '/data');
        } else {
          $this->assertNoLinkByHref('/node/' . $entity_type['nid'] . '/update');
          $this->assertNoLinkByHref('/node/' . $entity_type['nid'] . '/data');
        }

        $this->drupalGet('/node/' . $entity_type['nid'] . '/update');
        $this->assertResponse($entity_type['response']);

        $this->drupalGet('/node/' . $entity_type['nid'] . '/data');
        $this->assertResponse($entity_type['response']);
      }

      $this->drupalLogout();
    }

    // As someone without the specific permission
    $this->drupalLogin($this->staff);

    foreach ($this->entity_types as $entity_type) {
      $this->drupalGet('node/' . $entity_type['nid'] . '/edit');
      $this->assertNoLinkByHref('/node/' . $entity_type['nid'] . '/update');
      $this->assertNoLinkByHref('/node/' . $entity_type['nid'] . '/data');
      $this->drupalGet('/node/' . $entity_type['nid'] . '/update');
      $this->assertResponse(403);
      $this->drupalGet('/node/' . $entity_type['nid'] . '/data');
      $this->assertResponse(403);
    }

```

# Answer
The code in the question only works for Functional tests as they have that method. Lower level kernel and unit tests have no access to that, and thus, they would fail.

Instead, I found that you can add constants to phpunit.xml and then the tests have them defined:

```
    <php>
        <const name="MYMODULE_API_URL" value="https://api.myproject.localhost"/>
        <const name="MYMODULE_API_KEY" value="123456789"/>
        <!-- Set error reporting to E_ALL. -->
        <ini name="error_reporting" value="32767"/>

```

Then you can remove the `prepareSettings` method from functional tests. However, there seems to be another bug (that I can't track down) where tests that use drupalGet can sometimes fail with an undefined constant error, even though it is defined in the configuration file (you can do it in code too, and will still fail).

My only guess here is that its an issue with a new process spawn not getting the defined configuration from phpunit.xml, or files are loaded out of order (test file constants aren't seen?).

I settled on the following. I left the constants defined in phpunit.xml so my unit/kernel tests did not need them littered in the tests. For functional tests, I put prepareSettings back in with some changes:

```
  protected function prepareSettings() {
    parent::prepareSettings();
    $directory = DRUPAL_ROOT . '/' . $this->siteDirectory;
    copy(DRUPAL_ROOT . '/sites/functional.settings.php', $directory . '/functional.settings.php');
    $append = 'include dirname(__FILE__) . \'/functional.settings.php\';';
    file_put_contents($directory . '/settings.php', $append, FILE_APPEND | LOCK_EX);
  }

```

The contents of the file:

```
/**
 * @file
 * Functional tests settings file.
 *
 * There is a weird bug where constants are not recognized in certain cases
 * in functional tests, despite them being defined in phpunit.xml.dist.
 *
 * Functional tests should include any required constants here to avoid this
 * bug.
 *
 * @see https://drupal.stackexchange.com/questions/292713/functional-tests-report-constants-are-undefined-even-if-the-constant-is-set-in
 */

if (!defined('MYMODULE_API_URL')) {
  define('MYMODULE_API_URL', 'https://api.docker.localhost');
}

if (!defined('MYMODULE_API_key')) {
  define('MYMODULE_API_key', 'foobar');
}

```

Now, with the functional test uncommenting all the calls to drupalGet, all tests are passing with no errors about undefined constants.
> 0 votes

---
Tags: 8, testing, acquia-cloud
---