# Question
Title: Include initial price in commerce-order-receipt.html.twig
I have drupal 8 and commerce installed. The receipt email that is sent to the customers includes the final price of the product (with the promotion integrated). Is it possible to print the price of the product without the discount? I tried {{order\_item.getUnitPrice}} but I still get the price with the discount:

I paste below my template:

```
    {#
/**
 * @file
 * Template for the order receipt.
 *
 * Available variables:
 * - order_entity: The order entity.
 * - billing_information: The billing information.
 * - shipping_information: The shipping information.
 * - payment_method: The payment method.
 * - totals: An array of order totals values with the following keys:
 *   - subtotal: The order subtotal price.
 *   - adjustments: An array of adjustment totals:
 *     - type: The adjustment type.
 *     - label: The adjustment label.
 *     - total: The adjustment total price.
 *     - weight: The adjustment weight, taken from the adjustment type.
 *   - total: The order total price.
 *
 * @ingroup themeable
 */
#}

<!--[if gte mso 9]>
        <style>
            .ol {
              width: 100%;
            }
        </style>
    <![endif]--><!--[if gte mso 9]><table width="600" cellpadding="0" cellspacing="0"><tr><td>
                    <![endif]-->
                    <table border="0" cellpadding="0" cellspacing="0" class="container600" style="width:calc(100%);max-width:calc(600px);margin: 0 auto;" width="100%">
    <tbody>
        <tr>
            <td style="text-align:left" width="100%">
            <table cellpadding="0" cellspacing="0" style="min-width:100%;" width="100%">
                <tbody>
                    <tr>
                        <td style="color:#000000; padding:30px"><img alt="" src="http://itb.aserver.gr/sites/default/files/logo_idryma_voulis.jpg" style="display: block;" width="180" /></td>
                    </tr>
                </tbody>
            </table>

            <table cellpadding="0" cellspacing="0" style="min-width:100%;" width="100%">
                <tbody>
                    <tr>
                        <td style="color:#58585a; padding:30px">
                        <h3>{{ 'Order #@number details:'|t({'@number': order_entity.getOrderNumber}) }}</h3>

                        <p style="font-family:Arial,sans-serif; font-size:14px;">Ευχαριστούμε! Η παραγγελία σας καταχωρήθηκε επιτυχώς.</p>
                        <h3>Στοιχεία παραγγελίας:</h3>
                        </td>
                    </tr>
                    <tr>
                        <td style="padding-bottom:20px">
                        <table border="1" cellpadding="0" cellspacing="0" class="smarttable" style="min-width:100%;" width="100%">
                            <thead>
                                <tr>
                                    <th scope="col" style="padding:5px; font-family: Arial,sans-serif; font-size: 14px; line-height:20px;line-height:30px">Έκδοση</th>
                                    <th scope="col" style="padding:5px; font-family: Arial,sans-serif; font-size: 14px; line-height:20px;line-height:30px">Ποσότητα</th>
                                    <th scope="col" style="padding:5px; font-family: Arial,sans-serif; font-size: 14px; line-height:20px;line-height:30px">Σύνολο</th>
                                </tr>
                            </thead>
                            <tbody>
                                {% for order_item in order_entity.getItems %}
                                    <tr>
                                        <td style="font-family:Arial,sans-serif; font-size:14px; line-height:20px; padding:5px; vertical-align:top">
                                            <span>{{ order_item.label }}</span>
                                        </td>
                                        <td style="font-family:Arial,sans-serif; font-size:14px; line-height:20px; padding:5px; vertical-align:top">
                                        <span>x {{ order_item.getQuantity|number_format }}</span>

                                        </td>
                                        <td style="font-family:Arial,sans-serif; font-size:14px; line-height:20px; padding:5px; vertical-align:top">
                                            <span style="float: right;">{{ order_item.getTotalPrice|commerce_price_format }} {{order_item.getUnitPrice}}</span>

                                        </td>
                                    </tr>
                                    {% endfor %}
                                <tr>
                                    <td colspan="2" style="font-family:Arial,sans-serif; font-size:14px; line-height:20px; padding:5px; vertical-align:top"><strong>Αξία</strong></td>
                                    <td><strong>{{ totals.total|commerce_price_format }}</strong></td>
                                </tr>
                                    {% for adjustment in totals.adjustments %}
                                        <tr>
                                            <td colspan="2" style="font-family:Arial,sans-serif; font-size:14px; line-height:20px; padding:5px; vertical-align:top">
                                            {{ adjustment.label }}
                                            </td>
                                            <td>{{ adjustment.total|commerce_price_format }}</td>
                                        </tr>
                                        {% endfor %}
                                        <tr>
                                    <td colspan="2" style="font-family:Arial,sans-serif; font-size:14px; line-height:20px; padding:5px; vertical-align:top"> Σύνολο:</td>
                                    <td>{{order_entity.getTotalPrice|commerce_price_format}}</td>
                                </tr>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                    <tr>
                        <table border="1" cellpadding="0" cellspacing="0" class="smarttable" style="min-width:100%;" width="100%">
                            <thead>
                                <tr>
                                    <th scope="col" style="padding:5px; font-family: Arial,sans-serif; font-size: 14px; line-height:20px;line-height:30px">{{ 'Billing Information'|t }}</th>
                                    <th scope="col" style="padding:5px; font-family: Arial,sans-serif; font-size: 14px; line-height:20px;line-height:30px">{{ 'Shipping Information'|t }}</th>

                                </tr>
                            </thead>
                            <tbody>
                            <tr>
                                <td>
                                {% if billing_information %}
                                 {% block billing_information %}
                                {{ billing_information }}
                                {% endblock %}
                               {% endif %}
                               </td>
                            <td>
                            {% if shipping_information %}
                                {% block shipping_information %}
                                {{ shipping_information }}
                                {% endblock %}
                         {% endif %}
                         </td>
                            </tr>

                    </tr>
                    <tr>
                    <td>
                     <strong>{{ 'Selected Payment Method'|t }}</strong>
                    </td>
                    {# <td><strong>{{ 'Selected Shipping information'|t }}</strong></td> #}
                    </tr>
                    <tr rowspan="2">
                    <td>
                        {% if payment_method %}

                  <br/>
                    {% block payment_method %}
                      {{ payment_method }}
                    {% endblock %}
                    {% endif %}
                  </td>
                  {# <td>
                    {% if shipping_information %}
                   <br/>
                                {% block shipping_information_2 %}
                                {{ shipping_information }}
                                {% endblock %}
                         {% endif %}
                  </td> #}
                </tr>

                </tbody>
            </table>

            <table cellpadding="0" cellspacing="0" style="min-width:100%;" width="100%">
                <tbody>
                    <tr>
                        <td style="background-color:#2c3949; color:#ffffff; min-width:100%; padding:30px" width="100%">
                        <p style="font-size:16px;line-height:20px;font-family:Arial,sans-serif;text-align:center;">ΙΔΡΥΜΑ ΤΗΣ ΒΟΥΛΗΣ ΤΩΝ ΕΛΛΗΝΩΝ</p>
                        </td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<!--[if gte mso 9]></td></tr></table>
                    <![endif]-->

<p> </p>

```

# Answer
You could get the promotion value and add it back.

```
{% set promotions = order_item.getAdjustments(['promotion']) %}

{# assuming there is always one promotion, otherwise you'll want to loop here #}
{% set promotion_amount = promotions.0.getAmount.getNumber %}

{# since promotion is a negative number we have to substract to add back #}
{% set original_price = order_item.getUnitPrice - promotion_amount %}
{{ original_price }}

```
> 1 votes

---
Tags: commerce
---


# Question
Title: How to programmatically replace a field label and content before rendering?
I expected to be able to do it with `THEME_preprocess_field`, but the data at that point seems to have only the content's markup and not the label. I would need an instance where I can change both, because there's some mutual conditioning between them.

I also tried with `THEME_node_view` to no effect.

Note: I want to do this in a theme, not a custom module.

# Answer
> I expected to be able to do it with THEME\_preprocess\_field, but the data at that point seems to have only the content's markup

There are more template variables:

*field.html.twig:*

```
{#
/**
 * @file
 * Default theme implementation for a field.
 *
 * ...
 *
 * Available variables:
 * - attributes: HTML attributes for the containing element.
 * - label_hidden: Whether to show the field label or not.
 * - title_attributes: HTML attributes for the title.
 * - label: The label for the field.
 * - multiple: TRUE if a field can contain multiple items.
 * - items: List of all the field items. Each item contains:
 *   - attributes: List of HTML attributes for each item.
 *   - content: The field item's content.
 * - entity_type: The entity type to which the field belongs.
 * - field_name: The name of the field.
 * - field_type: The type of the field.
 * - label_display: The display settings for the label.
 *
 * @see template_preprocess_field()
 *
 * @ingroup themeable
 */
#}

```

So you can change for example `label`:

*mytheme.theme:*

```
/**
 * Implements hook_preprocess_HOOK() for field.html.twig.
 */
function mytheme_preprocess_field(&$variables) {
  $variables['label'] = 'foo';
}

```
> 2 votes

---
Tags: 8, theming, hooks
---


title: Assign roles at registration

text:
# Question
Title: Assign roles at registration
I am trying to assign a user role at registration using Webforms in Drupal 8. Is this possible or is there another form module that would do it better? I have two user roles 'Venue' and Artist' which will be used throughout the site still using Webforms to enter data specific to user role. New to D8. Thank you.

# Answer
Oneway you can do is using hook\_form\_alter()

```
function MYMODULE_form_user_register_form_alter(&$form, FormStateInterface $form_state, $form_id) {
     foreach (array_keys($form['actions']) as $action) {
        if ($action != 'preview' && isset($form['actions'][$action]['#type']) && $form['actions'][$action]['#type'] === 'submit') {
          $form['actions'][$action]['#submit'][] = '_add_role_submit';
        }
      }
}
/**
 * Implements submit to set role to user.
 */
function _add_role_submit(array &$form, FormStateInterface $form_state) {
  $values = $form_state->getValues();
// HERE YOU CAN SET ANY ROLE FOR USER.
}

```

Another way is using hook\_user\_insert()

```
use Drupal\user\UserInterface;
function MYMODULE_user_insert(UserInterface $user) {
  // HERE YOU CAN SET ANY ROLE FOR USER.
}

```
> 2 votes

# Answer
Above form alter solution didn't work for me and I don't want to use hook\_user\_insert() as I want to assign the role only when the user is created from user/register form, not from Admin interface. So I found a solution myself and sharing here if it helps any one else.

```
/**
 * Implements hook_form_FORM_ID_alter().
 */
function member_portal_form_user_register_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
    array_unshift($form['#validate'], "_add_default_role_validate");
}
/**
 * Implements _add_default_role_validate.
 */
function _add_default_role_validate(array &$form, \Drupal\Core\Form\FormStateInterface $form_state) {
    // Add default roles here
    $form_state->setValue('roles', [
       'authenticated',
        'venue_creator',
        'supplier_creator'
    ]);
}

```
> 0 votes

