# Question
Title: How do I download a dynamically-created file in a form submission?
I've got a form that builds an array of data. On submission, it updates a table displayed in the browser, using AJAX; that works fine.

I want a second submit button that downloads the same data as a CSV file. I've tried a number of variations, but I can't seem to both send the file response and satisfy the AJAX requirement for a returned array.

The button:

```
$form['download'] = [
  '#type' => 'submit',
  '#value' => $this->t('Download data'),
  '#weight' => '40',
  '#ajax' => [
    'callback' => '::downloadCallback',
    'event' => 'click',
  ],
];

```

...and the response section of the callback:

```
$file_content = $serializer->serialize($data, 'csv');
$response = new Response($file_content);
$disposition = $response->headers->makeDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, 'data.csv');
$response->headers->set('Content-Disposition', $disposition);
$form_state->setResponse($response);

```

I've also tried using this instead of setResponse:

```
$response->send();

```

These all result in an error:

> TypeError: Argument 1 passed to Drupal\Core\Render\MainContent\AjaxRenderer::renderResponse() must be of the type array, null given, called in /mnt/www/html/mowebd8dev/docroot/core/lib/Drupal/Core/Form/FormAjaxResponseBuilder.php on line 89 in /mnt/www/html/mowebd8dev/docroot/core/lib/Drupal/Core/Render/MainContent/AjaxRenderer.php on line 45 #0 /mnt/www/html/mowebd8dev/docroot/core/lib/Drupal/Core/Form/FormAjaxResponseBuilder.php(89): Drupal\Core\Render\MainContent\AjaxRenderer-\>renderResponse(NULL, Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\Routing\CurrentRouteMatch))

I've tried also returning a simple render array with some dummy markup, and that prevents the error, but still doesn't result in a file download. Is there a way to accomplish this? Or should I just not be using AJAX for this purpose?

# Answer
> 3 votes
I was off-track in even trying to do this with AJAX, as Clive mentioned in his comment. Instead, I just made it a normal submit button, and then overrode the form action. The result is that the data is downloaded as a file, the form doesn't reload, and the data output section doesn't update, which is the desired behavior in this case.

The button, along with a new format element:

```
$form['download']['format'] = [
  '#type' => 'select',
  '#options' => $this->getValidFormats(),
  '#title' => $this->t('Select format'),
  '#weight' => '0',
];
$form['download']['download'] = [
  '#type' => 'submit',
  '#value' => $this->t('Download'),
  '#weight' => '10',
];

```

The submit function:

```
public function submitForm(array &$form, FormStateInterface $form_state) {
  switch ($form_state->getValue('op')->__toString()) {
    case 'Download':
      $this->download($form, $form_state);
      break;
  }
}

```

And the relevant part of the download function:

```
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;

$response = new Response($file_content);
$disposition = $response->headers->makeDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, 'data.' . $format);
$response->headers->set('Content-type', $content_types[$format]);
$response->headers->set('Content-Disposition', $disposition);
$response->headers->set('Content-Transfer-Encoding', 'binary');
$response->headers->set('Content-length', strlen($file_content));
$form_state->setResponse($response);

```

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


# Question
Title: How do I programmatically get the link for a webform submission?
I have managed to create a table of webform submissions of a particular type, thanks to the answer from a question posted here. What I would like to do now is add a link for each webform submission, and I can't figure out how.

I tried looking through the API, and found a toUrl function, but I don't understand how to use it to get the link for each webform submission. Once I have the link, I would like to combine it with the rest of its info in submission\_data\[\] for display in the table.

Thanks in advance!

```
$query = \Drupal::entityQuery('webform_submission')
  ->condition('webform_id', 'sign_up');
$result = $query->execute(); // Gives me IDs associated with the "sign_up" webform.

$storage = \Drupal::entityTypeManager()->getStorage('webform_submission');
$submissions = $storage->loadMultiple($result);
$submission_data = array();
foreach ($submissions as $submission) {
  $submission_data[] = $submission->getData();
}
// $submission_data now contains all the submissions from "sign_up" webform.

```

How do I add a link to the webform submission? When I look through submission\_data\[\] it doesn't contain the ID of the webform submission

# Answer
Webform submissions are content entities, you can use any method defined in \Drupal\Core\Entity\EntityInterface including…
> 6 votes

# Answer
To get this working, I needed to use what jrockowitz suggested in his answer and also add toString() to get it to display properly in the table.

Without toString(), it gave me an error (*Drupal\Core\Link could not be converted to string*), because toUrl() returns an object rather than the url itself)

```
$url = $submission->toUrl()->toString();

```
> 0 votes

---
Tags: 8, webforms
---


# Question
Title: How can I trigger custom code when some other module is being installed/uninstalled?
I am using a third-party module. Whenever it is installed or un-installed, I want to programmatically create/delete some menus.

How can I detect that a module is installed or un-installed?

# Answer
You can use `hook_modules_installed()` to react to modules being installed, e.g.

```
function hook_modules_installed($modules) {
  if (in_array('lousy_module', $modules)) {
    variable_set('lousy_module_conflicting_variable', FALSE);
  }
}

```

and `hook_modules_uninstalled()` to react to the opposite, e.g.

```
function hook_modules_uninstalled($modules) {
  foreach ($modules as $module) {
    db_delete('mymodule_table')
      ->condition('module', $module)
      ->execute();
  }
  mymodule_cache_rebuild();
}

```
> 2 votes

---
Tags: 7, installation
---


title: Datelist element in webform not working

text:
# Question
Title: Datelist element in webform not working
I was just going through webform configurations and I changed the date list element format from default to raw. After doing this Im not able to add any element of type dateform to my webform and also not able to open the element configurations also. The error i get when clicked on element tab (refer the attached image) is "The website encountered an unexpected error. Please try again later."

# Answer
> 1 votes
This is a bug. I created Issue #3029964: Datelist element in webform not working in the Webform's issue queue. Please try the provided patch.

---
Tags: webforms, datetime
---


# Question
Title: Commerce order mail is empty for anonymous users
In the function below, there is the problem of sending email to anonymous users, the email sending only for users logged and to complete checkout and payment.

I get the following error message:

```
Error sending e-mail (from admin@mysite.com to ).

```

My Module:

```
function mymodule_commerce_checkout_complete($order){
            // send mails
            mymodule_send_order_emails($order);
    }

function mymodule_send_order_emails($order = NULL) {
    $module = 'mymodule';
    $key = 'my_message';
    $from = variable_get('site_mail', 'info@mysite.com');
    $language = language_default();
    $values['html'] = 'Html text value.';
    $params = $values;
    $send = TRUE;

    // load profile
    $profile = commerce_customer_profile_load($order->commerce_customer_billing[LANGUAGE_NONE][0]['profile_id']);

    // load user
    $user = user_load($order->uid);
    //$user->name;
    $to = $user->mail;

    $result = drupal_mail($module, $key, $to, $language, $params, $from, $send);
}

```

# Answer
You have anonymous orders so your code doing the loading of the user account obviously wont work as they dont have a user account:

```
 // load user
$user = user_load($order->uid);
//$user->name;
$to = $user->mail;

```

The above won't work for anonymous users as they don't have an account so the uid is always 0. I think the $order object has $order-\>mail to get the actual email address used on the order regardless if it was a full user or anonymous
> 0 votes

---
Tags: 7, commerce, emails
---


# Question
Title: hook_node_insert() sporadically not being fired after node_save()
I have a situation where, every once in a while, I'll save a new node, and `hook_node_insert()` appears not to be called--AT ALL, for any of the modules that implement it. For example, if I look through recent log messages, there is no watchdog message pertaining to the new node; no "your node has been created" message is displayed to the user; none of my custom modules which implement `hook_node_insert()` are fired. Yet, the node appears to have been successfully saved: It show up after being saved, shows up in content listings, etc. (Though anything that was supposed to happen via another module's `hook_node_insert()` call does not happen.)

The maddening thing about this situation is the "sporadically" part: Most of the time everything works as designed, and hook\_node\_insert() fires, but once in a while it doesn't.(Maybe, once out of ten or twenty times, it doesn't fire.)

So at this point I'm just looking for any clues or hints as to where I should be looking for the problem.
Is there anything that this kind of strange sporadic behavior might point to?

One thing I've wondered is if this could somehow be related so some kind of cache issue. Specifically, I'm using memcached on my site, which I'm using to hold every cache table from my database. Could there be some kind of issue there? I'm starting to experiment with removing certain tables from the memcached cache (like cache\_form), but no leads yet.

# Answer
> 0 votes
The only other note I'd make is to ensure that you don't have an & (ampersand) in front of $node in your function definition. I was porting from a drupal 6 site's nodeapi function and was using hook\_node\_insert(&$node) and it wasn't until I removed the ampersand that it started working.

# Answer
> 0 votes
i usually get the same issue in following cases :

* my module isn't enabled
* mistake when renaming the leading 'hook' to 'mymodule'
* the site i test in the browser is not in the same environment where my code is present (dev, qa, prod...)

---
Tags: 7, caching, nodes
---


# Question
Title: Getting the node object in hook_form_FORM_ID_alter
Follow up to this question but I don't have enough reputation to ask clarification in a comment.

I am porting a contributed module to Drupal 8. The sugested code on the above mentioned CR and post is not working:

```
$node = $form_state->getFormObject()->getEntity();

```

Nothing is loaded into the $node variable.

My PHPStorm IDE gives a warning for getEntity(): Method 'getEntity' not found in class Drupal\Core\Form\FormInterface less... Referenced method is not found in subject class.

It is also not presenting this method for code completion.

In the use cause I am referencing:

```
use Drupal\Core\Entity;
use Drupal\Core\Entity\EntityInterface;
use Drupal\node\Entity\Node;
use Drupal\Core\Render\Element;

```

# Answer
PhpStorm doesn't know as the type of form object is dynamic but it's fine.

If you want to make it happy, wrap it in a condition like:

```
if ($form_state->getFormObject() instanceof EntityForm) {
  ...
}

```

Either way, it should definitely work if you implement the correct form alter. If you don't, you should end up with a fatal error not just without a node object.

You need to share your exact code if you want a more specific answer, that's all I can tell you.
> 18 votes

# Answer
Though the correct answer has been chosen, I feel there's need to explain some things:

