# Question
Title: How to expose the user's email on the user's detail page?
Currently in the manage display page there is no way to display the email field in the manage display page. How do you expose this in Drupal 8 contacts details page?

There can be a work around for this as in user template or views-block rendering on profile page.

# Answer
> 0 votes
Simply with no code required use Show Email Address

# Answer
> 8 votes
By default the mail field is not configurable in view modes.

You can change this in a custom module. Place this hook in **mymodule.module**

```
function mymodule_entity_base_field_info_alter(&$fields, $entity_type) {
  if ($entity_type->id() == 'user') {
    if (isset($fields['mail'])) {
      $fields['mail']->setDisplayConfigurable('view', TRUE);
    }
  }
}

```

and you'll find the mail field in the *Manage Display* page.

# Answer
> 1 votes
There is not a direct way through "Manage Display" but a workaround through user.html.twig in your theme.

We get {{ user }} variable which can be accessed to get other values related to the user.

**Code** -

\`

```
<div class="col-sm-12">
      <header>
        <h2> My Profile </h2>
      </header>
      <div class="row">
        <div class="col-sm-8">
           <h4>About Me</h4>
           <ul class="profile-list">
              <li> Email:  {{ user.mail.value }}  </li>
              <li> Name:  {{ user.name.value }}  </li>
           </ul>
        </div>
      </div>
</div>

```

\`

# Answer
> -1 votes
I assume the reason this wasn't added was to encourage use of the Contact form instead (given email addresses are hidden, there's flood protection and you can allow users to enable/disable it). However, clearly there are reasons for it being convenient to see the actual address.

(Do take time to check your permissions for user profile pages though, so you're not exposing people to spam.)

Here's a modified `user.html.twig`, using *classy* as the base theme, with clickable address and a translatable string for the label:

```
<article{{ attributes.addClass('profile') }}>
  {% if content %}
    <div class="field field--name-email field--label-above">
        <div class="field__label">{% trans %}Email{% endtrans %}</div>
        <div class="field__item"><a href="mailto:{{ user.mail.value }}">{{ user.mail.value }}</a></div>
    </div>
    {{- content -}}
  {% endif %}
</article>

```

---
Tags: theming, 8, users
---


# Question
Title: Add upload/processing status bar/throbber
I am new to Drupal/web development and I have been trying to create a module to add files upload menu. Once the files are uploaded, they undergo processing and a message is displayed upon completion of the process. Everything works well but I would like to add a processing progress bar/throbber from the tile Submit button is selected to when the final output is displayed. I am clueless on how to implement this. Any help is appreciated

Here's part of the code I used:

```
//Before this part of the code, there is function to create Menu ($items[])
function g_p_proc_form($form, &$form_state, $values) {
    $form['#attributes']['enctype'] = 'multipart/form-data';
    $form['filter'] = array (
        "#type" => "fieldset",
        "#title" => t("File Process <BR> "),
        "#collapsible" => TRUE,
    );
  // without this attribute, upload may fail on submit
    $form['#attributes']['enctype'] = 'multipart/form-data';
    $form['filter']['file'] = array(
        // '#title' => t('File processing'),
        '#type'  => 'file',
        '#name' => 'files[]',
        '#description' => t('Select Submit to start processing the file'),
        '#type'  => 'file'),
        '#upload_location' => 'public://',
        '#attributes' => array('multiple' => 'multiple'),
    );

    $form['filter']['submit_upload'] = array(
        '#type'  =>  'submit',
        '#value' =>  t('Submit'),

    );

    // drupal_set_message(t("in fn"));

    return $form;
}

