# Question
Title: "Load a list of entity objects from a VBO View" rules action not working
I am trying to use the Rules action called "Load a list of entity objects from a VBO View." I had it working before, but I've since refreshed my DB from prod and I can't remember what my views looked like. I stripped the setup down to its most basic, vanilla configuration and I still can't get it to work.

Here's what I've done:

I created a view of Users. No page; no blocks; just a master display of users with no filter. Two fields: the user's name and the Bulk Operations checkbox (no actions; everything default).

I then created a rule. The event is just "view content" so I can iterate quickly. For the action, I selected "Load a list of entity objects from a VBO View." When I view a node (which triggers the rule), an error message pops up in the log that says, "Unable to get a data value. Error: Invalid data value given. Be sure it matches the required data type and format."

The reason is that the function `views_bulk_operations_action_load_list()` is trying to make an entity\_metadata\_wrapper out of `FALSE`. The exact line is `views_bulk_operations.rules.inc:176`:

```
$entities[] = entity_metadata_wrapper($entity_type, $vbo->get_value($result)); // $entity_type == 'user'

```

`$vbo->get_value($result)` ends up `FALSE` because `$vbo->entities` is `NULL`. Where are the entities? Did I miss something obvious when I set up my view?

# Answer
This issue has been reported and addressed on Drupal.org: https://www.drupal.org/node/2853029

The latest dev version has been updated to address this issue (version 7.x-3.x-dev).
> 0 votes

# Answer
You want to pass the **userid** as a parameter also, similar to what is shown around 7:30 in the video about Using VBO to load list of objects into Rules. Here is a summary of what is shown in this video:

> * You need a view that lists the entities you want to work on in Rules. Note that you don't need a display of the view – and it might even be better not to have one if you don't want the view to be displayed somewhere.
> * However, you need one bulk operations field. The type of bulk operations field determines what entity type will be sent to Rules. Note that you don't need any actions enabled for the field – it is enough that it is present.
> * You need a rule that, as an action, loads entities from a VBO. (This is available under the "Views bulk operations" group.) All view displayes with at least one VBO field will be selectable.
> * The action provides a list of entities, that can be used just like other lists in Rules. Combine with loops, actions and Rules Scheduler to make awesomeness happen.
> 0 votes

# Answer
I've identified the exact problem. I don't know if this will help others, as mine is a pretty obscure case, but I will post it just in case.

The site is using Open Atrium, which contains `views_bulk_operations`, but we had also created a separate copy of `views_bulk_operations`, patched it, and placed it in our own `sites/all/modules` directory. As far as I can tell, having two copies of it breaks the PHP class inheritance chain somehow. Specifically, in `views_bulk_operations.rules.inc:176`:

```
$entities[] = entity_metadata_wrapper($entity_type, $vbo->get_value($result));

```

`$vbo` is an instance of `views_bulk_operations_handler_field_operations`, which extends `views_handler_field_entity`, which in turn extends `views_handler_field`. In a properly functioning site, the line above calls `views_handler_field::get_value()`, but in my borked up site it calls `views_handler_field_entity::get_value()`. Not sure what the permanent fix will be, but removing our patched copy of VBO did get it working again.
> 0 votes

# Answer
Make sure that the VBO field is loaded in the *Master display*. In the Views module settings, it is possible to force this Master display.
> 0 votes

---
Tags: rules, views
---


# Question
Title: MarkupInterface interoperability with other PHP frameworks
## Situation in Drupal 8

Drupal 8 introduces a few classes and interfaces for safe markup:

* `Drupal\Component\Render\MarkupInterface`
* `Drupal\Component\Render\FormattableMarkup`
* `Drupal\Core\StringTranslation\TranslatableMarkup`

The purpose is

* to mark a string as being safe for use in html, without further sanitization.
* to have the string be lazy-evaluated.

The problem seems to be that all of these are specific to Drupal.

## Use case

I am designing an API I want to publish as a composer package, that should be used and implemented within Drupal 8 but also work outside of it. It should not depend on anything within Drupal.

There are interfaces that can return string labels, or arrays of such labels (e.g. to act as option labels in a select element).

Implementations within Drupal will want to use the `t()` function, which returns `TranslatableMarkup` objects. But the interface or the calling code know nothing about Drupal's `TranslatableMarkup` or `MarkupInterface`.

## Solutions considered so far

One option would be to require all implementations to return plain strings, which they can do via `(string)` cast, or by calling the `__toString()` method. This would work but it feels unnatural.

Another option would be to introduce a custom `TranslatableString` object which my own API can understand. This would replace a Drupalism with a my-own-ism, and also feel clumsy for implementations within D8.

Another option would be to allow the interface to return arbitrary values and later attempt to convert them to strings using either a flexible adapter layer, or attempting to call the \__toString() function. This would make it harder to require a specific return type, and detect if an implementation returns "illegal" values.

## Question

Have there been any attempts to make a "bridge" between Drupal's `MarkupInterface` (EDIT: And `TranslatableMarkup`) and the larger PHP ecosystem?

---

## Ongoing discussion

There are some comments below which point to interesting directions.

I'd say the main question is still open: How can we bridge the Drupal-specific classes and interfaces to the outside world? Are there Drupal-agnostic versions of these classes and interfaces?

# Answer
> 4 votes
## TLDR

*(this summarizes conclusions from the comments below)*

The `MarkupInterface` is available on packagist as part of the `drupal/core-render` package, which provides all the classes from `Drupal\Component\Render\*` without any heavy dependencies (only `drupal/core-util`). It does *not* give you `TranslatableMarkup`, though.

If you let your package depend on `drupal/core-render`, you can use `MarkupInterface` as a return type.

Implementations within Drupal modules, which call `t()` and return a `TranslatableMarkup` object, would satisfy the return type from the interface.

Implementations outside of Drupal would instead return `FormattableMarkup`, or `HtmlEscapedText`, or a custom implementation of `MarkupInterface`. Or something else, if the interface allows alternative return types (e.g. native string).

You need to decide if you accept this dependency, or do something else instead.

## Original (longer) answer

The ultimate goal of having the two names spaces in Drupal is

* `Drupal\Component` is for classes that do not need a bootstrapped kernel. In other words, these do not need a running Drupal system. These classes may depend on other classes outside `Drupal\Component` (eg, `Symfony`) or other classes in `Drupal\Component`, but not `Drupal\Core`
* `Drupal\Core` is for classes that require a bootstrapped kernel. These full from `Drupal\Core`, `Drupal\Component`, and elsewhere.

Take date/time objects.

* `DrupalDateTime` is in `Drupal\Core` because leverages the translation service.
* `DateTimePlus is in`Drupal\Component`because it adds some enhancements to the native`\DateTime\` class.

So, in theory, `Drupal\Component` can be used in anything. That said, the `composer.json` files for each component may not be accurate for dependencies and minimum PHP version.

In your case, `MarkupInterface` and `FormattableMarkup` should be able to be used outside of Drupal. `TranslatableMarkup` relies on the Drupal translation system, which needs a booted kernel to operate.

`TranslatableMarkup` essentially just extends `FormattableMarkup`, and acts a bridge to the string translation service. So, that on its own doesn't buy you much unless you need everything that surrounds translation (language management, the UI, etc).

All of that said, I am not sure how much you will really gain from this. Ignoring the translation parts, `FormattableMarkup` is a component, but they are really best used as part of the rendering service, which is part of core. For the purposes of making your own API, I would start with seeing if you can just leverage `FormattableMarkup` on its own.

---
Tags: 8
---


# Question
Title: How do I save data into a custom table on form submit?
Number of columns in my custom table is huge. How do i insert data in custom table on form submit in Drupal 8? I want to use something similar to `drupal_write_record('table_name', $form_state['values']);` in Drupal8.

# Answer
> 5 votes
As per the change record, `drupal_write_record` has been removed, with the new advice being:

> Developers should use `\Drupal::database()->merge()`, the Entity API or one of the provided services, like key value.

As you're using a custom table, you'll need the first method. An example from that change record:

```
\Drupal::database()->merge('example_deleted_entity_statistics')
  ->key(array('type' => $type, 'id' => $id))
  ->fields(array('count' => $count))
  ->execute();