* The method `getFormObject()` is only available on forms of type `EntityForm`.
* If you're doing `hook_form_node_form_alter()`, you know that the form is always a node form, so you're safe calling `getEntity()` on the form object.
* However, if you're doing a general `hook_form_alter()` hook, you might want to check for the correct `$form_id` or check if the form object is actually a `NodeForm` or an `EntityForm`. This will prevent PHP errors if the form is not an entity / node form.
* As for your IDE and code completion, you can tell your IDE that the `$form_object` you're dealing with is a `NodeForm` or an `EntityForm`. This will make it show more appropriate hints.

```
/** @var \Drupal\Core\Entity\EntityForm $form_object */
$form_object = $form_state->getFormObject();
if ($form_object instanceof EntityForm) {
  $entity = $form_object->getEntity();
  // Do something with the entity.
}

```
> 13 votes

# Answer
For your IDE to know what the variable type is and what is available to it, you need to type hint your variables.

The type hint is the variable type added before the parameter variable name (in the example below `array` and `FormStateInterFace`).

Example:

```
/**
 * On form submit, do something.
 *
 * @param array
 *   The form array.
 *
 * @param \Drupal\Core\Form\FormStateInterface
 *   The form state array.
 */
function _submit_hook_name(array $form, FormStateInterface $form_state) {
  $node = $form_state->getFormObject();
  // Do something...
}

```

For submit hooks, you should be using the `Drupal\Core\Form\FormStateInterface` type... therefore at the top of the file ensure you use that class `use Drupal\Core\Form\FormStateInterface;`.

Drupal coding standards states that you should type cast as well as explain the type in the docblock. The extra effort helps in future. ;)
> 3 votes

---
Tags: 8, forms
---


# Question
Title: Why doesn't the "Edit" option always appear?
I have a site with several custom entities. For one of the entity types, most objects are fully functional, viewable, usable, but on the entity list page do not offer the *Edit* option. As my admin user, user 1, I can edit them using a custom form, but not from the default entity\_form.

My EntityAccessControlHandler.php starts with:

```
$roles = $account->getRoles();
if (in_array('administrator', $roles)) {
  return AccessResult::allowed();
}

```

Why does the Edit option get suppressed? I cannot find corrupted data in these nodes.

At this point, I have a workaround, using a custom form, but am trying to understand the depths of drupal at work here :) !

# Answer
> 2 votes
The user looking at the page the screenshot was taken on doesn't have the required level of access/permissions to edit those nodes.

There are many different ways that access/permissions can be configured to a single node, so you'll need to do some digging in your installation to find out whether it's simple core permissions, a contributed module, or a custom module that's causing the problem.

---
Tags: entities
---


# Question
Title: point a subdomain to a page without using domain module
I want to add a subdomain to my site (mysite.local) so it is, x.mysite.local and I want that to land on a custom page, i.e. a node, a view. I do not want to use the domain module because it has way more stuff that I need. Is there an easy way to do that in a custom module?

I tried doing something like this in settings.php but that does not seem to work:

```
// Get the subdomain:
$sub = explode('.',  $_SERVER['HTTP_HOST'])[0];
if ($sub == 'test') {
  $config['system.site']['page']['front'] = "node/12664";
}

```

# Answer
> 1 votes
I'm going to assume 1) you already have the proper DNS records set up and 2) you want a redirect (tells the browser to go to URL `node/12664`) and not a proxy rewrite (i.e. serve the page at `node/12664`).

Your best option would be to handle this in your .htaccess with mod\_rewrite:

```
# Handle request for subdomain
RewriteCond %{HTTP_HOST} ^test\.mysite\.local$ [NC]
RewriteRule (.*) https://mysite.local/node/12664 [L,R]

```

If you do want to try to handle this as a redirect in your `settings.php` you could try something like this:

```
if ($_SERVER["HTTP_HOST"] == 'test.mysite.local') {
    // Tell the browser to redirect to the HTTPS URL.
    header("Location: https://mysite.local/node/12664");
    exit;
}

```

If you want to serve a page from a *different* subdomain/host, without changing the URL, you'll have to delve into the hell of Apache ProxyPassReverse

---
Tags: 8, subsites
---


# Question
Title: Mapping field columns with D8 migrate and d7_node source plugin
I'm trying to write a D8 migrations files but the following one isn't working on the source 'body/value' because it resolves to a null value instead of the intended string.

```
id: my_d7_node_news
label: 'Nodes (News)'
langcode: en
status: true
dependencies: {  }
class: Drupal\migrate\Plugin\Migration
field_plugin_method: null
cck_plugin_method: null
migration_tags:
  - 'Drupal 7'
source:
  plugin: d7_node
  node_type: news
process:
  nid: tnid
  vid: vid
  title: title
  uid: node_uid
  status: status
  created: created
  changed: changed
  revision_uid: revision_uid
  revision_log: log
  revision_timestamp: timestamp
  'body/value':
    plugin: get
    source: 'body/value'
  'body/summary':
    plugin: default_value
    default_value: some summary
  'body/format':
    plugin: default_value
    default_value: rich_text
destination:
  plugin: 'entity:node'
  default_bundle: news

```

I tried multiple writing for the source: 'body/value' (e,g: source: body\_value, etc, ...) with no luck...

Which syntax should I use to make successful mapping on body/value: body/value using the d7\_node source plugin?

# Answer
> 0 votes
Something like this:

```
  body:
    plugin: iterator
    source: body
    process:
      value: value
      format:
        plugin: default_value
        default_value: filtered_html

```

# Answer
> -1 votes
Just use 'body', as in:

```
body: body

```

That is what core d7\_node migration does.

---
Tags: migrations
---


# Question
Title: How can I theme the Captcha/ReCaptcha error message?
I'd like to change how the error message is when a user fails the recpatcha.

Currently it is just plain text on top of my form but I would rather have it be a modal or at least be in red.

I looked into the templates folder in both the Captcha module and ReCaptcha but did not see anything for the error message.

Is there a way to theme the error message?

# Answer
> 2 votes
Believe I found a solution.

Since I am using the captcha with Webforms I inserted the below JS to the form and it seems to be working without any drawbacks.

```
(function ($, Drupal) {
Drupal.behaviors.myModuleBehavior = {
attach: function (context, settings) {
$( "[role=alert]" ).dialog();
}
};
})(jQuery, Drupal);

```

---
Tags: 8, captcha
---


# Question
Title: Redirect rule doesn't contain all the query parameters
I\`ve set up a Rule to redirect a user after log in. The Rule works redirecting the user to the URL specified, but it doesn't contain all the query parameters after "?".

This is the URL value:

*user/login?destination=node/4?cid1=\[entity-fetched-household:0:contact-id\]&cs1=\[entity-fetched-household:0:hash\]&cid2=\[account:civicrm-contact:contact-id\]&cs2=\[account:civicrm-contact:hash\]*

But the user is redirected to the following one:

*user/login?destination=node/4?cid1=\[entity-fetched-household:0:contact-id\]*

just containing the first query parameter cid1.

I've checked the other parameters, cs1, cid2, cs2, contain the correct values.

This is the export of the Rule:

```
{ "rules_add_parameters_to_url_related_to_contact_id" : {

"LABEL" : "Add parameters to url related to contact id",
"PLUGIN" : "reaction rule",
"OWNER" : "rules",
"REQUIRES" : [ "rules", "path" ],
"ON" : { "user_login" : [] },
"DO" : [
  { "entity_query" : {
      "USING" : {
        "type" : "civicrm_contact",
        "property" : "display_name",
        "value" : [ "account:civicrm-contact:household-name" ],
        "limit" : "1"
      },
      "PROVIDE" : { "entity_fetched" : { "entity_fetched_household" : "Fetched entity" } }
    }
  },
  { "redirect" : { "url" : "user\/login?destination=node\/4?cid1=[entity-fetched-household:0:contact-id]\u0026cs1=[entity-fetched-household:0:hash]\u0026cid2=[account:civicrm-contact:contact-id]\u0026cs2=[account:civicrm-contact:hash]" } },
]
  }
}

```

Any help will be really appreciated.

# Answer
> 0 votes
That's the way drupal\_parse\_url() parses your URL. If you think this is wrong, you can escape your & characters and file an issue in the core Drupal issue queue.

```
$ drush php-eval 'print_r(drupal_parse_url("user/login?destination=node/4?cid1=[entity-fetched-household:0:contact-id]&cs1=[entity-fetched-household:0:hash]&cid2=[account:civicrm-contact:contact-id]&cs2=[account:civicrm-contact:hash]"));'
Array
(
    [path] => user/login
    [query] => Array
        (
            [destination] => node/4?cid1=[entity-fetched-household:0:contact-id]
            [cs1] => [entity-fetched-household:0:hash]
            [cid2] => [account:civicrm-contact:contact-id]
            [cs2] => [account:civicrm-contact:hash]
        )

    [fragment] =>
)