---
Tags: 8, users
---


# Question
Title: Image File Upload via REST case Error 500 response due destination directory not set
I'm struggling to upload images to the Drupal 8 site via REST. Finally, I managed to deliver the file to the server, but then the error 500 rased due destination folder not set. I can't figure where to define this destination directory: in request JSON data or header, or somewhere else in the settings.php or somewhere in REST configuration?

Here my code in Python:

```
def create_drupal_image(session, oauth, media_name, image_path):
    file_size = os.stat(image_path).st_size
    with open(image_path, "rb") as image_file:
        encoded_string = base64.b64encode(image_file.read())

    payload = {
        "filename": [
            {
                "value": media_name + ".jpg"
            }
        ],
        "filemime": [
            {
                "value": "image/jpeg"
            }
        ],
        "filesize": [
            {
                "value": str(file_size)
            }
        ],
        "type": [
            {
                "target_id": "image"
            }
        ],
        "data": [
            {
                "value": "data:image/jpeg;base64," + str(encoded_string)
            }
        ],
        "_links": {
            "type": {
                "href": oauth.base_url + REST_TYPE_FILE_IMAGE
            },
        }
    }
    return create_drupal_entity_impl(session, oauth, ENTITY_FILE_URL, payload)

def create_drupal_entity_impl(session, oauth, url, payload):
    payload_str = json.dumps(payload)
    # print(payload_str)
    endpoint = oauth.base_url + url
    # Set all required headers
    headers = {
        'Content-Type': 'application/hal+json',
        'Accept': 'application/hal+json',
        'Authorization': 'Bearer ' + oauth.access_token
    }
    # Post the new node (a Contact) to the endpoint.
    response = session.post(endpoint, data=payload_str, headers=headers, verify=oauth.verify)
    return handle_create_response(response)

```

Edited this source core/lib/Drupal/Core/File/FileSystem.php line 488 in order to print the $destination, and it appears to be empty. See **''** in the server log below:

```
AH01071: Got error 'PHP message: Uncaught PHP Exception Drupal\\Core\\File\\Exception
\\DirectoryNotReadyException: "The specified file 'temporary://filemDIAwD' could not be copied
because the destination '' directory is not properly configured. This may be caused by a problem
with file or directory permissions." at /var/www/vhosts/web.site/core/lib/Drupal/Core/File
/FileSystem.php line 488'

```

Tried to define 'file\_private\_path' folder in settings.php, added 'tmp' folder under 'sites/default/files' but with no result. What am I missing here?

# Answer
The missing property was destination "uri"

```
"uri": [
   {
      "value": "public://" + media_name + ".jpg"
   }
],

```
> 0 votes

---
Tags: files, configuration, 8
---


# Question
Title: what is the difference between Drupal.formatPlural() and Drupal.t()?
what is the difference between :

`Drupal.t(string, arguments, options )` and `Drupal.formatPlural()`

`Drupal.t()` is used in the javascript part to translate the string and it can accept a set of arguments that will translate the string placeholders ex:

```
var translatedString = Drupal.t('a string about @subject that needs to be translated', {'@subject': 'Javascript in Drupal'});

```

what about Drupal.formatPlural()

# Answer
> 3 votes
Actually after some playing aroud with the code I HAVE FOUND THE ANSWER :

```
formatPlural($count, $singular, $plural, array $args = array(), array $options = array());

```

# code

the **formPlural** function enable us to translate a string in plural or singular format according to the first argument **$count** , a **$singualr** string will display if **$count = 0 or 1** otherwise if **$count \> 1** the **$plural** string will be displayed , and in plural string we can get the **$count** value using **@count** , for example in the code bellow :

* the first **formPlural** function will return $singular string since $count = 1
* the second **formPlural** function will return $plural string since $count \> 1

```
var typeVar = 'list';
var singular = Drupal.formatPlural(1, 'I have 1 item', 'I have many @type items', {'@type': typeVar});
$('#translate_singular_item').html(  singular   );

var plural = Drupal.formatPlural(3, 'I have 1 item', 'I have @count @type items', {'@type': typeVar});
$('#translate_plural_item').html(  plural  );

```

# output

# Back-office Translation

now we can translate both singular and plural string :

---
Tags: i18n-l10n
---


# Question
Title: How to force rendering by the site theme instead of the admin theme?
When rendering HTML in `hook_node_presave()`, everything works as expected when I save the node manually.

However, when I use the "Save content" action on the content admin view (at /admin/content), then the page is rendered with the admin theme templates (Seven), instead of the templates of my custom theme/the site theme.

I tried using both Claro and Seven as the admin theme, and I get the same result: I can save the page manually and the site theme's templates are used, but if I use the "Save content" action to bulk re-save nodes, they are rendered incorrectly with the admin theme templates.

Here's the code that is causing the issue:

```
function MYMODULE_node_presave(NodeInterface $node) {
  $content_type = $node->getType();
  if ($content_type == 'page') {
    // Render the entire node and save that HTML to a specific field.
    $render_controller = \Drupal::entityTypeManager()
      ->getViewBuilder($node->getEntityTypeId());
    $render_output = $render_controller->view($node, 'mymarkup_torender', 'ja');
    $html = \Drupal::service('renderer')->renderPlain($render_output);
    $node->set('field_text_cached_html', $html);
    $node->field_text_cached_html->format = 'mymarkup_processed';
  }

```

Is there a way to force Drupal to use the site theme instead of the admin theme when rendering?

On the Appearance administration page, "Use the administration theme when editing or creating content" is unchecked.

# Answer
Based on the comment by @MrD, I found a working solution.

I implemented a custom theme negotiator based on this information:

I needed to change the theme for the admin content page, so here is the code I used:

**mymodule.services.yml**

```
  MYMODULE.theme.negotiator:
    class: Drupal\MYMODULE\Theme\ThemeNegotiator
    tags:
      - { name: theme_negotiator, priority: -20 }

```

Here, I used a low priority to ensure my code runs first.

**MYMODULE/src/Theme/ThemeNegotiator.php**

```
<?php

namespace Drupal\MYMODULE\Theme;

use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Theme\ThemeNegotiatorInterface;

/**
 * Select the correct theme for various routes.
 */
class ThemeNegotiator implements ThemeNegotiatorInterface {

  /**
   * {@inheritDoc}
   */
  public function applies(RouteMatchInterface $route_match) {
    return $this->negotiateRoute($route_match) ? TRUE : FALSE;
  }

  /**
   * {@inheritDoc}
   */
  public function determineActiveTheme(RouteMatchInterface $route_match) {
    return $this->negotiateRoute($route_match) ?: NULL;
  }

  /**
   * Select the theme for special cases.
   *
   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
   *   The currently matched route.
   *
   * @return bool|string
   *   The theme name to use (string) or false (bool).
   */
  private function negotiateRoute(RouteMatchInterface $route_match) {
    $route_name = $route_match->getRouteName();
    if ($route_name === 'system.admin_content') {
      return 'MYTHEMENAME';
    }
    else {
      return FALSE;
    }
  }

}

```
> 3 votes

---
Tags: 8, theming
---


# Question
Title: Clear only CSS/JavaScript cache when files are aggregated
When aggregating CSS/JavaScript files using performance page in Drupal 8, `drush cc css-js` doesn't work, and I've to clear/rebuild all cache.

How do I properly clear/rebuild only the JavaScript/CSS cache?

I want that the filenames change too, so that the browser resets its cache too.

# Answer
> 3 votes
**NOTE:** *I am using the s3fs plugin in order to store assets in an AWS S3 bucket, so if you are not using that your results could differ*

This is probably not a suggested method of forcing the system to clear the asset cache, but I was in the same boat and for some reason my file systems got mixed up during multiple edits between local, development, and the live site. For the live site I was only able to get the styles working if the files were not aggregated using the Performance page.

As far as I know, the system will not update the CSS or JS files unless a change has been detected. Aside from going in and making a change to every file I started digging into the database. I found that the file location for the CSS and JS assets were located in the "cache\_default" table with a value of something like below:

s3fs:uri:public://css/css\_0WFR6\_Et4WEJOkLOOpdg4f7EmvMRhsPkSk7KcrPyct4.css

and

s3fs:uri:public://js/js\_-YxTfPGZervj7hTx1tF6zyt9ua2DxHPROTbub3I\_WRg.js

**BACKUP YOUR DATABASE BEFORE GOING FURTHER! In case you mess anything up, CYA!**

1. I went through and deleted all entries that were a CSS or JS file. Be careful not to delete the directory reference entries that just have the JS and CSS folders.
2. THEN, since I was using s3fs I went into the "s3fs\_file" table and did the same thing.
3. I went back into the Performance page, enabled the CSS and JS aggregation, and saved.
4. Then cleared the site cache after that. This seemed to re-generate the CSS and JS assets, re-built the asset table data, and the site was back to normal!

I did have to dump the DB tables and import into my dev and local environments in order to mimic the new asset names, but this seemed to work like a charm.

**SIDE NOTE:** I am wondering if there would be some way for Drupal to add a style versioning system? Maybe that we could change the sites CSS versioning after major changes in order to have this done automatically? or maybe this is just something I will need to build my next module for!!

# Answer
> 0 votes
Drupal 8 Using Drush you can clear the generated files using

```
drush advagg-clear-all-files

```

or to force-generating new files by incrementing a global counter use

```
drush advagg-force-new-aggregates

```

# Answer
> -1 votes
You can run `drush ev` command to clear css-js cache, check example below:

```
drush ev '\Drupal::service("asset.css.collection_optimizer")->deleteAll(); \Drupal::service("asset.js.collection_optimizer")->deleteAll(); _drupal_flush_css_js();'

```

Above sample is taken from here.

---
Tags: 8, caching
---


# Question
Title: Adding to {{ html_attributes }} when a Twig Template is Used
I have a Paragraph Twig template that outputs FAQs in HTML format and also includes the Google FAQ data structure in the markup. What I need to do next is include `itemscope itemtype="https://schema.org/FAQPage"` into the `html` tag on any page in which that template is used, but I'm not entirely sure if:

* This is something that can be done in the faq.twig.html template, or
* If it needs to be done in the mytheme.theme file. If that's the case, I'd appreciate some guidance on how to do that when that particular Paragraph bundle is used.

Thanks in advance for you help.

# Answer
Drupal 8 collects metadata from any template rendered on a page and puts the result in placeholders of the html template. Unfortunately the html tag in html.html.twig is not placeholdered out-of-the-box:

*html.html.twig*

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

```

So you could add your own placeholder as dummy attribute:

*mytheme.theme*

```
/**
 * Implements hook_preprocess_HOOK() for html.html.twig.
 */
function mytheme_preprocess_html(&$variables) {
  $variables['html_attributes']['html-attribute-placeholder'] = '-';
}

```

and replace it with metadata you add to the faq template:

```
/**
 * Implements hook_preprocess_HOOK() for faq.html.twig.
 */