function g_p_proc_form_submit($form, &$form_state) {
    try{
        $number_file = count($_FILES['files']['name']);
        $f_name = array();
        for ($i=0; $i<$number_file;$i++)
        {
            $file = file_save_upload($i, array('file_validate_extensions' => array('pdf PDF')), 'public://', FILE_EXISTS_REPLACE);
            $f_name[] = $_FILES['files']['name'][$i]; //[]
        }
            }catch (Exception $error){
        echo 'Exception: ',  $error->getMessage(), "\n";
    }
    $n_f = count($f_name);
    drupal_set_message(t('Number of files: !n_f', array('!number_f'=>$n_f)));
    $fn_name = 'g_p';
    $fn_call = $fn_name($f_name);
function g_p($f_name=array()){
    $curr_l = getcwd();
    chdir('My file processing PHP script location ');
    $n_f = count($f_name);
    $shell_command = shell_exec("file_processing_php_script_name.php");
    //header("Location: "Current file processing module menu site"); //Commented out
    drupal_set_message($shell_command);
    chdir($curr_l);
}

```

As it can be seen from the code, I process the files upon upload and display the output message after processing. I would like to add a throbber/processing-progress bar from the time Submit is selected to the time the output is displayed, after the files are processed. How can I achieve this? Again, please understand that I am new to web development/Drupal and am not very proficient in terms/commands used in them.

# Answer
Change from file to manager\_file and use property #progress\_indicator (by default is already set so you won't have to add it).

https://api.drupal.org/api/drupal/developer%21topics%21forms\_api\_reference.html/7.x#managed\_file
> 0 votes

---
Tags: forms, files
---


title: How do I sort paragraph types?

text:
# Question
Title: How do I sort paragraph types?
Hello it is possible to order the output of the paragraphs for example

Type of content Blog I create a blog details field that calls the type of paragraphs and there I select image and description

In my content it goes in this order

* 1 Image
* 2 Description

In the view I call that field blog details and they appear to me but based on the order of the node

But I don't want it to look like this

* 1 description
* 2 image

and always look in that order

# Answer
> 0 votes
I don't believe there's a way to sort the values of a field at the view level. However, you can easily get the results you want by creating a custom field formatter and then using it to render your field in the view.

You can read more about field formatters by reading the Create a custom field formatter documentation on d.o.

Create a custom formatter that extends the formatter you're using now. I'm guessing you're using the default ERR formatter so you'll want to extend *Drupal\entity\_reference\_revisions\Plugin\Field\FieldFormatter\EntityReferenceRevisionsEntityFormatter*.

You'll need to override *viewElements()* or *getEntitiesToView()* \- I'd override *getEntitiesToView()*.

```
protected function getEntitiesToView(EntityReferenceFieldItemListInterface $items, $langcode) {
  // Let the parent class get all entities in the field first.
  $all_entities = parent::getEntitiesToView($items, $langcode);
  $my_entities = [];

  // Get first Description paragraph.
  $desc = $this->getFirstOfType($all_entities, 'MY_DESCRIPTION_BUNDLE');
  if (!empty($desc)) {
    $my_entities[] = $desc;
  }

  // Get first Image paragraph.
  $img = $this->getFirstOfType($all_entities, 'MY_IMAGE_BUNDLE');
  if (!empty($img)) {
    $my_entities[] = $img;
  }

  return $my_entities;
}

protected function getFirstOfBundle($entities, $bundle) {
  foreach($entities as $entity) {
    if ($entity->bundle() == $bundle) {
      return $entity;
    }
  }

  return FALSE;
}

```

---
Tags: views, paragraphs
---


title: How to correct a view query?

text:
# Question
Title: How to correct a view query?
I would like to know how to correct a view query, when Drupal goes nuts ?

I'm using a view that should list media by categories (taxonomy term). This view is called by a node, that held a reference to the same categories (same taxonomy term) that the medias I wish to display.

I need to order thos categories according to the delta field on my node object.

So in my views I did a join from the media taxonomy field to the taxonomy terms. Then, I have a join on my any node that hold the taxonomy field. I filter on the nid through contextual filters.

Until then all is good.

However, if I add the sort Critera on the delta value of categorie, the views module add another (unnecessaray) join on the table holding data for my taxonomy field on my node. This confuses my database and then I get a scalar product as results (every media is sent back, for each existing delta line).

Exemple of the query (I get two joins on **node\__field\_categorie**) :

```
    SELECT DISTINCT field_categorie_taxonomy_term_field_data__node__field_categorie.delta AS field_categorie_taxonomy_term_field_data__node__field_catego, media_field_data.mid AS mid, taxonomy_term_field_data_media__field_standard_termref_1.tid AS taxonomy_term_field_data_media__field_standard_termref_1_tid, field_categorie_taxonomy_term_field_data.nid AS field_categorie_taxonomy_term_field_data_nid
FROM
{media_field_data} media_field_data
LEFT JOIN {media__field_standard_termref_1} media__field_standard_termref_1 ON media_field_data.mid = media__field_standard_termref_1.entity_id AND media__field_standard_termref_1.deleted = '0'
INNER JOIN {taxonomy_term_field_data} taxonomy_term_field_data_media__field_standard_termref_1 ON media__field_standard_termref_1.field_standard_termref_1_target_id = taxonomy_term_field_data_media__field_standard_termref_1.tid
INNER JOIN {**node__field_categorie**} taxonomy_term_field_data_media__field_standard_termref_1__node__field_categorie ON taxonomy_term_field_data_media__field_standard_termref_1.tid = taxonomy_term_field_data_media__field_standard_termref_1__node__field_categorie.field_categorie_target_id AND taxonomy_term_field_data_media__field_standard_termref_1__node__field_categorie.deleted = '0'
INNER JOIN {node_field_data} field_categorie_taxonomy_term_field_data ON taxonomy_term_field_data_media__field_standard_termref_1__node__field_categorie.entity_id = field_categorie_taxonomy_term_field_data.nid
LEFT JOIN {media__field_domain} media__field_domain ON media_field_data.mid = media__field_domain.entity_id AND media__field_domain.deleted = '0' AND (media__field_domain.langcode = media_field_data.langcode OR media__field_domain.bundle = 'useful_document')
LEFT JOIN {**node__field_categorie**} field_categorie_taxonomy_term_field_data__node__field_categorie ON field_categorie_taxonomy_term_field_data.nid = field_categorie_taxonomy_term_field_data__node__field_categorie.entity_id AND field_categorie_taxonomy_term_field_data__node__field_categorie.deleted = '0'
WHERE ((media_field_data.status = '1') AND (media_field_data.bundle IN ('useful_document'))) AND (media__field_domain.field_domain_target_id LIKE 'intranet_adapei69' ESCAPE '\\')
ORDER BY field_categorie_taxonomy_term_field_data__node__field_catego ASC

```

Exemple of my view, so you can better understand.

How can I correct such a query ? I'm using Drupal 8.7.12 and can't upgrade for the moment. I guess the easier way around this would be to be able to add an order by clause using the column made available by my first join on : node\__field\_categorie

I looked into query\_alter and views\_query\_alter hooks, but it seems it is no longer possible to add an order by clause there (or I tried the wrong way). Any ideas ?

# Answer
Finally, I found how to do it. I don't understand why I got lots of errors previously.

```
 function sully_ad_import_views_query_alter(ViewExecutable $view, QueryPluginBase $query) {
if ($view->id() == 'document_list' && in_array($view->current_display,array('block_1','block_3'))) {

  $query->addField(
    'taxonomy_term_field_data_media__field_standard_termref_1__node__field_categorie',
    'delta',
    'delta'
  );
  $query->addOrderBy(
    NULL,
    NULL,
    'asc',
    'delta'
  );

}

```

}
> 1 votes

---
Tags: views
---


title: Alter Header Status Response to 410

text:
# Question
Title: Alter Header Status Response to 410
I have several urls with "/tag/" string; some of them have content and some of them don't, so they return 404.

How can I force them to return a 410 only for those that have no content?

I need a filter: has "/tag/" in URL and returns 404 -\> redirect to 410.

I tried in theme\_preprocess\_html(&$variables) like this:

```
if ($pattern2){ //it has "/tag/" string
      $status = \Drupal::requestStack()->getCurrentRequest()->attributes->get('exception');
      if ($status && $status->getStatusCode() == 404){
          $response = new Response();
          $response->setStatusCode(410);
          return $response;
      }
}

```

It filters is working but nothing it's not redirecting to 410.

Thank you for your help!!

# Answer
Yes, definitely higher up. When you are already inside of a 404 subrequest it is too late.

You could put the code in `on404()` of an HttpExceptionSubscriber, check the path and then replace the 404 with 410:

```
$event->setException(new HttpException(410));

```

See https://drupal.stackexchange.com/a/231263/47547
> 5 votes

---
Tags: 8, redirection, http-request
---


# Question
Title: Module Uninstall Validators and Lazy Services
I have recently been working on creating functionality for a module that requires certain content related to the module be deleted before the module itself can be uninstalled. https://www.drupal.org/project/commerce\_pos/issues/3006353

I used an example for core's book module where I saw that a service called module\_install.uninstall\_validator and a ProxyClass called BookUninstallValidator were used in order to implement functionality similar to what I was attempting to achieve.

My question is thus: why is the module\_install.uninstall\_validator set to lazy and what exactly is a proxy class?

I have searched in the documentation but have been unable to find any useful explanation; so any here or links to such pages would be much appreciated.

# Answer
> 2 votes
It's a property of services classes provided by Symphony's dependency injection framework. Per its docs on lazy services:

> In some cases, you may want to inject a service that is a bit heavy to instantiate, but is not always used inside your object. For example, imagine you have a NewsletterManager and you inject a mailer service into it. Only a few methods on your NewsletterManager actually use the mailer, but even when you don’t need it, a mailer service is always instantiated in order to construct your NewsletterManager.

In other words, proxy classes are quick-loading dummy stand-ins until the actual class methods are needed to do the heavy lifting. In this specific case, the Book uninstall validator isn't useful until it's needed during the book module uninstall so there's no need to fully instantiate the validator service.

---
Tags: services, installation, proxies
---


# Question
Title: How to rename a content type programmatically
There are many answers and tutorials addressing the problem of changing the machine name of a content type, or migrating content types. However, I would like to rename a content type, without changing the machine name. This is what I tried:

```
$type = node_type_load('my_content_type');
$type->name = 'A new name';
node_type_save($type);

```

But this has no effect. What is the proper way to do this?

# Answer
> 0 votes
Looking back on this after a year, I can't reproduce my own problem. This code works, even for content types defined by modules, not created through the UI:

```
$type = node_type_load('my_content_type');
$type->name = 'A new name';
node_type_save($type);

```

---
Tags: 7, nodes
---


# Question
Title: With managed file, dynamically set fileName and #upload_location
In a form I want to bulk upload jpgs renaming them using exif date information and **dynamically setting** the #upload\_location according to the value of a textfield in the same form.

I have no problem with accessing the exif date information. What I don't know how to do, is dynamically set the file name and file path (actual location on the server) programmatically.

This is my form upload element:

```
$form['images'] = array(
  '#type' => 'managed_file',
  '#multiple' => TRUE,
  '#upload_validators' => array(
    'file_validate_extensions' => array('jpg'),
  ),
  '#upload_location' => 'public://photos',
  '#required' => TRUE,
);

$form['file'] = [
  '#type' => 'fieldset',
  '#title' => $this->t('File'),
];

$form['file']['name'] = [
  '#type' => 'textfield',
  '#title' => $this->t('File name'),
  '#description' => $this->t(
    'Is suffixed by the exif creation date-time plus fid cleaned for urls. If not set the original file name will be used.'
  ),
];

$form['file']['path'] = [
  '#type' => 'textfield',
  '#title' => $this->t('File path'),
  '#placeholder' => 'path/to/directory',
  '#description' => $this->t(
    'Path to the files sub-directory, default is "photos". Sub-dirs will be create if necessary.'
  ),
];

```

I've tried using something like this in both validateForm() and submitForm().

```
$images = $form_state->getValue('images');
$file = File::load( $images[0] );
$file->setFileName("xxx2");
$file->setFileUri("public://photos/test/xxx2.jpg");

```

Although this changes the values of the $file object, it doesn't change the real path. The jpg files are also still in /sites/default/files/photos/ with their original name plus a unique counter.

So to repeat my question: How can I set the upload\_location and the fileName of a managedFile **dynamically and programmatically** in a submitForm() or validateForm() function using methods that are not marked deprecated in drupal 8.

# Answer
Thanks @Clive. I just read your comment, but in the mean time I found the answer myself. This is the essentials of my code in my submitForm() method. It still seems a bit hacky to me but it works.

```
$images = $form_state->getValue('images');
$file = File::load( $images[0] );

$file->setPermanent();
$file->save();

$new_filename = "photos/test/test-02.jpg";
$stream_wrapper = \Drupal::service('file_system')->uriScheme($file->getFileUri());
$new_filename_uri = "{$stream_wrapper}://{$new_filename}";

file_move($file, $new_filename_uri); // <===== The essential line!

$file = File::load( $images[0] );
dpm($file->getFilename()); // returns test-02.jpg
dpm($file->getFileUri());  // returns public://photos/test/test-02.jpg

```
> 3 votes

---
Tags: 8, forms, files
---


# Question
Title: Override remove entities link on module uninstall page
When a module needs to be uninstalled, Drupal adds links indicating there is content associated with the module which should be deleted first and provides a link Remove module\_name entities. This works fine for most modules, however we have a complex module that needs to perform clean up, is there a way to override this link and have it invoke a custom entity deletion method?

In our case the Remove links that are automatically added to the module uninstall page, don't end up cleaning all items, and leave the site in bad state.

Possibly related to this question asked earlier "How to remove custom module provided entity instances by the time the module being uninstalled?"

# Answer
If you're solely looking to *alter* those messages & links, you *could* to override the `required_module_uninstall_validator` service with a custom class that extends `ContentUninstallValidator` and alters its `validate()` method:

```
// In your ContentUninstallValidator child class
public function validate($module) {
  $reasons = parent::validate($module);
  // @TODO find/alter the message & link relevant to the module
  return $reasons;
}

```

However, you'll have to deal with the issue of searching through messages and being able to find the string relevant to the module. This could be problematic depending on how you're searching through the messages array.

A better approach might be to add *new messages* via a new uninstall validator service that can provide its own custom messages & links that will initiate your own custom entity cleanup code.

A good working example can be seen in the book module:

```
      book.uninstall_validator:
        class: Drupal\book\BookUninstallValidator
        tags:
          - { name: module_install.uninstall_validator }
        arguments: ['@book.outline_storage', '@entity_type.manager', '@string_translation']
        lazy: true

```

```
    public function validate($module) {
      $reasons = [];
      if ($module == 'book') {
        if ($this
          ->hasBookOutlines()) {
          $reasons[] = $this
            ->t('To uninstall Book, delete all content that is part of a book');
        }
      }
      ...
      return $reasons;
    }

```
> 0 votes

---
Tags: 8, entities
---


# Question
Title: save views->execute result as a static variable
Does it make sense (performancewise) to store view-\>execute() as a static variable in order to avoid running same view multiple times?

And then call view-\>render() wherewer I want to print the view? Does it make any sense? Or are there better options? Thank you

# Answer
It heavily depends on what you're trying to achieve with caching.

If you're trying to avoid additional DB queries, you won't be adding much here. The `view::execute()` & `view::render()` are already making use of its own caching system (if it's enabled on the view in question).

If you're trying to avoid all the theme/module hook execution overhead, yeah that will avoid it. Of course, the trade-off is modules/themes won't be able to modify a view (if that's needed) and you'll have to handle other cache invalidation scenarios as a result of your custom caching.

You'll have to make the call depending on how/what you're trying to optimize it that's worth the trade-off (generally, I would say no but that's opinion).
> 0 votes

---
Tags: 7
---


title: Class 'Mpdf\Mpdf' not found

text:
# Question
Title: Class 'Mpdf\Mpdf' not found
I am trying to download content in pdf.

I have done composer require mpdf/mpdf

Then in my code I have used the following:

```
use \Mpdf\Mpdf;

$mpdf = new Mpdf();

$filename = 'file.pdf';

$mpdf->Output($filename, 'D');

```

But I am getting error Class 'Mpdf\Mpdf' not found in Drupal. Following some blogs I have tried using

```
$mpdf = new mPDF()

```

But the error still persists. Please help.

# Answer
> 1 votes
I was not running composer require mpdf/mpdf in the Drupal root directory. Hence the error. Now it is resolved.

---
Tags: 8
---


title: How does generateFromLink work?

text:
# Question
Title: How does generateFromLink work?
How the **generateFromLink** method works ? And how to use it in the render array. What is the difference between this method and the other methods used to generate link ?

```
$url = new Url('test_route_1');

$link = new Link('Test', $url);

$generated_link = \Drupal::service('link_generator')->generateFromLink($link);

```

# Answer
> 1 votes
You shouldn't use this service because it is marked as internal and you shouldn't use any other method to generate links in custom code. Generating a link is like early rendering. See https://www.lullabot.com/articles/early-rendering-a-lesson-in-debugging-drupal-8

Instead add the link as render element to the build array.

Like this examples which also demonstrates how you can build nested render elements, here an image as link title:

```
      $link_title = [
        '#theme' => 'image',
        '#uri' => $image,
        '#alt' => $label,
      ];
      $image_link = [
        '#type' => 'link',
        '#title' => $link_title,
        '#url' => Url::fromUri($link_href),
        '#options' => [
          'attributes' => ['class' => ['feed-image']],
        ],
      ];

      $build[$id]['image'] = $image_link;

```

Example from */core/modules/aggregator/src/FeedViewBuilder.php*

---
Tags: 8
---


# Question
Title: Why does include() call PublicStream::stream_set_option()?
I am including a PHP file that in stored in the public:// directory.

(Yes, I know that's generally a bad thing, but there are reasons, and this is done on a local development server.)

I get this warning.

> User warning: stream\_set\_option() not supported for local file based stream wrappers in Drupal\Core\StreamWrapper\LocalStream-\>stream\_set\_option() (line 356 of core/lib/Drupal/Core/StreamWrapper/LocalStream.php).

I don't understand what's going on.

Why is `include()` calling `PublicStream::stream_set_option()`?

# Answer
> 2 votes
It happens with PHP 7.4, where one of the backward incompatible changes is the following one.

> When using include/require on a stream, `streamWrapper::stream_set_option()` will be invoked with the `STREAM_OPTION_READ_BUFFER` option. Custom stream wrapper implementations may need to implement the `streamWrapper::stream_set_option()` method to avoid a warning (always returning `FALSE` is a sufficient implementation).

Even with the latest code committed in Drupal 9, `LocalStream::stream_set_option()` triggers the user error you are seeing.

```
public function stream_set_option($option, $arg1, $arg2) {
  trigger_error('stream_set_option() not supported for local file based stream wrappers', E_USER_WARNING);
  return FALSE;
}

```

---
Tags: stream-wrappers
---


# Question
Title: How do I load the current items in cart of the anonymous user?
I am working on a custom module for our payment system using Drupal 8 and Commerce 2. When a user removes and item for the cart or updates the quantity, I need to sync the two systems (our internal and Drupal commerce's cart). Our site has one store and all products are associated with that store.

I need to be able to load (and loop) over all the items still in the cart after the CartOrderItemRemoveEvent and the CartOrderItemUpdateEvent events. I tried using the following code, but the order is an empty array, despite the cart still having other items in it.

```
$user = \Drupal\user\Entity\User::load(\Drupal::currentUser()->id()); //Which is 0 for anonymous
$order = \Drupal::entityTypeManager()->getStorage('commerce_order')->loadByProperties(['uid' => $user->get('uid')->value, 'cart' => '0']);

```

Is there a way to get the anonymous user's cart and a list of items still in that cart?

//updated

```
 public function cartItemRemoved(CartOrderItemRemoveEvent $event) {
      $cart_provider = \Drupal::service('commerce_cart.cart_provider');
      $cart = $cart_provider->getCart('default');
      $order_items = $cart->order_items->referencedEntities();
    \Drupal::logger('current cart items')->info('<pre><code>' . print_r(json_encode($order_items), TRUE) . '</code></pre>');

}

```

# Answer
> Get the current anonymous user's cart

```
  $cart_provider = \Drupal::service('commerce_cart.cart_provider');
  $cart = $cart_provider->getCart('default');

```

> Get a list of items still in that user's cart

```
$order_items = $cart->order_items->referencedEntities();

```

---

### Bonus

```
$cart_manager = \Drupal::service('commerce_cart.cart_manager');

```

Update order item

```
$cart_manager->updateOrderItem($cart, $order_item);

```

Remove order item

```
$cart_manager->removeOrderItem($cart, $order_item);

```

Empty cart

```
$cart_manager->emptyCart($cart);

```

Create order item

```
$order_item = $cart_manager->createOrderItem($entity, $quantity);

```

Add order item

```
$cart_manager->addOrderItem($order_item);

```
> 1 votes

---
Tags: commerce
---


title: Different custom view per taxonomy

text:
# Question
Title: Different custom view per taxonomy
I'm currently working on my first Drupal 8 project and while many things are now integrated in the core, others still stump me (for example restoring options to now bare bones CKEditor requires like 4 additional modules). As I relied on Taxonomy Display module to display different taxonomies with different views and this module is not ported to D8 while similar module TVI is still in beta, I am left wondering what's the current standard of handling this use case. I could use template\_preprocess\_views\_view to programatically switch displays depending on vid. Some suggested you can just use contextual filters to do the same, but I don't see how could you switch between different displays using contextual filters. To me it seems that multiple views would run at once, but some would return empty result sets, spamming database with duplicated queries. Is there really no cleaner way to do it?

# Answer
> 0 votes
You can use the option `Specify validation criteria` of the Contextual filter to restrict your Views display to one or more Vocabularies, as you've heard before.

Then clone the display and do the same for different combinations of Vocabularies. You can change the path of each new page to avoid conflicts between different Views and calling multiple queries.

I don't know how Taxonomy display module works, I'm not sure if it improves performance, maybe you end up with the same performance metrics in your custom solution. The nodes still have to be matched with taxonomy in another database table, no matter which options you choose. I'm not a SQL expert, maybe someone else will be able to enlighten about the performance and how it affect Taxonomy term queries.

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


# Question
Title: Exception handling for incorrect content type for request in custom REST API plugin
I have created a custom REST API plugin for an endpoint. I have set the accepted format to json using the configuration options. This works. However, if we set the content-type to something other than application/json I am getting a 500 error.

I am seeking to know how this exception can be handled more gracefully. However, what is preventing this is the fact that I am not able to get the Request object in the plugin code.

I tried extending the default EventSubscriber services but they do not seem to be of help. I am seeing that this seems to be an open issue in Drupal.org

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

I am thinking of altering the route and set the default format to json as in manually added custom routes but open to better ways.

Any help would be appreciated.

# Answer
> 0 votes
For the record, here is how I managed to solve the issue. This is a workaround but it allows for graceful degradation.

1. I created an event subscriber that extends HttpExceptionSubscriberBase
2. There is an onException method that retrieves the event that generated the exception
3. From the event, we can get the request type and handle the exception.
4. By overriding the method we can handle this exception

```

class MyClassService extends HttpExceptionSubscriberBase {
public function onException(GetResponseForExceptionEvent $event) {
    $exception = $event->getException();

    // Make the exception available for example when rendering a block.
    $request = $event->getRequest();
    $request->attributes->set('exception', $exception);

    $handled_formats = $this->getHandledFormats();
    $format = $request->query->get(MainContentViewSubscriber::WRAPPER_FORMAT, $request->getRequestFormat());
    if ($exception instanceof HttpExceptionInterface && (empty($handled_formats) || in_array($format, $handled_formats))) {
      $method = 'on' . $exception->getStatusCode();
      // Keep just the leading number of the status code to produce either a
      // on400 or a 500 method callback.
      $method_fallback = 'on' . substr($exception->getStatusCode(), 0, 1) . 'xx';
      // We want to allow the method to be called and still not set a response
      // if it has additional filtering logic to determine when it will apply.
      // It is therefore the method's responsibility to set the response on the
      // event if appropriate.
      if (method_exists($this, $method)) {
        $this->$method($event);
      }
      elseif (method_exists($this, $method_fallback)) {
        $this->$method_fallback($event);
      }
    }
    // We are now assuming that this a special RuntimeException
    // where the Content-type header is not set to json or missing.
    if ('json' != $request->getContentType()) {
      if (method_exists($this, 'on415')) {
        $this->on415($event);
      }
    }
  }

public function on415(GetResponseForExceptionEvent $event) {
    $method_exception = [];
    $method_exception['message'] = 'Missing or unsupported Content-Type request header.';
    $response = new JsonResponse($method_exception, 415);
    $event->setResponse($response);
}

```

---
Tags: 8
---


# Question
Title: Add extra custom permissions to Field Permissions
I'm using Field Permissions module to restrict access to each field.

If you choose `custom permission` on `/admin/structure/types/manage/CONTENT_TYPE/fields/FIELD_NAME`, you'll see these permissions are available:

* Enter own value for field \[FIELD\_NAME\]
* Edit own value for field \[FIELD\_NAME\]
* Edit any value for field \[FIELD\_NAME\]
* View own value for field \[FIELD\_NAME\]
* View any value for field \[FIELD\_NAME\]

I would like to add some permissions with extra conditions like 'Edit any value for field \[FIELD\_NAME\] if the field is empty'.

For D7 version of the module there was a hook called `hook_field_permissions_list_alter` but there's no such thing in D8 version.

Is there any way to modify the list?

# Answer
With Drupal 8, the module implemented the permission type plugins. To add more permissions, you implement a new permission type plugin, using one of the existing plugin classes as example, such as `Drupal\field_permissions\Plugin\FieldPermissionType\CustomAccess` or `Drupal\field_permissions\Plugin\FieldPermissionType\PrivateAccess`. `Drupal\field_permissions\Plugin\FieldPermissionType\Base` is used as base class, and simplifies the creation of new permission type plugins.

Note that the module invokes the `hook_field_permission_type_plugin_alter()` implementations, as described in the field\_permissions.api.php file. That hook can just be used to remove a permission type plugin, or change the plugin properties given in its annotation (which doesn't include the permissions exposed from the plugin, for what I can see).
> 2 votes

---
Tags: 8, entities
---


# Question
Title: Get the current ProductVariation from the formElement of a custom widget in the "Add to cart" form
I've a custom field in my Order Item, i need the value of a field of my ProductVariation in the widget of my custom field. Let's say that my Variation has a "remote ID" field, when i select one of the Variation in the Add to cart form, in my custom field i've to retrieve that ID and use it to do some things. If i've only one Variation everything works great doing something like that:

```
  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
    $purchased_entity = $items->getEntity()->getPurchasedEntity();

    $my_cusrom_id = $purchased_entity->get('my_variation_field')
      ->first()
      ->getValue()['value'];
  }

```

The only problem is that if I have multiple variations, when i chose one from the select, in this code always the first one is returned from the getPurchasedEntity method, and i see no informations in $form\_state or $form of something that could be useful.

Is there a way to retrieve the selected variation from there? seems strange that's not possible...

# Answer
At the moment i ended by getting the value directly from the $\_POST, sounds a bit hacky but can't find another way to do that...
> 0 votes

---
Tags: 8, commerce
---


# Question
Title: How do I set up an entityreference entity base field to show as a link to the target entity?
I have a base field on my entity type that's an entity reference, e.g.:

```
    $fields['type'] = BaseFieldDefinition::create('entity_reference')

```

How do I set this up so it displays as a link to the target?

# Answer
```
      ->setDisplayOptions('view', [
        'label' => 'above',
        'type' => 'entity_reference_label',
        'settings' => [
          'link' => TRUE,
        ],
      ])

```

and optionally to allow it to be configured in the UI:

```
      ->setDisplayConfigurable('view', TRUE)

```
> 0 votes

---
Tags: entities, 8
---


# Question
Title: How to automatically generate anchor ids to CKEditor added headers
How can i automatically generate anchor ids to h2 and h3 added using ck editor ? I need it for making a table of content.

# Answer
in JS, id set from the h2 label two first words :

```
const headings = document.querySelectorAll(
  ".article--full h2, .article--full h3"
);
const tocElements = createTocElementsArray(headings);

function createTocElementsArray(headings) {
  const tocElements = [];
  for (const item of headings) {
    if (item.id === "") {
      item.id = item.firstChild.data
        .split(" ")
        .slice(0, 2)
        .join("-");
    }
....
}

```
> 0 votes

---
Tags: wysiwyg
---


# Question
Title: How to combine two filters in search api views?
I have a search index which is indexing both content and files.

I have configured the search api views which displays the search results.

On this view, I have a filter on type which displays the content types as links using better exposed filter.

Is there any way to add another option to the same filter `files` but clicking on it will display files in the search results only.

Is it possible? Any custom solution hint?

I have tried the combined global filter but that only works with fields not with rendered entity.

# Answer
> 0 votes
I used an aggregated field of search api. And combined the `Content: content type` and `Media: bundle` fields.

And used that field in the search api views filter.

But the filter was a text field. So to display it as links, I have created a custom views filter for that aggregated field.

---
Tags: 8, views, search
---


# Question
Title: Displaying another entity's form on a node
I am trying to embed the edit form for a flag on my node (the full page view mode).

After some struggle, I finally figured out how to get the flagging form. But once I have the form, how do I actually get it to display on the page?

```
function MYMODULE_node_view(array &$build, NodeInterface $node, EntityViewDisplayInterface $display, $view_mode) {
  if ($node->getType() == 'MY_CONTENT_TYPE') {
    $flag = \Drupal::service('flag')->getFlagById('MY_FLAG_ID');
    $flagging_entity = \Drupal::service('flag')->getFlagging($flag, $node);
    $form = \Drupal::service('entity.manager')
      ->getFormObject('flagging', 'edit')
      ->setEntity($flagging_entity);
    $form_obtained = \Drupal::formBuilder()->getForm($form);
    // How do I actually show the form on the node?

```

I looked at this question on rendering forms (which says use the `formBuilder` service, which I am already using). I assume I need to put the form in a render array but the documentation is not clear about how to do that.

# Answer
> 4 votes
`\Drupal::formBuilder()->getForm()` already returns a render array, see the FormBuilder::getForm() documentation.

To render the form, you just need to pass the results of *getForm()* to your $build array, then render it in your template.

In *hook\_ENTITY\_TYPE\_view()*:

```
function MYMODULE_node_view(array &$build, NodeInterface $node, EntityViewDisplayInterface $display, $view_mode) {
  // ...
  $build['my_flagging_form'] = $form_obtained;
}

```

Then in your twig template:

```
{{ content.my_flagging_form }}

```

Or, if you're already rendering *content* in its entirety, you may not need to update your twig template at all.

As @4k4 noted in the comments, you can also add the appropriate meta data in hook\_entity\_extra\_field\_info to make your flagging form addition configurable (reorderable, etc) on your node's Manage Display screen. See Creating pseudo-fields in Drupal 8 for an example.

# Answer
> 0 votes
Thanks to @sonfd and @4k4 for the answer and comment, I was able to fix it with the following code:

```
/**
 * Implements hook_node_view() for MYMODULE.
 */
function MYMODULE_node_view(array &$build, NodeInterface $node, EntityViewDisplayInterface $display, $view_mode) {
  if ($node->getType() == 'MY_CONTENT_YTPE') {
    if ($display->getComponent('my_flagging_form')) {
      $flag = \Drupal::service('flag')->getFlagById('MY_FLAG');
      $flagging_entity = \Drupal::service('flag')->getFlagging($flag, $node);
      $form = \Drupal::service('entity.manager')
        ->getFormObject('flagging', 'edit')
        ->setEntity($flagging_entity);
      $build['my_flagging_form'] = \Drupal::formBuilder()->getForm($form);
    }
  }
}

/**
 * Implements hook_entity_extra_field_info() for MYMODULE.
 *
 * Https://www.webomelette.com/creating-pseudo-fields-drupal-8
 */
function MYMODULE_entity_extra_field_info() {
  $extra = [];

  $extra['node'][NodeType::load('MY_CONTENT_TYPE')->Id()]['display']['my_flagging_form'] = [
    'label' => t('My flagging edit form'),
    'description' => t('This shows the my flagging edit form.'),
    'weight' => 100,
    'visible' => TRUE,
  ];

  return $extra;
}

```

---
Tags: 8, forms
---


# Question
Title: The admin toolbar is messing up the sticky position set with fundation
i am using the sticky component from foundation to render a sidebar element sticky. It does work when unconnected but when connected the toolbar cover the sticky element. How could i fix this ?

fundation sticky component

```
<div data-sticky class='toc-desktop toc toc-tree sticky' data-top-anchor="main:top" data-btm-anchor="footer:bottom">
<div>a table of content</div>
</div>

```

# Answer
i used then the fundation data-margin-top attribute

```
<div id='toc-desktop' data-sticky class='toc-desktop toc toc-tree sticky' data-top-anchor="main:top" data-btm-anchor="main:bottom" data-margin-top="5">

```
> 0 votes

---
Tags: toolbar
---


title: How can I show a date in Urdu?

text:
# Question
Title: How can I show a date in Urdu?
I am working on printing dates in more than a language. With Drupal 7, I used the following code.

```
<span class="arabic-date">
 <?php
   $arrayurdudays = array('', '', '', '', '', '', '', '');
   print format_date(time(), 'custom', ' l , d F , Y', null, 'ur');
 ?>
</span>

```

With Drupal 8 and Twig, I tried more than one way and it didn't work for me.

I downloaded the *Configuration Translation* module, but it didn't work in my case; I read there is a way to print it inside a file (.theme), but I didn't understand the method well. I need it inside the header file.

>

>

# Answer
In a Twig template, you can use the `format_date()` filter. For example, in the node template, the following code could be used to show (using a custom format) when a node has been created. (The following code is a simplified version of the code used from the Unami theme used with the *Unami Demo* installation profile, in node.html.twig.)

```
{% set created_date = node.getCreatedTime|format_date('custom', 'l, d F, Y', null, 'ur') %}

{% if display_submitted %}
  <footer class="node__meta">
    <div{{ author_attributes.addClass('node__submitted') }}>
      {% trans %}<span class="by-author">by {{ author_name }}</span> {{ created_date }}{% endtrans %}
    </div>
  </footer>
{% endif %}

```

I would rather avoid passing a language code to `format_date()` to let the filter use the language set for the page. Setting the language code would make the template file always use that, even if the page is using a different language code.

```
{% set created_date = node.getCreatedTime|format_date('custom', 'l, d F, Y') %}

{% if display_submitted %}
  <footer class="node__meta">
    <div{{ author_attributes.addClass('node__submitted') }}>
      {% trans %}<span class="by-author">by {{ author_name }}</span> {{ created_date }}{% endtrans %}
    </div>
  </footer>
{% endif %}

```

Note that when the custom format is using *M* for the month, the month name could be not correctly translated. See Date formats with abbreviated month name (M) are not translated using context for more details.
> 1 votes

---
Tags: 8, theming, i18n-l10n, datetime
---


# Question
Title: Converting a page created with panel into PDF
I'm working on D7 Panels and I created few pages using panel. I have a use case to generate the pdf for the data existed in the panel rather than the whole page with header and footer. Are there any recommendations to implement this.

# Answer
Yes, you can, dowload Printer, email and PDF versions, patch module with Can Panel pages be sent to PDF for rendering?, download wkhtmltopdf libary, place it under /sites/all/libraries, and configure your module like: , and inside panels add print PDF widget like:, done!.

EDIT: today 7/7/2020 panles 7 had an upgrade, be carefull, i think patch apply to an older version in panels.
> 0 votes

---
Tags: 7, panels
---


# Question
Title: Restrict translation and editing of node to one language
# Edit

I found this in Workbench Access issue queue: https://www.drupal.org/project/workbench\_access/issues/2982941#comment-12670744

It seems as if I need to deactivate the `translate *bundle* *node*` permissions, because if those are set, the permission will be short circuited and no other access restrictions may apply, and create a hole bunch of new `*translate *bundle* *node* *language*` permissions on my own. In my case we have 15 node types and 6 languages. That would result in 90 new permissions. That is overwhelming.

# Original Question

I'm trying to restrict the access to creating and editing of nodes in the Drupal admin section to only one language for a user. I didn't find a module which provides for this feature. **Is there any module that does this?**

I then tried to create my own module. I came up with this solution

### File: custom\_i18n\_access.module

```
<?php

use Drupal\node\NodeInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Access\AccessResult;

/**
 * Implements hook_node_access().
 *
 * Prevent editor role to edit and/or delete fr/en nodes. Quick and dirty.
 */
function custom_i18n_access_node_access(NodeInterface $node, $op, AccountInterface $account)
{

    $roles = $account->getRoles();

    if (in_array('administrator', $roles)) {
        return AccessResult::neutral();
    }

    if ($op !== 'update' && $op !== 'delete') {
        return AccessResult::neutral();
    }

    // Access should be restricted only if this permission is set
    if (!$account->hasPermission('custom_i18n_access_restrict')) {
        return AccessResult::neutral();
    }

    $current_language = \Drupal::languageManager()->getCurrentLanguage();
    $lang             = $current_language->getId();

    if ($account->hasPermission("custom_i18n_access_{$lang}_allow")) {
        return AccessResult::neutral();
    }
    return AccessResult::forbidden();
}

```

### File: custom\_i18n\_access.permissions.yml

```
permission_callbacks:
  - Drupal\custom_i18n_access\Permissions::permissions

```

### File: src/Permissions.php

```
<?php

namespace Drupal\custom_i18n_access;

class Permissions {
    public function permissions() {
        $languages = \Drupal::languageManager()->getLanguages();

        $permissions["custom_i18n_access_restrict"] = [
            'title' => t("Restrict language access"),
            'description' => 'Restrict the edit access of nodes',
        ];

        foreach($languages as $lang) {
            $permissions["custom_i18n_access_{$lang->getId()}_allow"] = [
                'title' => t("Allow to edit @lang content", ['@lang' => $lang->getName()]),
            ];
        }

        return $permissions;
    }
}

```

This custom module successfully restricts the editing and deleting of **existing** content to only the language I specified in the permissions. But it does not prevent **new** translations of the content into other languages.

As I see it, the `HOOK_node_access` hook is not called for every language when on the translations subtask page. How can I achieve this? **Is there a different hook for that?** I didn't find any help online.

# Answer
I would suggest here checking NodeTranslationHandler class, in entityFormAlter you could find a way how to restrict a user from creating a new translation.
> 0 votes

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


# Question
Title: Is there a way to enable the Gutenberg editor so I can use it with custom blocks?
I've installed the Gutenberg Editor module and have it working with various content types, however I'd like to also use it to create content for custom blocks (as in structure \> block layout \> add custom block). I've tried googling but since Gutenberg uses the term 'blocks' to describe the sub-modular pieces of content it uses, I can't find any reference to the module itself being available as an editor for custom blocks, or another module that extends Gutenberg's functionality to custom blocks (or any block element).

# Answer
> 2 votes
Currently, it's not possible. Although Gutenberg module provides a Drupal text editor plugin, like CKEditor, it relies a lot on the node edit form to provide the editing experience.

### Disclaimer

I am the project owner and lead maintainer for the Gutenberg module.

---
Tags: 8, blocks, wysiwyg
---


# Question
Title: How do I change store based on location?
I need to have different prices for same products based on country. I was advised to use Price list module and to have different store per each country and I did that.

I.e. I have Swiss store and Serbian store. For Swiss store for supported billing countries I selected only Switzerland and for Serbian store only Serbia.

Swiss is default one and prices in product variations are defined in CHF. Now I'm trying to override prices for Serbian store (in RSD).

So, I created Serbian price list and added alternative prices for products. Problem is that those alternative prices are used only if I include also Swiss store for that Serbian price list (so price list is active also for Swiss store). If I select only Serbian store, as it suppose to be, then price list is not used (I see default prices in CHF).

I read here: https://drupalcommerce.org/blog/42419/commerce-2x-stories-stores

.. that stores are actually representing billing locations. But that confuses me because product and their prices are displayed before customer enters billing address?!?

What I'm missing here? Why Serbian store is not automatically active if I'm testing from Serbia? Do I need some GEO IP module or something? Even when I'm testing as a logged user (location entered before) I still use default Swiss store instead of local Serbian store.

# Answer
Configuring the stores is one thing, determining which one is used for any given page request is another. One store is configured to be your default, and absent any other code, that store will always be used for the current page request, influencing visible products, pricing, carts, etc. If you want to make the current store something other than the default, you have to write a store resolver.

An example module you can reference is the Commerce Store Domain module, which resolves the current store based on the current domain. You can do something similar using the GeoIP module. I'm not aware of any existing contrib that integrates that as of yet.
> 1 votes

---
Tags: 8, commerce
---


# Question
Title: How can I programmatically reindex Commerce products to AWS Elastic Search?
I am using Drupal 8 Commerce module.

I am using Elastic Search on AWS platform.

From the Admin whenever product is saved, those changes are directly applied on Elastic Search server, but when I try with `$product->save()` it is not working 100%.

So if I have to update 10 products in Elastic Search how to achieve that programatically?

In particular, I have to update one field only. Because what is happening that, it will update that field value in database but not on Elastic Search.

I found this useful post for Node How To Force Search API To Reindex a Node / an Entity

# Answer
So I have some updates answer relies in `search_api.module` file function `search_api_entity_update`.

So I am able to achieve for one product. Can loop & do for multiple.

```
use Drupal\commerce_product\Entity\Product;
use Drupal\search_api\Plugin\search_api\datasource\ContentEntity;

$entity = Product::load(1); // Replace 1 with your product id.

$indexes = ContentEntity::getIndexesForEntity($entity);

if (!$indexes) {
  return;
}

foreach ($indexes as $index) {
  $index->trackItemsUpdated('entity:commerce_product', ['1:en']);
}

```

It works like a charm :)
> 2 votes

---
Tags: 8, commerce, search
---


# Question
Title: I'm unable to install the Symfony var-dumper component
I am having issues installing symfony/var-dumper package via composer the command I ran is

```
composer require symfony/var-dumper

```

The result I get is

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

Problem 1
   - Conclusion: remove drupal/core-recommended 8.9.1
   - Conclusion: don't install drupal/core-recommended 8.9.1
   - Conclusion: don't install symfony/var-dumper v5.1.2
   - Conclusion: don't install symfony/var-dumper v5.1.1
   - Conclusion: don't install symfony/var-dumper v5.1.0
   - Conclusion: don't install symfony/var-dumper v5.1.0-RC2
   - Conclusion: don't install symfony/var-dumper v5.1.0-RC1
   - Conclusion: don't install symfony/var-dumper v5.1.0-BETA1
   - Installation request for drupal/core-recommended (locked at 8.9.1, required as ^8.8) -> satisfiable by drupal/core-recommended[8.9.1].
   - Conclusion: don't install symfony/var-dumper 5.2.x-dev
   - drupal/core-recommended 8.9.1 requires symfony/console v3.4.41 -> satisfiable by symfony/console[v3.4.41].
   - symfony/console v3.4.41 conflicts with symfony/var-dumper[5.1.x-dev].
   - symfony/var-dumper 5.1.x-dev conflicts with symfony/console[v3.4.41].
   - symfony/var-dumper 5.1.x-dev conflicts with symfony/console[v3.4.41].
   - Installation request for symfony/var-dumper ^5.1 -> satisfiable by symfony/var-dumper[5.1.x-dev, 5.2.x-dev, v5.1.0, v5.1.0-BETA1, v5.1.0-RC1, v5.1.0-RC2, v5.1.1, v5.1.2].
   Installation failed, reverting ./composer.json to its original content.

```

My composer.json file is

```
{
  "name": "drupal/legacy-project",
  "description": "Project template for Drupal 8 projects with composer following drupal/drupal layout",
  "type": "project",
  "license": "GPL-2.0-or-later",
  "homepage": "https://www.drupal.org/project/drupal",
  "support": {
    "docs": "https://www.drupal.org/docs/user_guide/en/index.html",
    "chat": "https://www.drupal.org/node/314178"
},
  "repositories": {
    "0": {
        "type": "composer",
        "url": "https://packages.drupal.org/8"
    },
    "drupal": {
        "type": "composer",
        "url": "https://packages.drupal.org/8"
    }
},
  "require": {
    "composer/installers": "^1.2",
    "drupal/core-composer-scaffold": "^8.8",
    "drupal/core-project-message": "^8.8",
    "drupal/core-recommended": "^8.8",
    "drupal/core-vendor-hardening": "^8.8",
    "phpmailer/phpmailer": "^6.1"
},
  "conflict": {
    "drupal/drupal": "*"
},
  "minimum-stability": "dev",
   "prefer-stable": true,
   "config": {
    "sort-packages": true
},
  "extra": {
    "drupal-scaffold": {
        "locations": {
            "web-root": "./"
        }
    },
    "installer-paths": {
        "core": [
            "type:drupal-core"
        ],
        "libraries/{$name}": [
            "type:drupal-library"
        ],
        "modules/contrib/{$name}": [
            "type:drupal-module"
        ],
        "profiles/contrib/{$name}": [
            "type:drupal-profile"
        ],
        "themes/contrib/{$name}": [
            "type:drupal-theme"
        ],
        "drush/Commands/contrib/{$name}": [
            "type:drupal-drush"
        ],
        "modules/custom/{$name}": [
            "type:drupal-custom-module"
        ],
        "themes/custom/{$name}": [
            "type:drupal-custom-theme"
        ]
    },
    "drupal-core-project-message": {
        "include-keys": [
            "homepage",
            "support"
        ],
        "post-create-project-cmd-message": [
            "<bg=blue;fg=white>                                                         </>",
            "<bg=blue;fg=white>  Congratulations, you’ve installed the Drupal codebase  </>",
            "<bg=blue;fg=white>  from the drupal/legacy-project template!               </>",
            "<bg=blue;fg=white>                                                         </>",
            "",
            "<bg=yellow;fg=black>Next steps</>:",
            "  * Install the site: https://www.drupal.org/docs/8/install",
            "  * Read the user guide: https://www.drupal.org/docs/user_guide/en/index.html",
            "  * Get support: https://www.drupal.org/support",
            "  * Get involved with the Drupal community:",
            "      https://www.drupal.org/getting-involved",
            "  * Remove the plugin that prints this message:",
            "      composer remove drupal/core-project-message"
        ]
    }
}
}

```

I haven't even customized it yet, this is pretty much out of the box at the moment and I am already having issues.

# Answer
> 4 votes
drupal/core-recommended 8.9.2 requires symfony/console v3.4.41 while the currently latest symfony/var-dumper requires symfony/console at minimum version 4.4. When you run `composer require symfony/var-dumper` without specifying any version it will try to install the currently latest version 5 of the var-dumper. Mismatched dependencies. Error. So simply install a version of the var-dumper that matches the dependencies and can be installed with Symfony 3.4 components.

```
composer require symfony/var-dumper:^4.4

```

---
Tags: 8, composer
---


# Question
Title: Error Unable to copy files settings files from BLT into your repository
When I try to run `blt sync` I am getting the following error.

> `blt:init:settings`
>
> Hash salt already exists. \[error\] Unable to copy files settings files from BLT into your repository. For troubleshooting guidance and support, see https://docs.acquia.com/blt/support/ The command failed. This often indicates a problem with your configuration. Review the command output above for more detailed errors, and consider re-running with verbose output for more information. \[error\] Command `blt:init:settings`  exited with code 1. For troubleshooting guidance and support, see https://docs.acquia.com/blt/support/

# Answer
I got resolved the same problem using the following steps.

1. run the blt sync with -v `blt sync -vvv`
2. Which will help you to find the cause of the error,

In my case, it was permission for the recipe settings.php file.

So I have to run the **chmod** command *outside* the box, then ssh into the box, delete the database and ran the `blt acsf:init`

After all these I ran the `blt sync` its worked fine. Hope this will be helpful for those facing the same issue. :)
> 0 votes

---
Tags: 8
---


title: Use url of media field in view twig

text:
# Question
Title: Use url of media field in view twig
I need to output the url for field\_slide\_media in views-view-unformatted--carousel.html.twig.

I can output the entity ID using:

```
{{ view.field.field_slide_media.value(view.result[i]) }}

```

I would like to use it in

```
<img src="url of field_slide_media">

```

I can also output the whole image, but I need to be able to add an img class to it in the twig, so it's too much being output. I need the uri not the whole output.

```
{{ view.style_plugin.getField(loop.index0, 'field_slide_media') }}

```

gives me:

```
<img src="/sites/default/files/styles/carousel_large_image/public/2020-07/Mal%20Event%20Instagram%20Grid%202%20V2.png?itok=ZHLLokti" alt="art" typeof="foaf:Image" >

```

# Answer
It seems that the easiest way to generate a url is to use View Modes.

I created a new Media view mode.

Then go to Media types \> Image \> Manage display and scroll to the very bottom and click on Custom display settings. Check the box next to the new media image to add it to display. then select the new media type to customise it. Under Format use the dropdown to select URL to image. There is a settings cog on the right of this dropdown. I had already created an image style for this type of image so selected that from the list to use it.

Go to the Content type \> Image field \> Display and select the correct image style from the dropdown in the cog setting on the right-hand-side of the screen.

To use the image in the twig I got the url by inserting:

```
 {% set uri = view.style_plugin.getField(loop.index0, 'field_slide_media') %}
 <img class="img-bg" src="{{ uri }}">

```

Just a little sidenote, you won't see the image if you have twig debug on.
> 0 votes

# Answer
If you are configuring the view with the fields. You can try setting the formatter of the image to 'URL to image' and then create the HTML yourself like

```
<img src="{{ view.field.field_slide_media }}" />

```

Or you can try file\_url
> 0 votes

---
Tags: views, media, uri
---


# Question
Title: How do I use a preprocess function for a node template?
I'm trying to preprocess my variable array in drupal 8, But it's not working well.I'm checked with the Bartik theme also, But getting the same error here. When I'm trying to print the variable array its giving a blank page result. How can I preprocess my variable array for a node template?

```
`function bartik_preprocess_node(&$variables) {
  // Remove the "Add new comment" link on teasers or when the comment form is
  // displayed on the page.
  if ($variables['teaser'] || !empty($variables['content']['comments']['comment_form'])) {
    unset($variables['content']['links']['comment']['#links']['comment-add']);
  }
  print_r($variables);
}`

```

This is the function I'm tried to checkout the issue in bartik theme.

# Answer
> 12 votes
Instead of using `print_r()` enable devel module and their new submodule called kint. And use `kint()` instead of `print_r()`. You can also use `print_r()` but is messy.

> How can I preprocess my variable array for a node template?

```
function YOURTHEME_preprocess_node(&$variables){
  kint($variables);
}

```

If this does not work it might be a cache problem. I will recommend you to set you website into dev mode using DrupalConsole. `drupal site:mode dev`

Why ?

> The Twig engine provides options for configuring debugging, automatic reloading (recompiling) of templates, and caching compiled templates in the filesystem. By default, the Twig theming engine compiles templates into PHP code and stores the compiled code in memory. Compiled code is unsuitable for development, since changes in Twig templates are not immediately updated in your Drupal site. Twig cache can be cleared through Drupal's clear cache interface, but for ongoing development it's easier to change Drupal's settings so that Twig doesn't cache anything at all.

Running `drupal site:mode dev` will disable all twig cache. For more information about debugging please visit - Debugging compiled Twig templates

# Answer
> 2 votes
Another option is to use the VarDumper module which isn't quite so memory intensive as Kint. I find it a bit more user-friendly and better-looking!

```
function YOURTHEME_preprocess_node(&$variables){
  vardumper($variables);
}

```

---
Tags: 8, theming
---


# Question
Title: Add ajax on hook_field_widget_paragraphs_form_alter
I'm working with paragraph and I try to change a paragraph with AJAX.

My content type have a content field which contains "section" paragraphs which can contain various paragraph types which themselves can contain various paragraphs types.

To do certain modification on paragraphs, I use hook\_field\_widget\_paragraphs\_form\_alter. It's work well but I meet a problem when I try to use #ajax because I don't know how to retrieve which paragraph has been modified in the ajax callback because I receive the entire form from the content and no information on which part has been modified. Here my code:

```
function mymodule_field_widget_paragraphs_form_alter(&$element, &$form_state, $context) {
  switch ($element['#paragraph_type']) {
    case 'block_special':
      $element['subform']['field_type']['widget']['#ajax'] = [
          'wrapper' => 'type-bs-wrapper',
          'callback' => '_type_paragraph_callback',
        ];

        $element['subform']['field_content']['widget']['#attributes'] = ['id' => 'type-bs-wrapper'];

        $values_paragraph = $form_state->getValues();
        if(!empty($values_paragraph)) {
          foreach ($element['#field_parents'] as $field) {
            $values_paragraph = $values_paragraph[$field];
          }

          $type = $values_paragraph['subform']['field_type'];
        }

        if (!empty($type) && $type === 'exception') {
          unset($element['subform']['field_content']['widget']['add_more']['add_more_button_paragraph_type1']);
          unset($element['subform']['field_content']['widget']['add_more']['add_more_button_paragraph_type2']);
        }
  }
}

```

```
function _type_paragraph_callback(array $form, FormStateInterface $form_state) {

  return $form; // <- How can I know what I should return?
}

```

I don't know which paragraph have been return. I don't know if I can pass the argument $element\['#parent'\] from the function hook\_field\_widget\_paragraphs\_form\_alter (but how in this case) or if I should do a recursive research between default value of all paragraphs of my form between form\_values (which will be laborious).

# Answer
You should be able to get this information from the submitted data in $form\_state, specifically the triggering element.

For example:

```
use Drupal\Component\Utility\NestedArray;

function _type_paragraph_callback(array $form, FormStateInterface $form_state) {
  $button = $form_state->getTriggeringElement();
  // Go one level up in the form, to the widgets container.
  $element = NestedArray::getValue($form, array_slice($button['#array_parents'], 0, -2));

  return $element;
}

```

I've copied this from the Paragraphs module: *modules/contrib/paragraphs/src/Plugin/Field/FieldWidget/InlineParagraphsWidget.php*
> 2 votes

---
Tags: 8, forms, paragraphs
---


# Question
Title: Show node summary (teaser) as tooltip/ Alt/ Title text on hover over nodes titles on front page with Views
I have a custom front page view showing nodes titles only without teasers. I want to have the teaser of each node show when hovering over any title. Something like:

```
<a href="{{ url }}" title="{{ node__teaser }}"> Node Title </a>

```

I am thinking I could edit the view to display teasers and I can then control their visibility on hover with css but I am curious to learn any idea to do it otherwise by including the node teaser in the title attribute instead if at all possible via Views or theme's twigs.

---

I'm going to answer my own question but first I'd love to learn from those who down-voted my question their reasons except for again discouraging a newbie here who's done all efforts to research and wrote a clear question. I only ask after I've exhausted all my search and it annoys me and discourage me when my question is unfairly down-voted and it seems this is an exclusive Drupal Answers trend !!!

# Answer
> 2 votes
After lots of digging and trial and errors playing with twig and then Views I made it work exactly as I wanted in my Homepage view as follows:

The view has the following four Content fields in the same order below:

`Content:Body [Hidden]` (**Formatter**: Summary or Trimmed)

`Content: Link to Content [hidden]` ("**Output the URL as text**" is checked)

`Content: Title` as follows:

**Link to the Content** is unchecked,

**Formatter**: *Plain text*

**Rewrite Rules**: *Output this field as a custom link* selected.

**Link path:** {{ view\_node }}

**Title text:** {{ body }}

Now whenever one hovers over a node link on front page they get a tooltip with the node summary. The link also links correctly and all as expected.

Please see the attached screenshot for more details.

`Content: Authored on (Authored on)` .....

---
Tags: views, theming, 9, tooltips
---


# Question
Title: How to make subprocess & migration_lookup plugins behave consistently with single and multiple items arrays
I have a JSON that can hold single or multi values arrays and I can't make subprocess + migration\_lookup behave consistently. It correctly imports the nodes in all cases, but it adds the reference to the imported nodes (entity reference field) only when I have more than 1 item in my array.

my JSON can looks like this:

```
"behaviour": [
          {
            "name": "behaviour name",
            "description": "behaviour description"
          }
        ]

```

or like this:

```
"behaviour": [
          {
            "name": "behaviour name",
            "description": "behaviour description"
          },
          {
            "name": "another behaviour name",
            "description": "another behaviour description"
          }
        ]

```

the process part of my migration config:

```
  field_behaviour:
    plugin: sub_process
    source: behaviour_array
    process:
      target_id:
        plugin: migration_lookup
        migration: import_behaviours_json
        source: name

```

# Answer
This is just guessing, but you could try forcing the multiple flag on the source field using the multiple\_value plugin from Migrate Plus:

```
field_behaviour:
  -
    plugin: multiple_values
    source: behaviour_array
  -
    plugin: sub_process
    process:
      target_id:
        plugin: migration_lookup
        migration: import_behaviours_json
        source: name

```
> 0 votes

# Answer
It urned out the issue was related with migrate\_source\_jsonpath (the modules used to grab data from JSON).

migrate\_source\_jsonpath was the one returning single items as strings instead of array.
> 0 votes

---
Tags: 8, migrations
---


# Question
Title: How do I unset a field in a node with the help of hook_node_view?
```
function test_node_view(array &$build, Drupal\Core\Entity\EntityInterface $entity, \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display, $view_mode) {
  updateDisplay();
}

function updateDisplay() {
  unset(['field_test']); //I want to Unset this field
}

```

# Answer
> 2 votes
It's hard to tell exactly what you're going for, but to elaborate on @kiamlaluno's comment, you'd want to do something like the following.

First, update your *updateDisplay()* function to accept your *$node's $build* array as a parameter passed by reference. This allows you to make alterations to the variable inside your function that will be preserved outside your function.

```
// Note the ampersand prepended to the variable's name.
function updateDisplay(&$node_build) {
  // ... code ...
}

```

Second, it's preferable to remove access to the field rather than unset it from the array. This will prevent it from being rendered. You can do this by setting the field's *#access* value to false. Your updated code might look like:

```
function updateDisplay(&$node_build) {
  // Remove access to field_test
  $node_build['field_test']['#access'] = FALSE;
}

```

Lastly, you'll have to update your *hook\_node\_view()* implementation to pass the build array to your *updateDisplay()* function.

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

```

---
Tags: 8, hooks
---


title: Advanced Migration - update nodes

text:
# Question
Title: Advanced Migration - update nodes
I'm a little bit new in Drupal but experienced in PHP. I would like to migrate data from CSV and assign to existing nodes in DB.

My question is about the possibility to match processing rows with existing data from the database.
I mean, I have CSV file with data and with `foreign key` called: `SERVICE_ACTION` and now I would like to assign that data to existing NODE which hasn’t `SERVICE_ACTION` key but has different KEY which is assigned to another specific entity with Service Action key. How can I get ID of that entity in migration script to assign?

Perhaps, I need target\_id to assign newly created paragraph to the specific node. I’m not sure what I’m working bad.

```
langcode: en
status: true
dependencies:
  enforced:
    module:
      - xxx_migration
      - paragraphs
id: xxx_release_notes
migration_tags:
  - custom-migrate
  - soap-apis
migration_group: xxx_soap_api
label: 'xxx release notes'
source:
  plugin: csv
  data_fetcher_plugin: file
  path: modules/custom/xxx_migration/artifacts/releases_notes.csv
  header_row_count: 1
  keys:
    - id
  column_names:
    -
      id: 'Unique Id'
    -
      title: Title
    -
      body: 'Post body'
    -
      service_action_code: 'Service Action Code'
process:
  type:
    plugin: default_value
    default_value: people
  field_service_action_code:
    plugin: migration_lookup
    migration: xxx_release_notes
    source: service_action_code
destination:
  plugin: 'entity_reference_revisions:paragraph'
  default_bundle: release_note
migration_dependencies:
  required: {  }
optional: {  }

```

here is my CSV file:

```
id,title,body,service_action_code
1,TITLE,example body,PassengerDetailsRQ
2,TITLE2,example body2,ePaymentRQ

```

# Answer
I don't know the exact answer. But maybe this information can get you on the right track. First the migration process has the ability to update earlier migrated entities, it does this with the help of high-water-marks and timestamps (see Drupal's documentation). Maybe you can do a trick to use this feature. Furthermore there is a lot of good documentation about the migration-process, I recommend this site, an extensive tutorial about the process in 31(!) steps/days, https://understanddrupal.com/31-days-of-migrations or https://www.phase2technology.com/blog/migration-making-it-all-work. Behind it some of the "Drupalstars" from the migration and comprehensibly written. Hope you find your answer there.
> 0 votes

---
Tags: 8, migrations
---


# Question
Title: Testing if email was sent in Kernel test
I am trying to write automated tests for a or that will sent an email on submission.
I can write the test to check for the presence of the entity that is created along side the email, but I also want to have my automated test check that the system is sending an email too.

The examples I can find seem to relate to Laravel and the use of spies to see if a particular class method is called, however I can't find any examples of how to do that in Drupal 8 and in my particular use case I am using the function \_user\_mail\_notify() and not a class method.

Does anyone have an example of testing that emails have seen sent at all?

# Answer
> 1 votes
Look at core tests that utilize email. For example:

The tests demonstrate ways to inspect the `plugin.manager.mail` service for signs that mail was successfully sent.

---
Tags: 8, emails, testing
---


# Question
Title: View to display content type and media type
Drupal 8

Say I have 1 content type and 2 media types users can create Content type: Post Media Type: Picture Media type: Movie

How can I create a view that pulls all 3? As far as I can see you can only create views that show content, or media but not both in the same view.

I wasnt to create a feed displaying all 3 types of all users on the site.

# Answer
If there are no relationships among the three entity types, as you have indicated in comments, you could use attachments or blocks. (I'm assuming you want a page that displays all the information.)

**Attachment Solution:**

* Create your View with a page display of one of the entity types.
* In the same View create two attachment displays, and use overrides to base them off the other entity types. Attach them to the page display.

**Block Solution:**

* Create your View with a page display of one of the entity types.
* Create additional, separate, Views of each of the other entity types, with block displays
* Use the block configuration system to place those blocks on the page display
> 0 votes

---
Tags: views, media
---


# Question
Title: Move my project from public_html/web to public_html
I have a Drupal site installed via composer, creating a structure like

```
vendor/
config/
composer.json
etc/
web/core
web/themes
web/index.php
web/etc

```

Is there a way to change the `web` folder to a `public_html` folder so I can use it on my hosting? So the structure needs to be:

```
vendor/
config/
composer.json
etc/
public_html/core
public_html/themes
public_html/index.php
public_html/etc

```

I got it working now by using .htaccess but I started using this method with the config outside of my root folder because of the security advantages. With this method, the config is still in my root but via htaccess I point everybody to the web folder. Is this still secure enough?

So how can I change this and is it necessary?

# Answer
> 10 votes
You should be able to change the installer paths in `composer.json`, which defines where the files are placed:

```
"installer-paths": {
  "web/core": ["type:drupal-core"],
  "web/modules/contrib/{$name}": ["type:drupal-module"],
  "web/profiles/contrib/{$name}": ["type:drupal-profile"],
  "web/themes/contrib/{$name}": ["type:drupal-theme"],
  "drush/contrib/{$name}": ["type:drupal-drush"]
},

```

to:

```
"installer-paths": {
  "public_html/core": ["type:drupal-core"],
  "public_html/modules/contrib/{$name}": ["type:drupal-module"],
  "public_html/profiles/contrib/{$name}": ["type:drupal-profile"],
  "public_html/themes/contrib/{$name}": ["type:drupal-theme"],
  "drush/contrib/{$name}": ["type:drupal-drush"]
},

```

You can then rename the `web` folder to `public_html` and everything should work.

# Answer
> 2 votes
The steps to install Drupal in public\_html is to make a 'modified install', this means initiating your project with this `composer create-project drupal/recommended-project my_site_name_dir --no-interaction --no-install`This will initiate Drupal 9, if you want Drupal 8 instead then use this `composer create-project drupal/recommended-project:^8 my_site_name_dir --no-interaction --no-install`

The `--no-install` flag will stop the installation of Drupal upon project initiation.

You should be in your Cpanel root (one step away from public\_html), this will initiate your project inside `my_site_name_dir` directory. Cd into the directory and move composer.json and composer.lock up inside the Cpanel root, move back to the root and delete the now empty `my_site_name_dir` directory.

Open composer.json in an editor and change the web-root and installer-paths from 'web/' to 'public\_html/', save the file and from Cpanel root run `composer install`.

Drupal will be installed inside public\_html and you can access your site on site.com without any sub-directories. Also vendor folder and the Composer files will be placed away from your web-root (public\_html) which is the recommended setup.

I explain this also in my blog post, https://www.skillmaticace.com/blog/how-install-drupal-8-composer-cpanel

---
Tags: 8, composer
---


# Question
Title: How can I update an user field via JSON:API?
How do I update user field via JSON API with D8?

```
EndPoint:https://domainname.com/jsonapi/user/user/

Method:PATCH

```

Request Header;

```
Accept:application/vnd.api+json
Content-Type:application/vnd.api+json
X-CSRF-Token:xxxxxxxxxx

```

Body:

```
"data": {
        "type": "user--user",
        "id": "xxxxxx-7798-45e5-a16c-xxxxxxxxxxxx",
        "attributes": {
            "field_test1": [
                "data1",
                "dara2"
            ]
        }
    }

```

But below error

```
        "title": "Method Not Allowed",
        "status": "405",
        "detail": "No route found for \"PATCH /jsonapi/user/user/\": Method
        Not Allowed (Allow: POST, GET, HEAD)",

```

# Answer
> 2 votes
You need to also put UUID in your request URL, so it should look like

```
EndPoint:https://domainname.com/jsonapi/user/user/xxxxxx-7798-45e5-a16c-xxxxxxxxxxxx

```

---
Tags: users, 8
---


# Question
Title: formBuilder()->getForm() outputs everything except the <form> tag in a view?
When displaying my entity edit form with `\Drupal::formBuilder()->getForm($form);` (for a flagging attached to a node) in a View that is set to show **Content** with the **Default** display, I noticed the `<form>` tag itself is missing:

```
<form class="flagging-myflag-edit-form flagging-form" data-drupal-selector="flagging-myflag-edit-form-iq8dn9lwifq" action="/flag/details/edit/MYFLAG/52" method="post" id="myform-myflag-edit-form--iq8dn9lWIfQ" accept-charset="UTF-8">
Everything between the form tags is printed properly.
</form>

```

The `<form>` tag appears on the node page correctly, but it does not appear in the view.

So somehow, Views is filtering out the `<form>` tag, but I need to keep this tag.

This is the code I am using:

```
function MYMODULE_node_view(array &$build, NodeInterface $node, EntityViewDisplayInterface $display, $view_mode) {
  if ($node->getType() == 'MY_CONTENT_YTPE') {
    if ($display->getComponent('my_flagging_form')) {
      $flag = \Drupal::service('flag')->getFlagById('MY_FLAG');
      $flagging_entity = \Drupal::service('flag')->getFlagging($flag, $node);
      $form = \Drupal::service('entity.manager')
        ->getFormObject('flagging', 'edit')
        ->setEntity($flagging_entity);
      $build['my_flagging_form'] = \Drupal::formBuilder()->getForm($form);
    }
  }
}

```

According to twig debugging, the custom form is being output through `core/modules/system/templates/form.html.twig`, but there's no form tag when output by Views (the tag does appear on the node page).

This is `form.html.twig`:

```
<form{{ attributes }}>
  {{ children }}
</form>

```

EDIT: I tried to render it based on the comment of @Ales:

```
  $form = \Drupal::service('entity.manager')
    ->getFormObject('flagging', 'edit')
    ->setEntity($flagging_entity);
  $form_to_render = \Drupal::formBuilder()->getForm($form);
  $renderer = \Drupal::service('renderer');
  $build['remember_form']['#markup'] = $renderer->render($form_to_render);

```

This gives me the same output as my original code; the form is there, but the `<form>` tag is not...

EDIT 2: I also tried using `template_node_preprocess()` instead of `hook_node_view()`:

```
function MYTHEME_preprocess_node__MY_CONTENT_TYPE(&$variables) {
  $node = $variables['node'];
  $flag = \Drupal::service('flag')->getFlagById('MY_FLAG');
  $flagging_entity = \Drupal::service('flag')->getFlagging($flag, $node);
  $form = \Drupal::service('entity.manager')
    ->getFormObject('flagging', 'edit')
    ->setEntity($flagging_entity);
  $form_to_render = \Drupal::formBuilder()->getForm($form);
  $variables['MY_FLAG_form'] = $form_to_render;
}

```

But when I rendered this variable in my theme template, I got the same result-- the `<form>` tag appears on the node page, but not in the view that shows Content with mode **full content**.

# Answer
Looks like views reformats rendering as a form if there are any form elements in a row. See `\Drupal\views\Plugin\views\display\DisplayPluginBase::elementPreRender`:

```
    // If form fields were found in the view, reformat the view output as a form.
    if ($view->hasFormElements()) {
      .....
    }

```

I guess you should see one `<form>` tag arround the entire view.

In this case a possible solution would be to create a custom views display plugin `Forms`, that overrides the `elementPreRender` method and ignores the form elements check.
> 1 votes

---
Tags: 8, views, forms
---


# Question
Title: Drupal downloads the module update but need FTP
As the above screen shots, from Drupal 7 shows, the updates are downloaded! However, it still says `Updating modules and themes requires FTP access to your server`.

I have tried the ownership of `sites` directory as whole `sudo chown www-data sites`. I also tried `chmod -R 777 sites`. Is there any other way beside having to configure an FTP server, and if it must need a FTP, what is the directory I should set it to files?

# Answer
> 4 votes
I sometimes have seen that message with Drupal 7, and I always got confused about why Drupal was asking for FTP access to save files in the same server it was running, and why I didn't get that message in some Drupal 7 installations.

Looking at the code used from Drupal to updates the modules, I then discovered Drupal first checks if local file transfers are allowed. If they aren't allowed, that message will be shown.
In particular, this is the code Drupal uses. (See `update_manager_local_transfers_allowed()`.)

```
  // Compare the owner of a webserver-created temporary file to the owner of
  // the configuration directory to determine if local transfers will be
  // allowed.
  $temporary_file = drupal_tempnam('temporary://', 'update_');
  $local_transfers_allowed = fileowner($temporary_file) === fileowner(conf_path());

```

In other words, if the account owning a temporary file created in the *temporary* directory set up for the site isn't the account owning the directory containing the *settings.php* file used for the site, Drupal will show the message you saw.
Setting the *temporary* directory and the directory containing the *settings.php* file to be owned from the same account will make updates from the user interface possible via local file transfers. In this case, Drupal won't show any message about the FTP access being required.

`update_manager_local_transfers_allowed()` is called from `_update_manager_check_backends()`, which contains the following code. (The comments explain what is happening and why.)

```
  // If file transfers will be performed locally, we do not need to display any
  // warnings or notices to the user and should automatically continue the
  // workflow, since we won't be using a FileTransfer backend that requires
  // user input or a specific server configuration.
  if (update_manager_local_transfers_allowed()) {
    return TRUE;
  }

  // Otherwise, show the available backends.
  $form['available_backends'] = array(
    '#prefix' => '<p>',
    '#suffix' => '</p>',
  );
  $available_backends = drupal_get_filetransfer_info();
  if (empty($available_backends)) {
    if ($operation == 'update') {
      $form['available_backends']['#markup'] = t('Your server does not support updating modules and themes from this interface. Instead, update modules and themes by uploading the new versions directly to the server, as described in the <a href="@handbook_url">handbook</a>.', array(
        '@handbook_url' => 'http://drupal.org/getting-started/install-contrib',
      ));
    }
    else {
      $form['available_backends']['#markup'] = t('Your server does not support installing modules and themes from this interface. Instead, install modules and themes by uploading them directly to the server, as described in the <a href="@handbook_url">handbook</a>.', array(
        '@handbook_url' => 'http://drupal.org/getting-started/install-contrib',
      ));
    }
    return FALSE;
  }
  $backend_names = array();
  foreach ($available_backends as $backend) {
    $backend_names[] = $backend['title'];
  }
  if ($operation == 'update') {
    $form['available_backends']['#markup'] = format_plural(count($available_backends), 'Updating modules and themes requires <strong>@backends access</strong> to your server. See the <a href="@handbook_url">handbook</a> for other update methods.', 'Updating modules and themes requires access to your server via one of the following methods: <strong>@backends</strong>. See the <a href="@handbook_url">handbook</a> for other update methods.', array(
      '@backends' => implode(', ', $backend_names),
      '@handbook_url' => 'http://drupal.org/getting-started/install-contrib',
    ));
  }
  else {
    $form['available_backends']['#markup'] = format_plural(count($available_backends), 'Installing modules and themes requires <strong>@backends access</strong> to your server. See the <a href="@handbook_url">handbook</a> for other installation methods.', 'Installing modules and themes requires access to your server via one of the following methods: <strong>@backends</strong>. See the <a href="@handbook_url">handbook</a> for other installation methods.', array(
      '@backends' => implode(', ', $backend_names),
      '@handbook_url' => 'http://drupal.org/getting-started/install-contrib',
    ));
  }
  return TRUE;

```

As side note, the *temporary* directory is the one set on admin/config/media/file-system, which by default is set to /tmp.

>

Note also that, as 4k4 said in a comment, updating modules or themes from the user interface is a security risk. In fact, it requires the system account used to run PHP to be able to write files in the directory containing the modules. For example, with that permission, a malicious script could alter the submission callback used for the user login form, and add code that sends the login credentials to a remote server.
For a general discussion see Should PHP run as www-data or as the user who owns the website? where one of the comments says:

> PHP should ***NEVER*** have write access to or ownership of the files it executes, or the directories they reside in. I cannot emphasize this strongly enough. It just takes one security vulnerability, and now you're phishing, hosting a reverse shell, spamming, participating in an outbound DoS, or otherwise compromised, because an attacker used PHP to write a malicious script into a place where it could be executed. #3 is the best solution, best implemented by changing the group of the upload directory to www-data and giving group write access. Also ensure that nginx will not ask PHP to execute scripts stored in that directory.

---
Tags: 7, updating
---


# Question
Title: How do I get the roles of the currently logged-in user?
In Drupal 8 I would use the following code.

```
$current_user = \Drupal::currentUser();
$roles = $current_user->getRoles();

```

What is the equivalent code I should use in Drupal 7?

# Answer
You can access the current user in D7 via the global $user object

```
global $user;
$roles = $user->roles;

```
> 0 votes

---
Tags: 7, users
---


# Question
Title: Converting a form field to multiple submit buttons?
I'm not sure how to explain this well in text, but I want to change this:

Into something like this:

In Drupal 8, I have an entity for which the only user-editable field is *Score*, which is a **List (integer)** with six possible scores, 0 to 5.

On the edit page, I want users to be able to press a button to assign the score. There should be one button for each score.

How can I implement something like this?

# Answer
I would like to suggest is, use hook\_form\_alter, create an ajax handler on value change on select list, disable ( remove) submit button.

```
/**
 * Implements hook_form_alter().
 */
function YOURMODULENAME_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if ($form_id == 'YOUR_FORM_ID') {
    $form['YOUR_FIELD_MACHINE_NAME']['#ajax'] = [
        'callback' => array('mycustomSubmit'),
        'wrapper' => 'vote-wrapper'
      ];

      $form['YOUR_FIELD_MACHINE_NAME']['#prefix'] = '<div id="vote-wrapper">',
      $form['YOUR_FIELD_MACHINE_NAME']['#suffix'] = '</div>';
    // disable submit button
    $form['actions']['submit']['#disabled'] = TRUE;
 }
}

  /**
   * {@inheritdoc}
   */
  public function mycustomSubmit(array &$form, FormStateInterface $form_state) {
    // YOU CAN DO NODE CREATION HERE,
    \Drupal::messenger()->addMessage($this->t('YOUR SUCCESSFUL MESSAGE'), 'status', TRUE);
  }

```

and in twig template theme the select options instead of radio, theme them in a button like what you want. ( **or even you can style radio options as button with just CS**S)

for reference: Customize Radio Button Appearance with CSS
> 2 votes

# Answer
Thanks to @Yuseferi's example, I was able to come up with the following code.

This completely hides the submit button and automatically submits the form whenever a radio value is changed.

Note that because this form was displayed in a node shown via Views, I needed the fix described here.

```
/**
 * Implements hook_form_alter().
 */
function MYMODULE_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if ($form_id == 'YOUR_FORM_ID') {

    $form['YOUR_FIELD_MACHINE_NAME']['#prefix'] = '<div id="vote-wrapper">',
    $form['YOUR_FIELD_MACHINE_NAME']['#suffix'] = '</div>';
    $form['YOUR_FIELD_MACHINE_NAME']['widget']['#after_build'] = ['MYMODULE_process_radios'];

    // Hide the submit button.
    $form['actions']['submit']['#attributes'] = ['style' => ['display: none;']];

  }
}

function MYMODULE_process_radios($element, $form_state) {
  $options = array_keys($element['#options']);
  foreach ($options as $values) {
    $element[$values]['#attributes']['onClick'] = ['document.getElementById("MY-FORM-ID").submit();'];
  }
  return $element;

```
> 0 votes

---
Tags: forms
---


# Question
Title: How can I show the flagging field edit form on a node?
On a flagged node, instead of showing the flag/unflag link, I want to show the flag edit form.

Here's my setup.

**Basic page** content type can be flagged with the flag **Bookmark**. **Bookmark** is a per-user flag that has an int list field **Rating**, which has values from 1 to 5. On the flag admin page (/admin/structure/flags/manage/bookmark), **Link type** is set to **Field Entry Form**.

What happens now:

1. Go to a basic page that has been flagged.
2. Click the "Unflag" link for bookmark.
3. The **Field Entry Form** pops up and lets me edit the value of **Rating** or delete the flag.

What I want to happen:

1. Go to a basic page that has been flagged.
2. The **Field Entry Form** is embedded in the page and the user can adjust the rating as he/she likes.

I don't know how to build the form. By digging through the flag module code, I managed to find the class that generates the form in **FieldEntry.php**:

```
/**
 * Class FieldEntry
 *
 * @ActionLinkType(
 *  id = "field_entry",
 *  label = @Translation("Field Entry Form"),
 *  description = "Redirects the user to a field entry form."
 * )
 */
class FieldEntry extends FormEntryTypeBase {

```

But I don't know how to embed this in a node.

I looked at Inline Entity Form but that only supports Commerce modules and Entity Reference fields out of the box.

I also tried the Twig Tweak module and tried to embed an entity edit form using a view that returns the flagging ID like this:

```
{{ drupal_entity_form('flagging', id__value) }}

```

However, this gives me an error:

```
Twig\Error\RuntimeError: An exception has been thrown during the rendering of a template ("The "flagging" entity type did not specify a "" form class.") in "__string_template__87f4d3d6f14aa36d2fb8ce031f07b73d8b577189b4e5f3c535809f672ffb6af8" at line 1. in Twig\Template->displayWithErrorHandling() (line 469 of /app/vendor/twig/twig/src/Template.php).

```

I can embed the entity itself with Twig Tweak just fine (but that is not the goal; the goal is to embed the entity edit form):

```
{{ drupal_entity('flagging', id__value) }}

```

# Answer
> 0 votes
Here's the code I ended up using:

```
/**
 * Implements hook_node_view() for MYMODULE.
 */
function MYMODULE_node_view(array &$build, NodeInterface $node, EntityViewDisplayInterface $display, $view_mode) {
  if ($node->getType() == 'MY_CONTENT_YTPE') {
    if ($display->getComponent('my_flagging_form')) {
      $flag = \Drupal::service('flag')->getFlagById('MY_FLAG');
      $flagging_entity = \Drupal::service('flag')->getFlagging($flag, $node);
      $form = \Drupal::service('entity.manager')
        ->getFormObject('flagging', 'edit')
        ->setEntity($flagging_entity);
      $build['my_flagging_form'] = \Drupal::formBuilder()->getForm($form);
    }
  }
}

/**
 * Implements hook_entity_extra_field_info() for MYMODULE.
 *
 * Https://www.webomelette.com/creating-pseudo-fields-drupal-8
 */
function MYMODULE_entity_extra_field_info() {
  $extra = [];

  $extra['node'][NodeType::load('MY_CONTENT_TYPE')->Id()]['display']['my_flagging_form'] = [
    'label' => t('My flagging edit form'),
    'description' => t('This shows the my flagging edit form.'),
    'weight' => 100,
    'visible' => TRUE,
  ];

  return $extra;
}

```

For more details, see this question.

---
Tags: 8, flags
---


# Question
Title: How can I force users to provide a reason when cancelling their accounts?
I would like to force users to provide a reason for cancelling (a text area would be ideal) their accounts. I have had several users close their accounts on one of my sites recently and I would like to know why.

# Answer
> 6 votes
Here you go, alter the user\_cancel\_confirm\_form.

```
function MYMODULE_form_user_cancel_confirm_form_alter(&$form, &$form_state, $form_id) {
  $form['reason'] = array(
    '#title' => t('Reason'),
    '#type' => 'textarea',
    '#description' => t('We are sad to see you go, why do you want to leave?'),
    '#required' => TRUE, // force to input
  );

  $form['#submit'][] = 'user_cancel_log_reason'; // add custom submit handler
}

function user_cancel_log_reason($form, &$form_state) {
  $reason = $form_state['values']['reason'];
  // do whatever with the reason, e.g watchdog
  watchdog('user', 'User cancel reason:' . $reason);
}

```

# Answer
> 0 votes
I think you can just use this api function http://api.drupal.org/api/drupal/modules!user!user.api.php/function/hook\_user\_cancel/7

# Answer
> 0 votes
For Drupal 8:

```
function MYMODULE_form_user_cancel_form_alter(&$form, &$form_state, $form_id) {
  $form['reason'] = array(
    '#title' => t('Reason'),
    '#type' => 'textarea',
    '#description' => t('Please let us know why you are closing your account.'),
    '#required' => TRUE,
  );

  $form['#submit'][] = 'MYMODULE_logcancelreason'; // add custom submit handler
}

function MYMODULE_logcancelreason($form, &$form_state) {
  $reason = $form_state->getValue('reason');
  $uid = $form['uid']['#value'];
  $reason = 'UID ' . $uid . ' cancellation reason: ' . $form_state['values']['reason'];
  // Log the reason.
  \Drupal::logger('user')->info($reason);
}

```

# Answer
> 0 votes
For Drupal 9:

```
/**
 * Implements a custom cancel form submit handler.
 */
function MYMODULE_user_cancel_form_submit(&$form, FormStateInterface &$form_state) {
  $uid = $form['uid']['#value'];
  $user = \Drupal::currentUser();

  if (!$user->hasPermission('administer users') && $uid == $user->id()) {
    // Hide "A confirmation request to cancel your account
    // has been sent to your email address.".
    \Drupal::messenger()->deleteByType('status');
    $account = User::load($uid);
    $reason = $form_state->getValue('reason');
    $account->set('field_text_log_cancel', $reason);
    $account->save();

    // Cancel the account (from user_cancel_confirm()).
    user_cancel($form_state->getValues(), $uid, $form_state->getValue('user_cancel_method'));

    // Since user_cancel() is not invoked via Form API,
    // batch processing needs to be invoked manually and
    // will redirect to the front page after completion.
    $batch = &batch_get();
    $batch['progressive'] = FALSE;
    batch_process('');
  }
}

```

This code assumes you have added a plain text (long) field with the machine name `field_text_log_cancel`.

---
Tags: users
---