```

---
Tags: rules
---


# Question
Title: How to set content-security-policy header?
I want to set Content-Security-Policy header in my site.

I found a module to set CSP (I have not tried it yet). But I want to know is there any option available in drupal 8 core itself to set CSP.

# Answer
I may be a bit biased in thinking that the Content Security Policy module is the best solution for adding a policy to your site, but here are some of the reasons for using the module:

* Integration with the Libraries API to automatically generate script and style directives
* An admin interface that validates your policy configuration
* Provides a reporting endpoint to receive policy violations and add them to your site log, so you don't *need* to use an external service like Report-URI.com (but it also provides a plugin to use it, if you do).
The Reporting API module is still in beta, but it will have improvements over CSP's reporting handler, and has a plugin to integrate with CSP module.
* Some optimizations to shorten your policy where possible (e.g. If a fetch directive like `img-src` that falls back to `default-src` has the same value, it is omitted)
* In the future modules will be able to integrate with CSP module to alter the policy as needed (enabling additional directives, altering the policy per-page)

---

There are a couple alternatives to the CSP module, if you don't want all of these additional features:

* The Security Kit module allows adding a CSP policy header, but it only allows either an enforced or report-only policy, and it does not have fields for many newer directives.
* The HTTP Response Headers module allows you to configure a static value for any HTTP header you want
* Set a static header in your own response event subscriber in a custom module.
* You can set the header directly in Apache or nginx configuration
> 5 votes

---
Tags: 8, security
---


# Question
Title: How is password hashing/encryption performed?
I am fielding a question for a project that is asking if we use Blowfish crypt in Drupal, or, if we could.

The class that performs password hashing in 8 is `PhpassHashedPassword`, based on https://www.openwall.com/phpass/. On that site, it states:

> At this time, if your new project can afford to require PHP 5.5+, which it should, please use PHP's native password\_hash() / password\_verify() API instead of phpass. This new API also happens to support the CRYPT\_BLOWFISH and CRYPT\_EXT\_DES hashes used by phpass, but unfortunately it does not support the phpass portable hashes (which are portable across all versions of PHP as long as you use phpass).

It goes on to state:

> The preferred (most secure) hashing method supported by phpass is the OpenBSD-style Blowfish-based bcrypt, also supported with our public domain crypt\_blowfish package (for C applications), and known in PHP as CRYPT\_BLOWFISH, with a fallback to MD5-based salted and variable iteration count password hashes implemented in phpass itself (also referred to as portable hashes). (phpass versions up to 0.4 also included an intermediary fallback to BSDI-style extended DES-based hashes, known in PHP as CRYPT\_EXT\_DES, but this has since been dropped except for authenticating against pre-existing hashes of this type.)

When reviewing the class in Drupal 8, it does not make use of `password_hash`, or `password_verify`. It also appears to use `sha512` as the algo. I can't find anywhere if `bcrypt` or Blowfish or `CRYPT_BLOWFISH` is used.

I did find this issue regarding supporting Blowfish style passwords but not one for creating them. I assume if I wanted to import their current userbase with Blowfish style passwords, I would need this patch.

Would it be difficult to implement my own class to do this that uses Blowfish? Are there any implications in Drupal of doing this? Why did version 8 opt to stick go with `SHA-512`? This project will be on PHP 7.2, so I don't care about PHP 5.x BC/reasons/etc.

Potentially related: https://stackoverflow.com/questions/16014282/why-crypt-blowfish-in-php-is-considered-better-when-it-produces-shorter-hashes

# Answer
> 2 votes
## Why does Drupal 8 use PHPass / `sha-512`?

* PHPass was originally implemented in Drupal 7, with custom code in order to use `sha-512` instead of `md5` which was used by other implementations at the time, and then ported to Drupal 8.
* Drupal 8 originally supported older versions of PHP where the password functions were not available, and didn't yet use composer to adopt an existing polyfill.
* It was (and still is) a low priority to update the hashing service after it was initially ported from Drupal 7.

## Would it be difficult to use Blowfish instead?

There's a module for that - as mentioned in the issue you linked the PHP Password module replaces the core service with one that understands legacy hashes, but will upgrade them to bcrypt when possible.

---
Tags: 8, users, security
---


# Question
Title: Can I setup the Security Kit module via Drush?
Does a Drush command exist which I can use to setup the Security Kit module? Something like this command:

`drush seckit --img-src:self,unsafe-inline`?

# Answer
You could update the Security Kit settings via the `config-set` command:

```
drush config-set seckit.settings seckit_xss.csp.img-src "'self' 'unsafe-inline'"

```

You can find the available configuration keys by looking at Security Kit's default configuration file, `config/install/seckit.settings.yml`, or you can view your site's current settings through the config export page.
> 3 votes

---
Tags: 8, drush
---


# Question
Title: How do I make a panel visibility rule work when the element to check for has to be not set or empty?
I am using Drupal 7, panels and page manager modules.

In page manager I created variants on the node template for showing a particular type of node in a different fashion to different user roles. My nodes have a Term Reference field called "Alternatives" that is NOT required to be set by the users so it can be either be "empty" aka "none" or set to some data value i.e. a taxonomy term of the vocabulary "Alternatives".

I created a visibility rule on another element on the same variant to hide this "other" element, a custom content.

From the element's gear icon (on the tab "Content" in the variant section) of the custom content, I have set the visibility rule to show: Alternatives is set to "". That's exactly what I want: if Alternatives is set to "nothing", this custom content should show and now it doesn't show.

It seems that the visibility rule doesn't seem to recognise or can't check if a term reference field (Alternatives) is empty or not set. How do I make this visibility rule work?

# Answer
> 0 votes
use flags module, and rules module, make a rule when save/update your content type, condition: your\_field\_value is empty, if true, flag your node, then in panels add your panels-rule visibility based on your new flag.

---
Tags: 7, panels
---


# Question
Title: How to submit form selecting an option in a <select> defined in inline_template?
I have this custom form in which there is this:
The corresponding code:

```
$form['actions'] = array(
    '#type' => 'details',
    '#title' => 'Tâches associées',
    '#open' => TRUE,
);
$form['actions']['1A'] = array(
    '#type' => 'inline_template',
    '#template' => '<select name="1B"><option value="" selected="selected">1. Choisir l\'année</option><option value='.$iY1.'>'.$iY1.'</option><option value='. $iY2.'>'.$iY2.'</option></select>',
);
$form['actions']['1C'] = array(
    '#type' => 'submit',
    '#name' => '1',
    '#value' => 'Oui',
    '#submit' => array('::executeActions'),
);
$form['actions']['2A'] = array(
    '#type' => 'inline_template',
    '#template' => '<BR>2. La période de renouvellement pour l\'année '.$iRenewalPeriodYear.' est ' . $sPeriodStatus . '. Voulez-vous ' . $sPeriodAction . ' ?  ',
);
$form['actions']['2B'] = array(
    '#type' => 'submit',
    '#name' => '2',
    '#value' => 'Oui',
    '#submit' => array('::executeActions'),
);

```

It works fine!
Using either of the two 'OUI' buttons triggers the 'executeActions' method.

I'd like to get rid of the first 'OUI' button.
Is there a way to trigger 'executeActions' method when selecting one of the options in the dropdown list?

If not possible, how could I have the 'OUI' button on the same line than the dropdown list?

# Answer
> 0 votes
Following the advice given from @Clive and @NoSssweat, I rewritten the code.

```
public function buildForm(array $form, FormStateInterface $form_state) {
  $form['suscribe'] = [
    '#type' => 'radios',
    '#title' => '',
    '#options' => [
      0 => $this->t('No'),
      1 => $this->t('Yes'),
    ],
    '#default_value' => $iWish,
    '#attributes' => [
      'onchange' => 'hasChanged(this)'
    ],
    '#validated' => TRUE,
  ];
  $form['submit'] = [
    '#type' => 'submit',
    '#value' => $this->t('Submit'),
  ];

  $form['actions'] = [
    '#type' => 'details',
    '#title' => 'Tâches associées',
    '#open' => TRUE,
  ];

  if ($rpStep == 0) {
    $iY1 = (int) strftime("%Y");
    $iY2 = $iY1 + 1;

    $form['actions']['1B'] = array(
      '#type' => 'select',
      '#title' => '1. Choisir l\'année et ouvrir la période de renouvellement.',
      '#options' => array(
        "" => "--",
        $iY1 => $iY1,
        $iY2 => $iY2,
      ),
      '#default_value' => $rpYear,
    );
  }
  else {
    $form['actions']['1A'] = array(
      '#markup' => '1. La période de renouvellement a été ouverte pour ' . $rpYear . '.',
    );
    $form['actions']['4B'] = array(
      '#type' => 'radios',
      '#title' => 'Voulez-vous fermer la période de renouvellement ?',
      '#options' => [
        0 => $this->t('No'),
        1 => $this->t('Yes'),
      ],
      '#default_value' => 0,
    );
  }

  $form['actions']['99'] = array(
    '#type' => 'submit',
    '#name' => '99',
    '#value' => $this->t('Submit'),
    '#submit' => array('::executeActions'),
  );

  return $form;
}

```

---
Tags: 8, forms
---


# Question
Title: How do I avoid caching a redirect response from a form?
I have a Drupal 8 form used by authenticated users which sometimes needs to redirect based on the presence of absence of something in session. I don't want the redirect to be cached.

My form is displayed directly with a route. i.e., the route has a \_form default pointing to the form class.

My buildForm method starts like this:

```
public function buildForm(array $form, FormStateInterface $form_state)
{
    $form['#cache'] = ['max-age' => 0];

    if (some value not in session) {
        $response = new TrustedRedirectResponse($some_url);
        $response->setMaxAge(0);
        throw new EnforcedResponseException($response);
    }

    // build the form.
}

```

I have not been able to avoid the redirect response being cached. It redirects as expected if the session variable does not exist but continues to redirect next time when the session variable does exist.

Users are authenticated so it is the dynamic page cache. `drush cr` or uninstalling the dynamic page cache "fixes" the problem.

# Answer
> 1 votes
I just discovered that it's related to the TrustedRedirectResponse.

A standard Symfony\Component\HttpFoundation\RedirectResponse is not cached.

---
Tags: forms, caching, redirection
---


title: Dynamic image style?

text:
# Question
Title: Dynamic image style?
I need to display profile image, but less blurred each day for example:

* day 1 : blur 30
* day 2 : blur 20
* day 3 : blur 10

Image style seems not to be dynamic. And I didn't find a way to do this.

Have you an idea I could explore?

# Answer
I think you can create the different image styles within the admin UI and then use a hook in your theme to override beased on your logic

```
function MYTHEME_preprocess_image(&$variables) {
    // ... add your logic
    $variables['style_name'] == 'image_style_machine_name';
}

```

OR another possibility could be

```
function MYTHEME_preprocess_image_style(&$variables) {
    // ... add your logic
    $variables['style_name'] = 'image_style_machine_name';
}

```

**NOTE:** both are untested
> 0 votes

# Answer
Finally, implemementing a proprocess function linked to block generation was too difficult for me actually.

I've found another solution (I think it's not the best, but it works) :

```
        case 'mymodule_block':
$block['content'] = theme('image_style',
          array(
            'style_name' => 'flou_80',
            'path' => $photo_profile,
            'attributes' => array('style' => 'border:1px solid #aaa;')
            )
          );