function mytheme_preprocess_faq(&$variables) {
  $variables['#attached'] = [
    'placeholders' => [
      'html-attribute-placeholder="-"' => [
        '#markup' => 'itemscope itemtype="https://schema.org/FAQPage"',
      ],
    ],
  ];
}

```

You are mentioning a faq template, but if this is a paragraph you probably don't have a specific template. Then add the metadata in a paragraph preprocess hook checking the bundle.
> 0 votes

# Answer
I had to do it in my website, so I can share a working example :

```
function mymodule_preprocess(array &$variables, string $hook) {
      if ($hook === 'paragraph' && $variables['paragraph']->getType() === 'your_paragraph_type') {
        if (is_array($variables['html_attributes'])) {
          $variables['html_attributes'] = new Attribute($variables['html_attributes']);
        }

        $variables['html_attributes']->setAttribute('itemscope', true);
        $variables['html_attributes']->setAttribute('itemtype', 'https://schema.org/FAQPage');
      }
}

```
> 0 votes

---
Tags: 8, theming, hooks
---


title: Drupal 8 Jquery/Ajax Views Arguments

text:
# Question
Title: Drupal 8 Jquery/Ajax Views Arguments
Setup: I have two contextual filters, service area and ID.

In my view if I send {service\_area}/{id} i get back the OR query, which is what I want. My question is, when I try to use Jquery to return this query, I do not get back the expected result, which is the OR of these two arguments.

Here is my code:

```
(function($) {
  Drupal.behaviors.searchresults = {
    attach: function (context, settings) {
      $('.currentFilters', context).once('search').click(function () {

        //hard set variable for this example.
        let args = [];
        args[0] = 'antelope valley';
        args[1] = '221';

        $.ajax({
          url: '/views/ajax',
          type: 'post',
          data: {
            view_name: 'webform_submissions',
            view_display_id: 'page_1',

            //This is where it may be causing an issue. I pass an array with the arguments, but no avail
            view_args: args,
          },
          ...
        });
      });
    },
  }
})(jQuery);