```

As always, inject the database service if possible, rather than requesting it from `\Drupal`.

# Answer
> 0 votes
You can find it under drupal documentation at Database API Section, for example for insert query check it here

> $connection = \Drupal\Core\Database\Database::getConnection() ;
> $connection-\>insert('mytable')-\>fields(\[ 'title' =\> 'Example', 'uid' =\> 1, 'created' =\> REQUEST\_TIME, \]) -\>execute();

---
Tags: forms, 8
---


# Question
Title: Automatically generate product variations
I'm creating a webshop with Drupal Commerce. I have a product variation (*T-shirt*) with three product attributes: color, size, and print.

If I need a t-shirt with 5 different colors, 5 different sizes, and 5 different prints, I would need to manually create 125 product variations from the user interface.

Is it possible to automatically create those product variations?

It should be possible to enter the default price for all the variations.

I found Product variant bulk creation, where it is said that functionality has been made in the Commerce Bulk module. I installed that module, but I could not find any option to bulk generate the product variations.

# Answer
I could not install the *Commerce Bulk module*. Then I saw Product variant bulk creation, which will be a sweet feature when it has been merged. I could not get the patch to apply so I ended up creating a sandbox module based on this.

Judging by your rank, you will know how to get the code.

This module will give you a route (no link yet). You need to create at least one Product variation manually, then go to /product/PRODUCTID/variations/VARIATIONID/bulk-generate (for example /product/331/variations/1/bulk-generate) to bulk generate your variations.

>
> 1 votes

---
Tags: 8, entities, commerce
---


# Question
Title: How Do I Change My Drupal Admin Password From a Drupal Test Install on My Local Machine
I am a complete Drupal beginner. My Drupal site is hosted with a provider. I have these questions and would really appreciate your insight.

1) I want to be able to change the front end log in pass from cPanel in the event I get locked out. My hosting company has provided me with (a) a lengthy way to do it and (b) a short way to do it.

(a)

1. Set up up SSH access
2. From Mod Security
3. Add and whitelist my current IP address
4. Manage SSH Keys
5. Generate New Key
6. Find the Key under Public Keys section
7. Manage
8. Authorize
9. SSH Access screen
10. Manage SSH Keys again and under Private Key View/Download
11. Then "convert "id\_dsa" key to PPK format"
12. Enter password and download key
13. Download/install PuTTY
14. In PuTTY go to connection, SSH, Auth and browse for coverted key file just downloaded.
15. Click Session and under Port enter 2222
16. Enter host name and Open to connect
17. Answer yes to all security prompts
18. When prompted to Login As, enter my cPanel username and for the password use the one I set for the SSH key.
19. Once connected via SSH enter "cd public\_html" and go to Drupal root
20. Then enter ""php core/scripts/password-hash.sh 'NEWPASSWORD'"
21. Copy the text after where it says "hash"
22. Return to cPanel, open phpMyAdmin, click on database, look for "users\_field\_data table"
23. Find the account with the name "Admin"
24. Click Edit and replace the text in the pass field by pasting in the hashcode I generated.
25. Lastly, go to the table in the database named "flood" and delete any rows with my IP address.
26. Then they say "You may want to enter your IP at the top, under Filter rows.
27. Do the same for the cache\_entity table.

(b) Go to your cPanel -\> Databases box -\> phpMyAdmin. Select the database which Drupal uses from the drop-down menu on the left. Select the right tab that says: (SQL) Click the SQL tab. (I tick SQL and a text field pops up with: "Run SQL query/queries on database" (database name) In the SQL text field page type the following text:

**update users set pass=md5(’NEW PASS’) where uid = 1;**

Where NEWPASS is your desired new administrative password.

Then click on the GO button and if no errors present, the Drupal password should have been changed.

(a) is very difficult.

(b) is easier but I'm not confident that (b) is correct. Is it?

(c) I want to download/install a test Drupal to my local machine and try these tasks before I attempt them on my live site.

(d) Can I test these tasks on a my local machine with Drupal installed as a test version?

(e) Of the three installers at https://bit.ly/2QeuFLd which one do you suggest for a beginner?

Thank you for your advice.

# Answer
> 0 votes
short version use "drush uli" longer version have a local install with known password, go to your cpannel -\> phpMyAdmin change the password to the known one. - done

---
Tags: users
---


# Question
Title: Second managed_file upload field fails with "An unrecoverable error occurred"
I have a form with two (ajax enabled) upload fields.

Submitting a file to the first one works, then submitting a file to the 2nd does not, giving

> An unrecoverable error occurred. The uploaded file likely exceeded the maximum file size (20 MB) that this server supports.

(the "likely exceeded" bit is wrong in this instance)

Looking at the code and the network requests it looks like the first is POSTed to a URL including the form build ID, and includes the same build ID in the POST body data. The second is posted to the same URL, however the result of uploading the first is that the form's hidden build id has changed -this is why the code in file.module rejects it and issues this error.

Thing is, I believe this has been working until recently (perhaps a recent upgrade of Drupal 7?) as I'm only getting these reports now but the code has been unchanged for at least a year.

Any suggestions?

(Drupal 7.69)

# Answer
> 0 votes
I'm the OP: This is not a full answer, but a fix:

Forcing the session to start with `$_SESSION['something'] = 1;` in the form build seems to cure this problem.

If you can provide better answers please do.

---
Tags: 7, forms
---


# Question
Title: Shopping Cart view, change quantity widget to select box
I have two kinds of price type: price per unit and price per weight. I have managed to use `hook_form_alter()` to change the widget textbox to a predefined select list.

For some items it fills the selectbox with '1 piece + price', '2 pieces + price'; for other items, I use '100 grams + price', '200grams + price' and so on. The code I have used for this is below.

```
function kmsol_quantity_form_alter(&$form, &$form_state, $form_id) {
    //add to cart form
    if (strpos($form_id, 'commerce_cart_add_to_cart_form_') === 0) {
        // Replace the text quantity field with a select list.
        if (isset($form['quantity']) && ($form['quantity']['#type'] == 'textfield')) {

            $product = commerce_product_load($form['product_id']['#value']);
            $price   = commerce_product_calculate_sell_price($product);

            $prd_wrapper      = entity_metadata_wrapper('commerce_product', $form['product_id']['#value']);
            $field_price_type = $prd_wrapper->field_prijs_type->value();

            $weight_array = array(
                '0.1' => '100 gram ' . commerce_currency_format(0.1 * $price['amount'], $price['currency_code'], $product),
                '0.2' => '200 gram ' . commerce_currency_format(0.2 * $price['amount'], $price['currency_code'], $product),
                '0.3' => '300 gram ' . commerce_currency_format(0.3 * $price['amount'], $price['currency_code'], $product),
                '0.4' => '400 gram ' . commerce_currency_format(0.4 * $price['amount'], $price['currency_code'], $product),
                '0.5' => '500 gram ' . commerce_currency_format(0.5 * $price['amount'], $price['currency_code'], $product),
                '0.6' => '600 gram ' . commerce_currency_format(0.6 * $price['amount'], $price['currency_code'], $product),
                '0.7' => '700 gram ' . commerce_currency_format(0.7 * $price['amount'], $price['currency_code'], $product),
                '0.8' => '800 gram ' . commerce_currency_format(0.8 * $price['amount'], $price['currency_code'], $product),
                '0.9' => '900 gram ' . commerce_currency_format(0.9 * $price['amount'], $price['currency_code'], $product),
                '1' => '1 KG  ' . commerce_currency_format(1 * $price['amount'], $price['currency_code'], $product)
            );
            $piece_array  = array(
                '0.1' => '1 stuks ' . commerce_currency_format(1 * $price['amount'], $price['currency_code'], $product),
                '0.2' => '2 stuks ' . commerce_currency_format(2 * $price['amount'], $price['currency_code'], $product),
                '0.3' => '3 stuks ' . commerce_currency_format(3 * $price['amount'], $price['currency_code'], $product),
                '0.4' => '4 stuks ' . commerce_currency_format(4 * $price['amount'], $price['currency_code'], $product),
                '0.5' => '5 stuks ' . commerce_currency_format(5 * $price['amount'], $price['currency_code'], $product),
                '0.6' => '6 stuks ' . commerce_currency_format(6 * $price['amount'], $price['currency_code'], $product),
                '0.7' => '7 stuks ' . commerce_currency_format(7 * $price['amount'], $price['currency_code'], $product),
                '0.8' => '8 stuks ' . commerce_currency_format(8 * $price['amount'], $price['currency_code'], $product),
                '0.9' => '9 stuks ' . commerce_currency_format(9 * $price['amount'], $price['currency_code'], $product),
                '1' => '10 stuks ' . commerce_currency_format(10 * $price['amount'], $price['currency_code'], $product)
            );

            if ($field_price_type == 'Prijs per kilo') {
                $select = $weight_array;
            }
            if ($field_price_type == 'Prijs per stuk') {
                $select = $piece_array;
            }

            $form['quantity']['#type']    = 'select';
            $form['quantity']['#options'] = $select;
            $form['quantity']['#size']    = 1;
        }
    }

```

I want to do the same thing more or less on the *Shopping Cart* page. However, this is a view and therefore my code is not working over there.

I have tried some code but its not working at all, and I think I'm looking at it the wrong way.

This is what I have for the moment.

```
function kmsol_customcart_commerce_cart_order_load($uid = 0)
{
    global $user;
    $order = commerce_cart_order_load($user->uid);
    dpm($uid);

        $order_wrapper = entity_metadata_wrapper('commerce_order', $order);

        foreach ($order_wrapper->commerce_line_items as $line_item => $line_item_wrapper)
        {
            $product = $line_item_wrapper->commerce_product->value();
            $field_price_type = $product->field_prijs_type->value();
            dpm($field_price_type);
            $weight_array = array(
                '0.1' => '100 gram ' ,
                '0.2' => '200 gram ' ,
                '0.3' => '300 gram ' ,
                '0.4' => '400 gram ' ,
                '0.5' => '500 gram ' ,
                '0.6' => '600 gram ' ,
                '0.7' => '700 gram ' ,
                '0.8' => '800 gram ' ,
                '0.9' => '900 gram ' ,
                '1' => '1 KG  '
            );
            $piece_array  = array(
                '0.1' => '1 stuks ' ,
                '0.2' => '2 stuks ' ,
                '0.3' => '3 stuks ' ,
                '0.4' => '4 stuks ' ,
                '0.5' => '5 stuks ' ,
                '0.6' => '6 stuks ' ,
                '0.7' => '7 stuks ' ,
                '0.8' => '8 stuks ' ,
                '0.9' => '9 stuks ' ,
                '1' => '10 stuks '
            );

            if ($field_price_type == 'Prijs per kilo') {    $select = $weight_array;    }
            if ($field_price_type == 'Prijs per stuk') {    $select = $piece_array;     }

            $form['edit_quantity']['#type']    = 'select';
            $form['edit_quantity']['#options'] = $select;
            $form['edit_quantity']['#size']    = 1;
        }
 }

```

The issue is that the quantity widget will be filled based upon the product type, so grams will remain grams and units stay units.

# Answer
I found the solution So i'll share it if someone else needs it..

---

```
hook_form_alter(&$form, &$form_state, $form_id)
{//add to cart form
if (strpos($form_id, 'commerce_cart_add_to_cart_form_') === 0) {
    // Replace the text quantity field with a select list.
    if (isset($form['quantity']) && ($form['quantity']['#type'] == 'textfield')) {

        $product = commerce_product_load($form['product_id']['#value']);
        $price   = commerce_product_calculate_sell_price($product);

        $prd_wrapper      = entity_metadata_wrapper('commerce_product', $form['product_id']['#value']);
        $field_price_type = $prd_wrapper->field_prijs_type->value();

        $weight_array = array(
            '0.1' => '100 gram ' . commerce_currency_format(0.1 * $price['amount'], $price['currency_code'], $product),
            '0.2' => '200 gram ' . commerce_currency_format(0.2 * $price['amount'], $price['currency_code'], $product),
            '0.3' => '300 gram ' . commerce_currency_format(0.3 * $price['amount'], $price['currency_code'], $product),
            '0.4' => '400 gram ' . commerce_currency_format(0.4 * $price['amount'], $price['currency_code'], $product),
            '0.5' => '500 gram ' . commerce_currency_format(0.5 * $price['amount'], $price['currency_code'], $product),
            '0.6' => '600 gram ' . commerce_currency_format(0.6 * $price['amount'], $price['currency_code'], $product),
            '0.7' => '700 gram ' . commerce_currency_format(0.7 * $price['amount'], $price['currency_code'], $product),
            '0.8' => '800 gram ' . commerce_currency_format(0.8 * $price['amount'], $price['currency_code'], $product),
            '0.9' => '900 gram ' . commerce_currency_format(0.9 * $price['amount'], $price['currency_code'], $product),
            '1' => '1 KG  ' . commerce_currency_format(1 * $price['amount'], $price['currency_code'], $product)
        );
        $piece_array  = array(
            '1' => '1 stuks ' . commerce_currency_format(1 * $price['amount'], $price['currency_code'], $product),
            '2' => '2 stuks ' . commerce_currency_format(2 * $price['amount'], $price['currency_code'], $product),
            '3' => '3 stuks ' . commerce_currency_format(3 * $price['amount'], $price['currency_code'], $product),
            '4' => '4 stuks ' . commerce_currency_format(4 * $price['amount'], $price['currency_code'], $product),
            '5' => '5 stuks ' . commerce_currency_format(5 * $price['amount'], $price['currency_code'], $product),
            '6' => '6 stuks ' . commerce_currency_format(6 * $price['amount'], $price['currency_code'], $product),
            '7' => '7 stuks ' . commerce_currency_format(7 * $price['amount'], $price['currency_code'], $product),
            '8' => '8 stuks ' . commerce_currency_format(8 * $price['amount'], $price['currency_code'], $product),
            '9' => '9 stuks ' . commerce_currency_format(9 * $price['amount'], $price['currency_code'], $product),
            '10' => '10 stuks ' . commerce_currency_format(10 * $price['amount'], $price['currency_code'], $product)
        );

        if ($field_price_type == 'Prijs per kilo') {
            $select = $weight_array;
        }
        if ($field_price_type == 'Prijs per stuk') {
            $select = $piece_array;
        }

        $form['quantity']['#type']    = 'select';
        $form['quantity']['#options'] = $select;
        $form['quantity']['#size']    = 1;
        $form['quantity']['#default_value'] = 0.1;
    }
}

// Cart page
if (strpos($form_id, 'views_form_commerce_cart_form_default') === 0)
{
    //dpm($form_id);
    //dpm($form);
    //dpm($form_state);

    if (isset($form['edit_quantity'])) {
        foreach ($form['edit_quantity'] as $key => $quantity_field) {
            if (is_array($quantity_field)) {
                // query the DB for each line item in order to get the product id
                $entity_type = 'commerce_line_item';
                $query = new EntityFieldQuery();
                $query->entityCondition('entity_type', $entity_type, '=')->propertyCondition('line_item_id', $quantity_field['#line_item_id'], '=');
                $result = $query->execute();

                if (!empty($result[$entity_type])) {
                    // load the full line item information
                    $line_item = entity_load($entity_type, array_keys($result[$entity_type]));

                    // get the options array if a select box is necessary
                    $product = $line_item[$quantity_field['#line_item_id']]->commerce_product['und'][0]['product_id'];
                    $prd_wrapper = entity_metadata_wrapper('commerce_product', $product);
                    $field_price_type = $prd_wrapper->field_prijs_type->value();

                    $weight_array = array(
                        '0.10' => '100 gram ' ,
                        '0.20' => '200 gram ' ,
                        '0.30' => '300 gram ' ,
                        '0.40' => '400 gram ' ,
                        '0.50' => '500 gram ' ,
                        '0.60' => '600 gram ' ,
                        '0.70' => '700 gram ' ,
                        '0.80' => '800 gram ' ,
                        '0.90' => '900 gram ' ,
                        '1.00' => '1 KG  '
                    );
                    $piece_array  = array(
                        '1.00' => '1 stuks ' ,
                        '2.00' => '2 stuks ' ,
                        '3.00' => '3 stuks ' ,
                        '4.00' => '4 stuks ' ,
                        '5.00' => '5 stuks ' ,
                        '6.00' => '6 stuks ' ,
                        '7.00' => '7 stuks ' ,
                        '8.00' => '8 stuks ' ,
                        '9.00' => '9 stuks ' ,
                        '10.00' => '10 stuks '
                    );

                    if ($field_price_type == 'Prijs per kilo') {
                        $select = $weight_array;
                    }
                    if ($field_price_type == 'Prijs per stuk') {
                        $select = $piece_array;
                    }
                    //dpm($line_item);
                    //dpm($line_item[$quantity_field['#line_item_id']]->quantity);

                    $form['edit_quantity'][$key]['#type']           = 'select';
                    $form['edit_quantity'][$key]['#options']        = $select;
                    $form['edit_quantity'][$key]['#size']           = 1;
                    $form['edit_quantity'][$key]['#default_value']  = $line_item[$quantity_field['#line_item_id']]->quantity;
                }

            }
        }
    }
}

```

}

---
> 1 votes

# Answer
Streamlining the above answer. To switch quantity textbox to be a select field...

```
function THEME_form_alter(&$form, $form_state, $form_id) {
  switch ($form_id){
    case 'views_form_commerce_cart_form_default':
      $select = array('1' => '1 ','2' => '2 ','3' => '3 ','4' => '4 ','5' => '5 ','6' => '6 ','7' => '7 ','8' => '8 ','9' => '9 ');

      foreach ($form['edit_quantity'] as $key => $quantity_field) {
        $form['edit_quantity'][$key]['#type']           = 'select';
        $form['edit_quantity'][$key]['#options']        = $select;
        $form['edit_quantity'][$key]['#size']           = 1;
        $form['edit_quantity'][$key]['#default_value']  =    $line_item[$quantity_field['#line_item_id']]->quantity;
      }
      break;
  }
}

```
> 0 votes

---
Tags: views, commerce, forms
---


# Question
Title: How to make a text field box appear after clicking select option by using ajax?
I created a content type with a select field whose options are the following ones.

1. Text
2. Text area
3. File

When I select *Text area* (\*text), a text area box (a text box) should appear below the select field. When I select *File*, a button should appear after the select field.

I heard this can be done using AJAX, but I don't know where to start and how to do it.

# Answer
You can use the Conditional Fields module, which allows you to show/hide fields based on other field's values.

From the module description:

> Conditional Fields allows you to manage sets of dependencies between fields. When a field is “dependent”, it will only be available for editing and displayed if the state of the “dependee” field matches the right condition.
>
> When editing a node (or any other entity type that supports fields, like users and categories), the dependent fields are dynamically modified with the States API.
>
> A simple use case would be defining a custom “Article teaser" field that is shown only if a "Has teaser" checkbox is checked, but much more complex options are available.
> 1 votes

---
Tags: ajax
---


title: Show user based on subdomain

text:
# Question
Title: Show user based on subdomain
Im using Domains Access to create a subdomain and already created all the virtualhosts, so that one is working.

Is it possible to show a user based on domain name?

Im creating a view, and i need to show for example:

**lucas.site.com** and show user **lucas**.

I have tried by adding contextual filter: User ID context on route.
But it doesn't take effect, it looks in **lucas.site.com/lucas** maybe im missing something?

# Answer
Reply to my self:

I have created a custom Controller that get the user from db based on the domain, i get the subdomain using this:

```
$subdomain = substr_count($_SERVER['HTTP_HOST'], '.') > 1 ? substr($_SERVER['HTTP_HOST'], 0, strpos($_SERVER['HTTP_HOST'], '.')) : '';

```

Not sure if its the best.

Then i compare to the user on db:

```
$result = \Drupal::database()->select('user_data', 'n')
            ->fields('n', array('id', 'user_domain', 'user_email'))
            ->condition('n.user_domain', $subdomain)
            ->execute()->fetchAllAssoc('id');

```

First you need to create a install schema with the domain created so you can fetch this.

Then loading by user email:

```
$user = user_load_by_mail($userEmail);

```

and pass the variable to the Twig. Not sure if its the best way.
> 0 votes

---
Tags: 8, domain-access
---


title: How to allow html tag in menu?

text:
# Question
Title: How to allow html tag in menu?
How to allow html tag in menu in Drupal 8. For example if use home <sup>@reg</sup> used in menu title it display the html tag.

# Answer
> 8 votes
Following solution works:

```
use Drupal\Core\Render\Markup;

/**
 * Implements hook_preprocess_HOOK()
 */
function YOURTHEME_preprocess_menu(&$variables){
  foreach($variables['items'] as &$link){
    $link['title'] = Markup::create($link['title']);
  }
}

```

Source: Allow html into menu item names - Solution for Drupal 8

# Answer
> 1 votes
I recommend to use a plugin for this. Full tutorial here: Create a menu link with html markup in drupal 8

```
namespace Drupal\MYMODULE\Plugin\Menu;

use Drupal\Core\Menu\MenuLinkDefault;

/**
 * A menu link that displays number of points.
 */
class MyMessagesMenuLink extends MenuLinkDefault {

  /**
   * {@inheritdoc}
   */
  public function getTitle() {
    $count = 0;
    if(\Drupal::currentUser()->isAuthenticated()) {
      // Load in your count here
      ...
    }
    return $this->t('My messages <span class="badge badge-dark">@count</span>', ['@count' => $count]);
  }

  /**
   * {@inheritdoc}
   */
  public function getCacheMaxAge() {
    return 0;
  }

}

```

---
Tags: 8
---


title: Customizing menu link output

text:
# Question
Title: Customizing menu link output
In Drupal 7, how I can intercept menu rendering in template.php and add pipes after menu links?

I tried using template\_preprocess\_menu\_tree but I don't think that is what I am looking for. I want to change the HTML structure of a couple of menus.

# Answer
theme\_menu\_link() did the trick. It contains an array under element of `#original_link` which has the menu name in it. Using that, I can add pipe delimited links to certain menus.

http://api.drupal.org/api/drupal/includes--menu.inc/function/theme\_menu\_link/7
> 7 votes

# Answer
This may be helpful. You can use preprocess functions to change or add something to menu link.

```
function THEME_preprocess_menu_link(&$variables) {
  $variables['element']['#below']['#markup'] = ' <span>→</span>';
}

```

In this code span added to every navigation link item.
> 5 votes

# Answer
Personally I'd just add the pipe with CSS - you don't really want the pipes in your markup as they're purely presentational:

```
.breadcrumb li:after {
  content: "|";
  margin: 0 5px; // optional styling nicety
}

.breadcrumb li:last-child::after {
  content: "";
}

```
> 5 votes

# Answer
Menus are themed with the theme\_links function. You'll want to create a copy in your \[themes folder\]/MYTHEME/template.php and rename it to MYTHEME\_links. You can find the default function for drupal 7 by visiting: http://api.drupal.org/api/drupal/includes--theme.inc/function/theme\_links/7

Now you'll be able to customize how the menus look from the template.php file.
> 1 votes

# Answer
I recommend to use a plugin for this. Full tutorial here: Create a menu link with html markup in drupal 8

```
namespace Drupal\MYMODULE\Plugin\Menu;

use Drupal\Core\Menu\MenuLinkDefault;

/**
 * A menu link that displays number of points.
 */
class MyMessagesMenuLink extends MenuLinkDefault {

  /**
   * {@inheritdoc}
   */
  public function getTitle() {
    $count = 0;
    if(\Drupal::currentUser()->isAuthenticated()) {
      // Load in your count here
      ...
    }
    return $this->t('My messages <span class="badge badge-dark">@count</span>', ['@count' => $count]);
  }

  /**
   * {@inheritdoc}
   */
  public function getCacheMaxAge() {
    return 0;
  }

}

```
> 0 votes

---
Tags: 7, routes, theming
---


title: PHP not Updating for Anonymous Users

text:
# Question
Title: PHP not Updating for Anonymous Users
I have been running a personal dashboard on Drupal 7 for years (currently on 7.69). I rendered the dashboard in Homebox and some of the blocks use PHP (using PHP Filter) to get stock quotes, weather updates, etc.

I recently rebuilt the site in Drupal 8.8.1. I use Panels for the dashboard blocks since there is no Homebox for Drupal 8. I also added the PHP Filter module for my PHP blocks. I'll eventually put my PHP code in modules, but I'm going with PHP Filter for now. I'm using the included Bootstrap theme and caching is set to 'no caching'.

My problem is, everything runs fine when I am logged in as administrator -- the PHP code in the blocks executes every time I do a page refresh. However, when I am not logged in and I do a page refresh as an anonymous user, the PHP blocks do not update. In Drupal 7.69 the page will update for an anonymous user, which is the behavior I want. I've compared permissions between the two installations and everything looks the same. I must be missing something here.

Has anyone else used PHP Filter with Drupal 8 and run into this?

# Answer
> 1 votes
Looking at the code of the PHP filter:

```
class Php extends FilterBase {

  /**
   * {@inheritdoc}
   */
  public function process($text, $langcode) {
    $result = new FilterProcessResult(php_eval($text));
    $result->setCacheMaxAge(0);
    return $result;
  }

```

https://git.drupalcode.org/project/php/blob/8.x-1.x/src/Plugin/Filter/Php.php

it sets already a cache max age of 0, so you only need to remove the page cache for anonymous users by uninstalling the module "Internal Page Cache".

---
Tags: 8
---


# Question
Title: How should I setup Drush to work with Drupal 8.8.1 using Git Bash on Windows 10
I am using a Windows computer and using Git Bash, I just installed a new 8.8.1 site and also did 'composer require drush/drush'. I can't use Drush from anywhere so I am wondering if I should have installed Drush globally on the computer.

# Answer
> 0 votes
No, you don't install Drush globally anymore. You install the Drush Launcher instead. It will provide you a global `drush` command that automagically uses the local Drush from each project.

> # Drush Launcher
>
> A small wrapper around Drush for your global $PATH.

---
Tags: 8, drush
---


# Question
Title: How to get a user's profile picture URL?
I need to get the user's profile picture using the following code:

```
\Drupal::service('renderer')->renderPlain(\Drupal\user\Entity\User::load(\Drupal::currentUser()->id())->user_picture->first()->view('large'))

```

It returns an object with the image tag, but it fails with the `_Call to a member function view() on a non-object_` error when a user has no profile picture set.

I also tried the answer to "How do I get the default user picture?", but it gives the error

> Drupal\Core\Database\InvalidQueryException: Query condition 'file\_managed.uuid IN ()' cannot be empty.

# Answer
> 6 votes
The code is OK, but you have to check if the field is not empty:

```
if ($user = \Drupal\user\Entity\User::load(\Drupal::currentUser()->id())) {
  if (!$user->user_picture->isEmpty()) {
    $picture = $user->user_picture->view('large')
  }
  else {
    $picture = // get default picture
  }
}

```

In Drupal 8 don't use render service. The new template system does this automatically.

# Answer
> 5 votes
```
// Getting the actual user uid.
$uid = \Drupal::service('current_user')->id();
// Getting the actual user entity.
$user = \Drupal::service('entity.manager')->getStorage('user')->load($uid);
// Getting the user picture.
$user_picture = $user->user_picture->entity->getFileUri();

// To use dpm you need the devel module.
dpm($user_picture);

```

# Answer
> 2 votes
1. Use the getAccount method on the AccountProxy class, which should save an entity load if the account object already exists.
```
$account = \Drupal::currentUser()->getAccount();

```
2. Use methods to on the field item (entity reference) to check if there is a value.
```
if (!$account->user_picture->isEmpty()) {

```
3. Instead of using the renderer to render the plain output from the field item. This data can be retrieved via some other methods.
```
   $image_url = $account
                  ->user_picture
                  ->first()
   // Fetch the file entity associated with the image item entity reference.
                  ->get('entity')
   // Use the url() to call file_create_url() as in Drupal 7 to get the URL.
                  ->url();
}

```

# Answer
> 1 votes
This is really more of a PHP issue. You shouldn't put calls to object methods within the arguments of another function, especially if you're dealing with fields on a drupal entity, as they may be set or not set.

```
$uid = \Drupal::currentUser()->id();

// Might be zero if user is logged out.
if ($uid) {
  $user = \Drupal\user\Entity\User::load($uid);
   // check that the field exists and that it has a value.
  if (!empty($user->user_picture) && $user->user_picture->isEmpty() === FALSE) {
    $image = $user->user_picture->first();
    $rendered = \Drupal::service('renderer')->renderPlain($image);
  }
}

```

Also, Drupal coding standards suggest you try and keep your lines under 80 characters, and I feel that's good practice, as it makes the code more readable. See:

https://www.drupal.org/node/935284

Also, here's a post about getting the default image for a user. You might want to set a default image for this field.

How get the default user picture?

# Answer
> 1 votes
This is the best way on Drupal 8, create a custom module with Controller and send a variable to Twig:

```
$pictureUri = $user->user_picture->entity->getFileUri();
                         $style = \Drupal::entityTypeManager()->getStorage('image_style')->load('thumbnail');
                         $urlPicture = $style->buildUrl($pictureUri);

```

---
Tags: 8, users, uri
---


# Question
Title: How can I check to see differences across my multisites?
Currently, we're using Acquia Content Hub to syndicate content across our sites with a spoke and wheel syndication architecture. We essentially use a single site (that content editors use to create/maintain our content) and push out content to all of our subscribing sites.

However, it seems that some of our developers implemented changes on certain sites but not all sites and this is causing differences for each of our site environments (example: All sites would have an article content type but with different fields/naming conventions for fields). These differences then end up preventing our synchronization (especially if there is a field on the main content site and not on a subscribing site) from moving past the item and then requires a clear (and re-queue) of all items to syndicate.

Is there any easy way to set up a PHP script or something to check each site for differences against the main content site for entities?

---

For example:

```
If on the main (content) site the article had 3 fields:
- Article Title
- Article Body
- Article Image

And on a subscribing site, the article had only 2 fields:
- Article Title
- Article Body

```

I would expect said magical script to print out some indication that on the main (content) site, there is an "Article Image" field present that's not available on the subscribing site.

Is there any way that I could accomplish this? Any and all assistance would be greatly appreciated, thanks!

# Answer
That's a task for the Features module. Before Drupal 8 and its superb configuration management the Features module was used to track and deploy changes to entities or settings from local to prod or to your coworkers. Nowadays you can use it to track changes and sync features across multiple instances of Drupal.

Let's say you have two Drupal 8 sites or two Drupal 8 multisite instances and both of them have a content type "Foobar". Then there's Features that lets you export the whole content type into a so called Features module. Which is just another module but also holds the whole config for this "Foobar" content type in it. Now you activate this Features module on both sites or instances and both will have the same content type with the same fields in it.

From now on when you change something in this content type on either instance Features will recognize the changes and offers you to recreate the Features module. Do that and the other instance will recognize the Features module had been recreated and offers you to import these changes.

And that's what you can do now. Go to the instance you consider being the master. Use Features to export the content type in a Features module. Enable this module in this instance and also in the other instance which you think got overridden or which you think is missing the changes and use Features to explore the differences and to maybe sync the changes.

> The features module enables the capture and management of features in Drupal. A feature is a collection of Drupal entities which taken together satisfy a certain use-case.
>
> Features provides a UI and API for taking different site building components from modules with exportables and bundling them together in a single feature module. A feature module is like any other Drupal module except that it contains additional information in its info file so that configuration can be checked, updated, or reverted programmatically.
> 3 votes

---
Tags: 8, nodes, external-scripts
---


# Question
Title: Locked out of my locally hosted Drupal site
I am running a local distribution of Drupal "commons" using Acquia Dev Desktop on a mac and somehow got locked out of my site. I saved my login info and am almost sure it's correct, but I'm still locked out.

Anyone know how I can remedy this situation?

Just for context, I am new to Drupal, so would need a detailed guideline for the fix.

# Answer
Since you are using Acquia Dev Desktop on a Mac, you have access to the best Drupal tool - Drush. In a terminal, navigate to the folder containing your Drupal website and run

```
drush uli

```

It will return a link to reset the password for user 1. The URL returned from the command will look something like

```
http://default/user/reset/1/[numbers]/[hash]/login

```

Paste that URL into your browser and replace "default" with the (local) domain name for your site. Good luck!
> 3 votes

---
Tags: authentication-authorization, acquia-dev-desktop
---


title: How can I sum aggregate of expression

text:
# Question
Title: How can I sum aggregate of expression
I have a problem that looks relatively simple.

An activity entity has multiple invitation entities, the reference is from the `invitation.activity_id` =\> activity.

Invitation has a `completion_date` (when the user completes the activity) which can be zero (not complete) or a timestamp of when it was completed.

(I created a reverse relationship so I can go from the activity to the invitations, that works fine.)

I want to create a table view where each row is an activity, and it has two columns - total invitations and completed invitations.

The total is easy: switch on aggregation and count the number of invitations.

Calculating the number of completed is another matter.

I've created my own views field plugin (extended from boolean) which inserts an expression field instead of using the actual field.

```
class InvitationCompletionState extends Boolean {
  /**
   * Called to add the field to a query.
   */
  public function query() {
    $table_alias = $this->ensureMyTable();
    $this->query->addField(
      NULL,
      "IF($table_alias.completion_date > 0, 1, 0)",
      'completion_state'
    );
  }

```

But I can't aggregate it. I know aggregation doesn't work with everything, and I suppose this is a situation where it doesn't.

I wanted to use the boolean option (although INT might be better) because I can count the number of completed by simply SUMming the results.

This is the Views query if I try to use the aggregation

```
SELECT activity.name AS activity_name, activity.type AS activity_type, activity.start_date AS activity_start_date, activity.end_date AS activity_end_date, activity.estimated_time AS activity_estimated_time, COUNT(invitation_activity.id) AS invitation_activity_id, SUM(invitation_activity.completion_date) AS invitation_activity_completion_date, MIN(activity.id) AS id, MIN(invitation_activity.id) AS invitation_activity_id_1
FROM {activity} activity
LEFT JOIN {invitation} invitation_activity ON activity.id = invitation_activity.activity
GROUP BY activity_name, activity_type, activity_start_date, activity_end_date, activity_estimated_time
ORDER BY activity_start_date DESC

```

And it just forgets about inserting the expression.

**Further investigation:**

Pasting the following code into Workbench works and gives me the answer I want:

```
SELECT
    activity.name AS activity_name,
    activity.type AS activity_type,
    activity.start_date AS activity_start_date,
    activity.end_date AS activity_end_date,
    activity.estimated_time AS activity_estimated_time,
    COUNT(invitation_activity.id) AS invitation_activity_id,
    SUM(IF(invitation_activity.completion_date > 0, 1, 0)) AS completion_state,
    MIN(activity.id) AS id,
    MIN(invitation_activity.id) AS invitation_activity_id_1

FROM activity activity

LEFT JOIN invitation invitation_activity ON activity.id = invitation_activity.activity

GROUP BY activity_name, activity_type, activity_start_date, activity_end_date, activity_estimated_time

ORDER BY activity_start_date DESC

```

which means that MySQL can handle the code, it's just that Views does not know how to generate it.

I need to be able to make this work in a standalone handler (for any future devs), writing a hook to modify a query is not really an option.

Any thoughts?

# Answer
> 2 votes
Yeah, no way to do it without major surgery to the Views Query class - the assumptions it makes are hardwired.

The only practical solution seems to be the Views Aggregator module, which has a D8 dev version. This provides a Views Table Style which performs aggregation functionality on the fetched records - in other words, you do an ordinary non-aggregated fetch and the module does the aggregating just before display.

It has the advantage that you can do all sorts of interesting things - far more than you can in SQL, against the fact that it adds to processing time for large data sets. (And I can think of other potential issues too.)

However it solves my problem, so that's good.

https://www.drupal.org/project/views\_aggregator

The conversion from D7 to D8 is minimal (still uses hooks instead of plugins) but, as I say, it works.

# Answer
> 1 votes
Recently I ran into the same issue, but I think there's a fairly simple solution to this.

Oddly enough, disabling the grouping settings for your plugin and passing the function parameter to the addField method works just fine.

I'll show you what I mean:

```
class InvitationCompletionState extends Boolean {
  /**
   * Called to add the field to a query.
   */
  public function query() {
    $table_alias = $this->ensureMyTable();

    // Of course parameters should be taken from the plugin's options (buildOptionsForm function)
    // but in this case I'll just hardcode sum.
    $params = ['function' => 'sum'];

    $this->query->addExpression(
      "IF($table_alias.completion_date > 0, 1, 0)",
      'completion_state',
      $params // We pass the function to the method.
    );
  }

  public function usesGroupBy() {
    return FALSE;
  }

}

```

---
Tags: views, 8
---


# Question
Title: Error when adding BCC to email handler with webforms and smtp
I use SMTP to handle emailing and Webform to generate my forms on a drupal just upgraded to 8.7.10

I have recently discovered an issue where webforms that have an emal handler set to include a BCC email address throw the follwing error:

```
error: Call to undefined method Drupal\smtp\Plugin\Mail\SMTPMailSystem::_get_components()

```

The form submission does get saved but the confirmation process breaks so the user is not notified the submission saved and no emails of any kind are sent out.

Not including BCC fixes the problem. I use BCC in email handles to debug on a number of my sites and have never had this issue before. Any ideas? Is this a problem with webforms or smtp modules?

# Answer
> 2 votes
It looks like the issue lies with the SMTP module. The release notes for 8.x-1.0-beta6 include a bug fix for:

```
#2993124 by jmuzz, qichanghai, Chris Matthews: Call to Undefined Method error _get_components when there is a BCC

```

---
Tags: webforms, emails
---


title: Popup message not coming

text:
# Question
Title: Popup message not coming
I am using the Popup After Login module to show a pop-up after the users log in.

I want to display a Youtube video on the popup.

The steps I followed after installing the module and enabling it are:

* Go to admin/config/popup\_after\_login
* Configure it by selecting the role which should see the message
* Enter title, message body and save
* Clear cache and log in with an account to which is assigned that role

For the video, I used the Youtube embed code.

```
        <?php
          print(<iframe width="560" height="315" src="https://www.youtube.com/embed/-DYSucV1_9w" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>);

```

The output is not showing.

I checked whether the PHP code is running, adding the following code.

```
        <?php
          $variable = 1+2;
          print($variable);
        ?>

```

Again, only the title was shown, not the message.

Please help.

# Answer
The message body is of type text so it accepts "plain text", "filtered HTML" and "Full HTML" by default and it wont run php codes so try to insert this code :

```
<iframe width="560" height="315" src="https://www.youtube.com/embed/-DYSucV1_9w" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

```

instead. or if you want to use a php code you can use PHP module, but it is not recommended. PHP filter was removed from Drupal 8 due to security considerations, so try not to add it to your project.

when I checked the module I realized that this module use jquery swal function for pop up, so Iguess you need to change line 10 of its js to something like this :

```
swal.fire(title: result['title'], html:result['message']);

```

this might work.
> 0 votes

# Answer
The settings page on /admin/config/popup\_after\_login allows to select the text format for the message, which by default is *Full HTML*.

>

On a fresh Drupal 8 installation, the other available text formats are *Restricted HTML* and *Basic HTML*. All those text formats filter out `<?php`. Looking at the help for the *Full HTML* format (*About text formats*), I get that even HTML attributes are filtered out.

> ### Full HTML
>
> You can align images, videos, blockquotes and so on to the left, right or center. Examples:
>
> * Align an image to the left: `<img src="" data-align="left" />`
> * Align an image to the center: `<img src="" data-align="center" />`
> * Align an image to the right: `<img src="" data-align="right" />`
> * … and you can apply this to other elements as well: `<video src="" data-align="center" />`
>
> You can caption images, videos, blockquotes, and so on. Examples:
>
> * `<img src="" data-caption="This is a caption" />`
> * `<video src="" data-caption="The Drupal Dance" />`
> * `<blockquote data-caption="Dries Buytaert">Drupal is awesome!</blockquote>`
> * `<code data-caption="Hello world in JavaScript.">alert("Hello world!");</code>`

I take that, even removing the `<?php` tags, that HTML markup would not work as expected.
> 0 votes

---
Tags: 8
---


# Question
Title: How to set multiple arguments for views contextual filters from twig
Am using twig tweak module to render views from Twig file. I have pass multiple values for the country contextual filter in the view. I was able to pass single parameter like:

```
{{ drupal_view('our_services', 'services',  countryTermId) }}

```

Not sure how to pass multiple values here:

```
{{ drupal_view('our_services', 'services',  countryTermId+globalId) }}

```

This is not working.

# Answer
> 3 votes
To pass contextual filters with OR logic, you can make use of the Views Contextual Filters OR module:

> The module provides a views plugin to modify query of contextual filters.
> The module can changes contextual filters condition to OR logic.

When you install and enable the module from **Query settings** in your display check ***Contextual filters OR*** option and save:

Than in your twig:

```
{{ drupal_view('our_services', 'services', countryTermId, globalId ) }}

```

# Answer
> 1 votes
Directly from the Drupal documentation, you can pass multiple variables like this:

`{{ drupal_view('who_s_new', 'block_1', arg_1, arg_2, arg_3) }}`

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


# Question
Title: Modify the store for hundreds of products
I have a drupal 8 commerce website with 2 stores (store1 and store2). Most of the products belong to both stores but there are a few that only belong to either one.

Now, I need all the products (hundreds) to belong to a new store(store3) that i created on the website.

Obviously, I will not manually edit each product to assign it to the new store but what i was looking into is to write a SQL script (given that it's a one time thing) that will update the products in the DB. Soon after that i found out that it's more than the commerce\_product\__stores table that i would need to update, i would also have to update the commerce\_promotion\__stores and commerce\_shipping\_method\__stores tables. and to make the things more complicated, some tables like the commerce\_product\__stores need its values updated where as with the other ones, i need to add the entries.

What better, Drupal way, ways of doing it are out there? Another option that i found was talking about exporting all the products with the views data export module, modify the data and import it back in with the Feeds module but the author was complaining about some issues that were still not resolved in D8...

Any suggestions?

# Answer
There are two methods that are the "Drupal" way.

One is to write a PHP script that changes the products as needed. You would write a loop, load the products, update, and then save them. You then can the execute this script with drush as `drush scr whatever.foo`. This will bootstrap Drupal, and then execute the script in the context of a running Drupal install. Just keep in mind that loading a lot of entities in the same process can cause problems with the static cache getting too big. There are other questions here about how to handle this.

The second is to write a `hook_update_N()` function, and put it in a custom module. This is essentially the same as the standalone script. If you go with this approach, you can batch the changes (say update 50 at a time). You can then run the update from the UI or with `drush updb`. This approach works a little better with database backups / restores, and also works nicely if you have a dev -\> staging -\> production environment, especially if it also pulls the database backwards at each step and automatically runs updates.
> 4 votes

---
Tags: commerce
---


# Question
Title: Rule condition to check which language is used by the visitor?
I have a multilingual website (English, Spanish).

Is there any way to create a rule condition to compare the language used by the visitor against a fixed value?

The condition would something like: if language is **English** then go ahead with the actions.

# Answer
Seemed like a useful thing to have.

I created a patch for Rules, adding this functionality. I posted it in the Rules issue queue. That seemed better than providing the code directly here, as this way you can still use it anyway that suits you, yet it may actually get into core Rules.

Also see this question, "How do I add a new condition in Rules 2?".
> 13 votes

# Answer
Actually there are two ways for that:

## **1- The easy one :**

Add new **condition** select **Data comparison** and in the parameter:

> Parameter: **Data to compare**: \[site:current-page:language\], **Data value**: English

---

## **2- The Hard one:**

```
/*
* Implements hook_rules_condition_info().
*/

function MODULE_NAME_rules_condition_info() {
 $conditions = array();

 $conditions['MODULE_NAME_check_current_user_language'] = array(
   'label' => t('Current user language'),
   'group' => t('YOUR GROUP NAME'),
   'parameter' => array(
     'language' => array(
       'type' => 'token',
       'label' => t('Language'),
       'description' => t('Select language that will be compared against the
user current language.'),
       'options list' => 'entity_metadata_language_list',
       'default value' => LANGUAGE_NONE,
     ),
   ),
 );

 return $conditions;
}

```

Then:

```
/*
*  Compare site current language with required language
*/

function MODULE_NAME_check_current_user_language($required_language) {
 global $language;

 return $language->language == $required_language;
}

```

Don't forget to clear the cache.
> 2 votes

# Answer
You can implement a new condition in a module, using the following implementation of `hook_rules_condition_info()`.

```
function mymodulename_rules_condition_info() {
  return array(
    'check_current_user_language' => array(
      'label' => t('Language for current user'),
      'parameter' => array(
        'string' => array(
          'type' => 'text',
          'label' => t('Language to check'),
        ),
      ),
    ),
  );
}

function mymodule_check_current_user_language($string) {
  global $user, $language_content;

  return ($user->language == $string);
}

```
> 1 votes

# Answer
One of the rules maintainers, fago, has a patch under development (started recently and marked as "needs work") that adds a variety of internationalization features to rules, including functions for checking the language of users as well as setting languages for rules themselves.
> 1 votes

# Answer
You can find this function in the I18n bundle for translating. In rules use date comparison
> 0 votes

# Answer
You can try to accomplish this adding additional field to profile and using 2 different rules.

1st will set the value of the field, using this functions

2nd will compare the profile field value using account:profile\_lang data selector
> -1 votes

---
Tags: rules
---


title: settings.php.lock error

text:
# Question
Title: settings.php.lock error
I've been working on a Drupal 8 site for a month or so now and development has been progressing nicely until a week ago. It looks like the issues started at just about the same time that the website host applied a server update. The first part of the issue is that I now have a WSOD with the error - The website encountered an unexpected error. Please try again later. I thought that issue might be related to the hosting environment as it's still running php5.6 (now no longer supported by version of Drupal from what I understand).

I thought that if I copied the site files and database to a different environment running php7.2 or 7.3 I might be able to resolve the issue. However since I don't have root access to the dev server I decided to export the database from the dev server as a sql.zip file and then import it into my new database on the new 'test' server and copy the site files across. However while performing the Drupal install I added a prefix for the 'test' database tables. I realised what I had done and went to the settings.php file to change it. When I tried to push the file up via FTP I got a 'failed to write file' error. Instead of trying to sort out the permission via FTP I logged into the Cpanel. I set the permissions of the sites folder to 755 and checked the box to apply the permissions to all sub-folders and files. I checked and all files permissions were updated. I open the settings.php file using the edit option in Cpanel and edited the line with the database prefix (to target the imported tables from the dev site -they have no prefix) to

'prefix' =\> '',

and clicked 'save changes' and I got the error

"The system failed to create the file “/home/user\_account\_name/public\_html/sites/default/settings.php.lock” (as EUID: 1045, EGID: 1040 1040) because of the following error: Permission denied"

If I change the prefix value and edit anything else like the username I can then save the file without an issue.

Can someone please explain what is happening here. I believe that there is some flag set in the database (or another file) that is preventing me from updating and saving the settings.php and it may also be the reason for my WSOD issue.

Drupal version is 8.6.10 on dev server and 8.7.3 on the test server.

# Answer
> 2 votes
Edit the **permissions** of the folder it self. The folder "**default**" set to 0555, set them to 0755 for editing. Don't forget to restore the default values afterwards!

---
Tags: 8
---


# Question
Title: New installation showing HTML source instead of rendered HTML
I just installed drupal 8.8.1 using Composer.

When starting installation it displays HTML source in browser window instead of rendering the HTML of the installation script. The code below is what is displayed:

```
<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8" />
<meta name="Generator" content="Drupal 8 (https://www.drupal.org)" />
<meta name="MobileOptimized" content="width" />
<meta name="HandheldFriendly" content="true" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="robots" content="noindex, nofollow" />
<link rel="shortcut icon" href="/core/misc/favicon.ico" type="image/vnd.microsoft.icon" />

    <title>Choose language | Drupal</title>
    <link rel="stylesheet" media="all" href="/core/assets/vendor/normalize-css/normalize.css?0" />
<link rel="stylesheet" media="all" href="/core/misc/normalize-fixes.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/stable/css/system/components/ajax-progress.module.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/stable/css/system/components/align.module.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/stable/css/system/components/autocomplete-loading.module.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/stable/css/system/components/fieldgroup.module.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/stable/css/system/components/container-inline.module.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/stable/css/system/components/clearfix.module.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/stable/css/system/components/details.module.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/stable/css/system/components/hidden.module.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/stable/css/system/components/item-list.module.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/stable/css/system/components/js.module.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/stable/css/system/components/nowrap.module.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/stable/css/system/components/position-container.module.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/stable/css/system/components/progress.module.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/stable/css/system/components/reset-appearance.module.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/stable/css/system/components/resize.module.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/stable/css/system/components/sticky-header.module.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/stable/css/system/components/tabledrag.module.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/stable/css/system/components/tablesort.module.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/stable/css/system/components/tree-child.module.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/stable/css/system/system.admin.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/stable/css/system/system.maintenance.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/seven/css/base/elements.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/seven/css/base/typography.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/seven/css/base/print.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/seven/css/layout/layout.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/classy/css/components/action-links.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/classy/css/components/breadcrumb.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/classy/css/components/button.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/classy/css/components/collapse-processed.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/classy/css/components/container-inline.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/classy/css/components/exposed-filters.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/classy/css/components/field.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/classy/css/components/form.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/classy/css/components/icons.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/classy/css/components/inline-form.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/classy/css/components/item-list.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/classy/css/components/link.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/classy/css/components/links.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/classy/css/components/menu.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/classy/css/components/more-link.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/classy/css/components/pager.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/classy/css/components/tabledrag.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/classy/css/components/tableselect.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/classy/css/components/tablesort.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/classy/css/components/tabs.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/classy/css/components/textarea.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/classy/css/components/ui-dialog.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/classy/css/components/messages.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/seven/css/components/admin-list.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/seven/css/components/content-header.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/seven/css/components/container-inline.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/seven/css/components/container-inline.module.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/seven/css/components/breadcrumb.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/seven/css/components/buttons.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/seven/css/components/details.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/seven/css/components/messages.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/seven/css/components/dropbutton.component.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/seven/css/components/entity-meta.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/seven/css/components/field-ui.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/seven/css/components/form.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/seven/css/components/help.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/seven/css/components/menus-and-lists.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/seven/css/components/modules-page.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/seven/css/components/node.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/seven/css/components/page-title.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/seven/css/components/pager.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/seven/css/components/panel.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/seven/css/components/skip-link.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/seven/css/components/tables.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/seven/css/components/search-admin-settings.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/seven/css/components/tablesort-indicator.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/seven/css/components/system-status-report-general-info.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/seven/css/components/system-status-report.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/seven/css/components/tabs.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/seven/css/components/system-status-report-counters.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/seven/css/components/system-status-counter.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/seven/css/components/views-ui.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/seven/css/theme/colors.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/seven/css/theme/maintenance-page.css?0" />
<link rel="stylesheet" media="all" href="/core/themes/seven/css/theme/install-page.css?0" />

<!--[if lte IE 8]>
<script src="/core/assets/vendor/html5shiv/html5shiv.min.js?v=3.7.3"></script>
<![endif]-->

  </head>
  <body class="install-page path-frontpage db-offline">
        <a href="#main-content" class="visually-hidden focusable skip-link">
      Skip to main content
    </a>

      <div class="dialog-off-canvas-main-canvas" data-off-canvas-main-canvas>
    <div class="layout-container">

  <header role="banner">
          <h1 class="page-title">
        Drupal
                  <span class="site-version">8.8.1</span>
              </h1>
      </header>

      <aside class="layout-sidebar-first" role="complementary">
      <h2 class="visually-hidden">Installation tasks</h2>
<ol class="task-list">
  <li class="is-active">
    Choose language
    <span class="visually-hidden"> (active)</span>  </li>
  <li>
    Choose profile
      </li>
  <li>
    Verify requirements
      </li>
  <li>
    Set up database
      </li>
  <li>
    Install site
      </li>
  <li>
    Configure site
      </li>
</ol>

    </aside>
  <main role="main">
          <h2 class="heading-a">Choose language</h2>

    <form class="install-select-language-form" data-drupal-selector="install-select-language-form" action="/core/install.php" method="post" id="install-select-language-form" accept-charset="UTF-8">
  <div class="js-form-item form-item js-form-type-select form-type-select js-form-item-langcode form-item-langcode form-no-label">
      <label for="edit-langcode" class="visually-hidden">Choose language</label>
        <select data-drupal-selector="edit-langcode" id="edit-langcode" name="langcode" class="form-select"><option value="af">Afrikaans</option><option value="ast">Asturianu</option><option value="az">AzÉ™rbaycanca</option><option value="id">Bahasa Indonesia</option><option value="jv">Basa Java</option><option value="bs">Bosanski</option><option value="ca">CatalÃ </option><option value="cy">Cymraeg</option><option value="da">Dansk</option><option value="de">Deutsch</option><option value="et">Eesti</option><option value="en" selected="selected">English</option><option value="es">EspaÃ±ol</option><option value="eo">Esperanto</option><option value="eu">Euskera</option><option value="fil">Filipino</option><option value="fr">FranÃ§ais</option><option value="fy">Frysk</option><option value="fo">FÃ¸royskt</option><option value="ga">Gaeilge</option><option value="gl">Galego</option><option value="gd">GÃ idhlig</option><option value="hr">Hrvatski</option><option value="it">Italiano</option><option value="sw">Kiswahili</option><option value="ht">KreyÃ²l ayisyen</option><option value="ku">KurdÃ®</option><option value="lv">LatvieÅ¡u</option><option value="lt">LietuviÅ³</option><option value="xx-lolspeak">Lolspeak</option><option value="hu">Magyar</option><option value="mg">Malagasy</option><option value="nl">Nederlands</option><option value="nb">Norsk, bokmÃ¥l</option><option value="nn">Norsk, nynorsk</option><option value="oc">Occitan</option><option value="pl">Polski</option><option value="pt-br">PortuguÃªs, Brasil</option><option value="pt-pt">PortuguÃªs, Portugal</option><option value="ro">RomÃ¢nÄƒ</option><option value="gsw-berne">SchwyzerdÃ¼tsch</option><option value="sco">Scots</option><option value="sq">Shqip</option><option value="en-x-simple">Simple English</option><option value="sk">SlovenÄina</option><option value="sl">SlovenÅ¡Äina</option><option value="fi">Suomi</option><option value="sv">Svenska</option><option value="se">SÃ¡mi</option><option value="vi">Tiáº¿ng Viá»‡t</option><option value="tr">TÃ¼rkÃ§e</option><option value="is">Ãslenska</option><option value="cs">ÄŒeÅ¡tina</option><option value="el">Î•Î»Î»Î·Î½Î¹ÎºÎ¬</option><option value="be">Ð‘ÐµÐ»Ð°Ñ€ÑƒÑÐºÐ°Ñ</option><option value="bg">Ð‘ÑŠÐ»Ð³Ð°Ñ€ÑÐºÐ¸</option><option value="ky">ÐšÑ‹Ñ€Ð³Ñ‹Ð·Ñ‡Ð°</option><option value="mk">ÐœÐ°ÐºÐµÐ´Ð¾Ð½ÑÐºÐ¸</option><option value="ru">Ð ÑƒÑÑÐºÐ¸Ð¹</option><option value="sr">Ð¡Ñ€Ð¿ÑÐºÐ¸</option><option value="tyv">Ð¢Ñ‹Ð²Ð° Ð´Ñ‹Ð»</option><option value="uk">Ð£ÐºÑ€Ð°Ñ—Ð½ÑÑŒÐºÐ°</option><option value="mn">Ð¼Ð¾Ð½Ð³Ð¾Ð»</option><option value="kk">ÒšÐ°Ð·Ð°Ò›</option><option value="hy">Õ€Õ¡ÕµÕ¥Ö€Õ¥Õ¶</option><option value="he">×¢×‘×¨×™×ª</option><option value="ug">Ø¦Û‡ÙŠØºÛ‡Ø±Ú†Û•</option><option value="ur">Ø§Ø±Ø¯Ùˆ</option><option value="ar">Ø§Ù„Ø¹Ø±Ø¨ÙŠØ©</option><option value="ms">Ø¨Ù‡Ø§Ø³ Ù…Ù„Ø§ÙŠÙˆ</option><option value="fa">ÙØ§Ø±Ø³ÛŒ</option><option value="ne">à¤¨à¥‡à¤ªà¤¾à¤²à¥€</option><option value="mr">à¤®à¤°à¤¾à¤ à¥€</option><option value="hi">à¤¹à¤¿à¤¨à¥à¤¦à¥€</option><option value="bn">à¦¬à¦¾à¦‚à¦²à¦¾</option><option value="pa">à¨ªà©°à¨œà¨¾à¨¬à©€</option><option value="gu">àª—à«àªœàª°àª¾àª¤à«€</option><option value="ta">à®¤à®®à®¿à®´à¯</option><option value="ta-lk">à®¤à®®à®¿à®´à¯, à®‡à®²à®™à¯à®•à¯ˆ</option><option value="te">à°¤à±†à°²à±à°—à±</option><option value="kn">à²•à²¨à³à²¨à²¡</option><option value="ml">à´®à´²à´¯à´¾à´³à´‚</option><option value="si">à·ƒà·’à¶‚à·„à¶½</option><option value="th">à¸ à¸²à¸©à¸²à¹„à¸—à¸¢</option><option value="lo">àºžàº²àºªàº²àº¥àº²àº§</option><option value="bo">à½–à½¼à½‘à¼‹à½¦à¾à½‘à¼‹</option><option value="dz">à½¢à¾«à½¼à½„à¼‹à½</option><option value="my">á€—á€™á€¬á€…á€€á€¬á€¸</option><option value="ka">áƒ¥áƒáƒ áƒ—áƒ£áƒšáƒ˜ áƒ”áƒœáƒ</option><option value="am">áŠ áˆ›áˆáŠ›</option><option value="km">áž—áž¶ážŸáž¶ážáŸ’áž˜áŸ‚ážš</option><option value="ja">æ—¥æœ¬èªž</option><option value="zh-hans">ç®€ä½“ä¸æ–‡</option><option value="zh-hant">ç¹é«”ä¸æ–‡</option><option value="ko">í•œêµì–´</option></select>
        </div>
<div data-drupal-states="{"invisible":{"select[name=\u0022langcode\u0022]":{"value":"en"}}}" id="edit-help" class="js-form-item form-item js-form-type-item form-type-item js-form-item-help form-item-help form-no-label">
        <p>Translations will be downloaded from the <a href="http://localize.drupal.org">Drupal Translation website</a>. If you do not want this, select <a href="https://actionfund.nfb.org/core/install.php?langcode=en">English</a>.</p>
        </div>
<input autocomplete="off" data-drupal-selector="form-i-o33hif7d1m-uxztfnjrb8op-dmeqk-qza61jsd-mm" type="hidden" name="form_build_id" value="form-i_o33hif7D1m_uxztfNjRB8op-DMeqK-qZA61Jsd-mM" />
<input data-drupal-selector="edit-install-select-language-form" type="hidden" name="form_id" value="install_select_language_form" />
<div data-drupal-selector="edit-actions" class="form-actions js-form-wrapper form-wrapper" id="edit-actions"><input data-drupal-selector="edit-submit" type="submit" id="edit-submit" name="op" value="Save and continue" class="button button--primary js-form-submit form-submit" />
</div>

</form>

  </main>

</div>
  </div>

    <script type="application/json" data-drupal-selector="drupal-settings-json">{"path":{"baseUrl":"\/core\/install.php\/","scriptPath":null,"pathPrefix":"","currentPath":"","currentPathIsAdmin":false,"isFront":false,"currentLanguage":"en","currentQuery":{"rewrite":"ok"}},"pluralDelimiter":"\u0003","suppressDeprecationErrors":true,"ajaxTrustedUrl":{"form_action_p_pvdeGsVG5zNF_XLGPTvYSKCf43t8qZYSwcfZl2uzM":true}}</script>
<script src="/core/assets/vendor/jquery/jquery.min.js?v=3.4.1"></script>
<script src="/core/assets/vendor/jquery-once/jquery.once.min.js?v=2.2.0"></script>
<script src="/core/misc/drupalSettingsLoader.js?v=8.8.1"></script>
<script src="/core/misc/drupal.js?v=8.8.1"></script>
<script src="/core/misc/drupal.init.js?v=8.8.1"></script>
<script src="/core/misc/states.js?v=8.8.1"></script>
<script src="/core/themes/seven/js/mobile.install.js?v=8.8.1"></script>

  </body>
</html>

```

I *rightly* assumed that the server isn't sending Content-Type header. I open ../core/install.php and add:

```
header("Content-Type: text/html");

```

to install.php and all starts working as expected.

Is this a bug in this version of Drupal setup or am I missing something in this server's setup? Not a huge deal but I'd like to fix things properly.

Here is what the server is sending out (which includes pertinent info about environment)

```
Cache-Control: must-revalidate, no-cache, private
Connection: close
Content-Type: text/html;charset=UTF-8
Date: Fri, 27 Dec 2019 16:17:01 GMT
ETag: "1577463421"
Expires: Sun, 19 Nov 1978 05:00:00 GMT
Last-Modified: Fri, 27 Dec 2019 16:17:01 +0000
Server: Apache/2.4.6 (Red Hat Enterprise Linux) OpenSSL/1.0.2k-fips PHP/7.1.27
X-Content-Type-Options: nosniff
X-Powered-By: PHP/7.1.27

```

# Answer
> 0 votes
Adding the following to .htaccess in ../web solved issue:

```
<IfModule mod_headers.c>
  <Files ~ "\.(php)$">
    Header set Content-Type "text/html; charset=utf-8"
  </Files>
</IfModule>

```

As long as you explicitly set Content-Type headers when your php is outputting files (such as .pdf, .csv etc) which you should be doing anyway, this won't break your code.

# Answer
> 2 votes
It looks like you are using Apache webserver on Red Hat. The advice on fixing clean urls on Drupal 8 will probably solve this problem.

First, check to confirm there is a `.htaccess` file in your document root.

After that, there are 2 solutions to get those rules to be followed.

One solution is to enable Apache to follow the `.htaccess` rules that Drupal provides. Quoting from that article:

> You will need to have the Allow Override directive set in your Apache configuration file (this will allow local .htaccess overrides on your site):
>
> ```
> AllowOverride All
> AccessFileName .htaccess
>
> ```

The other solution is simply to copy the configuration from the .htaccess into your webserver's configuration.

Be sure to restart the apache server after changing the configuration. There are many more bits of advice in this document that are worth reading.

---
Tags: installation
---


title: Show AJAX throbber during AJAX call

text:
# Question
Title: Show AJAX throbber during AJAX call
I created custom module to make simple Ajax call. This module looks like this:

```
<?php

/**
 * Implements hook_menu().
 */
function module_ajax_contact_menu() {
  $items['node/get/ajax/%'] = array(
    'page callback' => 'module_ajax_contact_ajax_get_ajax', // Render HTML.
    'page arguments' => array(3),
    'type' => MENU_CALLBACK,
    'access arguments' => array('access content'),
    'delivery callback' => 'module_ajax_contact_ajax_callback',
  );
  return $items;
}

function module_ajax_contact_ajax_get_ajax($nid) {
  $node = node_load($nid);
  return node_view($node, 'default');
}

function module_ajax_contact_ajax_callback($page_callback_result) {
  // Only render content
  $content = drupal_render($page_callback_result);

  // Add CSS and JS files, add some markup
  $html = '<html><head><title></title>' . drupal_get_css() . drupal_get_js() . '</head><body class="jquery-ajax-load">' . $content . '<script type="text/javascript" src="/sites/all/themes/pub/js/map.js"></body></html>';
  print $html;

  // Perform end-of-request tasks.
  drupal_page_footer();
}

```

After that I make call in JS like this:

```
function module_ajax_contact_ajax_load(n) {
    $("#popup-contact").load("/node/get/ajax/" + n, function () {
        $("#popup-contact").foundation('open');
    });
}

$('.contact-link').click(function (e) {
       e.preventDefault();
        module_ajax_contact_ajax_load(10);
    });

```

So, after content is loaded from node id 10 (in this case) Reveal from Foundation opens.

I want to add Drupal's default throbber during the loading of this node.

Any idea how I could do it?

# Answer
In Drupal 7, The throbber has a class of `.ajax-progress-throbber`.

Before the Ajax call, add an element with that class to wherever you want it in the DOM, and simply remove it again when the Ajax request completes. Drupal doesn't have any helper methods for this, just use jQuery.
> 6 votes

# Answer
In Drupal 8+, there are some methods provided in the ajax library of core

> docroot/core/misc/ajax.es6.js

to allow you to add the loading message/icon to the your page.

> Drupal.theme.ajaxProgressThrobber
>
> Drupal.theme.ajaxProgressIndicatorFullscreen
>
> Drupal.theme.ajaxProgressMessage

Simply call them like

```
$('body').after(Drupal.theme.ajaxProgressIndicatorFullscreen())

```

before you start an ajax request. and remove it by

```
$("body").remove(".ajax-progress-fullscreen")

```

once the request is finished.

Also make sure you add core/drupal/ajax to your library dependencies.
> 6 votes

---
Tags: 7, ajax
---


# Question
Title: How do I modify a template file to show elements side-by-side?
I am working on views with embedded filters and my resultant view fields have the following code.

```
{ % set index = 0 %}
<div class='row'>
  <div class="panel panel-default">
    <div class="panel-body">
      {% for key, field in fields %}

        {% if index == 0 or index == 5 %}
          <div class='col-md-6'>
        {% endif %}

        {% if field.wrapper_element %}
          <{{ field.wrapper_element }}{{ field.wrapper_attributes }}>
        {% endif %}

        {% if field.label %}
          {% if field.label_element %}
            <{{ field.label_element }}{{ field.label_attributes }}>{{ field.label }}{{ field.label_suffix }}</{{ field.label_element }}>
          {% else %}
            {{ field.label }}{{ field.label_suffix }}
          {% endif %}
        {% endif %}

        <a href="#" data-toggle="tooltip" data-placement="right" title="{{ tooltips[key] }}">

          {% if field.element_type %}
            <{{ field.element_type }}{{ field.element_attributes }}>{{ field.content }}</{{ field.element_type }}>
          {% else %}
            {{ field.content }}
          {% endif %}
         </a>
        <br/>
        {% if index == 4 %}
          <br/>
          <div class="row">
            <div class="col-md-4">
              <div class="space"></div>
              <button class="button js-form-submit form-submit btn-info btn" type="button" value="Btn1" name="">Btn1</button>
            </div>
            <div class="col-md-4">
              <div class="space"></div>
              <button class="button js-form-submit form-submit btn-info btn" type="button" OnClick = "window.print();" value="PRINT" name="">PRINT</button>
            </div>
          </div>
        {% endif %}

        {% if field.wrapper_element %}
          </{{ field.wrapper_element }}>
        {% endif %}

        {% if index + 1 == fields | length %}
          <a href="">Click to go to next page</a>
        {% endif %}

        {% if index == 4 or index + 1 == fields | length  %}
          </div>
        {% endif %}

        {% set index = index + 1 %}

      {% endfor %}
    </div>
  </div>
</div>

```

In this setup the label is showing above the text. Is there a way to show them on the same line?

# Answer
> 2 votes
It’s likely because `field.label_element` contains a `<p>` tag.

You should instead use a `<span>` tag.

```
<span {{ field.label_attributes }}>{{ field.label }}{{ field.label_suffix }}</span>
<a href="#" data-toggle="tooltip" data-placement="right" title="{{ tooltips[key] }}">
  <span {{ field.element_attributes }}>{{ field.content }}</span>
</a>

```

You can also add a `<br>` tag after the closing `<a>` tag to show all the label/content sets on separate lines.

If this doesn't work, you can add a `<div>` tag around the two elements and add some simple Flexbox styling in the CSS to get the desired result.

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


# Question
Title: How to add custom page.html.twig for views page?
I have a view page with url and machine id search

I need to add a custom page.html.twig for that specific view page so that it does not affect the rest pages.

How can I implement it?

I tried adding page--search.html.twig but it did not work.

# Answer
> 2 votes
Instead of sticking on page URL, I've done this:

```
/**
 * Implements hook_theme_suggestions_page_alter().
 */
function mytheme_theme_suggestions_page_alter(array &$suggestions, array $variables) {

  $parameters = \Drupal::routeMatch()->getParameters()->all();
  if (isset($parameters['view_id']) && isset($parameters['display_id'])) {
    ['view_id' => $view_id, 'display_id' => $display_id] = $parameters;
    $suggestions[] = 'page__view__' . $view_id;
    $suggestions[] = 'page__view__' . $view_id . '__' . $display_id;
  }
}

```

Then you can simply use page--view--search.html.twig

# Answer
> 1 votes
page--\[url of your view\].html.twig

Put the file in `drupal/themes/YourTheme/templates` folder

Remember to flush/clear the cache to see the changes.

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


# Question
Title: How to get parent node from a attachment in drupal8 search api results
I have apachesolr index search with Search API attachments. In the results I get a link to the file but I would like to get a link to the parent node. I tried in the view but there is no such field with relationship to file usage. I wrote the following in a module to override the field fid in the view but it returns an error

```
function hook_preprocess_views_view_field(&$variables) {
$view = $variables['view'];
$field = $variables['field'];
    if ($view->storage->id() == 'saa' &&
    $view->current_display == 'page_1' &&
    $field->field == 'fid') {
        $fid =  $variables['output'];
        $file = \Drupal\file\Entity\File::load($fid);
        $file_usage = \Drupal::service('file.usage')->listUsage($file);
        $variables['results'] = $file_usage;
    }
}

```

It returns

> The website encountered an unexpected error. Please try again later. TypeError: Argument 1 passed to Drupal\file\FileUsage\DatabaseFileUsageBackend::listUsage() must implement interface Drupal\file\FileInterface, null given, called in /home/rebecca/public\_html/new5/modules/pdf\_app/pdf\_app.module on line 262 in Drupal\file\FileUsage\DatabaseFileUsageBackend-\>listUsage() (line 123 of core/modules/file/src/FileUsage/DatabaseFileUsageBackend.php).

# Answer
Thanks to the help I got I manage to get it working

```
function hook_preprocess_views_view_field(&$variables) {
 $view = $variables['view'];
$field = $variables['field'];
if ($view->storage->id() == 'saa' &&
$view->current_display == 'page_1' &&
$field->field == 'fid') {
$fid = $variables['output'];
if (!is_string($fid)){
$fid = $variables['output']->__toString();
}

$file = \Drupal\file\Entity\File::load($fid);
if ($file && $file instanceof Drupal\file\FileInterface) {
  $file_usage = \Drupal::service('file.usage')->listUsage($file);
  //var_dump($file_usage);
 if (array_key_exists("node",$file_usage['file'])){
  $essai = $file_usage['file']['node'];
}
 elseif (array_key_exists("media",$file_usage['file'])){
$essai = $file_usage['file']['media'];
}
  $news = (array_keys($essai));
  $new2 = (array_values($news));
  $nef = array_values($new2)[0];
  $event = \Drupal::entityTypeManager()->getStorage('node')->load($nef);
if (!$event)
 return false;

// add ->toString() or other if needed
$abs_link = $event->toLink(NULL, 'canonical', ['absolute' => true]);
  $variables['output'] = $abs_link;
  }
 }
}

```
> 0 votes

# Answer
`$file` should be instance of `Drupal\file\FileInterface` but in this case `$file` is null so you should check first on `$file` something

```
function hook_preprocess_views_view_field(&$variables) {
  $view = $variables['view'];
  $field = $variables['field'];
  if ($view->storage->id() == 'saa' &&
    $view->current_display == 'page_1' &&
    $field->field == 'fid') {
    $fid = $variables['output']->__toString();
    $file = \Drupal\file\Entity\File::load($fid);
    if ($file && $file instanceof Drupal\file\FileInterface) {
      $file_usage = \Drupal::service('file.usage')->listUsage($file);
      $variables['output'] = $file_usage;
    }
  }
}

```
> 0 votes

---
Tags: 8, search
---


title: Ajax loader when facet is selected

text:
# Question
Title: Ajax loader when facet is selected
When we add a facet block to the page, a filter is selected and the page starts to load the results. However there is no loading icon or indicator the change is being applied.

When we check the page, there is no JS error and nothing visible.

**How do we get the loading icon or throbber to show when a facet is selected?**

# Answer
You can try the following.

Add in your JS file:

```
$(document).ajaxStart(function(){
  $('#ajax_loading').show();
});

$(document).ajaxStop(function() {
  $('#ajax_loading').hide();
});

```

Add the HTML in your page:

```
<div id="ajax_loading" style="display:none">

```

Add in your CSS file:

```
#ajax_loading {
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  background: rgba(0,0,0,0.5);
  z-index: 9999;
}

```
> 1 votes

---
Tags: 8, theming, blocks, search
---


# Question
Title: Get url of referenced entity in twig based on target_id
I have a content type with a field « referenced entity » called `field_suggestion_articles`.

User can choose related content and a view displays this list of related content at the bottom of the content. The views uses "content" (display mode, a template like teaser) and not fields.

I use a loop to display this list in `node--article--related-content.html.twig`:

```
{% for key,value in node.field_suggestion_articles.value %}
    {# display the title #}
    {{ content.field_suggestion_articles[key] }}

    {# display a text field #}
    {{node.field_suggestion_articles[key].entity.field_resume_suggestion_article.value|raw}}

{% endfor %}

```

But I don’t know how to get the node urls of these related content.

When I dump `node.field_suggestion_articles.value`, I get the `target_id` of the node so I guess I should use it to retrieve the url. But I’ve tried a lot of solutions found on Drupal forums and here on stackExchange but without success.

Could you point me in the right direction ?

# Answer
What they've done on this post should do the trick How do I get the node URL in a Twig template?

So in your case this should work:

```
{{ path('entity.node.canonical', {'node': node.field_suggestion_articles[key].entity.id}) }}

```
> 2 votes

---
Tags: theming, entities
---


# Question
Title: Computed twig Automatically update the computed value using Ajax
Whe I use computed twig with "Automatically update the computed value using Ajax" checket, it create "update" button next to my computed twig field. How I make the field update really automaticlally without this update button. Thanks.

# Answer
> 0 votes
I figgured out. It was because the theme template rewrite the form input element and this broke automatic comuting on forms.

---
Tags: webforms
---


# Question
Title: How can we define twig template based on checkout flow in Commerce 2.x?
I am using Drupal Commerce 2.x. I try to build different twig templates based on the checkout flow.

So, I use `hook_theme_suggestions_HOOK_alter` to register other theme suggestions. However, I can't find any useful variable which we can use in the function.

The following code is what I tried now.

Please give me some advice.

Thanks a lot.

```
/**
 * Implements hook_theme_suggestions_HOOK_alter().
 */
function bootstrap_sass_theme_suggestions_commerce_checkout_form_alter(array &$suggestions, array $variables) {
    if( $variables['form']['#id']=="commerce-checkout-flow-multistep-default" ){
    //add theme suggestions.
    $suggestions[]='my_new_checkout_template';
    }
}

```

# Answer
I found out the answer. Share here if someone needed in the future.

I think if we want to define the twig template based on the checkout flow, we shouldn't create ones using the same plugin. (default is `Multistep - Default`)

Instead, we need to create a new plugin for the checkout flow. I followed the instruction here. https://docs.drupalcommerce.org/commerce2/developer-guide/checkout/create-custom-checkout-flow

After I finished the custom checkout flow plugin, we can create another flow based on the custom one.

Therefore, we can use `Implements hook_theme_suggestions_HOOK_alter()` to implement what we need.

```

/**
 * Implements hook_theme_suggestions_HOOK_alter().
 */
function bootstrap_sass_theme_suggestions_commerce_checkout_form_alter(array &$suggestions, array $variables) {
  $suggestions[] = $variables["form"]["#form_id"];
}

```
> 0 votes

---
Tags: 8, theming, commerce
---


# Question
Title: How to redirect user for specific pages not found
I have developed a module that creates a certain set of pages. What I would like to do is create a specific redirect for those pages if they are not found while keeping the generic Drupal 7 wide redirect for all other pages. Is this possible and how would I go about doing it?

Thanks.

# Answer
I suggest to try the Redirect or rules module.

Update:

You can create URL redirects manually for each of these pages, but the ***Redirect*** module makes this much easier.

* Go to "Configuration \> Search and metadata \> URL redirects \> Fix 404 pages" (`admin/config/search/redirect/404`).

So, you can see that there are a few paths that I have tried to access that do not exist. Next, to each one there is an "Add redirect" operation.

* Click "***Add redirect***"

When Clicking on "Add redirect" link we can specify where we would like users to be redirected when they reach the page that does not exist.

See more how to Fix 404 Pages Using redirect Module.
> -2 votes

# Answer
You can try by going on "admin/config/system/site-information"page. There you can give links where to redirect on the "Default 403 (access denied) page" and "Default 404 (not found) page". For example if you type "node", it will take you to front page.
> 1 votes

# Answer
Create a Page in Page Manager where you use an HTTP response code and disable all form elements on that page.

Give your path a (random) name.

Set the Response code of the Page to: 404 Page not found.

Create a rule with Rules that:

1. fires if a hidden field on your form is filled out OR if the email address has a certain TLD e.g. ".site"
2. removes all roles and adds a role of e.g. "spammer"
3. blocks them
4. and redirects them to that Page path or a website that collects spammers (I'm not sure which one)

That's how I'd do it.
> 0 votes

---
Tags: 7, redirection
---