```
> 0 votes

---
Tags: 7, media
---


# Question
Title: Solr search api indexing referenced fields by their id not value
So i created a basic Solr core and index. In the index i added several diff. content types and added a lot of fields from those CT, including a aggregated field (union of several diff. fields: plain text, entity ref. fields, etc) Now i built a view based on that index (displaying rendered entities), and in the filter added a Fulltext search which will search on the Aggregated field.

For the most part it all works as designed, except that the fields which are entity reference fields (taxonomies) are indexed by their reference id (tid) and not the human readable value. E.g.: if a term (Math) from the vocabulary Subjects is indexed, the value which will be stored by solr is 5 (which is the term id), so when you use the fulltext search field and search Math there will be no results, but if you search 5, the content type where Math is selected will be displayed, not the best UI if you agreee.

Is there any way to search by the human readable values, without me altering the query and then finding the corresponding `tid` of the value entered in the search and then passing it back to the query, because that kinda defeats the purpose of having a backend search engine.

Thanks, Will

# Answer
> 0 votes
Just to provide an answer, maybe it'll be useful to someone. **You can't** At least not without a lot of hacking/patching the solr api module.

---
Tags: search
---


# Question
Title: Upgrade to Devel 8.x-2.0 without Composer
I have Devel 8.x-1.2 installed and need to upgrade to 8.x-2.0 but I cannot install Composer/Drush on the server as it is not included in the hosted service. Any guidance how can I execute this upgrade?

# Answer
> 1 votes
Click the tarball or zip file link, extract folder. Upload devel folder to /modules folder.

Then run **update.php** by going to `yourwebsite.com/update.php` and then flush all caches.

> Note that if the module requires any external dependencies this will not work.

Indeed, I don't believe this is the case for Devel. But if your module has external dependencies and must be installed via composer. Simply in a local or some other environment install it using composer and then upload all the files that were installed, including the /vendor directory files.

---
Tags: composer
---


title: Embed a View into a render array

text:
# Question
Title: Embed a View into a render array
In Drupal 7, I used the following code implementing views\_embed\_view in a render array.

```
  $view_output = views_embed_view($view_name, $display_id, $uid);

  $page['profile']['bio_mobile'] = array(
    '#type' => 'markup',
    '#markup' => $view_output,
    '#prefix' => '<div class="mobile-display">',
    '#suffix' => '</div>',
  );

```

How do I do that using Drupal 8? Although the function is still documented, it return nothing more than just the array I passed in.

# Answer
I don't know about using `#markup` but I can create a variable with a renderable View array like so:

```
  // Staff snippet.
  $view = Views::getView('staff');
  $view->setDisplay('user_snippet');
  $view->preExecute();
  $view->execute();

  if (count($view->result)) {
    $variables['user_snippet'] = $view->buildRenderable('user_snippet');
  }

```

Then in the twig file I am sending the variable to:

```
{% if user_snippet %}
  {{ user_snippet }}
{% endif %}

```
> 2 votes

# Answer
Indeed, `#markup` only allows string, but you can by using a block type

```
  $entityTypeManager = \Drupal::entityTypeManager();
  $viewExecutableFactory = \Drupal::service('view.executable');

  $view = $entityTypeManager->getStorage('view')->load($view_name);
  $view = $viewExecutableFactory->get($display_id);
  $view->setArguments([$uid]);
  $view->preExecute();
  $view->execute();

  $page['profile']['bio_mobile'] = [
    '#type' => 'block',
    'content' => [
      'system_main' => $view_output,
     ],
    '#cache' => $view->getCacheTags(),
    '#prefix' => '<div class="mobile-display">',
    '#suffix' => '</div>',
  ];

```
> 3 votes

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


title: Custom submit button text

text:
# Question
Title: Custom submit button text
I have a classic contact form. I can add for example some custom placeholder like this :

```
function my_theme_form_contact_message_about_your_project_form_alter(&$form, FormStateInterface $form_state, $form_id) {
    // placeholder
    $form['field_contact_name']['widget'][0]['value']['#placeholder'] = t('Saisir votre nom');

}

```

It works very well and I can also easily modify wrapper, name, etc.

But for a reason I can’t understand, I am not able to modify the text of the submit button.

Here is what I’ve tried among a lot of things and I think it should be the right thing (as seen on other answers) :

```
$form['actions']['submit']['#value'] = 'hello world!';

```

Here is the html of the button :

```
<button data-drupal-selector="edit-submit" class="button button--primary js-form-submit form-submit btn-primary btn" type="submit" id="edit-submit" name="op" value="Envoyer">Envoyer</button>

```

I use a custom theme based on Bootstrap theme.

Of course, I can do it with jQuery :

```
$('#edit-submit').text('lorem ipsum');

```

But I would like to know how to do it the Drupal way.

**EDIT** :

The solution is :

```
form['actions']['submit']['#value'] = 'hello world!';

```

It works on a clean Drupal install but not on the website I am currently working on.

# Answer
> 1 votes
> Do you know why it is not working ?

Because it seems to me that you're playing the guessing game.

How about installing the Devel and adding `kint($form)` to inspect the `$form` array?

You will see its

```
$form['actions']['submit']['#value'] = t('Post Comments');

```

---
Tags: forms
---


# Question
Title: Allow customers to add arbitrary data to products when adding to cart
I've got a product type called workshop and I want customers to be able to specify the names of their kids when they add a workshop to the cart. If I could figure out how to add any arbitrary data at all I'm sure I could carry this through to where I ultimately want it to be, which is that the arbitrary data would actually be a choice of some number of Paragraph entities referenced by their user profile, but all the solutions I have been able to find seem to be for Drupal 7, so I'm dead in the water.

Any suggestions?

# Answer
For the benefit of anyone who comes looking, the answer is that the fields need to be added to the order item type. Commerce sees each product as a sort of Platonic object and stamps out instances as order items -- think line items. You can add fields to this. Whee. Unfortunately, you can't reference Paragraph entities because, as ridiculous as it seems to me, Paragraph entities only support a single reference.
> 1 votes

---
Tags: commerce
---


# Question
Title: How can I apply logic in user registration welcome emails?
I am trying to put some logic into user registration welcome emails. Simple "if-then" logic, based on tokens.

The tokens I use show up as expected, but both twig and php code gets sent as plain text.

Can I somehow make twig or php code execute before the email is sent to the new user?

---

UPDATE, to make the question more specific:

I have token module enabled.

I am trying to add this logic to the welcome email sent to new users at "/admin/config/people/accounts":

```
{% if [user:field_marketing_package] == "Yes" %}
<p>Marketing selected</p>
{% endif %}

```

The \[user:field\_marketing\_package\] field is filled out at user registration.

I would like to add logic like this. If I have the above twig code in the message, it just gets sent as plain text and does not execute.

Twig or php or any other solution is fine as long as I can include the token in the if statement.

Can you point me to the right direction?

# Answer
Pretty ugly, but I have a solution. Please post if you have a better one that can be applied for more use cases.

So I installed the https://www.drupal.org/project/computed\_field module.

I added a hidden computed filed to my user registration form with my logic.

Then I used the token module to include the value of that computed field in my user welcome email.

It does the job, but again, it is pretty ugly. Hopefully this helps someone until someone posts a more direct solution.
> 0 votes

---
Tags: 8, users, emails
---