```

In my view I am able to see this OR if I preview with contextual filters as as seen in the image below:

If I just send `service_area` by itself as the argument, it will work. So my question is, what is the correct way of sending multiple arguments in ajax, any references/blogs to help me would be appreciated. Thank you!

# Answer
> 0 votes
I figured it out. I needed to pass a string not an object, the lack of documentation confused me.

```
    let args = 'antelope valley';
    args = args + '/207'

    $.ajax({
      url: '/views/ajax',
      type: 'post',
      data: {
        view_args: args,
 ...

```

---
Tags: views, javascript, ajax
---


# Question
Title: Clean GET parameters after submitting a 'GET' form
How to remove `form_build_id`, `form_id`, `op` parameters that are added to a URL after submitting a form using GET method in Drupal 8?

# Answer
`FormState::cleanValues` does exactly that:

> Removes internal Form API elements and buttons from submitted form values.
>
> This function can be used when a module wants to store all submitted form values, for example, by serializing them into a single database column. In such cases, all internal Form API values and all form button elements should not be contained, and this function allows their removal before the module proceeds to storage. Next to button elements, the following internal values are removed by default.
>
> * form\_id
> * form\_token
> * form\_build\_id
> * op

But as you're not POSTing the form you can't really use it. Two options spring to mind:

1. Implement your own cleaning method. This might be tricky as you don't have the form fields to work with so unless you have a list of known good fields available, there's always the possibility you'll include something you don't mean to
2. Change your form's flow to Post/Redirect/Get (PRG). The steps are roughly:

* Change the form method to POST
    * In the submit handler:
        + Use `FormState::cleanValues` to clean the input
        + Build a new Url with the desired redirect path, and query options made up of the clean form state values
        + Use `$form_state->setRedirect($url);` to redirect the user to the new URL

From the user's point of view, nothing really changes. They still end up at the same URL, just without the undesired query args.
> 2 votes

# Answer
If you want to avoid a redirect after POST, you can keep the form method as GET and add these two tweaks:

In your form definition:

```
$form['#method'] = 'get';
$form['#action'] = Url::fromRoute($destination_route)
  ->toString();
$form['submit'] = [
  '#type' => 'submit',
  '#value' => 'Whatever',
  // Prevent op from showing up in the query string.
  '#name' => '',
];

```

In your .module file:

```
/**
 * Implements hook_form_ID_alter().
 */
function your_module_form_your_form_alter(&$form, FormStateInterface $form_state) {
  // Hide these fields from the query string.
  $form['form_id']['#access'] = FALSE;
  $form['form_build_id']['#access'] = FALSE;
}

```
> 0 votes

---
Tags: 8
---


title: SMTP Module not sending email

text:
# Question
Title: SMTP Module not sending email
Using XAMPP on Mac

I have installed https://www.drupal.org/project/smtp

After setting up **admin/config/system/smtp**

It gives above error. Unable to send test email.

Do we have to any setting on gmail or i'm missing anything?

# Answer
> 0 votes
You probably have to be auth to be able to send mail from gmail's SMTP (smtp user/ smtp password). Moreover, you have to "allow" the sender's email in your google account.

theMailYouSendFrom@whatever.com have to be allowed to send mail with account yourAccount@gmail.com; somewhere in gmail's parameters, you can validate this mail.

I remember there is a limit, 450 mails/day for each google account (this could have change now, that was 3 or 4 years ago), and more with payed gapps.

# Answer
> 0 votes
I got this same error on 8.7.1 and smtp 8.x-1.0-beta4 version.

Followed the steps provided in the below link will solve the issue.

https://stevepolito.design/blog/drupal-configure-smtp-module-work-gmail-updated/

# Answer
> 0 votes
Check settings.php for overwritten SMTP settings.

# Answer
> 0 votes
try to use port 587 for gmail. Use encrypted protocol 'TLS'. Enable TLS encryption automatically On. Timeout 300.

this configuration is working fine for me

---
Tags: 8, emails
---


title: Programmatically get View Custom Text

text:
# Question
Title: Programmatically get View Custom Text
I created a view with a "Custom text" field and want to get this field programmatically in Drupal 8.

I have:

```
$view = Views::getView('my_view');
$view->execute();
foreach($view->result as $row){
    $node = Node::load($row->nid);
    // Get here the view custom field with label "An example view field".
}

```

The $row field doesn't have the fields, nor the $node.

A screenshot of the view:

I now have:

```
$customField = $view->field['nothing'];

```

customField is an instance of Drupal\views\Plugin\views\field\Custom.

```
dpm($customField->render($row));

```

This returns class Drupal\views\Render\ViewsRenderPipelineMarkup with protectecd string with the same markup: `{{ title }} test`.

Thanks,

# Answer
You should have something like

```
//already loaded
$node = $row->_entity;

```

Best way to get properties easily is probably to inspect variables with xdebug

If it is some king of header/footer, you can get the rendered array this way :

```
$view = \Drupal\views\Views::getView('Your view');
$view->execute();
/* @var $area \Drupal\views\Plugin\views\area\Text */
$area = reset($view->header); // $view->header['area'] or something else
$rendered = $area->render(); // rendered array

```

Ok, then :

```
$view = \Drupal\views\Views::getView('YOUR VIEW');
$view->execute('YOUR DISPLAY ID OR DEFAULT');
$nothing = $view->getHandler('YOUR DISPLAY ID OR DEFAULT','field', 'nothing');
$text = $nothing['alter']['text'];

```
> 2 votes

# Answer
Please install the devel module

Go to /drupal8/devel/php

You can try:

```
$view = \Drupal\views\Views::getView('my_view');
$view->execute();

foreach($view->result as $row){
dpm($row->_entity->get('Custom text')->getValue());
}

```

***note:*** *change "Custom text" by machine name of the field*

if your result is similar to:

```
Array
(
    [0] => Array
        (
            [value] => 43
        )

)

```

you can access the field with

```
$row->_entity->get('Custom text')->value

```

if your result is similar to:

```
Array
(
    [0] => Array
        (
            [target_id] => 1
        )

)

```

you can access the field with

```
$row->_entity->get('Custom text')->target_id

```
> 2 votes

# Answer
You can also use `hook_preprocess_views_view_field` in order to change your custom text field:

```
function hook_preprocess_views_view_field(&$variables) {
  if ($variables["view"]->id() == "VIEW_ID" && $variables["field"]->options["id"] == "nothing") {
    $doYourCalculation = "New Text";
    $variables["output"] = ViewsRenderPipelineMarkup::create($doYourCalculation);
  }
}

```
> 2 votes

# Answer
This is what I have, however, I feel there must be a better way to do this.

Some notes:

* $view-\>render(); is critical, without it, it doesn't work
* 'nothing' is the default name of custom field, adding additional fields will result 'nothing\_1', 'nothing\_2', etc. You can see the name when hovering over the field (in the link) or in the replacement patterns.
* The value returned with a lot of \n in it. I'm replacing them here, but this can have unwanted side effects.

The code:

```
// The machine name of your view.
$viewname = 'name_of_the_view';

// Get the view.
$view = \Drupal\views\Views::getView($viewname);

// Display machine name.
$view->setDisplay('default');

// Execute the view.
$view->preExecute();
$view->execute();
$view->render();

foreach(array_keys($view->result) as $row_index){
  $custom_field = str_replace("\n", '', $view->field['nothing']->tokenizeValue((string)$view->field['nothing']->original_value, $row_index));
}

```
> 0 votes

# Answer
I had a similar problem and the only way worked for me was the following:

```
function MODULENAME_preprocess_views_view_fields(&$vars) {
  $view = $vars['view'];
  if(isset($view) && $view->id() === 'test') {
    foreach ($view->field as $id => $field) {
      // change the global custom text content for a specific
      // result row.
      if ($vars['row']->nid == 149) {
        $vars['fields']['nothing']->content = 'some new text';
      }
    }
  }
}

```
> -2 votes

# Answer
```
  $view = \Drupal\views\Views::getView( 'view_name' );
  $view->execute();
  foreach ($view->result as $row) {
  kint($row->_entity->get( 'nid' )->getValue()[0]['value']);
  }

```
> -2 votes

---
Tags: views, 8
---


# Question
Title: How do "Order Types" and "Order Item Types" work?
I'm using the Commerce framework. I'm trying to understand exactly how "Order Types" and "Order Item Types" work. (I've consulted the docs; they don't really address this question.)

So far, I've deduced that:

* The Checkout Flow that Drupal uses is determined by the Order Type that's in play.
* Every Order has an Order Type.
* Every Order Item has an Order Item Type.
* Every Order Item Type belongs to an Order Type.

...but that's as far as I've gotten. I'm trying to understand:

* What rules does Drupal use to decide which Order Type it's dealing with? (That is, *how* does it know which Order Type is in play?)
* At what point in the is this decision made? (When the user first adds an item to their cart? When they begin the checkout process? At some other point?)

Thanks!

# Answer
> 4 votes
> To pose my question a bit differently: using only the Drupal web dashboard, how can I configure Drupal to use a particular checkout flow in a particular scenario?

From a UI perspective, here is how it works:

1. Product Type -- Points to a Product Variation Type.
2. Product Variation Type -- Points to an Order Item Type.
3. Order Item Type -- Points to an Order Type.
4. Order Type -- Points to a **checkout flow** and **workflow**.
5. Checkout Flow

**Side Note:** When creating these you should do it in reverse order, as for example 1. depends on 2. to be created already.

So when you add a product to the cart, Drupal checks the chain from 1 to 4.

If at 4. product A has a different Order Type than Product B then a separate cart is created. Even if both order types have the same checkout flow and workflow.

Now when you go to `/cart` you should see two separate carts.

 **Note:** There is a bug where it doesn't display the Product name on the top cart, you can get around it by adding order item title to the cart form view, as I did, as you can see in the last column.

So whichever you decide to checkout, that workflow is used and for that particular cart. Which means you would have to checkout two separate times in order to buy product A and B in this scenario.

# Answer
> 3 votes
> What rules does Drupal use to decide which Order Type it's dealing with?

That's determined by order type resolvers (implementing `OrderTypeResolverInterface` in this case). Such resolvers are given an order item, and must use that to determine the type of order.

Out of the box, the default resolver (`DefaultOrderTypeResolver`) uses the bundle of the given order item, which will be an order item type ID, to load that item type entity, and get the associated order type ID from it.

> At what point in the is this decision made?

There are probably multiple places that decision is made (creating orders in the admin UI for example), but in terms of the cart, it happens when the cart is created, which in turn happens when an item is first added to it via the standard `AddToCartForm` submission.

So I think it's fair to say that the type of an order that originated from a cart will always be the type associated with the first item that was added to it.

---
Tags: 8, commerce
---


# Question
Title: How to programmatically copy Webform handler config?
I would like to copy the Webform handler from 1 Webform into another. I can get hold of Webform settings via:

```
/** @var \Drupal\webform\WebformInterface $webform */
$webform = \Drupal::entityTypeManager()->getStorage('webform')->load('example_webform_id');
$webform->getSettings();
=> [
     "ajax" => false,
     "ajax_scroll_top" => "",
     "ajax_progress_type" => "",
     "ajax_effect" => "",
     ...

```

However that doesn't include the handler config that I would need and a way to save its new config as well.

I also tried it via the handler object itself:

```
/** @var \Drupal\webform\Plugin\WebformHandlerInterface[] $handlers */
$handlers = $webform->getHandlers('example_webform_handler_id');
$handler = $handlers->getIterator()->current();
$handler->setConfiguration($new_handler_config)->save();

```

for which it appears that there is no `save()` operation in the handler class:

> Error: Call to undefined method ::save()

Any way I can do this programmatically that you may know of?

# Answer
Ended up using the `ConfigFactory` service, which I believe is fine to do:

```
$config = \Drupal::configFactory()->getEditable('webform.webform.' . $webform->id());
$config_key = 'handlers.' . $webform_handler_id;
$config->set($config_key, $new_handler_config)->save();

```
> 2 votes

---
Tags: 8, webforms
---


# Question
Title: How do I add custom content fields to content types in Open Social?
I am trying to add fields to my new custom content type in Open Social (OS), the Drupal social networking distribution. I follow the regular procedure of adding a new custom content type from `/admin/structure/types/add`. OS will add the custom content type fine, but then after the new content type is created, the list of content types at `/admin/structure/types` shows only `Edit` or `Delete` operations in the combo box for the operations, with `Edit` being the default. Normally, there are possible operations of `Manage fields`, `Manage form display`, and `Manage display` as well in the combo box for the operations. Furthermore, when I use the normal path for adding a custom field for the content type, namely `/admin/structure/types/manage/<content type>/fields` where `<content type>` is the content type I just created, I get an error message of `The requested page could not be found`. OS exhibits the same behavior for existing content types like **Topic**. I have found this to be the case for version 8.7.8 and 8.8.10 of OS.

Does anyone know how to enable to ability to add and manage custom fields for new content types in Open Social?

# Answer
> 1 votes
Simple answer after I looked into it more. The issue is just whether the Field UI module (field\_ui) is enabled or not. This is a Drupal core module and by default it is not enabled in Open Social. But once field\_ui is enabled, then all of the custom fields can be managed appropriately.

---
Tags: 8
---


# Question
Title: Drupal module upgrade via Composer not being recognized
A Drupal 8 site started pestering me to upgrade Twig Tweak from 8.x-2.8 to 8.x-2.9. I went to the directory and ran `composer require 'drupal/twig_tweak:^2.9'` which seemed to work. I also did `drush cr`. When I go back into the Drupal web interface it still thinks I'm on the older version of Twig Tweak and wants me to upgrade. If I run the composer command again, it thinks I'm already upgraded. How do I get these two things to play nice with each other?

(You might be wondering why I didn't just use the web interface to upgrade. If I do that I have even bigger problems so I'm sticking to composer for now.)

Update: output of composer show

descrip. : A Twig extension with some useful functions and filters for Drupal development.
keywords : Drupal, Twig
versions : * 2.9.0
type     : drupal-module
license  : GNU General Public License v2.0 or later (GPL-2.0+) (OSI approved) https://spdx.org/licenses/GPL-2.0+.html#licenseText
homepage : https://www.drupal.org/project/twig_tweak
source   : [git] https://git.drupalcode.org/project/twig_tweak.git 8.x-2.9
dist     : [zip] https://ftp.drupal.org/files/projects/twig_tweak-8.x-2.9.zip 8.x-2.9
path     : /var/www/html/ycfld/modules/contrib/twig_tweak
names    : drupal/twig_tweak

support
source : https://git.drupalcode.org/project/twig_tweak
issues : https://www.drupal.org/project/issues/twig_tweak

requires
drupal/core ^8.7 || ^9.0
twig/twig ^1.41 || ^2.12

suggests
symfony/var-dumper Better dump() function for debugging Twig variables```

# Answer
> 1 votes
Do you have more than 1 copy of twig\_tweak.info.yml located anywhere under Drupal root? Composer will install the module in `<drupalroot>/modules/contrib`. Installation through the UI will put modules in `<drupalroot>/modules`.

Did you originally install Twig Tweak with composer? If you originally installed the module manually/through the UI and then did a composer require, you will have two copies of the module. That won't work. You have to ensure you have one and only one copy of the module's code on your site.

The cleanest way to fix this is to uninstall the module from the UI, then remove both versions of the module code - remove both the `<drupalroot>/modules/contrib` version and the `<drupalroot>/modules` version. Then you can re-install the module using composer and re-enable it.

---
Tags: composer
---


title: How to add a js script as type="module"

text:
# Question
Title: How to add a js script as type="module"
How to add **type="module"** to script added in ***MODULENAME.libraries.yml*** when i do:

```
my-library:
  version: 1.x
  js:
    js/App.js: { }

```

I get

```
<script src="/modules/custom/MODULENAME/js/App.js?v=1.x"></script>

```

I need to add **type="module"** to script tag like:

```
<script type="module" src="/modules/custom/MODULENAME/js/App.js?v=1.x"></script>

```

I have tried:

```
my-library:
  version: 1.x
  js:
    js/App.js: { type: module }

```

But i doesn’t work.
Is this possible to add a script of type module?

# Answer
> 13 votes
Yes, it is possible, with the *attributes* property.

```
my-library:
  version: 1.x
  js:
    js/App.js: { attributes: { type: module } }

```

See Adding attributes to script elements and JS properties.

---
Tags: javascript, 9
---


# Question
Title: Placeholders must have a trailing [] if they are to be expanded with an array of values
In Drupal 8 I am trying to insert some data in my custom table. While executing query I am getting error:

> InvalidArgumentException: Placeholders must have a trailing \[\] if they are to be expanded with an array of values. in Drupal\Core\Database\Connection-\>expandArguments()

Please find my code below:

```
$qt = new \stdClass();
$qt->name = 'test name';
$qt->machine_name = 'test machine name';
$qt->settings = array('setting1'=>value1, 'setting2'=>value2);

$query = \Drupal::database()->insert('my_custom_table');
$query->fields([
  'machine_name',
  'name',
  'settings',
]);
$query->values([
  $ob->machine_name,
  $ob->name,
  $ob->settings,
]);
$query->execute();

```

If I am giving values like below it is working. Please help me whats wrong with above code.

```
$query->values([
  'test',
  'ttt',
  'dfs',
]);
$query->execute();

```

# Answer
> 4 votes
That issue got resolved. It was regarding passing array in to the db. Added serialise function resloved the issue.

```
$query->values([
$ob->machine_name,
$ob->name,
serialize($ob->settings),
]);
$query->execute();

```

# Answer
> 6 votes
This is all explained in the Drupal documentation. If you are forming a query that can take an array of arguments, then the (arbitrary) placeholder string needs to indicate this. So a placeholder of `:column` will only work for a single value, but if you want to use an array of values you need to use the syntax `:column[]`.

See https://www.drupal.org/docs/drupal-apis/database-api/static-queries#placeholder-arrays

Specifically, from the documentation, you can use (for example):

```
$result = $database->query("SELECT * FROM {mytable} WHERE id IN (:ids[])", [':ids[]' => [13, 42, 144]]);

```

OR you can use (for example):

```
$result = $database->query("SELECT * FROM {mytable} WHERE id IN (:ids_1, :ids_2, :ids_3)", [
  ':ids_1' => 13,
  ':ids_2' => 42,
  ':ids_3' => 144,
]);

```

But you CANNOT use (for example):

```
$result = $database->query("SELECT * FROM {mytable} WHERE id IN (:ids)", [':ids' => [13, 42, 144]]);

```

because in this case you're passing in an array ( \[`13, 42, 144]` ) but the placeholder ( `:ids` ) does not use the proper syntax for array placeholders.

# Answer
> 0 votes
that also happen to me when adding a string to an expected int so casting was necessary

```
(int)$ob->number_as_string

```

---
Tags: 8, database
---


title: How to make a custom composite field?

text:
# Question
Title: How to make a custom composite field?
Is it possible to create a custom field widget or use `hook_form_alter()` to show multiple form elements that, used together, can set the value of a single field?

For example, I added a textfield **Personalization**.

But on the entity edit form, I do not want users to edit the **Personalization** field directly; instead, I want them to check some boxes and fill in some text fields, and then I want to process that data and set the value of the **Personalization** field as a result of that processing. **How do I set up the extra form elements and use them to set the value of the field?**

I tried to do this by override the textarea FieldWidget:

**/MYMODULE/src/Plugin/Field/FieldWidget/TextareaPersonalizationWidget.php**

```
<?php

namespace Drupal\MYMODULE\Plugin\Field\FieldWidget;

use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\Plugin\Field\FieldWidget\StringTextareaWidget;
use Drupal\Core\Form\FormStateInterface;

/**
 * Plugin implementation of the 'text_textarea_personalization' widget.
 *
 * @FieldWidget(
 *   id = "text_textarea_personalization",
 *   module = "MYMODULE",
 *   label = @Translation("Personalization widget"),
 *   field_types = {
 *     "text_long",
 *     "string_long"
 *   }
 * )
 */
class TextareaPersonalizationWidget extends StringTextareaWidget {

  /**
   * {@inheritdoc}
   */
  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {

    $element['a']['#type'] = 'textfield';
    $element['a']['#title'] = 'Your fav animal';
    $element['a']['#maxlength'] = '255';
    $element['b']['#type'] = 'textfield';
    $element['b']['#title'] = 'Your fav fruit';
    $element['b']['#maxlength'] = '255';
    return $element;
  }

}

```

This causes two textfields to be shown instead of the textarea. Great! Except the value never gets saved, and I can't process the input text in `hook_entity_presave()`. **So how can I process the input in the custom form elements and save the result in the original field?**

I also tried the same thing in `MYMODULE_field_widget_string_textarea_form_alter()` but I had the same problem.

**More details about how my site is set up**

Here's my setup: I have a flag called **Collection**. This flag contains a textfield, **Personalization**. This textfield will contain pairs of strings for replacing text with JavaScript in order to customize the text on terms that have been flagged by the user.

Of course, I don't want users to type in arbitrary strings into a textfield; this would be a terrible UI. So, when a user flags a taxonomy term, I want to show some form elements that allow the user to input some options for personalization. These form elements will be different depending on which term is being flagged. For example, if flagging the **Fruits** term, I want to add a text field "What is your favorite fruit?" And on the **Cakes** term, I want to add a list of checkboxes "Choose all the types of frosting you like."

In other words, I want to define a custom form per taxonomy term that sets the value of the **Personalization** field, and I want to somehow embed this custom form on the flag add form.

# Answer
> 1 votes
> Except the value never gets saved, and I can't process the input text in hook\_entity\_presave().

You can add a new validate for your widget:

```
/**
* {@inheritdoc}
*/
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
  // Your logic code

  // Add validate for your widget.
  $element['#element_validate'] = [
    [$this, 'validate'],
  ];

  return $element;
}

```

And convert value before save:

```
/**
* Validate the fields and convert data before save.
*/
public function validate($element, FormStateInterface $form_state) {
    // Logic validate.
    // Code here

    // Convert value and set.
    // Field type text_long
    $value = [
     'value' => 'your value',
     'format' => 'your format'
    ];

    // Field type string_long
    $value = [
      'value' => 'your value'
    ];

    $form_state->setValueForElement($element, $value);
}

```

# Answer
> 1 votes
Have a look at https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Field%21WidgetBase.php/function/WidgetBase%3A%3AmassageFormValues/8.9.x

> Massages the form values into the format expected for field values.

You may need to implement that function for your custom widget.

---
Tags: 8, forms
---


# Question
Title: How to override Page Title of View using Contextual Filter
I have a view that uses a contextual filter for part of the URL. For example: www.example.com/categories/%/all

I have successfully replaced the % with the name of the taxonomy term from a specific category (for example, www.example.com/categories/**shirts**/all), but I cannot get the Title Override options to work.

Here's how I have things set up...

```
Contextual Filter - Indexed Content: Clothing Categories
When the filter value is NOT in the URL -  Display empty text
Override title - %1
Specify validation criteria: Validator: Taxonomy Term
Filter value type - Term Name Converted to Term ID
Transform dashes in URL to spaces in term name filter values  (checked)

```

When I preview the View result by typing the contextual filter "shirts", it does display the shirts and it does display the title "Shirts". However, on the live page, the View's title is displayed instead ("Category View"). I have tried deleting the View's title, but that just causes the front-end page to display no title.

Any idea on how I can get this to work, or any other methods to make it work?

Thanks!

# Answer
In **Drupal 8**, if you are using a contextual filter to pass a taxonomy term to a View and want to change the page title to match with the term title, you can:

```
/**
 * Implements hook_preprocess_views_view().
 */
function HOOK_preprocess_views_view(&$variables) {

  $id = $variables['id'];

  if( $id == 'YOUR_VIEW_NAME' && $variables['view']->args[0]) {

    // Get tid from contextual argument of the view
    $tid = $variables['view']->args[0];

    // Load the Term Entity
    $term = Term::load($tid);

    // Term Title
    $new_title = $term->getName();

    // Set the new Page Title
    $request = \Drupal::request();
    if ($route = $request->attributes->get(\Symfony\Cmf\Component\Routing\RouteObjectInterface::ROUTE_OBJECT)) {
      $route->setDefault('_title', $new_title);
    }
  }
}

```
> 4 votes

# Answer
After hours of searching, trial and error, and then posting this question, I came across the correct method minutes later: Get term name for page title from term id passed in the contextual filter?

> do the following for this field:
>
> ```
> Check "Provide default value".
> Select Type: "Taxonomy term ID from URL"
> Select checkbox: "Load default filter from term page"
>
> ```
> 3 votes

# Answer
I'm using Drupal 8, this worked for me.

In ***/core/modules/views/views.theme.inc*** file I appended following code to ***template\_preprocess\_views\_view*** method:

```
$view = $variables['view'];
$id = $view->storage->id();

...
...
...

if( $id == '__VIEW_ID__' && $view->args[0]) {

    // Get tid from contextual argument of the view
    $tid = $view->args[0];

    // Load the Term Entity
    $term = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->load($tid);
    // $term = Term::load($tid);

    // Term Title
    $new_title = $term->getName();

    // Set the new Page Title
    $request = \Drupal::request();
    if ($route = $request->attributes->get(\Symfony\Cmf\Component\Routing\RouteObjectInterface::ROUTE_OBJECT)) {
      $route->setDefault('_title', $new_title);
    }
 }

```
> 0 votes

---
Tags: views, 7
---


# Question
Title: How to get a list/array of all content entities?
I need a list of all content entities, to query them all and check if they have a specific field.

Couldn't find this in the API doku.

# Answer
> 10 votes
This is what you need:

```
use Drupal\Core\Entity\ContentEntityType;

$content_entity_types = [];
$entity_type_definations = \Drupal::entityTypeManager()->getDefinitions();
/* @var $definition EntityTypeInterface */
foreach ($entity_type_definations as $definition) {
  if ($definition instanceof ContentEntityType) {
    $content_entity_types[] = $definition;
  }
}

```

But a better approach would be to get the field first and then the bundles which has this field. For example, we are looking for the "field\_image" in "node" typed entities:

```
   use Drupal\field\FieldStorageConfig;

   $field_image = FieldStorageConfig::load('node.field_image')
   $bundles = $field_image->getBundles();

```

# Answer
> 1 votes
Builds a list of entity type labels suitable for a Form API options list

```
\Drupal::entityManager()->getEntityTypeLabels(TRUE);

```

Use in form API

```
$element['target_type'] = [
  '#type' => 'select',
  '#title' => t('Type of item to reference'),
  '#options' => \Drupal::entityManager()->getEntityTypeLabels(TRUE),
  '#default_value' => '',
  '#required' => TRUE,
];

```

# Answer
> 1 votes
```
\Drupal::service('entity_type.repository')->getEntityTypeLabels(TRUE)['Content'];

```

---
Tags: 8, entities
---


# Question
Title: How can I target the first item in a view?
I have a views page that shows all the latest articles that were posted. I want to show case the latest article in a different div on it's own, and then have my loop with all the other articles.

This is my code for the loop, which is in the node--view.html.twig file -

```
    <div{{ attributes.addClass('col-4')}}>
      <div class="news-card">
        <img src="{{ file_url(node.field_image.entity.fileuri) }}">
        <h3>{{ node.label }}</h3>
        {% set text = content.body|render|striptags %}
        <p>{{ text|length > 100 ? text|slice(0, 120) ~ '...' : text }}</p>
        <a href="{{ url }}" class="btn black-btn">Read More</a>
      </div>
    </div>

```

and in my views-view-unformatted.html.twig file I have -

```
<h2>{{ view.getTitle() }}</h2>
  {% if title %}
      <h3>{{ title }}</h3>
  {% endif %}
<div class="row news-row">
{% for row in rows %}
  {%
    set row_classes = [
      default_row_class,
    ]
  %}
    {{- row.content -}}
  {% endfor %}
</div>

```

# Answer
> 3 votes
You could also do

**views-view-unformatted.html.twig**

<sub>**Note:** add the view name if you want to target a specific view, *views-view-unformatted--view-name.html.twig*</sub>

```
{% if title %}
  <h3>{{ title }}</h3>
{% endif %}
{% set count = 1 %}
{% for row in rows %}
  {%
    set row_classes = [
    default_row_class ? 'views-row',
  ]
  %}
  {% if count == 1 %}
    {%  set row_classes = row_classes|merge(['first-row']) %}
  {%  endif %}
  <div{{ row.attributes.addClass(row_classes) }}>
    {{- row.content -}}
  </div>
  {% set count = count + 1 %}
{% endfor %}

```

and then in css

```
.first-row { ... }

```

---

OR alternatively follow How can I get numbered classes on rows?

and

```
.views-row-1 { ... }

```

# Answer
> 3 votes
One possible solution ist to create two views. One for your featured content (only 1 item or as much you want to feature) and the second one for the rest with an offset. You can set the offset under pager options (items to skip).

---
Tags: views, theming
---


# Question
Title: How can I let a plugin depend on another module?
Is it possible to let a plugin depend on a module (other than the declaring one)?

Use case: I want to create a field widget plugin that should depend on the 'date\_all\_day' contrib module, but I don't want the entire declaring module depend on this.

Is it possible to declare this in the annotation?

E.g.

```
/**
 * @FieldWidget(
 *   id = "my_daterange",
 *   label = @Translation("Date and time range + All day"),
 *   field_types = {"daterange"},
 *   dependencies = {"date_all_day"}
 * )
 */
class MyPlugin {...}

```

The plugin should only become available if both the declaring module and the dependency module are enabled.

# Answer
Yes, this is possible.

You may declare a dependency on a module by using the "provider" key in the annotation. For your example, this would look like:

```
/**
 * @FieldWidget(
 *   id = "my_daterange",
 *   label = @Translation("Date and time range + All day"),
 *   field_types = {
 *     "daterange"
 *   },
 *   provider = "date_all_day"
 * )
 */
class MyPlugin {...}

```

Note that you can only list ONE provider, but of course that provider module can depend on other modules ...

This is a feature added to the DefaultPluginManager in order to allow plugins to declare a dependency on one (and only one) module. This only works for plugins that use a plugin manager derived from DefaultPluginManager.

Specifically, @FieldWidget plugins are managed by the WidgetPluginManager, which DOES subclass DefaultPluginManager, so this will work. (Most, if not all, core plugin managers subclass DefaultPluginManager.)
> 7 votes

# Answer
First, it's probably preferable to use the provider option if you can.

However, Field widgets and formatters also make use of an isApplicable() method. You can use this for any additional logic to determine whether your widget should be available for a field, a field in the subset of fields defined in your annotation.

You can use this method to limit the widget to just a datetime field with a particular machine name, or only datetime fields on nodes, etc.

You can also use it for your case, to check if other modules are enabled.
> 7 votes

---
Tags: 8, plugins
---


# Question
Title: How can I make the "field_media_document_display field be filled with a 1?
Although I have the Files displayed by default set as true and when I manually add one it defaults to `1` , when I use the step one process it put s a null there . Since it has a null the next time a user tries to change the name it doesn't work.

I am using the Migrate File Entities to Media module, this is my code in step 1. where can I add something to make it fill in the `field_media_document_display_field` as a `1` ?

```
field_media_document/title: title
field_media_document/target_id:
    plugin: media_file_copy
    move: FALSE
    reuse: TRUE
    path: 'public://grants/'

```

# Answer
> 1 votes
In media-migration-step1.yml.twig I see:

So should be:

```
field_media_document/display: TRUE
field_media_document/target_id:
    plugin: media_file_copy
    move: FALSE
    reuse: TRUE
    path: 'public://grants/'

```

If still not, try:

```
field_media_document/display:
    plugin: default_value
    default_value: TRUE
field_media_document/target_id:
    plugin: media_file_copy
    move: FALSE
    reuse: TRUE
    path: 'public://grants/'

```

---
Tags: migrations
---


# Question
Title: How to notify user using ->messenger() and ajax?
I would like to send a message to the user on an event in the backend without a refresh. I have a 2fa login form that will send a token text. That form has a "did not receive sms" button/link using ajax that causes the text to be sent again. I would like to inform the customer of the incoming message.

You can send a notification to the user using the MessengerInterface. But this requires a refresh to show the message.

```
\Drupal::messenger()->addStatus('Some conditional message to the user');

```

I would imagine that there is a way to send a message to the user using ajax/XHR? Which would not require a refresh.

My form has a wrapping div which I can target, the button/link has an `'#ajax'` element with, as far as I know, all the prerequisite elements:

```
'#ajax' => [
  'callback' => '::ajaxCallback',
  'event' => 'click',
  'wrapper' => 'twofa_wrapper',
],

```

I found this comment on the Drupal forum but using this code, with obvious replacements, does nothing apart from sending a XHR response, visible in the network tab. The json response contains a number of things one being the html for the form which contains the message that I would like to show, but it doesn't show this content on the actual page.

```
public function ajaxCallback(array &$form, FormStateInterface $form_state) {
  $response = new AjaxResponse();
  // This by some Drupal magic gets the messages
  $messages = ['#type' => 'status_messages'];
  $messages = \Drupal::service('renderer')->render($message);
  $response->addCommand(new HtmlCommand('#twofa_wrapper', $messages));
  $response->addCommand(new ReplaceCommand(null, $form));
  return $response;
}

```

What am I missing?

**edit:**

---

The wrapping element was (is) not rendering for some reason, if I include it in the template the callback shows the messages in that element at the top of the form.

The problem is that I need to renew the entire form because the contents might change on the ajax call. Replacing the contents works when I actually enclose the form in the wrapper element, but then the messages are no longer included.

I can see that the messages are part of the response but separate from the form contents. Second element messages third element the new form. The strange thing is the message are also not shown on a refresh.

# Answer
> 2 votes
This works for me:

```
$element = NULL;
if (!empty($triggering_element['#ajax']['element'])) {
  $element = \Drupal\Component\Utility\NestedArray::getValue($form, $triggering_element['#ajax']['element']);
}
// Element not specified or not found. Show messages on top of the form.
if (!$element) {
  $element = $form;
}
$response = new \Drupal\Core\Ajax\AjaxResponse();
$response->addCommand(new \Drupal\Core\Ajax\ReplaceCommand('[data-drupal-selector="' . $form['#attributes']['data-drupal-selector'] . '"]', $form));
$response->addCommand(new \Drupal\Core\Ajax\PrependCommand('[data-drupal-selector="' . $element['#attributes']['data-drupal-selector'] . '"]', ['#type' => 'status_messages']));
return $response;

```

---
Tags: 8, ajax
---


title: testing scheduled file deletions

text:
# Question
Title: testing scheduled file deletions
Long story short, is there a correct way to override `DRUPAL_MAXIMUM_TEMP_FILE_AGE`?

I'm working on testing a fix to a module I wrote a while back that handles some uploaded files. I neglected to call `file_usage_delete` and set `file_managed` status to 0. To test my changes more quickly, I'd like to schedule files for deletion after doing some operations on them. To do this reasonably I had to reduce the turn around time on deletions to something on the order of minutes than hours. I went ahead and edited system.module where `DRUPAL_MAXIMUM_TEMP_FILE_AGE` is defined as 6 hours, but the comments immediately preceding the defines indicate:

> @file Configuration system that lets administrators modify the workings of the site.

I checked the places where this value is used, and it doesn't look to be actually configurable besides editing system.module directly. Maybe I'm missing something?

**Is there a correct way to set this that doesn't involve "hacking core"?**

# Answer
> 1 votes
It isn't configurable. You would be better served writing your own routine that executes on a regular interval and searches for temporary files whose creation age is greater than 10 minutes ago.

The DRUPAL\_MAXIMUM\_TEMP\_FILE\_AGE constant is specifically intended to inform Drupal on when a file that has not yet been set to permanent should be removed.

If you take a look at **system.module**, the relevant code is contained in a hook\_cron() implementation. The code reads:

```
  $result = db_query('SELECT fid FROM {file_managed} WHERE status <> :permanent AND timestamp < :timestamp', array(
    ':permanent' => FILE_STATUS_PERMANENT,
    ':timestamp' => REQUEST_TIME - DRUPAL_MAXIMUM_TEMP_FILE_AGE,
  ));

```

My recommendation is to simply implement your own `hook_cron()` and use the same code, but calculate for files older than 10 minutes.

You will also need for cron to execute on a 10 minute interval. For this, you'll need to add a crontab and install either ultimate\_cron or elysisia\_cron. I prefer **ultimate\_cron**.

Please see my answer to this question for more information on setting up crontab on a 60 second interval for maximum timeliness. You'll then use elysia\_cron or ultimate\_cron to control the actual job execution interval.

---
Tags: 7, files, configuration
---


title: Changing entity base field settings

text:
# Question
Title: Changing entity base field settings
Changing entity base field settings

I have a custom car entity with 8 base fields like the following:

```
  $fields['color'] = BaseFieldDefinition::create('list_string')
    ->setLabel(t('Color'))
    ->setRequired(TRUE)
    ->setSettings([
      'allowed_values' => [
        'Blue' => 'Blue',
        'Green' => 'Green',
        'Red' => 'Red',
      ],
    ])
    ->setDisplayOptions('view', [
      'label' => 'inline',
      'type' => 'string',
      'weight' => 1,
    ])
    ->setDisplayOptions('form', [
      'type' => 'options_select',
      'weight' => 1,
    ])
    ->setDisplayConfigurable('form', TRUE)
    ->setDisplayConfigurable('view', TRUE);

```

I have a requirement to allow the end user to partially change some parts of some of the base fields like order and allowed values using custom simplified forms. I have the following code in the 'submitForm' function of a form.

```
  $field_definition = $this->entityDefinitionUpdateManager->getFieldStorageDefinition('color', 'car_module');
  $field_definition->setRequired(FALSE);
  $this->entityDefinitionUpdateManager->updateFieldStorageDefinition($field_definition);

```

When the 'Save' button is hit, the server takes a long time to respond like database changes are being made but the field definition does not get updated.

# Answer
Base fields are defined in code. When code updates change the database schema you can implement the updates via entityDefinitionUpdateManager in an update hook as shown in the question. This is not possible in a form submit.

If you want to store field settings in a form submit load the field config and save it:

```
// if the entity type has no bundles use the entity type id:
$entity_type_id = 'vehicle';
$bundle = 'vehicle';

$fields = \Drupal::service('entity_field.manager')->getBaseFieldDefinitions($entity_type_id);
$field_config = $fields['field_example']->getConfig($bundle);
// make changes
$field_config->save();

```

For form and view display settings you can use EntityDisplayRepositoryInterface::getFormDisplay and EntityDisplayRepositoryInterface::getViewDisplay:

```
$display_repository = \Drupal::service('entity_display.repository');
$display = $display_repository->getViewDisplay($entity_type_id, $bundle, 'default');
$display->setComponent('field_example', $display_options);
$display->save();

```

For both code examples if there is no configuration stored yet it will be created.

---

Your question is about a custom form. Instead you could expose the core field admin UI by adding `field_ui_base_route` to your entity, even if you don't intend to use bundles or view modes. This works also for base fields marked as configurable. See How do I add a view mode to a simple custom entity?
> 1 votes

---
Tags: 8, entities
---


# Question
Title: Web service APIs returns HTML content instead of JSON response
I have used Drupal 7 before and the web services were working perfectly fine. I recently started working on Drupal 8 (8.8 to be precise), and the login service is not working properly. When I do not give the username or the password it should ideally give a message that username/password must be entered. But I am not getting any response here.

It's just returning HTML content. I have been searching lot of posts on this and nothing seems to work for me. I am testing the same in Postman. Below is the screenshot of the same.

I have gone through the below links before posting here..

https://stackoverflow.com/questions/31230351/drupal-8-restful-webservices-only-delivering-html

User login REST POST returns HTML format

User login REST format

Nothing seems to work for me. Kindly suggest. Need your help. Thanks in advance!!

# Answer
For the postman section of your issue: /user/login?\_format=json is a POST request (not get as in your screenshot) and the body should be JSON not x-www-form.
> 0 votes

---
Tags: symfony-services
---


title: Why does #submit apply to all buttons?

text:
# Question
Title: Why does #submit apply to all buttons?
I have added a #submit handler to the default submit action on a node edit form:

```
$form['actions']['submit']['#submit'][] = '_app_submit_to_usercart';

```

and it works correctly. But I then add a 2nd submit button as:

```
  $form['actions']['save'] = [
    '#type' => 'submit',
    '#name' => 'Standard Save',
    '#value' => t('Print and Mail Check'),
    '#button_type' => 'primary',
    '#weight' => 6,
  ];

```

and for some reason the submit handler for the submit button gets run for this button as well. I am sure in my handler I can act depending on which button was pressed; but wondering why I need to do that.

## EDIT

Apparently I am asking the wrong question. From my code above it seems that regardless of which button i click it is still submitting as if the main button is pressed. So question is how can i add another button (I have done this dozens of times in D7 and I thought a few times in D8; so not sure why this isn't working).

# Answer
> 4 votes
Give your submit button a unique and valid `#name` attribute. I don't think it will work if you put spaces in it:

```
$form['actions']['save'] = [
  '#type' => 'submit',
  '#name' => 'standard-save',
  '#value' => t('Print and Mail Check'),
  '#button_type' => 'primary',
  '#submit' => [
    '_my_module_form_submit',
  ],
];

```

**Submit handler**

```
function _my_module_form_submit($form, \Drupal\Core\Form\FormStateInterface $form_state) {
  \Drupal::messenger()->addStatus(t('Standard Save button triggered.'));
}

```

---
Tags: 8, forms
---


# Question
Title: How to display a custom block in a view twig file?
I added a custom block in the header of a view, and I am trying to get it to display. The block contains social media icons and links.

If I want to add a custom text area, I can use this code -

`{{ view.header.area.options.content.value }}`

In my kint I see this for the block I added -

```
      "header" => array:3 [▼
          "entity_block" => array:12 [▼
            "id" => "entity_block"
            "table" => "views"
            "field" => "entity_block"
            "relationship" => "none"
            "group_type" => "group"
            "admin_label" => ""
            "empty" => true
            "tokenize" => false
            "target" => "socialicons"
            "view_mode" => "default"
            "bypass_access" => false
            "plugin_id" => "entity"
          ]

```

So I tried to do  `{{ view.header.entity_block }}` but I get an error -

`Exception: Object of type Drupal\views\Plugin\views\area\Entity cannot be printed. in Drupal\Core\Template\TwigExtension->escapeFilter() (line 425 of core/lib/Drupal/Core/Template/TwigExtension.php).`

What can I do to display the block?

# Answer
> 0 votes
You probably are confusing `{{ header }}` and `{{ view.header }}`.

The first prints the header section including the block:

*views-view.html.twig*

```
{{ header }}

```

The second one returns ViewExecutable::$header, an array of handler plugins you have configured in the View. You can try to extract configured string values like in the first example but in case of a block entity you probably only find the block id and you have to load and render the block yourself. It would be much easier though to print `{{ header }}`.

---
Tags: views, theming, blocks
---


title: Message template with mail key

text:
# Question
Title: Message template with mail key
In `template_preprocess_mimemail_message()` I checked that mail key is `mimemail_message__subscriptions_mail__node-type-post`, but none of these templates is using in the email:

```
mimemail_message__subscriptions_mail__node-type-post.tpl.php
mimemail_message--subscriptions_mail--node-type-post.tpl.php
mimemail-message--subscriptions-mail--node-type-post.tpl.php

```

What I'm doing wrong?

# Answer
Templates must be put in the theme's directory, not in the Mime Mail module directory or in your own custom module directory. The Mime Mail documentation explains the proper template naming and location. See https://www.drupal.org/docs/7/modules/mime-mail/theming-html-mail-sent-through-mime-mail

The most specific template name should have three parts, separated by "--". These parts are:

1. "mimemail-message" This is the same for all templates.
2. "modulename" This is the machine name of the module that provides the `hook_mail()` implementation used to send the mail. This is also the module name that appears as the first argument to your `drupal_mail()` call.
3. "key" This is an identifier used to differentiate multiple emails sent by the same module. This appears as the second argument to your `drupal_mail()` call.

Any underscores appearing in the "modulename" or the "key" should be replaced by dashes.

For example, if my module has a machine name of "example\_module" and the mail key is "example\_key" then the specific template name, used just for email with that key sent by that module, should be:

```
  mimemail-message--example-module--example-key.tpl.php

```

The documentation for `drupal_mail()` explains a number of these things. See https://api.drupal.org/api/drupal/includes%21mail.inc/function/drupal\_mail/7.x
> 0 votes

---
Tags: 7, mimemail
---


title: Media html not rendering in blocks

text:
# Question
Title: Media html not rendering in blocks
I'm experiencing an issue on multiple sites where (image) media aren’t appearing in blocks despite working fine in node fields.

I first thought it only happened to me when using the linkicon module, but since then i created a custom block type for image blocks (using entity reference media fields) and the same thing happens, ie. the html renders nothing:

```
<div class="content"></div>

```

There's no problem rendering the fields in nodes on the same sites using the exact same display settings.

I've checked both the media, block and block\_content logs and they show no errors.

My setup:

* Drupal 8.9.7
* Barrio 5.1.3
* Local environment running on ddev
* Remote environment running on cloudways

Any ideas what the issue might be?

# Answer
> 1 votes
This turned out to be a conflict with the songkick module. I'm a maintainer so I'll make sure the issue is handled and post further updates in the issue cue on Drupal.org here.

---
Tags: blocks, media
---


title: How do I manage landing pages?

text:
# Question
Title: How do I manage landing pages?
How can I easily manage landing pages in Drupal 8? Do I need to created separate content types for landing page? Is there any other way to manage this with a single content type?

The landing pages I want to create are the following ones.

* Blog landing page
Fields: banner title, body, image, blogs
* Publication landing page
Fields: banner title, body, image, publications
* News & events landing page
Fields: banner title, body, image, news and events landing

# Answer
> 1 votes
Generally speaking, as @Kevin aknd @kiamlaluno have noted, it's probably easiest to make one content type **Landing page** and use that for all landing pages on your site. I actually did a similar thing on a site earlier this year.

You noted that you wanted to do three kinds of landing pages with different fields.

So to implement this, you could add all of the fields to the **Landing page** content type:

* banner title
* body
* image
* blogs
* publications
* news and events

Then, when you are adding content of type **Landing page**, just fill out the necessary fields.

Then you can make a theme template for your custom content type. Copy the file `web/core/modules/node/templates/node.html.twig` and copy it to your custom theme's templates folder and rename the file `node--LANDINGPAGE_MACHINE_NAME.html.twig`.

For example: `web/themes/contrib/MY_THEME_NAME/templates/node/node--landing-page.html.twig` (Note: If the machine name is `landing_page`, you need to replace the `_` with `-`.)

You can then edit this file to display the fields however you want to create the three kinds of landing pages. You can display a field like this: `{{ content.field_blogs }}` where `field_blogs` is the machine name of your blogs field, for example.

If other users who don't know the rules might mistakenly fill out all the fields when they shouldn't (for example, if a node should not have values for both **blogs** and **news and events**), then you can add custom form validation to check for this.

---
Tags: 8
---


title: Redirection cached?

text:
# Question
Title: Redirection cached?
I have 2 versions of site (with same code), one for Switzerland (.ch) and other for rest of the world (.com).

What I need is that if someone from Switzerland visits .com is redirected to .ch And other way, if someone out of Switzerland visits .ch should be redirected to .com

I registered even subscriber like:

```
services:
  smart_ip_redirect.event_subscriber:
    class: Drupal\smart_ip_redirect\EventSubscriber\SmartIpRedirectSubscriber
    tags:
      - {name: event_subscriber}

```

The inside my event subscriber I have code like:

```
if ($host != 'site.ch' && $countryCode == 'CH'){
  $event->setResponse(new TrustedRedirectResponse('https://site.ch/'));
  return;
} else if ($host == 'site.ch' && $countryCode != 'CH'){
  $event->setResponse(new TrustedRedirectResponse('https://site.com/'));
  return;
}

```

Everything works well for the first time after clearing the cache. First user is redirected (if needed) to correct domain.

However that redirection is cached somehow.

I.e. first user (i.e. using first browser) is from CH, visits .com domain. He is well redirected to .ch domain.

But then if second user (second browser) visits from some other country visits .com domain previous redirection is somehow remembered and he is also redirected to .ch domain and that request falls into endless loop.

Then I clear drupal cache (on both sites), it again works well for first user and after that every other attempt gets stuck into endless loop.

How should I register my event subscriber so it's called for every page opening and avoid page caching?

**Update:**

Maybe I was not clear enough so I'll try to be more specific. I have the same code for 2 totally independent sites. So one will always have $host == "site.com" and other $site=="site.ch" So its not multisite setup. They do not share database nor current code (even code is the same for simplicity sake - they have the same ancestor).

Other thing is that I don't need caching based on ip address (and obviously not on host since it will be always the same for each site) . Everything should work as default. Only difference is that at very beginning of handling the request my code should be executed and it will decide should redirection happen or request processing should continue as normal.

So only that my code should be excluded from caching and executed before everything else and after that everything else including caching should happen as normal.

Hope that this makes some more sense.

**Update 2:** Followed @sonfd suggestion and my code now looks like:

```
$response_headers = [
  'Cache-Control' => 'no-cache, no-store, must-revalidate',
];

if ($host != 'site.ch' && $countryCode == 'CH'){
  $event->setResponse(new TrustedRedirectResponse('https://site.ch/', '302', $response_headers));
} else if ($host == 'site.ch' && $countryCode != 'CH'){
  $event->setResponse(new TrustedRedirectResponse('https://site.com/', '302', $response_headers));
}

```

}

Also set higher priority in services file:

```
services:
  smart_ip_redirect.event_subscriber:
    class: Drupal\smart_ip_redirect\EventSubscriber\SmartIpRedirectSubscriber
    tags:
      - {name: event_subscriber, priority: 250}

```

But didn't help. I still get stuck in infinite redirection loop after changing country (using HideMyAss for testing).

**Update 3:**

Trying that middleware soluiton, but now inside my handle method I can not use SmartIp module functionality any more. Before I could read current user country code like:

```
$location = \Drupal::service('smart_ip.smart_ip_location');
$countryCode = $location->get('countryCode');

```

Now it's shooting error:

> The website encountered an unexpected error. Please try again later. TypeError: Argument 1 passed to Drupal\Core\Session\SessionConfiguration::getOptions() must be an instance of Symfony\Component\HttpFoundation\Request, null given, called in /var/www/html/drupal/web/core/lib/Drupal/Core/Session/SessionManager.php on line 111 in Drupal\Core\Session\SessionConfiguration-\>getOptions() (line 40 of core/lib/Drupal/Core/Session/SessionConfiguration.php).

Tried avoid services and calling static method directly like:

```
$client_ip = $request->getClientIp();
$location = SmartIp::query($client_ip);
$countryCode = isset($location['countryCode']) ? strtolower($location['countryCode']) : '';

```

but error remains.

Noticed that inside handle method getting request like before:

```
$request = \Drupal::request();

```

is not working. However $request is passed to handle method, but point is that some functionality is not available here.

And experimented additionally on this: will this error appear on not depends on priority parameter from services.yml file. If priority is bellow 100 error will not appear, so I guess some needed initialization is done before and Smart Ip works well. However, if priority is that low page and this code is cached. By looking at suggested middleware soluiton I need to set priority above 200 (it's set to 250 at example). And with priority that hing SmartIp module call won't work. So request are contradictory (less than 100 so Smart Ip will work but more than 200 so caching will be avoided).

Any idea?

# Answer
The code depends on host name and IP address. So you could add the cache contexts `url.site` and `ip`:

```
$response = new TrustedRedirectResponse('https://site.ch/');
$response->getCacheableMetadata()->addCacheContexts(['ip', 'url.site']);
$event->setResponse($response);

```

In this case, though, caching doesn't make much sense because it doesn't save many cpu cycles and fills the cache tables with ip addresses of site visitors. Set a cache max age of 0 instead of the two contexts:

```
$response->getCacheableMetadata()->setCacheMaxAge(0);

```

Furthermore the code doesn't depend on any Drupal internals since the location could be resolved through a 3rd party library only based on the IP. So you could move the code outside of the Drupal kernel in a middleware as @NoSssweat commented.

In any case you need to disable reverse proxies. Uninstall the built-in Internal Page Cache (in case of the middleware you can achieve this by setting a higher priority) and external ones through response headers. See @sonf comment.
> 5 votes

---
Tags: 8, caching, redirection
---


# Question
Title: How do I get the number of rows affected from an update query?
I'm having trouble figuring out how to get the number of affected rows from an update query in Drupal.

I have a form where users can update their profile details. Now, not every user is going to update everything from their profile. They may just update one field or two.

How do I account if there was a change or not and check for the affected rows?

This is the code I am running.

```
$update_query = $db->update('TABLE NAME')
  ->fields([
    'uid' => $uid,
    'name_of_user' => $name,
    'url' => $url,
    'website' => $website,
    'industry' => $industry,
    'company_size' => $companySize,
    'company_type' => $companyType,
    'headquarters' => $headquarters,
    'founded' => $founded,
    'page_picture' => $upload_picture,
    'tagline' => $tagline,
    'updated_at' => $time,
  ])
  ->condition('uid', $uid);

  $affectedRows = $update_query->execute()->rowCount();
  return new AjaxResponse($affectedRows);

```

The code doesn't return anything. I even checked the network tab and there's nothing displayed in the response tab. I should be getting back either 0 or 1. Am I missing something?

# Answer
> 1 votes
`$update_query->execute()->rowCount()` would cause a *Call to a member function rowCount() on a non-object* (or *Call to a member function rowCount() on int*, on PHP 7.4) since `$update_query->execute()` returns the number of rows matched by the update query, including the ones that actually didn't have to be updated.
`rowCount()` can be called only when `execute()` returns an object implementing `StatementInterface`, which is the case for `Select::execute()`, `Truncate::execute()`, `Upsert::execute()`, and `Query::execute()`.

Unfortunately, the only way to get the number of rows changed from an update query is to fetch the rows matching the update condition (in your case, the rows for which *uid* is equal to `$uid`), and count which rows have, for the desired fields (in your case, *name\_of\_user*, *url*, *website*, *industry*, *company\_size*, *company\_type*, *headquarters*, *founded*, *page\_picture*, *tagline*, and *updated\_at*), a value different from the value set by the update query.

---
Tags: 8, database
---


# Question
Title: What do Contextual Filters filter against?
I've been banging my head against a wall trying to understand contextual filters for about 6 months now so I thought I'd give up and finally ask. Most recently I read this article on cofiguring contextual filters, which renewed my confusion and frustration on this topic.

Normally in query or procedural languages when you filter something, you specify 2 or 3 things;

1. The value to filter (e.g. "blonde")
2. The place to look for the values (e.g. the "hair color" column)
3. Optionally, the operator to use.

My understanding is that contextual filters only use the "equal to" operator, so I'll leave out 3.

For example, if I wanted to filter a `nodes` table on all nodes whose value in the `title` column is equal to the contents of the `my_title` variable, then in SQL I'd write something like this;

```
SELECT * FROM nodes WHERE title = @my_title

```

There's a left hand side (title) and right hand side (my\_title). But in the Contextual views section of the view I can only pick the dynamic value to check against (the equivalent of `my_title`) but where do I pick what I'm actually filtering on (ie. the title column)?

As far as I can tell this is telling the filter to filter on the ID of the current page. Which is fine, but what am I filtering? What are the left and right hand operators to the filtering operation?

# Answer
Generally speaking, a view is used to show data for a list of entities. View filters are used to select (or filter) which entities are handled by the view; contextual filters are used to select the entities basing on the values passed in the URL.

For example, the *Files* view that comes with Drupal 8 has two pages: one whose path is /admin/content/files and one whose path is /admin/content/files/usage/%.

>

The second page shows data (the entity label and the entity type for the entity containing a reference to the file; the module managing the file relationship; the number of times the file is used by the entity) for the file whose ID is passed in the view path.

>

When I visit /admin/content/files/usage/3 on the test site I created, the view shows the following data.

>

On /admin/content/files/usage/2, the view shows the following data.

>

Using as another example a default view that is already enabled on /admin/structure/views, the *Taxonomy term* view has a page shown on /taxonomy/term/% which uses the *Content: Has taxonomy term ID* contextual filter.

>

It shows all the nodes using the taxonomy term whose ID is passed in the URL. In the test site I am using, /taxonomy/term/1 shows all the nodes using the taxonomy term whose ID is 1 (the *test* taxonomy term), while /taxonomy/term/2 shows all the nodes using the taxonomy term whose ID is 2 (the *view* taxonomy term).

>

>

Contextual filters are still filters, as they select (or filter) the entities from which the data is taken. The difference is that their values are passed from the view URL, not from a form like the filters set in the *Filter criteria* section.

The number of entities from which the data is taken and what entities are handled by the contextual filter is hard-coded in the class implementing the contextual filter: *Content: Has taxonomy term ID* selects all the nodes using the taxonomy term whose ID is equal to the value passed in the URL, which could be zero or more than one node, while *Content: ID* selects only the node whose ID is passed in the URL; *User: Created* selects all the user accounts that have been created at the time passed in the URL. The category of the contextual filter (another value set by the the class implementing the contextual filter), which is shown in the contextual filter name, helps to understand which entities a contextual filter selects: *Content: Has taxonomy term ID* and *Content: ID* select nodes, while *User: Created* selects users.
> 6 votes

# Answer
In Views, if you go into the Settings (`/admin/structure/views/settings`), you can check the box **Show the SQL query** to see the magic.

I made a very simple view of content. Here's the SQL query:

```
SELECT node_field_data.created AS node_field_data_created, node_field_data.nid AS nid
FROM
{node_field_data} node_field_data
WHERE node_field_data.status = '1'
ORDER BY node_field_data_created DESC
LIMIT 11 OFFSET 0

```

Next I added a contextual filter for **Content: ID** and accepted the defaults.

**In this case, the SQL query does not change.** This is because "Display all results for the specified field" is the default for **When the filter value is NOT available** in the contextual filter settings.

The query only changes if the contextual filter is provided with a value. (To provide a dummy value for testing purposes, you can input a value in **Preview with contextual filters**.)

Here, I tested by inputting `1` for **Preview with contextual filters**, which gave me this query:

```
SELECT node_field_data.created AS node_field_data_created, node_field_data.nid AS nid
FROM
{node_field_data} node_field_data
WHERE ((node_field_data.nid = '1')) AND (node_field_data.status = '1')
ORDER BY node_field_data_created DESC
LIMIT 11 OFFSET 0

```

"Contextual filters" is a hard-to-understand name, but back in Drupal 6 (as long as I'm remembering right) this was called "Arguments", which makes more sense to me.
> 5 votes

---
Tags: 8, views
---


title: How do I run PHPUnit tests?

text:
# Question
Title: How do I run PHPUnit tests?
Having just kind of gotten my head around Simpletest functional testing in Drupal 8.x, I've now started trying to use PHPUnit testing since Simpletest has been deprecated in Drupal 9.1.x.

I started by looking at the instructions on Running PHPUnit tests. However, when I get to the step on running the tests I get this.

> Fatal error: Uncaught Error: Class "Drupal\Tests\node\Functional\NodeTestBase" not found in /opt/drupal/web/core/modules/node/tests/src/Functional/PagePreviewTest.php:22

This looks a bit like an autoload issue to me. I ran the following command to verify it was effectively so.

```
php -r "require_once('autoload.php'); var_dump(class_exists('\Drupal\Tests\node\Functional\PagePreviewTest'));"

```

The command outputs *bool(false)*.

My knowledge really ends here. The documentation seems to be moot on this, and it looks like I'm not the only one with this problem. (See How to run PHPUnit tests?).

How do I run PHPUnit tests?

This is the Docker file content that can be used to reproduce what I described in the question.

```
FROM drupal:9.1.0

RUN composer require -n \
  phpunit/phpunit:9.5.0 \
  phpspec/prophecy-phpunit:2.0.1 \
  symfony/phpunit-bridge:5.2.1

RUN cd web/core; phpunit -c phpunit.xml.dist modules/node/tests/src/Functional/NodeTestBase.php

```

Building this causes the error I described above.

# Answer
I believe the problem is that you are using the sample `phpunit.xml.dist` instead of copying it to `phpunit.xml` and then making a few teaks for your installation.

Part of the `phpunit.xml` file is setting up the autoloader to find test classes and modules (they are not in the normal autoloader). And you tend to get some really weird errors if you don't set up the DSN for the database (to run Kernel and Functional tests).

I would do the following (adjust paths as needed ; I'm looking at a core-dev project right now and not a live site).

* In your install, do `composer require --dev drupal/core-dev:~9.1.0`. You may want to tweak the version number, depending on you you have core defined.
* Make sure you are running the binary from `vendor/bin` in your install. I suggest looking into direnv.
* Copy `phpunit.xml.dist` to `phpunit.xml` and edit
    + `SIMPLETEST_BASE_URL`
    + `SIMPLETEST_DB`
    + `BROWSERTEST_OUTPUT_DIRECTORY` to reflect your installation.

Then cd to `core`, and run

```
../vendor/bin/phpunit -c phpunit.xml --testsuite unit

```

This should start to loop through the Unit tests. Abort that if they look like they are working, and then do

```
../vendor/bin/phpunit -c phpunit.xml --testsuite kernel

```

Then, if that looks OK you can start to run your own tests.

All of that said, it is much easier to run individual tests through PhpStorm. You just need to got through the preferences to point to the right PHP interpreter, and set a few things for phpunit.

In your case, it may be better to just start the `drupal:9.1.0` container, and then shell into it for initial testing before updating the `Dockerfile`.
> 2 votes

---
Tags: testing, 9
---


# Question
Title: Fatal error: Cannot redeclare uc_order_views_data()
After clicking Continue @ `/update.php`, we receive:

> Fatal error: Cannot redeclare uc\_order\_views\_data() (previously declared in /home/user/public\_html/sites/all/modules/ubercart/uc\_order/views/uc\_order.views.inc:13) in /home/user/public\_html/sites/all/modules/contrib/ubercart/uc\_order/views/uc\_order.views.inc on line 708

When I remove either version of the ubercart directories, the `/update.php` process complains that the directory is missing.

I can't see a double-up of modules in `/admin/modules`

The two ubercart directories both contain the same subfolders.

I did not develop the website, but took over maintenance of it.

# Answer
"When I remove either version ..."

"I can't see a double-up of modules in /admin/modules"

"The two ubercart directories both contain the same subfolders."

It sounds like you have two copies of Ubercart on your server. THAT IS NOT ALLOWED for ANY Drupal module. You must have one, and only one, copy of each module.

The correct way to update a Drupal module is to completely remove the old version of the module code first, then replace it with the new version of the code. Then you can run update.php.
> 0 votes

---
Tags: updating
---