# Question
Title: Is upgrading MySQL to MariaDB seamless for Drupal sites
My server has an outdated version of MySQL (5.5, which EOL'd in December). The WHM panel has an update option and the recommended upgrade is MariaDB 10.3.

In theory (with all usual "test first" caveats), should a major upgrade like this be seamless for the Drupal sites running on the server?

# Answer
> 1 votes
Drupal runs fine on both MariaDB and MySQL, so you should be able to replace one with the other without any issues at the application layer (Drupal). I don't believe the abstraction layer does anything differently between the two so you shouldn't have issues with needing to change field types (swapping to Postgres or other engines Drupal supports would change that answer significantly).

I would expect with an update like that to require some downtime, and a change of username and passwords for the database itself. So you will probably need to update the database connection settings once the update is complete.

All that of course depends on WHM doing the actual update of the database layer correctly so that "test first" caveat is a big deal.

---
Tags: database
---


# Question
Title: Have Database Update ignore prefix for multisite with shared database
I currently have a multisite with a single database. Each instance has a different prefix for their tables, except for one with no prefix which is considered to be the main instance. Now there is a custom table I made that contains custom data. That table is meant to be shared across all instances. In a function I'm updating a field like so

```
$database = \Drupal::database();
$database->update('custom_table')->condition('id', $my_id, '=')->fields(['full_name' => $fullname, 'address' => $address])->execute();

```

This works on my main site. Unfortunately in the other multisite instances that's using the same function, this is causing an error. In the error I have

> Base table or view not found: 1146 Table 'database.myprefix\_custom\_table' doesn't exist

I realize that it's trying to prepend the prefix for the table. But it's a table that every site is meant to share. I don't want a prefix to be used.

I noticed that the update method can use options as a parameter https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Database%21Connection.php/function/Connection%3A%3Aupdate/8.2.x

But I'm not sure if I can tell it not to use a prefix in the options I can supply.

I understand that I can just use the query method instead of using the update method (I think) but I would like to know: Is it possible to force the update method for the connection object to not use the database prefix?

UPDATE: This was suggested as a duplicate: How to identify multi-site programmatically? But that isn't related to my problem.

In that example it's identifying what site it's on, but it's not performing anything with a database. I know how I can check what site it's on. That's not a problem. I need to call an actual database method and get rid of the prefix it's automatically applying.

In my code

```
$database->update('custom_table')->condition('id', $my_id, '=')->fields(['full_name' => $fullname, 'address' => $address])->execute();

```

I'm not even supplying the prefix. It's automatically applying it without my knowledge if it's being run on another site.

# Answer
Looking at the comments in settings.php, you may well be able to do something like this:

```
$databases['default']['default'] = [
  'database' => 'db_name',
  'username' => 'root',
  'password' => 'root',
  'host' => 'localhost',
  'port' => '3306',
  'driver' => 'mysql',
  'prefix' => [
    'default' => 'shared_',
    'custom_table' => '',
  ],
];

```

I haven't tried it, but in theory that should set the prefix for all tables to `shared_`, except for the custom one, which would have no prefix.
> 2 votes

---
Tags: 8, database
---


# Question
Title: Sort taxonomy terms alphabetically by default
I created a taxonomy vocabulary and added some taxonomy terms to it. How can i sort alphabetically the listing of terms in taxonomy vocabulary page. The same sorting needs to reflect in content type fields when this vocabulary is added as term reference.

# Answer
> 3 votes
I hijacked the code from /modules/taxonomy/taxonomy.admin.inc that runs when you click "Reset to alphabetical". I tweaked it a bit and you can place this code in a custom module and it will run every time you insert a taxonomy term.

```
/**
 * Implements hook_taxonomy_term_insert()
 */
function YOURMODULE_taxonomy_term_insert($term) {

  $vocabulary = taxonomy_vocabulary_load($term->vid);
  $tree = taxonomy_get_tree($vocabulary->vid);

  if($vocabulary->machine_name = 'MACHINE_NAME_YOU_WANT_TO_FORCE_ORDERING') {
    //Make sure the taxonomy doesn't have terms with two parents
    if ($vocabulary->hierarchy < 2 && count($tree) > 1) {
      $params = array(
        'values' => array(
          'vid' => $term->vid,
          'name' => $vocabulary->name,
          'machine_name' => $vocabulary->machine_name,
        ),
      );

      taxonomy_vocabulary_confirm_reset_alphabetical_submit(NULL, $params);
    }
  }
}

```

If you want it to apply to all vocabularies, you can remove the IF statement on line 7. Good luck!

# Answer
> 0 votes
Simply scroll to bottom and click on reset alphabetical at /admin/structure/taxonomy/, do that after doing changes, you maybe be able to have a cron run and do this every few hours or so.

---
Tags: taxonomy-terms
---


title: How to invoke a post drush command?

text:
# Question
Title: How to invoke a post drush command?
I am using Drush 9 and Drupal 8. When I execute `drush site:install` I find that it also modifies the permission of the web/site/default directory to r-xr-x--x, which troubles me delete that directory later. I want that directory to be 740 in my case. So two methods came to my mind. One is to run a custom shell script as post `drush si` or to override the default `dush si` command. I tried to go through some blogs but I couldn't understand them. Please explain stepwise.

How can I invoke a custom shell script to `drush site:install` which will be run just after that command is executed.

How can I override the default `site:install` command?

Note: I am using Drupal composer project. So I have a drush folder outside the webroot but I don't know if I can edit some files in that directory and write my custom commands.

# Answer
Greg's answer is great. But to more precisely answer this particular question follow the below steps.

1- As you are using Drupal composer project template, Go to the directory `your_drupal_project/drush` and create a file called `SiteInstallCommands.php`. You can see there are another similar file `PolicyCommands.php`.

2- **SiteInstallCommands.php** should have below code snippets. `installTest()` is your custom commands that is going to be executed post site:install. So change it according to your needs.

```
<?php

namespace Drush\Commands;

class SiteInstallCommands extends DrushCommands
{

    /**
     * Executing command just after `drush site:install`
     *
     * @hook post-command site-install
     *
     */
    public function installTest() {
        drush_shell_exec('echo test');
    }
}

```
> 2 votes

# Answer
See the example file PolicyCommands.php in the Druhs examples directory. Create a directory named "Commands" in your site's "drush" directory, and put your command file there. Its name must end with "Commands.php" or "Hooks.php".

Create a hook similar to one of the ones shown in the example file. You'll want `@hook post-command site:install`.
> 3 votes

# Answer
To create a site:install hook I just needed to create a file SiteInstallCommands.php inside drush/Commands dir. then `drush cc drush` to clear the drush cache and my custom post command is up. Thanks to @greg\_1\_anderson for guiding. Note you have to add **`@hook post-command site-install`** not `@hook post site:install`.

```
<?php

namespace Drush\Commands;

class InstallCommands extends DrushCommands
{

    /**
     * Modify files/directory permission as per project's need executing just after `drush site:install`
     *
     * @hook post-command site-install
     *
     */
    public function installChmod() {
        $this->logger()->success(dt('Executing post site:install commands'));
        drush_shell_exec('chmod -R 740 sites/default');

    }
}

```
> 0 votes

---
Tags: 8, drush
---


# Question
Title: Exposed Views Combine filter not working
Exposed Views Combine filter is working fine for administrator role, But its showing "Page not found" when I am trying to access with authenticated user role. I rebuild the cache so many times and rechecked the permissions.

For authenticated user its showing result on : http://localhost/example/testfilter?combine=&title=abc

But showing "Page not found" on http://localhost/example/testfilter?combine=textdata&title=abc

Again for administrator , Both URLs are displaying correct result.

# Answer
> 1 votes
Check which fields you are combining.

If e.g. you have a user field as combined field, Drupal needs the "Administer users" permission to use this filter.

An issue about this can be found at https://www.drupal.org/project/drupal/issues/3030696

---
Tags: 8, views
---


# Question
Title: Add class to "link to content" view field
I'm using Drupal 8 and building a `view`. I have a field, which happens to be a `title` field, and I have set it to `link to content`. I would like to know how I can simply add a `btn` class to the `anchor` tag. Right now the output looks like this:

```
<a href="/node/{id}" hreflang="en">... custom text ...</a>

```

I know I can use the `Rewrite Results` view feature to accomplish this, however, I need more power than that because I am building a theme for a client. The theme needs to be more generic, so I need to be able to accomplish this in a template. Is there template suggestion/hook that would allow me to override this in a template such as `.../templates/views-view-field--link.html.twig`? Or is there a theme function that I could use to override the markup by adding the class I would like?

I've considered using the `views-view-field.html.twig` template and overriding the `node_view` type to accomplish this, but I'm not sure how to do that whilst keeping the custom text a user could be using because it's really hard to debug the `field` options.

### Edit

I forgot to mention, this needs to rely on Drupal `core`. I can't expect the user to install any additional modules for it to work.

# Answer
> 5 votes
Along with Wims suggestion, I would suggest (as I usually do) to bypass fields in views, and render the view mode of the entity in question. Usually, this is sufficient in most cases if this is a presentation based view, and not a 'report' style view (where records are in table format and fields serve as cell data).

Then, supply the twig template for view modes, where the title is linked, and you can add the class(es) there. Now when you use that view mode to render in Views, it uses one template and is consistent, and Views that rely on rendering entities become easier to maintain and quicker to setup.

Here is an article that explains the difference and the benefit: https://www.amazeelabs.com/en/blog/views-field-rewriting-to-views-modes

That said, no, links themselves do not have a twig file (where you would see the anchor tag markup). I have seen the `|merge` option before that Wim linked to, though I have been unsuccessful in getting that to work in 8.2.5.

You could also implement `theme_preprocess_field` and supply the class to the attributes before it is rendered, though as you can imagine, if you have a lot of these, it'll be some work.

# Answer
> 4 votes
**Override just one field**

There is a detailed answer in this Q: Overriding views-view-field.html.twig for specific fields.

You can simply use `views-view-field--fieldname.html.twig`. Use `core/modules/views/templates/views-view-field.html.twig` as the base template. It also contains information about which variables you can use:

```
view: The view that the field belongs to.
field: The field handler that can process the input.
row: The raw result of the database query that generated this field.
output: The processed output that will normally be used.

```

**Override all links**

Use `field--node--field-link.html.twig` which you can get from this source. It contains all the information about variables you can use.

**Remember**

Of course, don't forget to clear your cache after creating the new template or making changes to it.

# Answer
> 3 votes
> I need to be able to accomplish this in a template
>
> This needs to rely on Drupal core. I can't expect the user to install any additional modules

Based on these constraints:

**OPTION A**

create **views-view-field--field-name.html.twig**

Inside put `<div class="btn">{{ output -}}</div>`

Then in your CSS file `.btn a { .... };`

---

But I really need to have the class inside the `<a>` tag... Ok then:

**OPTION B**

Inside **mytheme.theme**

```
use Drupal\Core\Url;
use Drupal\Core\Link;

function mytheme_preprocess_views_view_field(&$variables) {

  // check if it's the title field and also if "Link to the Content" (from the Views UI) is checked marked.

  if ($variables['field']->options['field'] == 'title' && $variables['field']->options['settings']['link_to_entity'] == TRUE){

    // kint($variables['field']); <-- if you need to use kint

    $og_link = $variables['field']->original_value;

    // make this into XML so we can grab the href value

    $xml_link = new SimpleXMLElement($og_link);

    global $base_url;

    // problem is that $base_url contains the /drupal folder path (http://example.com/drupal) in url
    // also the xml_link has it too (/drupal/node/5).
    // Since we only need of them to have it
    // lets grab some parts of the $base_url by parsing it.

    $complete_url = parse_url($base_url);

    $complete_url = $complete_url['scheme'] . '://www.' . $complete_url['host'] . $xml_link['href'];

    // Now create a brand new link

    $url = Url::fromUri($complete_url);
    $link_options = array(
      'attributes' => array(
        'class' => array(
          'btn',
        ),
      ),
    );
    $url->setOptions($link_options);
    // $xml_link = the title between the <a>title</a> tags
    $link = Link::fromTextAndUrl(t((string)$xml_link), $url )->toString();

    // re-writes, sets the output to our link.
    $variables['output'] = $link;
  }

}

```

Basically, we grab the url of the title and the title text. Then we create a brand new link (the Drupal way) using those values and add the class `btn` to our link and set the field output to our newly created link.

# Result

# Answer
> 3 votes
I've achieved the same result in this way, without doing anything with custom templates or code, only with rewriting of the result:

It is for a commerce product instead of node, but i think that it works with every entity. I think that for the most of cases it should be easiest and without the need for coding and new templates.

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


# Question
Title: How can I redirect users to the order information after adding product
This is the goal: Once user click on a link, product needs to be added to the basket, and order information page needs to appear, so user can fill it.

I've created a controller, and everything works, unless the user in anonymous. In that case, a "You are not authorized to access this page." error appears, and product is not added. However, (not sure if this is important), if the user visits a product first (just visit, without additional interaction), and then visit the link there is no that error. Also, if there are some items already in the added (with classic buttons), everything also works, for anonymous users as well.

I've used this to add the product: https://www.drupal.org/node/2866020

Shortly, it creates order item, and adds with cart manager.

and at the end, I've added

`$cart_id = $cart->get('order_id')->getValue();
$cart_id_value = $cart_id[0]['value'];
$response = new RedirectResponse('/checkout/' .$cart_id_value.'/order_information');
$response->send();
return;`

Any help or guidance will be appreciated.

Thanks

# Answer
> 0 votes
I've solved this by replacing last 3 lines with

`return $this->redirect('commerce_checkout.form', array('commerce_order' => $cart_id_value));`

And as ssibal suggested, here I do not use hard-coded URL (thanks for that).

---
Tags: 8, commerce
---


# Question
Title: How to set all values of a field as body classes
I want users to easily modify the layout of a node by selecting options in a 'Layout' field that the node contains. The field is a entityreference field referencing taxonomy terms. (For example, the user can select term 'hide-images' and the body class 'hide-images' will be used in the css to hide images.)

I have found this code that sets the first value of a field as body class. But how can I add all field values (taxonomy terms) as body classes?

```
/**
 * Implements hook_preprocess_html
 */
function THEME_preprocess_html(&$vars){
  // Check if on an article node page
  if($node = menu_get_object('node') && $node->type == 'article'){
    // Get field values
    if($term = field_get_items('node', $node, 'field_layout')){
      // Add first term value to body class
      $vars['classes_array'][] = drupal_html_class(reset($term));
     }
  }

}

```

# Answer
Instead of reinventing the wheel, you could take a look at Display Suite. DS has this functionality built in.

DS comes with a sub-module (DS extras) that has a feature that allows users to select a style right from the node edit page.

After enabling ds, ds\_ui, ds\_extras you can enable `/admin/structure/ds/list/extras` -\> Other Tab -\> View mode per node to use the feature.

Description of the feature:

> Change view modes for individual nodes. A new tab 'Display settings' will appear on the content create form. You can also pass the name of a view mode through the URL, eg node/x?v=full. If you install the Page manager module and override the node view, Page manager will win.

Update: If you still want to do it the way you started, you can just change this bit to use a foreach:

Change:

```
if($term = field_get_items('node', $node, 'field_layout')){
  $vars['classes_array'][] = drupal_html_class(reset($term));
}

```

To:

```
if ($term = field_get_items('node', $node, 'field_layout')) {
  foreach ($term as $item) {
    $vars['classes_array'][] = drupal_html_class($item['taxonomy_term']->name);
  }
}

```
> 3 votes

# Answer
For D8:

Using `template_preprocess_html()`

```
/**
 * Implements template_preprocess_html().
 */
function themename_preprocess_html(&$variables) {
  // CSS Class on the basis of Color Selection.
  $node = \Drupal::request()->attributes->get('node');
  if ($node->getType() == 'article') {
    $node_array = $node->toArray();
    $field_color = reset($node_array['field_color']);
    $color_class = 'color-' . $field_color['color'];
    $variables['attributes']['class'][] = $color_class;
  }
}

```

Using `template_preprocess_page()`

```
/**
 * Implements template_preprocess_page().
 */
function themename_preprocess_page(&$variables) {
  // CSS Class on the basis of Color Selection.
  $node = \Drupal::routeMatch()->getParameter('node');
  if ($node->getType() == 'article') {
    $node_array = $variables['node']->toArray();
    $field_color = reset($node_array['field_color']);
    $color_class = 'color-' . $field_color['color'];
    $variables['attributes']['class'][] = $color_class;
  }
}

```
> 1 votes

---
Tags: theming, taxonomy-terms
---


# Question
Title: How to print all values of a multi-value field, except the first?
Suppose that in a Twig template, I want to print the first value of a multi-value field, then something else, and finally all other values of the same field. Is there a way to do that?

I know how to get the first value of the field, but I don't know how to exclude that first value from the place where I'm printing all other values.

This is what I tried, but doesn't work:

```
{# print first field value #}
{{ content.field_foo.0 }}
{# print something else #}
<hr>
{# print remaining field values #}
{{ content.field_foo|without(0) }}

```

Alternatives for the last line that didn't work either:

```
{{ content.field_foo|without('0') }}
{{ content.field_foo|without('field_foo.0') }}

```

Looking at the code in `twig_without()`, I would expect `{{ content.field_foo|without(0) }}` to work, but instead the entire field disappears.

# Answer
> 4 votes
In field preprocessing this while loop which fills the field items doesn't get started if the first delta is removed:

```
  $delta = 0;
  while (!empty($element[$delta])) {
    $variables['items'][$delta]['content'] = $element[$delta];
    $delta++;
  }

```

So if you bypass the field template to print the `0` delta do the same with the other deltas:

```
{# print first field value #}
{{ content.field_foo.0 }}
{# print something else #}
<hr>
{# print remaining field values #}
{% for key, item in content.field_foo if key > 0  %}
  {{ item }}
{% endfor %}

```

---
Tags: theming
---


title: Token insert with CKEditor doesn't work

text:
# Question
Title: Token insert with CKEditor doesn't work
I'm using the CKEditor Module in combination with the Token insert (ckeditor) to show a user property in my body.

It looks like this:

But the results shows just the static text instead of the user property. What am I doing wrong?

**UPDATE:**

I've also tried to add the Token insert button to my editor like this:

But every time I save this and check again it is switched back.

These modules are enabled:

* Entity Tokens
* Token insert (ckeditor)
* Token insert (text)
* Token insert UI
* Token

**UPDATE:**

The test gave me a result like this:

I tried to add a random number in my text field but the result just gave me the static text `[random:number]` instead of a random number...

# Answer
You need to install the token filter module for the token insert to work.

Download the module.

Configure the tokens you want to use by role or globaly.

and add the filter in the Text Format:

Then you can use the ckeditor plugin to add the token in the Fields that have this Text format, and thats all.

I've just test and it works perfect.
> 5 votes

# Answer
You can try the Advanced Text Formatter module.

It has Token Replace feature. Personally, I like the idea replace the tokens using Field Display, you can choose to replace any fields in whatever (display) mode you want.

It's more flexible and good for performance. The con is it works only for field :)
> 0 votes

# Answer
token\_filter was not installed for me. It's not a dependency but it is required for this to work. "Replace tokens" filter is not available without it.
> 0 votes

---
Tags: webforms, tokens, wysiwyg
---


# Question
Title: backing out of a module update after uploading it and before the database update (new update is incompatible with my version of PHP)
I got a situation here and I don't know what to do. Drupal 7.

There's an update for reCAPTCHA so I click the button and checkboxes and whatever to update it, it uploads the files to the server and unpacks them and stuff, and then I click the "update database" link. BTW, there's two other modules being updates: rules and GA.

On the resulting page, /update.php, it first check the requirements (I rarely see this screen, it usually breezes right past it) and there's a big red error message saying that "reCAPTCHA requires at least PHP 5.5.\*" and I have PHP 5.4.45.

Should I delete the reCAPTCHA module from /sites/all/modules/, and then put the files for the old version in there? If I do that, will the database updates script be confused?

Thanks!!

# Answer
> Should I delete the reCAPTCHA module from /sites/all/modules/, and then put the files for the old version in there?

Yes, that's exactly what you should do.

> If I do that, will the database updates script be confused?

They shouldn't be - when you start an update, the current versions of modules are queried from fresh again. So as long as the current version of the module in the database matches the version in the file system (which it will if you restore to before the file system change), you should be fine.
> 1 votes

---
Tags: 7, database, updating
---


# Question
Title: how to inject dependencies into an access controller?
I am altering an existing route and adding a custom access. The custom access is a method that I want to have it in it's own access controller:

```
  /**
   * Alters existing routes.
   */
  public function alterRoutes(RouteBuildEvent $event) {
    $collection = $event->getRouteCollection();

    if ($route = $collection->get('entity.node.clone_form')) {
      // Add custom access
      $route->setRequirement('_custom_access', '\Drupal\eclone_extras\Controller\EcloneExtrasAccessController::access');
    }
  }

```

Then in my access controller I have:

```
namespace Drupal\eclone_extras\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

class EcloneExtrasAccessController extends ControllerBase{

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * The entity type ID.
   *
   * @var string
   */
  protected $entityTypeId;

  /**
   * Constructs a new ContentEntityCloneBase.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   * @param string $entity_type_id
   *   The entity type ID.
   */
  public function __construct(EntityTypeManagerInterface $entity_type_manager, $entity_type_id) {
    $this->entityTypeManager = $entity_type_manager;
    $this->entityTypeId = $entity_type_id;
  }

  /**
   * {@inheritdoc}
   */
  public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
    return new static(
      $container->get('entity_type.manager'),
      $entity_type->id()
    );
  }
  /**
   * Custom access checker for the create lock requirements route.
   *
   * @see \Drupal\content_lock\Routing\ContentLockRoutes::routes()
   */
  public function access() {
    // do access stuff
    return TRUE;
  }

}

```

But I keep getting the following errors:

```
0 passed in /var/www/drupal8/web/core/lib/Drupal/Core/Controller/ControllerBase.php on line 118 and exactly 2 expected in Drupal\eclone_extras\Controller\EcloneExtrasAccessController->__construct() (line 36 of modules/custom/eclone_extras/src/Controller/EcloneExtrasAccessController.php).

```

# Answer
This can be done using services. Here's an example which injects the entity type manager interface.

eclone\_extras.services.yml:

```
services:
  eclone_extras.access:
    class: Drupal\eclone_extras\Access\EcloneExtrasAccess
    arguments: ['@entity_type.manager']

```

Route subscriber:

```
 /**
   * Alters existing routes.
   */
  public function alterRoutes(RouteBuildEvent $event) {
    $collection = $event->getRouteCollection();

    if ($route = $collection->get('entity.node.clone_form')) {
      // Add custom access
      $route->setRequirement('_custom_access', 'eclone_extras.access::access');
    }
  }

```

Access class:

```
namespace Drupal\eclone_extras\Access;

use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;

class EcloneExtrasAccess {

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * Constructs a new ContentEntityCloneBase.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   * @param string $entity_type_id
   *   The entity type ID.
   */
  public function __construct(EntityTypeManagerInterface $entity_type_manager) {
    $this->entityTypeManager = $entity_type_manager;
  }

  /**
   * Custom access checker for the create lock requirements route.
   *
   * @see \Drupal\content_lock\Routing\ContentLockRoutes::routes()
   */
  public function access() {
    // do access stuff
    return AccessResult::allowed();
  }

}

```

The access callback gets some parameters as well, such as Account and possibly request.

Refs:
> 1 votes

---
Tags: 8, dependency-injection
---


title: Product category pages

text:
# Question
Title: Product category pages
I've had experience creating product catalogues in Drupal 7, but this is my first time using Drupal 8.

I have some categories defined as a taxonomy, and I simply want to create category pages that show the products in that category, with a friendly URL, e.g.:

/products/my-category-name

I'm not expecting anyone to explain the full process, but I'm hoping someone has **a link to a decent guide/tutorial** as so far hours of Googling hasn't uncovered anything.

The official Commerce documentation goes into making search pages and using facades and filters, but I don't need anything that complicated.

# Answer
The easiest way to do this is just create a view using a page display if you did not know you can use dynamic replacement in your views page urls

aka "This view will be displayed by visiting this path on your site. You may use "%" in your URL to represent values that will be used for contextual filters: For example, "node/%/feed". If needed you can even specify named route parameters like taxonomy/term/%taxonomy\_term" - copied direct from views (page) PAGE SETTINGS - path.

so you would set the path to be "/products/%taxonomy\_term"

then in views "ADVANCED", CONTEXTUAL FILTERS you would add taxonomy term filter you can look at "yoursite.com/admin/structure/views/view/taxonomy\_term" . for a better idea on how to do this...

if all this sounds hard please look into creating filters: example https://www.youtube.com/watch?v=aVwclF9TfBo

NOTE: this will use the term\_id as there is no default filter for term name if you want to use the term name ... then follow https://evolvingweb.ca/blog/how-create-custom-views-argument-plugin-drupal-8

**or In a nutshell with no code:**

1. Add a new field to your term and call it `URL To Access` of type plain text and make it required. Edit your terms and in the `URL To Access` field you would enter for a example "t-shirt" or "pants" or "what-ever-you-are-selling".
2. On your product type add the term reference field such as "Category"
3. Edit products to make sure they have a value for the "Category" field
4. Make New View of type product with page display and url "/products/%"
5. Add RELATIONSHIPS of the field "Category" and require that relationship
6. Add a CONTEXTUAL FILTER for the field field `URL To Access`. Inside the settings do the followin:
a From the 'WHEN THE FILTER VALUE IS NOT IN THE URL' section
b Click on 'Provide default value'
c Then from the 'Type' dropdown select "Raw value from URL"
d And from the 'Path component' dropdown select "2"

then save it.

You can now go to : `/products/t-shirt` and see the products under this category.
> 3 votes

---
Tags: 8, commerce
---


# Question
Title: Unclickable Menu link keeps refreshing my page
Hello and sorry for my bad English. I am using Drupal 8 and i want to make a menu with categories. The menu title has to be CATEGORIES and when someone click on it, the menu has to show the categories with a drop down. So i've created categories. Then i created a menu called - CATEGORIES and i marked "show as expanded". In the menu link i added - "**`route:<nolink>`**" . So now i have Categories menu with drop down listing categories, but when i click on it, the page is refreshed. I dont whant the page to be refreshed everytime i click on CATEGORIES. I just want to show me the drop down and not refreshing the page... I am using this theme https://www.drupal.org/project/news\_zymphonies\_theme and if you click on Live demo you can see in main navigation the menu link - "LAYOUT". When you click on it, the menu shows 2 categories - "two sidebar" and "left , right". In my case when i click on LAYOUT will show me this two categories but it will refresh the page too and i dont want to refresh it. How to fix that? Please help me i've readed so many topics and didn't find a solution :(

# Answer
Ok, i've solved the problem for now. I've just typed `##` in "CATEGORIES" link instead of one `#`. Now when i click on CATEGORIES, the page is not refreshing and a drop down menu appears.
> 0 votes

---
Tags: navigation
---


title: Create a link using the render API

text:
# Question
Title: Create a link using the render API
Back in Drupal 7, I was able to create a link (Ajax enabled) like this:

```
$page['profile']['links']['videos'] = array(
        '#type' => 'link',
        '#title' => t('Videos'),
        '#href' => 'profile/videos/' . $uid . '/nojs',
        '#attributes' => array('class' => array('use-ajax', 'profile-button-videos')),
        '#prefix' => '<div class="profile-bio-link button-profile button-profile-video">',
        '#suffix' => '</div>',
      );

```

Though there are plenty of examples about how to create a link from a URI, or external URL; and how to attach attributes, I can't find a shred of documentation on how to append something as simple as "nojs" on the end of the URL...

My code so far is this in Drupal 8 (and it works). But, it lacks the /nojs on the end.

Note: I an not using the the Forms API; strictly Render Elements.

```
$url = Url::fromRoute('people.profile', ['uid' => $uid]);
    $render_array['people']['bio'] = [
      '#title' => $this->t('Publications link'),
      '#type' => 'link',
      '#url' => $url,
      '#attributes' => array('class' => array('use-ajax', 'profile-button-bio')),
    ];

```

The end result should be a link that looks something like this:

> /profile/publications/{uid}/nojs

# Answer
You will not be able to use a route, as /no-js would be its own route. Instead, you should use Url::fromUri. You should be able to use:

```
Url::fromUri('internal:/profile/publications/' . $user->id() . '/nojs');

```
> 2 votes

---
Tags: 8
---


# Question
Title: Manipulate a render array in hook_node_view
I'm wanting to modify the contents of some fields at display time so looked at `hook_node_view()`, however, the `$build` array is not what I'm expecting, if I dump it with `var_dump` it is thousands of lines long and not in the format I'm expecting a render array to be, it includes all sorts of exciting things like SQL connection objects which are of no use to me but there is no obvious set of elements that I'd be expecting to see given the Drupal documentation. If I drill down the array, I can find the data I need, however, I can't see how to get this sorted in the correct display order.

If I add a simple tweak like

```
$build['title'] = ['#markup' => "Hello World"];

```

the node title is rendered correctly as the new value so I know I'm roughly in the right place.

Question, how can I get at the fields collection after extraction from the database and sorting into display order but before it hits the template as I need to be able to make changes at this point as future development will require potential output via differing templates.

# Answer
## Suggestions

* Get the node from the `$build` (it should be in there somewhere) and build custom content for your field like `$build['custom_field'] = [...]`.
* Override the twig template for the field - this will let you alter the presentation of a particular field. Ex: implement `node--field-custom-field.html.twig` based on `field.html.twig` and alter the output of the field there.
* Override the twig template for the entire node. Ex: implement `node--article.html.twig` based on `node.html.twig` and alter the output of the node there.

Let me know if any of these helps. More details on exactly what or why you want to alter stuff will be helpful.
> 0 votes

# Answer
I wrestled with this far longer than I care to admit... You're dealing with an object; you can't just write over a value in the an array (as you were attempting in the example).

Load the object, then use a method to get or set it. For example, if I were looking at a custom field on a user object, the following code would: 1. Load the object 2. Fetch the specific custom field 3. Update the specific custom field. 4. Reload the value (just to make sure it is what I think it should be)

```
//  Load user object (UID is the userid I'm interested in)
$userProfile = \Drupal\user\Entity\User::load($uid);

// Get field data from that user.
$firstname = $userProfile->get('field_user_first_name')->value;
$userProfile->set('field_user_first_name', 'Newname');
$firstname = $userProfile->get('field_user_first_name')->value;

```

'field\_user\_first\_name' is the machine name I assigned when I created the custom field
> 0 votes

---
Tags: debugging
---


title: Groups and Private File Visibiility

text:
# Question
Title: Groups and Private File Visibiility
I have created a content type Agenda - the body is paragraphs - there are two types: (1) Text and public files and (2) Private Files. The fields work properly - Anonymous cannot see Private Files. Authenticated Users can see Private files.

My issue occurs when I create group content for Agenda. Non-members can see Private Files. I cannot figure out where to go to turn this off. The paragraph Private Files is set for view for authenticated user. I cannot find in group how to change paragraph.

Any help is appreciated.

# Answer
> 0 votes
You may need to implement hook\_file\_download().

---
Tags: 8, files, paragraphs, group
---


# Question
Title: Import from feed using a selector only if it has a given XML attribute
I'm working on an import from an RSS feed that includes two types of XML `<category>` elements:

* Subject Areas, e.g. `<category>Economics | Social and Behavioral Sciences</category>`
* Keywords, e.g. `<category domain="keywords">immigration, emigration, immigrants, international migration, poverty, immigration enforcement, asylum policy</category>`

I want to import the Keywords as their own taxonomy field. I can write the YAML as follows, but it predictably imports both Keywords and Subject Areas:

```
source:
  fields:
    -
      name: keywords
      label: Keywords
      selector: 'category'
process:
  field_keywords:
    -
      plugin: explode
      delimiter: ', '
      source: keywords
    -
      plugin: entity_generate

```

How do I adjust the selector so it only pulls from the `<category>` element that includes the `domain="keywords"` attribute?

# Answer
I figured this out with the help of an XPATH cheatsheet that shows how selectors I might have written to target HTML would transfer to XPATH values.

To only pull `<category domain="keywords">` items, I can use `category[@domain="keywords"]` as my selector. The other set of `<category>` items don't have a `domain` attribute, so I pulled them separately using the selector `category[not(@domain)]`.
> 0 votes

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


# Question
Title: Clean way to programmatically add attributes to a view field entity label link
I have a View that lists entities. One of the fields is the entity label field, which is set to output a link to the entity itself. I would like to add attributes to the `<a>` tag to grab later with a jQuery plugin.

I can use `template_preprocess_views_view_field()` and `hook_views_pre_render()` to get the rendered markup and alter it there, but it's very dirty and not something I'll consider. I could also create a specific theme suggestion and field template and do it that way, but I don't want to rely on something that's potentially editable or changeable. It needs to be as generic as possible.

Is there a clean solution for this?

# Answer
Generate the scaffolding of a Views field plugin with Drupal Console

```
drupal generate:plugin:views:field

```

and put the link in the render() method generated by the command above:

```
  public function render(ResultRow $values) {
    if ($entity = $values->_entity) {
      return [
        '#type' => 'link',
        '#title' => $entity->label(),
        '#url' => $entity->toUrl(),
        '#attributes' => [
          'class' => ['foo'],
        ],
      ];
    }
  }

```

After clearing the cache you'll find the new field plugin when adding a field to the FIELDS list.
> 1 votes

---
Tags: views, 8
---


# Question
Title: How do I point to a particular installation of simplesamlphp with the simplesamlphp_auth module?
I am trying to integrate our company's SSO into our Drupal installation. As a POC to see if it even works, I have a copy of the SimpleSAMLPhp Library located at `/foo/bar/simplesamlphp`. I configured my apache vhost and the SAML configs and that's all fine for now.

Per the instructions from Acquia on this page, I tried installing the `drupal/simplesamlphp_auth` module.

```
composer require drupal/simplesamlphp_auth

```

This installed the module and as a dependency, installed *a second copy* of the `simplesamlphp` library in `vendor/simplesamlphp`. Now it looks like the module `simplesamlphp_auth` is using the installation in `vendor`.

**How do I configure this module to use the one I already placed** in `/foo/bar/simplesamlphp`? There doesn't seem to be any options on the page `/admin/config/people/simplesamlphp_auth`.

I have configuration files that I would like to avoid copying over to the `vendor` directory after each deployment if possible, since that's not as secure as keeping the configs outside of the project altogether.

**EDIT 1**

Clarification on the configuration files: I need to define configuration files in `/foo/bar/simplesamlphp/config` in order for it to work. These configuration files are missing from `vendor/simplesamlphp/config` and without them the application encounters a fatal error. As stated in the Acquia document above, the library lives outside of `vendor/` or `docroot/` in their setup.

# Answer
> 1 votes
You can just create a symlink to your temporary SAML folder

```
ln -s /foo/bar/simplesamlphp ./simplesaml

```

In settings.php add next line:

```
$settings['simplesamlphp_dir'] = '/foo/bar/simplesamlphp';

```

In config.php file in your /simplesamlphp/config library add following settings:

```
// Load necessary environmental data
$ps = json_decode($_SERVER['PRESSFLOW_SETTINGS'], TRUE);
$host = $_SERVER['HTTP_HOST'];
$db = $ps['databases']['default']['default'];

// Define basic variables
$config = array (
   'baseurlpath' => 'https://'. $host .':443/simplesaml/', // SAML should always connect via 443
   'certdir' => 'cert/',
   'loggingdir' => '/files/private/log/',
   'datadir' => 'data/',
   'tempdir' => '/tmp/simplesaml',
   'store.type' => 'sql',
   'store.sql.dsn' => 'mysql:host='. $db['host'] .';port='. $db['port'] .';dbname='. $db['database'],
   'store.sql.username' => $db['username'],
   'store.sql.password' => $db['password'],
);

```

Now if you open your-site.com/simplesaml url in the browser, /foo/bar/simplesamlphp library will be used instead of vendor folder.

---
Tags: 8, composer
---


# Question
Title: Any advantage to using Profile2 module vs. custom user account fields?
I'm trying to decide if I should bother messing with the Profile2 module. I need my users to have information like a real name stored and made available for other uses, but I'm not sure if there is an advantage to using the Profile2 module, or if I should just create custom user account fields for whatever I need.

# Answer
The Profile2 module is only good if you need more then 1 type of profiles. For example: \- a student profile, with certain fields. \- a teacher profile, with different fields.

If you don't need different types, just stick with the custom user account fields.

Hope this helps!
> 16 votes

# Answer
There are a few other things that you could take advantage of if profiles are nodes, for example, keep track of the number of page views to a profile. Or you could use node revisions.
> 3 votes

# Answer
When needing private fields you can use http://drupal.org/project/profile2 too.

Or stick with custom user account fields and and http://drupal.org/project/field\_permissions module which complicates configuration.
> 1 votes

# Answer
I don't have enough reputation to add comment. So, adding in answer. I am looking for the same functionality as #dimitril mentioned here. I saw Profile2 Module. I am using Drupal-7 and profile2 is deprecated for Drupal 7. So, can I still use Profile2 module? or is there any other way?

I wanted to hide edit profile page for user role students, so that they can't change the password.

Appreciate your help!

Thank you!
> 0 votes

# Answer
Disagree that the only use case is if you need multiple profile types.

Use Profile2 if you want to allow other users to view a user's profile but not his account information. you can create a separate page for the public profile and keep sensitive information in the user fields.
> 0 votes

# Answer
Another reason might be resource load. If you have a 100 fields and you load 20 users, that's a lot of data to get. If you split that in multiple profiles, you only need to load the profile that contains the relevant data.
> 0 votes

---
Tags: users
---


# Question
Title: Change checkboxes in a node edit form alter
I have a problem with an ajax function which doesn't work properly and I don't understand why. I done a similar thing long time ago in Drupal 7 and it seems I forget how it works.

I have a node type with terms references, a type and options. In the node edit, the selection for the type is a select list and for options it's a list of checkboxes. In function of this type, I want only show related options to my user.

Here my code:

```
function my_module_form_my_content_type_node_form_alter(&$form, &$form_state) {
  $form['field_options']['#prefix'] = '<div id="options-choice">';
  $form['field_options']['#suffix'] = '</div>';
  $form['field_types']['#ajax'] = [
    'callback' => 'ajax_options_choice',
    'wrapper' => 'options-choice',
    'method' => 'replace',
    'effect' => 'fade',
  ];
  if(isset($form_state['values']['field_types']) || isset($form['field_types'][LANGUAGE_NONE]['#default_value'][0])) {
    $type_tid = isset($form_state['values']['field_types'])? $form_state['values']['field_types']: $form['field_types'][LANGUAGE_NONE]['#default_value'][0];
    $type = taxonomy_term_load($type_tid);
    $type_option = $type->field_type_option[LANGUAGE_NONE][0]['value'];
    $bundle = "my_content_type";
    $results = db_query("SELECT nid, title FROM {node} as n inner join {field_data_field_is_$type_option} as fdf on n.nid = fdf.entity_id  WHERE n.type = :bundle AND n.status = '1' AND fdf.field_is_". $type_option . "_value = '1'", array(":bundle" => $bundle))->fetchAllKeyed(0, 1);
    $options = [];
    foreach ($results as $nid => $title) {
      $path_alias =  drupal_get_path_alias("node/$nid", "en");
      $value = '<span class="views-field views-field-title"> <span class="field-content"><a href="' . $path_alias. '">' . $title . '</a></span> </span>';
      $options[$nid] = $value;
    }
    $form['field_options'][LANGUAGE_NONE]['#options'] = $options;
  } else {
    $form['field_options'][LANGUAGE_NONE]['#options'] = [];
  }
}

function ajax_options_choice(&$form, &$form_state) {
  return $form['field_options'];
}

`

```

When I edit a content which have already a type, options are correctly limited. But when I change the value of the select list, the ajax doesn't seem work and options stay the same. I have no error in the firefox or chrome console so I suppose the ajax is simply not execute.

Additionnal questions: Which ways can I test the ajax works or not? Is that possible to use dpm() in the callback?

# Answer
> 0 votes
> But when I change the value of the select list, the ajax doesn't seem work and options stay the same.

Simply because there is no `db_query` logic inside the `ajax_options_choice` callback.

How is Drupal suppose to know that it needs to run again the results `db_query` and then assign it to `#options`?

So essentially, currently, AJAX is executing, but you're just returning the same value that was calculated on initial page load.

---

> Which ways can I test the ajax works or not?

```
function ajax_options_choice(&$form, &$form_state) {
  drupal_set_message('Yes AJAX was called');
  dpm('yay dpm works!');
  watchdog('my_module', 'ajax was fired', array(), WATCHDOG_NOTICE); // now check /admin/reports/dblog
  return $form['field_options'];
}

```

---
Tags: 7, forms, ajax
---


title: Order relationship in RESTful

text:
# Question
Title: Order relationship in RESTful
I'm using https://www.drupal.org/project/restful module. I can sort base entity using annotation:

```
/**
 * Class Things__1_0
 * @package Drupal\restful_thing\Plugin\resource\node\thing
 *
 * @Resource(
 *   name = "things:1.0",
 *   resource = "things",
 *   label = "things",
 *   description = "Export the things with all authentication providers.",
 *   authenticationTypes = TRUE,
 *   authenticationOptional = TRUE,
 *   dataProvider = {
 *     "entityType": "node",
 *     "bundles": {
 *       "course"
 *     },
 *     "sort" = {
 *       "field_weight": "ASC"
 *     },
 *   },
 *   majorVersion = 1,
 *   minorVersion = 0
 * )
 */

```

But when it comes to relationship, the related data isn't ordered the way I need.

Inside `public_fields()`:

```
$public_fields['modules'] = array(
  'property' => 'field_modules',
  'resource' => array(
    'name' => 'modules',
    'fullView' => TRUE,
    'majorVersion' => 1,
    'minorVersion' => 0,
    'dataProvider' => array( //here I'm trying to override dataProvider values
      'sort' => array(
        'field_weight' => 'ASC'
      )
    )
  )
);

```

Is there any way to sort related data?

---edit---

I've also placed "sort" inside the annotation of the modules plugin, but It doesn't have effect too.

# Answer
I've resolved the sorting problem with sorting data inside the formatter. Here's my code in case someone had similar problems.

```
<?php

/**
 * @file
 * Contains \Drupal\restful\Plugin\formatter\OrderFormatter.
 */

namespace Drupal\my_module\Plugin\formatter;

use Drupal\restful\Plugin\formatter\FormatterJson;
use Drupal\restful\Plugin\formatter\FormatterInterface;

/**
 * Class OrderFormatter
 * @package Drupal\restful\Plugin\formatter
 *
 * @Formatter(
 *   id = "order_formatter",
 *   label = "ORDER FORMATTER",
 *   description = "Output filtered data",
 *   curie = {
 *     "name": "dis",
 *     "path": "doc/rels",
 *     "template": "/{rel}",
 *   },
 * )
 */
class OrderFormatter extends FormatterJson implements FormatterInterface {

  /**
   * Content Type
   *
   * @var string
   */
  protected $contentType = 'application/json+sort; charset=utf-8';

  /**
   * {@inheritdoc}
   */
  public function render(array $structured_data) {
    $i=0;
    foreach ($structured_data['data'] as $v) {

      $structured_data['data'][$i]['unsortedThings'] = $this->sortBy($structured_data['data'][$i]['unsortedThings']);
      $i++;
    }
    return drupal_json_encode($structured_data);
  }

  public function sortBy($arr) {
    $results = [];
    foreach ($arr as $k=>$v) {
      $results[$k] = $v['weight']; //this is my sorting field
    }
    asort($results, SORT_REGULAR);

    foreach (array_keys($results) as $key) {
      $results[$key] = $arr[$key];
    }
    $results = array_values($results);
    return $results;
  }

}

```

You run this formatter by adding header to your request: `Accept: application/json+sort; charset=utf-8`
> 0 votes

---
Tags: 7, services
---


# Question
Title: PHP evaluation for "Send HTML email body"
I'm trying to compose the body of an email using PHP evaluation within a rule. The rule is triggered when a new content is saved. Part of the email body is composed using HEREDOC and that works fine. This is the code I'm having trouble with:

```
//  Provide download link.
 if ($node->field_software_product_sku === "Some Product Name")
     echo "<a href=\"http://www.mywebsite.com/Some Product Name/some.exe\">Trial Version Download Link</a><br />";

```

The above code comes directly after the ending of the HEREDOC, but, before the closing '**?\>**'. I anticipate that in the future, I will need to add more clauses to the 'if' statement, so, it's important that I get this to work.

I've tried several different incantations for coding the 'if'. I've tried using the token name enclosed in single quotes. And, I've tried using “==” instead of “===”. The only thing that seems to work consistently is commenting out the 'if'. Then, the “*Trial Download Link*” text does appear in the email. Unfortunately, the rule is to be used for multiple “skus”, so, I need to use the 'if'.

I'm hoping I've made a subtle mistake, or, overlooked something.

Can someone point me in the right direction?

Is there a way to debug the code to see why the 'if' may be failing?

# Answer
If `field_software_product_sku` is text field you should test on value of the field something like:

```
if ($node->field_software_product_sku[LANGUAGE_NONE][0]['value'] === "Some Product Name"){
    echo "<a href=\"http://www.mywebsite.com/Some Product Name/some.exe\">Trial Version Download Link</a><br />";
  }

```

other ways if it doesn't work, i suggest you to use Devel Module and dump the `$node->field_software_product_sku` using dpm function to see the value of the field:
`dpm($node->field_software_product_sku)` and then check on the value of the field.
> 1 votes

---
Tags: 7, rules, emails
---