# Question
Title: Export node display with Features not taking in account format of fields
I'm trying to export a node display with features and I already created the feature with the display and imported it to another site.

The problem is that the display has some differences, mainly in the format of the fields (see the graph in yellow). It seems that the format of fields are not exported. I checked the generated code and found nothing about these formats.

Moreover, I'm changing the formats of the fields and features do not change at all, it status is not "Overriden", and I generated it anyway and there is no change at all, despite the different formats.

I don't know if it is a common issue with Display Suite or if I should active another module to do a better export.

How to fix this problem? Do you have exported node displays with features? What else can I do.

# Answer
The format and other settings of the field in a DS display are exported as part of the **field instance** element containing an array of settings per DS display. So, except from the DS display you have to track all the Field instances (from the related Feature section) in your feature.

An example of an exported field instance of a text field field\_location with format **Plain text** in the Full DS view mode in feature file my\_module.field\_instance.inc is:

```
// Exported field_instance: 'node-image-field_location'.
  $field_instances['node-image-field_location'] = array(
    'bundle' => 'image',
    'default_value' => NULL,
    'deleted' => 0,
    'description' => '',
    'display' => array(
      'default' => array(
        'label' => 'inline',
        'module' => 'text',
        'settings' => array(),
        'type' => 'text_plain',
        'weight' => 42,
      ),
      'full' => array(
        'label' => 'above',
        'module' => 'text',
        'settings' => array(),
        'type' => 'text_plain', // This is the exported format
        'weight' => 0,
      ),
      'teaser' => array(
        'label' => 'above',
        'settings' => array(),
        'type' => 'hidden',
        'weight' => 0,
      ),
      'token' => array(
        'label' => 'above',
        'settings' => array(),
        'type' => 'hidden',
        'weight' => 0,
      ),
    ),
    'entity_type' => 'node',
    'field_name' => 'field_location',
    'label' => 'Location',
    'required' => 0,
    'settings' => array(
      'entity_translation_sync' => FALSE,
      'text_processing' => 0,
      'user_register_form' => FALSE,
    ),
    'widget' => array(
      'active' => 1,
      'module' => 'text',
      'settings' => array(
        'size' => 60,
      ),
      'type' => 'text_textfield',
      'weight' => 21,
    ),
  );

```
> 1 votes

---
Tags: 7, features, display-suite
---


# Question
Title: How to set order of Grouping Field in Format Settings
I'm on D7. I have a taxonomy "projects". A project can be "ongoing" or "completed. I currently have a view that get's all projects (projects are a taxonomy/vocabulary). The "ongoing" and "completed" are project types which are also a taxonomy/vocabulary.

In the view, I set Grouping field Nr.1 to Taxonomy Term: Project Type

I want to make sure that "ongoing" is above "completed". How can I do that? Somehow the order changed from "ongoing, completed" to "completed, ongoign" after I updated an ongoing project to completed.

The order of the taxonomy terms seem to not matter.

# Answer
> 1 votes
First, you can set the weight of the Project Type terms in the vocabulary.

Then you have to create the following relationship:

> Entity Reference: Referenced Entity
>
> A bridge to the Taxonomy term entity that is referenced via field\_project\_type

Then, add a Sort Criterion (first) Taxonomy term: Weight using the above relationship.

---
Tags: 7, views
---


# Question
Title: Is it possible to add PHP code in Global: Custom Text?
I have two links to redirect based on if a field is empty or not. Now I use the *Global text* setting to create a link for redirection with A basic `<a>` tag.

How can I add PHP code in a view to verify the field is empty?

# Answer
> 1 votes
First, install the Views PHP module and you can now add a "Global: PHP field" to your views that can include PHP code.

Then add your condition field first in your view and after that your PHP field, so that the condition field value is included in available tokens.

The code of your PHP field should be sth like this:

```
  <?php
      if ($field_test) { // use the field token here and check if empty
       return '<a href="$url1">Exists</a>';
      } else {
       return '<a href="$url2">Not exists</a>';
      }
   ?>

```

See also:

How can I enable Global: PHP field

add Global PHP code field to Views on condition

---
Tags: 7, views, theming
---


# Question
Title: Change Bootstrap column classes based on the result of a view
I have a D8 site with a Bootstrap 3 subtheme and two columns with one region and a block inside each.

I need to change the first column width (col-md-12) to take 100% width when the view block in the second column is empty, and to take just 50% (col-md-6) when it has something to display.

An easy way to achieve this without custom modules?

With this solution I can hide the second region, but how to make the regions talk together and change the first accordingly? Should I make one single region with two blocks within and then change column classes in the region twig template? Is it possible?

Thanx for your attention

# Answer
One way to solve your problem is to implement an hook\_preprocess() in your custom themes' `.theme` file, where you check whether your second block is empty or not and use this information to apply the appropriate (Bootstrap grid) class (to your block in the first column).

Although above suggestion is not using a custom module (it's in your sub-theme), however, I can imagine that this might not be the answer you're looking for.

As you suggest you can also put this logic in your Twig template, but checking whether your block is empty can be a bit troublesome (due to the fact that blocks can be lazy loaded using placeholders, see e.g. Drupal 8 regions with and empty blocks).
> 0 votes

# Answer
I solved putting the logic in my twig template using this construct to check if the view block is empty:

```
{% if page.myregion|render|striptags|trim|length > 0 %}

```

I also had to uncheck "show title" in the block configuration to make it work.

Thanx for the suggestions :-)
> 0 votes

---
Tags: views, 8, theming, blocks, bootstrap-theme
---


# Question
Title: Anonymise Webform submission in database
I am asked to modify the behavior of some webforms on a Drupal 8 instance; data who could identify a user submitting a form should not be stored in the database. Submissions must be sent by email though.

Webforms do have a "Disable saving of submissions" option, however, some of the forms have file fields; files that must be sent as attachements to the mail I mentionned, and those forms cannot work if I activate the option.

I tried creating my own Webform handler but I couldn't find a way to successfully alter submission there. I managed to alter data by using a custom validation class but as I suspected, the data is altered before it gets emailed.

Drupal 'Cron' tasks won't do it either. The legal team asks that the data does not persist in database longer than the time required by the processing of the form.

I may be blind, but am running out of ideas and cannot find a relevant documentation for my problem.

**TL;DR: On webforms with file fields, how can I prevent storage of specific fields in the database or rewrite them while still sending the original data by email**

# Answer
I would intercept on the **redirect/thank you** page after form submission assuming the mail is send directly (is it).

See modules/webform/src/EventSubscriber/WebformSubscriber.php where `$webform_submission = WebformSubmission::load($route_parameters['webform_submission']);`.

You probably need to override the service webform.event\_subscriber defined in webform.services.yml
> 1 votes

---
Tags: 8, webforms
---


# Question
Title: Is it possible to use an image style with a path rather than a URI?
I want to be able to send an image included in a custom module to the `image_style` theme like:

```
  $render_image = [
    '#theme' => 'image_style',
    '#style_name' => $imagecache_template,
    '#uri' => '/modules/custom/MYMODULE/default.png',
    ...
  ];

```

But '#uri' is expecting something in the format `public://` . Is it possible to marshall a relative path somehow?

# Answer
I'll expand a bit on what acrosman answered, only because I needed this exact same thing so hopefully this will help the next person who comes across this.

I'm working from preprocess\_page and using a view to grab my images.

Like his answer make sure you add the ImageStyle:

```
use Drupal\image\Entity\ImageStyle;

```

Once I grabbed the view entity I was able to narrow down my image field and then work my way to the styled image.

```
$image = $entity->get('field_images')->getValue();
$image_entity = File::load($image[0]['target_id']);
$image_uri = $image_entity->get('uri')->value;
$style = ImageStyle::load('my_image_style');
$image_url = $style->buildUrl($image_uri);

```

So overall my whole function to grab the image from a View and apply a custom image style looked like.

```
function _mytheme_preprocess_page_front_projects(array &$variables) {
  $projects = array();
  $view = Views::getView('projects');

  if (is_object($view)) {
    $view->setDisplay('page_1');
    $view->preExecute();
    $view->execute();

    foreach ($view->result as $k => $v) {
      $entity = $v->_entity;

      // Grab image entity.
      $image = $entity->get('field_images')->getValue();

      // Load the first value for preview image.
      $image_entity = File::load($image[0]['target_id']);

      // Grab the uri of that first image.
      $image_uri = $image_entity->get('uri')->value;

      // Using ImageStyle you then load your style.
      $style = ImageStyle::load('my_image_style');

      // Use buildUrl to create the path to your styled image.
      $image_url = $style->buildUrl($image_uri);

      // Then I return the url as an image variable to grab in page template.
      $projects[$k]['image'] = $image_url;
    }

    return $projects;
  }
}

```
> 1 votes

# Answer
I haven't tried it from a render array, but you can load the ImageStyle entity and have it build a URL from a path using `buildUrl()`.

If you are doing this right in the .module file make sure to tell PHP you'll be using ImageStyle, in a plugin or controller you'll want to inject the class.

```
use Drupal\image\Entity\ImageStyle;

```

Then load you're style and build the URL (warning, I have not tested this):

```
$style = ImageStyle::load('img_style');
$image_path = $style->buildUrl('/modules/custom/MYMODULE/default.png');

```

From there you should be able to place that into whatever context you need to get the image rendered the way you'd like.
> 0 votes

---
Tags: 8, media
---


# Question
Title: How to change the path in which are stored the media modules files and images?
When using media entity reference fields, is it possible to change the path where are stored the files and how? Is it possible to store them in the private folder?

# Answer
i have found the radio button for selecting private in

```
/admin/structure/media/manage/file/fields/media.file.field_media_file/storage

```

how to change folder path , using possibly tokens?
> 0 votes

---
Tags: 8, media
---


# Question
Title: How to fetch fields related to node in view templates?
Hi I am trying to do similar in Drupal 8 :

Can we write php conditions in view field templates?

Is that possible to fetch fields related to node such as terms, comments count and comment form link, revisions, voting count and voting widget and edit link in one field template. If I create template file of title field like How can we override view field template in drupal 8 and need to fetch other fields related to node in that same template, But we should not add other fields in view itself but fetch other fields related to node in preprocess or by some other method.

Please suggest, I am trying but not able to conclude exact approach.

File made template based on above which is in action for title field everywhere :

> views-view-field--title.html.twig

Is that possible to fetch other fields related to node in this template without adding fields in view ?

Thanks!

# Answer
In my opinion it's better to write a template preprocess for your view in yourtheme.theme file. hook\_preprocess\_views\_view()

```
function yourtheme_preprocess_views_view(array &$variables) {
  if($variables['view']->id() == "your_view_id") {
    if (isset($variables['rows'][0]['#rows'])) {
      $nodeValues = [];
      foreach ($variables['rows'][0]['#rows'] as $value) {
        $nodeValue['taxonomyValues'] = $value['#row']->_entity->field_taxonomy->entity;
          :
          :
        $nodeValues[] = $nodeValue;
      }
      $variables['node_values'] = $nodeValues;
    }
  }
}

```

Above, is a sample code for fetching a taxonomy reference field. Fetch required fields and pass it in your own variable to views-view.html.twig file

To further give template suggestion for views-view.html.twig use

```
function yourtheme_theme_suggestions_views_view_alter(array &$suggestions, array $variables)

```

In your views-view.html.twig

```
{% for value in node_values %}
   {{value.taxonomyValues}}
{% endfor %}

```
> 1 votes

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


# Question
Title: PDF Preview module not working in ubuntu for Drupal 8.5 version
PDF Preview module not creating the image(first page of PDF) in docker (Ubuntu) for Drupal 8.5 version.

I have installed imagick(configured the exce path in imagetoolkit module) and Ghostscript and also configured the PDF Preview to the file filed of my content type.

But when I upload the Pdf file I get below error,

```
ImageMagick error 1:
convert: no images defined '/var/www/html/web/sites/default/files/pdfpreview/58-samplepdf_9.jpg' @ error/convert.c/ConvertImageCommand/3210.

```

Could any one please help me to resolve this issue? Please find more details below, PHP version - 7.0; Imagick version- 7.x; Ghostscript version - 9.18; OS - Ubuntu 16.04

I guess ghostscript is creating the issue here. Is there any post installation configuration required in docker that we need do for imagic or ghostscript.

# Answer
> 2 votes
I found the solution by running the below command in Docker file and run the docker build.

# Install ImageMagick

RUN apt-get update && apt-get install -y \ libmagickwand-dev --no-install-recommends \ && pecl install ImageMagick\* \ && docker-php-ext-enable ImageMagick

# Install GhostScript

RUN apt-get update && apt-get -y install ghostscript && apt-get clean

---
Tags: 8, media, files
---


# Question
Title: Returning an array of all content types in a folder
I exported all my configuration files to config/sync. Now i'm trying to get all the content types from that folder into an array.

Its a bit like what this code does:

```
$manager = \Drupal::entityTypeManager();

$manager->getStorage('node_type')->loadMultiple();

```

But that returns all the Installed content types on my drupal. I just want the ones from my sync folder because i'm making twig templates from them.

# Answer
> 1 votes
If you mean node types, every node type generates (amongst others) a file called `node.type.NODE_TYPE_MACHINE_NAME.yml` when exporting to config/sync

# Answer
> 0 votes
To know the list of files in your config/sync folder

* Open terminal
* Go to config/sync folder in your site folder `cd config/sync`
* Run a grep command like `ls | grep node.type`

---
Tags: 8, entities
---


# Question
Title: How do I write a custom migrate destination plugin in for a node type?
I've got a node type in Drupal 8 that uses field collections (from the module of the same name). The Field Collections module doesn't yet have a working migration destination plugin, so what I'd like to do is use some kind of post-processing to (ugh) brute-force the field collection data into the nodes (note that I've tried the -dev version of Field Collection, and the destination plugin doesn't appear to be functional). Note that my source is an SQL database and not a Drupal instance.

Here are the relevant files:

The migration definition file:

```
id: fm_quiz
label: FM Quiz
migration_group: quizzes
source:
  plugin: fm_quiz
  key: source
destination:
  plugin: fm_quiz
process:
  type:
    plugin: default_value
    default_value: quiz
  title: title
  uid:
    plugin: default_value
    default_value: 1
  sticky:
    plugin: default_value
    default_value: 0

```

The destination plugin:

```
<?php

/**
 * @file
 * Contains \Drupal\fm_quiz\Plugin\migrate\destination\FMQuiz.
 */

namespace Drupal\fm_quiz\Plugin\migrate\destination;

use Drupal\migrate\Plugin\migrate\destination\EntityContentBase;
use Drupal\migrate\Row;

/**
 * @MigrateDestination(
 *   id = "fm_quiz"
 * )
 */
class FMQuiz extends EntityContentBase {

  /**
     * {@inheritdoc}
     */
  public function import(Row $row, array $old_destination_id_values = array()) {
    $node = $this->getEntity($row, $old_destination_id_values);
    print_r($node);

    return [$node->id()];
  }

}

```

At the moment, Drupal doesn't seem to want to recognize that this migration exists as written.

If I change the destination to "entity:node", then it imports the nodes as expected. If I change the destination in both files to "entity:node:fm\_quiz", then Drupal says that "Migration fm\_quiz did not meet the requirements" (and provides no other information).

Am I doing something wrong, or is what I'm trying to do just not possible right now? Do I need to just make an end run around the migration system?

# Answer
> 4 votes
It's my understanding that your migration problem lies in the fact that you can't add a custom destination plugin for nodes. Your exact migration strategy is not entirely understood from your question, so I'm going to address only the part related to destination migration plugin, which might help you addressing the problem with adding custom logic to a migration process.

Destination plugins for entity migrations are indeed created by a deriver (see MigrateEntity::getDerivativeDefinitions()) and adding custom destination plugins is not as straightforward as creating, for example, a custom source plugin which extends an existing source plugin, because destination entity type is determined from the ID of destination plugin (`entity:[name]`).

You can still create custom destination plugins for entity migrations in the following way:

Migration definition file:

```
id: fm_quiz
label: FM Quiz
migration_group: quizzes
source:
  plugin: fm_quiz
  key: source
destination:
  plugin: fm_quiz
process:
  type:
    plugin: default_value
    default_value: quiz
  title: title
  uid:
    plugin: default_value
    default_value: 1
  sticky:
    plugin: default_value
    default_value: 0

```

Custom migration destination plugin:

```
<?php

namespace Drupal\fm_quiz\Plugin\migrate\destination;

use Drupal\Core\Entity\Entity;
use Drupal\migrate\Plugin\migrate\destination\EntityContentBase;
use Drupal\migrate\Plugin\MigrationInterface;
use Drupal\migrate\Row;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * @MigrateDestination(
 *   id = "fm_quiz"
 * )
 */
class FmQuizNodeDestination extends EntityContentBase {

  /** @var string $entityType */
  public static $entityType = 'node';

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) {
    return parent::create($container, $configuration, 'entity:' . static::$entityType, $plugin_definition, $migration);
  }

  /**
   * {@inheritdoc}
   */
  public function import(Row $row, array $old_destination_id_values = array()) {
    // Add custom code here, if needed.
    return parent::import($row, $old_destination_id_values);
  }

}

```

Technically, it's the same class that `entity:node` destination plugin would use, but the `create()` method of the custom class *tricks* parent class to use storage of `node` entity type.

# Answer
> 0 votes
Field Collection is deprecated in Drupal 8. From the project page:

> Paragraphs is likely to replace field collection for Drupal 8. Field collection is on its way to being deprecated. It is recommended to use paragraphs instead of field collection for Drupal 8 projects.

You should replace your Field Collections with Paragraphs, and migrate Field Collection data into those. Assuming that you're migrating from a Drupal 7 site, this process is mostly working as per \[META\] Migrate support for importing field collections as paragraphs. The only remaining task still open (at the time of this writing) is Field collections deriver and base migration, which is awaiting feedback from additional reviewers.

So it shouldn't be necessary for you to write a custom migration.

---
Tags: 8, migrations, entities
---


# Question
Title: Drupal Search - Not searching for menu items
The default search module inside Drupal works perfect my project but the client wants to search for menu items too. The search module won't find menu items and I can't find a normal description or tutorial that demonstrates how to search them.

Has anyone done something like this?

# Answer
As a work around I would try to creat a "funny" content type for each Menu Item and them redirect it to the original page link of each Menu Item.
> 0 votes

---
Tags: search, navigation
---


# Question
Title: How to permit users to add more items to a multivalue field conditionally?
I'm working on a publication management site and need a multivalue field collection (which contains several file upload fields). Our authors can upload multiple versions of their publication but only after reviewers (or managers) allow it. Basically I would like to hide the "add another item" button and show if certain conditions are met.

# Answer
Just place this in a custom module replacing what is given in CAPITAL letters:

```
function my_module_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'CONTENT_TYPE_node_form') {
    if (CONDITIONS) {
      unset($form['field_files_collection'][LANGUAGE_NONE]['add_more']);
    }

  }
}

```
> 0 votes

---
Tags: 7, entities
---


# Question
Title: How to re-upload an image but not removing it
I have an image field which has 1 value limited. I need to change the uploading photos frequently, and I hope the old images will not be removed. Is it possible to achieve this?

# Answer
> 0 votes
For those who really think that they want to hack core: Open includes/file.inc and look for the function drupal\_unlink. Add return FALSE; as the first line and NO files will be deleted. Better yet, add a conditional statement that checks the $uri to ensure that it is a file that you don't want to delete.

I got above solution here, How to keep underlying file when deleting a Filefield value

# Answer
> 0 votes
It's not really clear what you're trying to achieve, but basically there are two ways to go:

* Don't use an image field, but use an "entity relation" to a media entity instead. (Media is a core module \>= Drupal 8.4, or a contrib module \<= Drupal 8.3)
* User revisions: Create a new revision of your node every time you update the image field. You then can view older versions of the image in the version history of your page.

---
Tags: media
---


# Question
Title: Ability to flag each uploaded image separately after doing multiupload
I want to create some kind of photography website where users will be able to flag some images for later use.

This is the user story:

1. Photographer upload images of the client event on the website
2. Page with a gallery is created
3. A client comes to the gallery page and marks few items using Flag module
4. A view is created with a list of flagged images so Photographer can get a list of images for further manipulation

The problem is if I use multiple image field there is no way to use Flag module as it works only with nodes, and I have all images in a single node.

There is this issue in Flag module where it says why is not possible.

So I'm wondering if there is a way to convert images to nodes after creating an initial node that contains all of the images?

Or do you have any other suggestion how to handle this?

# Answer
> 0 votes
I kinda went on another way, instead of doing this conversion I actually just used Media module which is now in the Core, and with that, I get every image as a single entity that is then able to be flagged.

So

* Use Media with Entity Browser instead of regular Image Field
* Create view block and placed it in the content with contextual filters to take current ID from URL which then lists all images + flags
* Hide images on manage display in the content type so I don't get duplicates
* Create another View with flag relationship to list only flagged content

And that did the trick, I now have a gallery on a page where every image has a flag under it, and I'm able to export only flagged ones.

# Answer
> 0 votes
It's easily possible to create a node per uploaded picture using a custom module. Alternatively, you could use https://www.drupal.org/project/node\_gallery to let users upload every picture to its node from the very beginning.

---
Tags: nodes, ajax, flags
---


# Question
Title: A different template based on a taxonomy term in views
I'm using drupal 8.

I use the view provided by default: "taxonomy term".

I would like to make a presentation of the page (and not only of the node) different according to the term of taxonomy.

I tried with this code (in .theme) and template suggestion :

```
use Drupal\taxonomy\Entity\Term;

function THEME_NAME_theme_suggestions_page_alter(&$suggestions, &$vars) {
  if (\Drupal::routeMatch()->getRouteName() == 'entity.taxonomy_term.canonical' && $tid = \Drupal::routeMatch()->getRawParameter('taxonomy_term')) {
    $term = Term::load($tid);
    $suggestions[] = 'page__taxonomy__' . $term->getVocabularyId();
  }
}

```

But it does not work because (i think) it is a view.

I tried with the views template suggestion but it works only for the whole page and not for each taxonomy term.

Does anyone have the solution ?

# Answer
> 2 votes
You can define each template by using template page--taxonomy--term--xxx.html.twig where xxx is your term id.

In your code, `$term->getVocabularyId();` will return machine name of vocabulary, not the term id. It mean all term of this vocabulary will use this template.

# Answer
> 2 votes
If you are looking to add suggestions based on the name of each term then you may add as below

```
use Drupal\taxonomy\Entity\Term;

function THEME_NAME_theme_suggestions_page_alter(&$suggestions, &$vars) {
  if (\Drupal::routeMatch()->getRouteName() == 'entity.taxonomy_term.canonical' && $tid = \Drupal::routeMatch()->getRawParameter('taxonomy_term')) {
    $term = Term::load($tid);
    $suggestions[] = 'page__taxonomy__' . $term->getVocabularyId();
    // To add suggestions based on route name
    $suggestions[] = 'page__taxonomy__term__' . strtolower(str_replace(' ', '_', $term->getName()));
  }
}

```

---
Tags: views, 8
---


# Question
Title: How to override Entity Autocomplete required validation error message?
I have entity reference autocomplete field (which is term reference field )

users are not allowed to create new terms while node creation.

The validation error shows like below on form submit :

> There are no entities matching "newterm".

I need to override this message with something like ***"No new terms are allowed please select from existing terms"***

When I tried to find code from where it is working it looks from this :

**core/lib/Drupal/Core/Entity/Element/EntityAutocomplete.php** and function where message is there : https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21Element%21EntityAutocomplete.php/function/EntityAutocomplete%3A%3AmatchEntityByTitle/8.0.x

Please suggest how I can override this. I tried searching lot but was not able to find right direction and have tried overriding status message as well but sure how to proceed with this.

Thanks!

# Answer
In HOOK\_form\_FORM\_ID\_alter() add `#element_validate` attribute to the form element

```
$form['field_your_field_name']['#element_validate']

```

**Reference:** https://api.drupal.org/api/drupal/developer!topics!forms\_api\_reference.html/7.x#element\_validate
> 2 votes

---
Tags: 8, entities
---


# Question
Title: Is Drupal Console aimed to replace Drush?
Does the Drupal Console project available for Drupal 8) aim to replace, partially or totally, Drush?

# Answer
> 22 votes
Drupal console is a Drupal CLI tool, from the-ground-up, that leverages Symfony CLI components and modern PHP OOP design practices. Drush is a venerable Drupal CLI tool that has been around since Drupal 4.7, thus built with an older design practice. However, since Drush 9 it's been rearchitected to use the Symfony components as well.

There is overlap based on both projects being a general purpose Drupal administration CLI tool. Drush has more features, due to its age, but Drupal Console has some new features due to its more modern design.

In a commercial software world, there would be some profit motive to merge/buy-mind-share/etc. However, in the open source world they both stand as their own independent projects, with its maintainers motivated for other reasons than to build the *one true Drupal CLI tool to bind them all* (tm).

It might help to read *Ten things you need to know about Drupal Console* coming from Ray Saltini of FFW (the company supporting the lead developer Jesus Olivas of Drupal Console), & *Drush and the Drupal Console with Drupal 8* from Greg Anderson (one of the maintainers of Drush).

To explicitly answer the question, *maybe*. If you're wondering *which should I use?*, the answer is *maybe both* for the time being. Perhaps Drupal Console will eclipse Drush, but right now both have useful feature sets for administering your Drupal site.

# Answer
> 3 votes
Sean Hamlin - 10 things I learnt building in Drupal 8

> 1. Drupal Console is awesome
>
> Every time you need to generate a custom module, or a new block in a custom module, you can quickly and easily use Drupal Console to produce the code scaffolding for you. This quite easily makes the job of a developer a lot less stressful, and allows you to focus on actually writing code that delivers functionality.

Sounds like DC does things that Drush can't.

Now to answer your question, IDK if their objective is to replace Drush, but it's definitely looking like a Drush substitute. To me this is like Display Suite Vs Panels.

# Answer
> 2 votes
I'm facing the fact of I should write Drush Commands or Drupal Console Commands, but in my case I need to maintain the same module in Drupal 8 and Drupal 7.

As you know we don't have Drupal Console in Drupal 7, so in this case if I create Drupal Console Commands I don't will have this commands available in my Drupal 7 module. But if I use Drush Commands I will have quickly the same commands in Drupal 8 and Drupal doing a few changes related to the API.

So, I don't think that Drupal Console will replace for the moment Drush, but maybe in the future we will need to write some post like:

"How to migrate my Drush Commands to Drupal Console Commands?" :-D

# Answer
> 1 votes
* Drupal Console is built on top of Symfony and POO.
* Drush up to 8 (included) isn't built on top of Symfony and POO.
* Drush 9 is built on top on top of Symfony and POO.

On the other way:

* Drupal Console use Command dir on your website installation
* Drush use Commands dir on your website installation

I think, and it's my own opinion, work on 2 different console tools is a less of time. Drush is more know into the community. Maybe Drupal Console will be forked to Drush and just Drush will survive.

---
Tags: 8
---


title: Drush stuck in "Killed" loop

text:
# Question
Title: Drush stuck in "Killed" loop
I recently installed Drush 8.1.2 from the tarball distribution available on Github and `composer install`-ed it (this is after trying to use the `.phar` to very similar ends).

Oddly, whenever I try to run `drush` from my shell (with or without subcommands), I get no output for a while, then `drush` just keeps printing `Killed` over and over, every few seconds.

Running `ps aux | grep drush` reveals *dozens* of spawned `drush` processes; simply sending an interrupt via `^C` doesn't make the `Killed` stop. Because the processes spawn about as quickly as I can `kill` them, don't respond to `killall`, and cause surprisingly large amounts of when inputting commands, I have to reboot the system to kill the processes.

The same thing happens with the `.phar` version. This is not an issue with `drush` available via `apt`, but that's drush 5, which is horribly outdated. The same thing happens with `drush-8.1.1`, the previous release. This also occurs when installing globally via:

```
$ composer global require drush/drush:dev-master

```

According to my host's monitoring tools, this also sends my CPU usage skyrocketing up to about 70% until reboot, as well.

I'm on an otherwise brand-new Ubuntu 16.04 VM, with Drupal 8 installed.

**Update:** I've now tried the snippet at `drush.org` (below) on my laptop (running OS X 10.11, 8GB RAM) as well as on a much larger cloud instance with similar CPU and RAM specs, running Ubuntu. The out-of-memory error persists on this new box, but the installation succeeds without issues and produces a working `drush` on my laptop.

```
# Download latest stable release using the code below or browse to github.com/drush-ops/drush/releases.
php -r "readfile('http://files.drush.org/drush.phar');" > drush
# Or use our upcoming release: php -r "readfile('http://files.drush.org/drush-unstable.phar');" > drush

# Test your install.
php drush core-status

# Make `drush` executable as a command from anywhere. Destination can be anywhere on $PATH.
chmod +x drush
sudo mv drush /usr/local/bin

# Optional. Enrich the bash startup file with completion and aliases.
drush init

```

I suspect that `drush` requiring more than 8GB of RAM for normal operation isn't expected behaviour; it's probably pointless to spawn boxes with higher-performance CPU and RAM configurations at this point.

**Notes**:

* I've allowed PHP to allocate 384M of RAM in my `php.ini` -- the process still respawns and prints `Killed`, all while making my system lag intensely.
* as much as I'd like to bring out `strace`, the lag on my system is a major impediment. Keystrokes take a second or two to register as long as the processes are spawning.
* This particular box has PHP 5.6, but the issue is also present on a box running PHP 7.0.

# Answer
> 0 votes
I haven't found a solution to the "`Killed`" loop issue (even after scaling up to the largest instance offered by my host, which has 64GB of RAM), but I've managed to get `drush` itself to work by pulling the `.phar` from Github and making it executable.

Using the install script still doesn't work (still leads to the `Killed` loop) despite making sure that everything that should be executable is executable, and installing from the tarballs or via composer likewise fails in a similar way.

# Answer
> 0 votes
Same happened for me, PHP 7.1 / Drupal 8.5

The issue itself was from an old version of drush 9 (9 beta 8 in my case)

Updating to 9.2.1 fixed it.

---
Tags: drush
---


# Question
Title: How to check if an edited form is editing a translated node
I have a content type named film.

Original language of a film is FR.

Let say I have 2 translatable fields on a total of 10 fields in film.

I am using this code to alter the add/edit form of film:

```
function mymodule_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  switch ($form_id) {
    case 'node_film_edit_form': // edit
    case 'node_film_form': // Add
      alter_film($form, $form_state, $form_id);
      break;
    ...
  }
}

```

In the alter\_film function, I would like to add a custom submit only if the edited form is for French (Original language)

```
function alter_film(&$form, FormStateInterface $form_state, $form_id) {
  ...
  //HERE IS MY PROBLEM:
  //HOW TO KNOW IF IT IS TRANSLATED FILM
  if (! $is_translated_film){
    $form['actions']['submit']['#submit'][] = "submit_film";
  }
  ...
}

```

The question is: what check could be made to know which form is edited: the original language form (10 fields) or the translated language form (2 fields)

As a side question, I don't understand why there is no difference in the dpm($form); output if I execute one in the French form and the other one in the English form. I am asking this, because in `/admin/config/regional/content-language`, I have checked `Hide non translatable fields on translation forms`. And I would expect to have 10 fields in the french form array and only 2 (translatable) fields in the translated form array.

In the translated form, only 2 fields are **displayed** as expected, but I am wondering why the 10 fields are **included in the array**.... I ask that just out of curiosity

# Answer
I could answer myself for the first question. The following line will give me the edited language.

```
$form_state->getFormObject()->getEntity()->get('langcode')->value;

```

But, maybe, the following is better:

```
$is_original_language = $form_state->getFormObject()->getEntity()->get('default_langcode')->value;

```

It is better, because original language could vary. In this case on the Add/Edit Node, Add new translation and Edit translations the return value can be parsed directly. Add Node or add new translation returns a Boolean while the edit forms return an int (1/0).
> 1 votes

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


# Question
Title: \Drupal\search_api\Entity\Index::load('INDEX_ID'); returns null
I am trying to create a module that executes a search -- I tried to utilize the documentation for calling a search in code but

$index = \Drupal\search\_api\Entity\Index::load('INDEX\_ID');

gives me $index == NULL so the very second line

$query = $index-\>query();

blows it up. I tried replacing 'INDEX\_ID' with 'default\_index' but that didn't help. Search API is definitely enabled. Any idea why \Drupal\search\_api\Entity\Index::load would keep giving me NULL?

# Answer
> 0 votes
That is because you need to create an index first.

Go to

```
/admin/config/search/search-api

```

and create your index then replace the **INDEX\_ID** in your code with the id you have set for the new index.

You might have to create a server too if you don't have any configured. I have used the default DB Search API. Enable ***Database Search***.

```
/admin/modules?filter=search

```

Then create the server where you created the index:

```
/admin/config/search/search-api

```

Then configure the index to use the server and enable the index.

*Don't forget to process the indexing for your new index. :)*

---
Tags: search
---


# Question
Title: How to tell if my Drupal site is comprised from the SA-CORE-2018-002 -- 2018 March exploit?
Just released exploit: https://www.drupal.org/sa-core-2018-002 --- Drupal core - Highly critical - Remote Code Execution - SA-CORE-2018-002

* How can I tell if someone used this exploit to hack my site?
* What can they do with this exploit if executed properly?
* I can't update my Drupal sites now, what is a good alternative to patch up this hole easily?

# Answer
> 8 votes
**What could happen**

I had a personal Drupal site hacked during Drupalgeddon, an exploit of similar severity (though of a different type). In terms of "what could happen," in that case the hacker put several "back door" files into my codebase (I knew very little about development at the time, and had no Git repository), from which he could send out spam email. The domain involved was blacklisted in spam filters, and it was a huge mess to be able to send email from that domain for the several months I had kept it afterward.

Since this vulnerability permits remote code execution, the attacker could presumably install modules to carry out phishing attacks, carry out commands on the command line with php exec(), steal passwords, and thereby compromise much of your server. The damage could range from something as simple as your machine being recruited as a spam engine or botnet node, or if you have sensitive information, the attacker might steal it and either resell it or blackmail you, depending on the information and the attacker's motives.

**How to tell if you've been hacked**

Most of the time, your site will not be defaced. When two groups of 14 year old script kiddies go at each other you might see a site defaced with Goatse images (NSFW), but unless the hacker has something against you personally he isn't going to do this. The goal for the hacker is either money or the ability to commit crimes with someone else's computer.

Now with that in mind, common things you will see are new users being created (especially admin users), and in the logs you may see a particular IP sending only one type of (abnormal) request. In the Drupalgeddon case, I was able to figure it out by seeing POST requests to a php file in my access log.

**If you cannot patch your site right away**

If you cannot patch the site now, I would recommend cutting the apache/nginx server so no one can get to your site. Or, have the server direct all traffic to an HTML page explaining you are down for maintenance, aka "hard maintenance mode." In all cases, you do not want to allow a visitor to have any shot at bootstrapping Drupal, until you can get an upgrade or patch in place.

And thinking back to my site getting hacked, remember that the first Drupalgeddon attacks started 7 *hours* after the release, and it was in the form of a script that auto-hacked thousands of sites. Move quickly!

**If you are hacked**

Hopefully you have a backup, in which case the best bet is to "nuke the whole site from orbit" and start over with a new server. I did a manual DB and file audit once because I didn't have Git and regular backups in place - it takes a *very* long time, but if it does happen, take a deep breath, and learn Git and learn how to set up a proper backup environment. If you have a business and its a customer site, tell them the truth up front. You will probably lose them, but better to lose a customer (you can get new ones) than your reputation.

# Answer
> 10 votes
**How can I tell if someone used this exploit to hack my site?**

Your Drupal 7 or 8 site can experience loss or theft of data, data can be removed, deleted or changed, wreaking havoc on the site in many different ways.

See this Stack Exchange post for general information on checking to see if your website has been hacked.

**What can they do with this exploit if executed properly?**

The exploit is a remote code execution vulnerability, which means any data has the potential of being affected.

This exploit has been given a risk score of 21/25, which is almost the highest that it gets. This risk score also defines the following vulnerabilities, among others:

* AC (Access complexity): easy (no skill) to access and exploit
* A (Authentication): no special authentication needed
* Cl (Confidentiality impact): all non-public data is accessible
* II (Integrity impact): All data can be modified or deleted

Read more about risk scoring and definitions here.

**I can't update my Drupal sites now, what is a good alternative to patch up this hole easily?**

There is a patch available if you are unable to update core right away. From Drupal.org:

> If you are running 7.x, upgrade to Drupal 7.58. (If you are unable to update immediately, you can attempt to apply this patch to fix the vulnerability until such time as you are able to completely update.)
>
> If you are running 8.5.x, upgrade to Drupal 8.5.1. (If you are unable to update immediately, you can attempt to apply this patch to fix the vulnerability until such time as you are able to completely update.)

To read more, here is an FAQ about the exploit

# Answer
> 1 votes
**How to patch Drupal 7.x by hand against Drupal core - Highly critical - Remote Code Execution - SA-CORE-2018-00**

If you are on Drupal 7.x and are unable to update your live site to 7.58, aren't familiar with applying patches, or are on a Drupal version for which the patch fails do the following :

1\> Download and extract Drupal 7.58.

2\> Copy the /includes/request-sanitizer.inc file from the 7.58 distribution into your website's /includes directory ( easiest via FTP or your hosting control panel file manager ).

3\> Edit the version of /includes/bootstrap.inc on your live website ( backup first ! ). Find the function \_drupal\_bootstrap\_configuration(). Add the following 3 lines after the statement drupal\_settings\_initialize(); :

```
// Sanitize unsafe keys from the request.
require_once DRUPAL_ROOT . '/includes/request-sanitizer.inc';
DrupalRequestSanitizer::sanitize();

```

Save.

Relax.

# Answer
> 0 votes
Here's a simple 1-2-3 process all here:

1. Copy code to clipboard from here https://cgit.drupalcode.org/drupal/rawdiff/?h=7.x&id=2266d2a83db50e2f97682d9a0fb8a18e2722cba5 or as quoted below.
2. create a blank file called 2018march.patch file in the root folder of your drupal directory.
3. Paste the code into the file
4. Run the command in the terminal: **patch -p1 \< 2018march.patch**

If you don't have SSH or terminal access. You'll need to do it manually by hand using user's @elb solution.

```
diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc
index 655db6d..880557e 100644
--- a/includes/bootstrap.inc
+++ b/includes/bootstrap.inc
@@ -2632,6 +2632,10 @@ function _drupal_bootstrap_configuration() {
   timer_start('page');
   // Initialize the configuration, including variables from settings.php.
   drupal_settings_initialize();
+
+  // Sanitize unsafe keys from the request.
+  require_once DRUPAL_ROOT . '/includes/request-sanitizer.inc';
+  DrupalRequestSanitizer::sanitize();
 }

 /**
diff --git a/includes/request-sanitizer.inc b/includes/request-sanitizer.inc
new file mode 100644
index 0000000..1daa6b5
--- /dev/null
+++ b/includes/request-sanitizer.inc
@@ -0,0 +1,82 @@
+<?php
+
+/**
+ * @file
+ * Contains code for sanitizing user input from the request.
+ */
+
+/**
+ * Sanitizes user input from the request.
+ */
+class DrupalRequestSanitizer {
+
+  /**
+   * Tracks whether the request was already sanitized.
+   */
+  protected static $sanitized = FALSE;
+
+  /**
+   * Modifies the request to strip dangerous keys from user input.
+   */
+  public static function sanitize() {
+    if (!self::$sanitized) {
+      $whitelist = variable_get('sanitize_input_whitelist', array());
+      $log_sanitized_keys = variable_get('sanitize_input_logging', FALSE);
+
+      // Process query string parameters.
+      $get_sanitized_keys = array();
+      $_GET = self::stripDangerousValues($_GET, $whitelist, $get_sanitized_keys);
+      if ($log_sanitized_keys && $get_sanitized_keys) {
+        _drupal_trigger_error_with_delayed_logging(format_string('Potentially unsafe keys removed from query string parameters (GET): @keys', array('@keys' => implode(', ', $get_sanitized_keys))), E_USER_NOTICE);
+      }
+
+      // Process request body parameters.
+      $post_sanitized_keys = array();
+      $_POST = self::stripDangerousValues($_POST, $whitelist, $post_sanitized_keys);
+      if ($log_sanitized_keys && $post_sanitized_keys) {
+        _drupal_trigger_error_with_delayed_logging(format_string('Potentially unsafe keys removed from request body parameters (POST): @keys', array('@keys' => implode(', ', $post_sanitized_keys))), E_USER_NOTICE);
+      }
+
+      // Process cookie parameters.
+      $cookie_sanitized_keys = array();
+      $_COOKIE = self::stripDangerousValues($_COOKIE, $whitelist, $cookie_sanitized_keys);
+      if ($log_sanitized_keys && $cookie_sanitized_keys) {
+        _drupal_trigger_error_with_delayed_logging(format_string('Potentially unsafe keys removed from cookie parameters (COOKIE): @keys', array('@keys' => implode(', ', $cookie_sanitized_keys))), E_USER_NOTICE);
+      }
+
+      $request_sanitized_keys = array();
+      $_REQUEST = self::stripDangerousValues($_REQUEST, $whitelist, $request_sanitized_keys);
+
+      self::$sanitized = TRUE;
+    }
+  }
+
+  /**
+   * Strips dangerous keys from the provided input.
+   *
+   * @param mixed $input
+   *   The input to sanitize.
+   * @param string[] $whitelist
+   *   An array of keys to whitelist as safe.
+   * @param string[] $sanitized_keys
+   *   An array of keys that have been removed.
+   *
+   * @return mixed
+   *   The sanitized input.
+   */
+  protected static function stripDangerousValues($input, array $whitelist, array &$sanitized_keys) {
+    if (is_array($input)) {
+      foreach ($input as $key => $value) {
+        if ($key !== '' && $key[0] === '#' && !in_array($key, $whitelist, TRUE)) {
+          unset($input[$key]);
+          $sanitized_keys[] = $key;
+        }
+        else {
+          $input[$key] = self::stripDangerousValues($input[$key], $whitelist, $sanitized_keys);
+        }
+      }
+    }
+    return $input;
+  }
+
+}

```

---
Tags: security, version-control
---


title: Send user email through rest services

text:
# Question
Title: Send user email through rest services
I made a view, with a contextual filter in the user id. The fields are:

* Name
* uid
* Email.

\[ { "username": "pruthiswebar", "id": "8" } \]

If I am logged, I can see the email, if I go to anonymous user, I can´t. There is not a permission for "show user email" or something? How can I configure this?

# Answer
> 1 votes
To add informations to the view, which are not displaying of whatever reasons - you can hook into the view and "print" the informations manually.

**Step 1** Create a custom module (https://www.drupal.org/docs/8/creating-custom-modules) I'm not sure, but probably you can add the preprocess in the `MYTHEME.theme`-File. Then you do not need your own module for this.

**Step 2** Add the preprocess hook (https://api.drupal.org/api/drupal/core%21modules%21views%21views.theme.inc/function/template\_preprocess\_views\_view/8.5.x)

```
MYMODULE_preprocess_view(&$variables) {
    // Todo: check if the view is the view you want to add the user email.
    $user_id = 1; // Change for other users.
    $user = Drupal::entityTypeManager()->getStorage('user')->load($user_id);
    $variables['users'][$user_id] = $user;
}

```

**Step 3** In the twig-template of the view you can add the userdata (https://api.drupal.org/api/drupal/core%21modules%21views%21views.theme.inc/group/views\_templates/8.5.x)

```
{{ dump(users) }}     {# for the user array. #}
{{ dump(users[1]) }}  {# for the user with the id 1 #}

```

---
Tags: users, 8
---


title: Get labels of view modes in Drupal 8

text:
# Question
Title: Get labels of view modes in Drupal 8
I'm trying to rebuild the pullquote module in Drupal 8 but am running into an issue accessing view modes. In the Drupal 7 version, the view\_modes variable is set by the following lines:

```
$entity_info = entity_get_info('node');
$view_modes = $entity_info['view modes'];
$view_mode_options = array();

foreach ($view_modes as $mode => $settings) {
  $view_mode_options[$mode] = $settings['label'];
}

```

However, `entity_get_info()` has been depreciated in Drupal 8, and according to the documentation I found, replaced with `\Drupal::entityTypeManager()->getDefinition()`.

So I tried replacing the first line:

```
$nodeEntity = \Drupal::entityTypeManager()->getDefinition('node');

```

but the array was empty, so maybe I'm using the wrong tool.

I then found this answer for accessing a list of all view nodes.

```
$view_modes = \Drupal::entityQuery('entity_view_mode')
  ->condition('targetEntityType', 'node')
  ->execute();

```

It worked, however, they were returned like this:

```
['node.full', 'node.rss', 'node.teaser']

```

But here's the problem. I'm using these view modes as options in a form. When the form is saved in configuration, having a key with a period breaks the YAML file with the following error: `The website encountered an unexpected error. Please try again later. Drupal\Core\Config\ConfigValueException: node.full key contains a dot which is not supported. in Drupal\Core\Config\ConfigBase->validateKeys()`. I'm confused though, because I map over the array so that I'm stripping the names of ".node"

Here's my full code for reference:

```
// Load the list of avialable view modes.
$view_modes = \Drupal::entityQuery('entity_view_mode')
  ->condition('targetEntityType', 'node')
  ->execute();

// remove "node."
$view_mode_options = array_map(function ($mode) {
  $parsed = substr($mode, 5);
  return $parsed;
}, $view_modes);

$form['view_mode_settings']['pullquote_view_modes'] = [
  '#type' => 'checkboxes',
  '#title' => t('View Modes'),
  '#options' => $view_mode_options,
  '#default_value' => $config->get('pullquote_view_modes'),
  '#description' => t('Choose which view modes will load pullquote code and render pullquotes. For better performance you should only load pullquote where you need it.'),
   '#states' => array(
     'visible' => array(
       ':input[name="pullquote_load_by_view_mode"]' => array('value' => 1),
       ':input[name="pullquote_scope"]' => array('value' => 0),
     ),
   ),
];

```

Now the view modes display properly on the page, but I still get the error that Drupal can't save "node.full" in configuration, which is confusing because the page displays only "full."

Is there a method for getting the label of different entity types? Or is there a way to actually parse "node.full" down to a string that is only "full"--both when it displays and how Drupal understands it?

# Answer
Drupal 8 services are essentially helpful objects (tools), which live inside the services container (tool belt). Calling a service returns an object, essentially providing a clear path to the helper methods within that class. As previously answered, `EntityDisplayRepository` class contains various methods, specifically one that will return an array of entity view modes (see a list of available methods). By calling `\Drupal::service('entity_display.repository')` and storing it in a variable, you now have an object that you can then call `EntityDisplayRepository` methods from, which in your case, is to return 'node' view modes.

```
/**
 * Implements hook_preprocess_page().
 *
 * This function is called before the page is rendered.
 */
function modulename_preprocess_page(&$vars) {
  // call the entity service.
  $nodeEntity = \Drupal::service('entity_display.repository');

  // call the necessary method in order to return 'node' view modes.
  $nodeEntity->getViewModes('node');

  // one line: \Drupal::service('entity_display.repository')->getViewModes('node');
}

```
> 5 votes

# Answer
You are looking for `\Drupal\Core\Entity\EntityDisplayRepository::getViewModeOptions()` aka the service `\Drupal::service('entity_display.repository')`, that gives you an array with the label.
> 4 votes

---
Tags: 8, nodes, configuration
---


# Question
Title: Why is my twig variable not working inside my block twig?
I have a field I'm pulling into a block twig template `block--block-03.html.twig`, and it outputs fine by itself (= `{{content.field_content_side}}`). But when I put it inside of a conditional it is not working.

Here's my code to illustrate what I mean:

```
<h1>{{ content.field_content_side }}</h1>
<h2>{% if content.field_content_side == 'left' %}col-sm-push-7{% else %}wtf{% endif %}</h2>

```

The output is here:

Why is it recognizing the twig variable correctly as `left` (= 1st line of my code), but in the conditional it is saying it's not `left` (= 2nd line of my code)?

# Answer
Because the field is being rendered, which is different than evaluating its value. `content.field_content_side` is a render array which holds a lot more than just 'value'.

Try:

```
{% if node.field_content_side.value == 'left' %}

```

To get this in a block, you would add this to `mytheme.theme`:

```
/**
 * Implements hook_preprocess_block().
 * @param $variables
 */
function mytheme_preprocess_block(&$variables) {
  if (isset($variables['elements']['content']['#block_content'])) {
    $variables['block_content'] = $variables['elements']['content']['#block_content'];
  }
}

```

Then:

```
{% if block_content.field_content_side.value == 'left' %}

```
> 2 votes

---
Tags: 8, theming
---


title: How to add files using rules module?

text:
# Question
Title: How to add files using rules module?
This question follows Override webform module submit

Based on this answer, I used the rules module to create a node after webform submissions.

My webform contains an `<input type="file" />`

for other `<input type="text" />` I used this solution to How to save webform submissions data in fields using rules module

How can I add this file data in the field-image table?

# Answer
> 0 votes
The tricky part of what you're trying to do, seems to be related to correctly specifying the filename of the attached file (= the value to be stored in your `field-image` field). For this, have a look at what is suggested in Comment # 25 of the support issue (not bug ...) #1431572 and which states that the correct way to do so is something like so:

```
[node:field-file-attachments:file:path]

```

### Use Rules debugging

This question is pretty tough to answer with the limited info you provided (and without access to "your" site). Therefor, if needed, you might also consider some Rules debugging, by (temporary) enabling the Devel module, so that you can (temporary) add a Rules Action like "Display a value" (in your case of the entire node/webform that's used to submit that attached file). For way more details about such debugging, refer to **Rules debugging**, as explained in the answer to "How can I display the value of a variable inside a condition?".

---
Tags: 7, rules, webforms, files
---


# Question
Title: Swap out blocks based on domain name extension
We have a European site that is the same exact site for three different domain names. So `www.mysite.eu`, `www.mysite.ie` and `www.mysite.ch` all go to the same site. However, we would like to make very small subtle changes based on which domain extension they come from. Really, I just need to swap out a couple blocks based on the domain.

I know there is the `Domain Access` module, which we actually use on another site, but I really didn't want to have the huge overhead and configuration and headache of everything that comes with the Domain Access module, just to swap out a couple blocks and that's it. The rest of the site in it's entirety will be exactly the same for all three domains.

I have put a hack in place using JavaScript right now, but it's not the most elegant solution. I was wondering if there is something else I could try besides Domain Access.

# Answer
> 0 votes
If you're still using D7 (there's no D8 port at the time of writing this), you could use Context Domain in conjunction with the Context module, or port the D7 version to D8. There's also option of creating a `hook_block_access` invocation to control display on a `view` operation.

---
Tags: blocks, domain-access
---


title: Batch API timeout during initialization

text:
# Question
Title: Batch API timeout during initialization
I'm creating a module to batch import/update nodes in Drupal 7 based on input files that can be XML or other formats. Worst case scenario is they are like ~10-20MB and can contain 10-20k entries.

Currently, the module works fine for small files (~2k entries), but I get timeouts during initialization (before the actual batch job) for bigger files. The input file parsing is not the problem, it works fine and this is an example table of parsing times:

```
ENTRIES  PARSING (s)  FORMAT
     63        0.056  xml
    544        0.144  xml
   1706        0.202  xml
   2741        0.940  xml  <- batch job doesn't start
   3398        0.419  txt  <- batch job doesn't start
   7916        8.726  xml  <- batch job doesn't start
   8607       29.734  xml  <- batch job doesn't start

```

This is the relevant part of my module's code:

```
function batch_import($ps_platform, $ps_input_file) {
    # I've tried to change timeout limit with no luck
    set_time_limit(500);

    # Parsing the input file to my own class. The time spent for
    # different size files can be in the table above.
    $o_dat = new DatContainer($ps_input_file);

    # [1/2] Preparing the batch job array we will output
    #---------------------------------------------------
    $a_batch_job = array(
        'title' => t('Importing dat file'),
        'init_message' => t('Beginning dat import process'),
        'operations' => array(),
        'finished' => 'batch_finished',
        );

    # [2/2] Populate the operations sub-array with all the jobs we want to do
    # -----------------------------------------------------------------------
    foreach ($o_dat as $o_entry) {
        $a_batch_job['operations'][] = array('process_entry', array($ps_platform, $o_entry));
    }

    batch_set($a_batch_job);
}

```

The actual function to process each individual task doesn't do anything by now, it simply prints the progress.

```
function process_entry($ps_platform, $po_entry, &$context) {
    $context['message'] = "Processing: {$po_entry->s_name}";
    $o_node = _get_entry_node_by_id($ps_platform, $po_entry->s_id);
    $_SESSION['http_request_count']++;
}

```

Does anybody see where is the problem? After checking many examples for batch api, I'm quite frustrated because my code **seems** to be correct.

Regards and thanks for your time.

# Answer
> 3 votes
The timeout happens because of large amount of operations within `$a_batch_job['operations']` array. For every operation defined queue item is created and stored in the **queue** table of the database.

Check the \_batch\_populate\_queue() method.

### Workaround

Instead of defining **Pre-set list of calls**, you can take a route of **Alterable list of calls**. So in your case it could be like this:

```
function batch_import($ps_platform, $ps_input_file) {
  # Parsing the input file to my own class. The time spent for
  # different size files can be in the table above.
  $o_dat = new DatContainer($ps_input_file);

  # [1/2] Preparing the batch job array we will output
  #---------------------------------------------------
  $a_batch_job = array(
    'title' => t('Importing dat file'),
    'init_message' => t('Beginning dat import process'),
    // Pass our parsed file as a parameter to the batch operation callback.
    'operations' => array('process_entry', array($o_dat, $ps_platform)),
    'finished' => 'batch_finished',
  );

  batch_set($a_batch_job);
}

```

And your `process_entry()` would look like this:

```
function process_entry($o_dat, $ps_platform, &$context) {
  if (empty($context['sandbox'])) {
    $context['sandbox']['progress'] = 0;
    $context['sandbox']['current_entry'] = 0;
    // Assuming you implemented method for DatContainer class, that can
    // return number of records in the file and it's named rowCount.
    $context['sandbox']['max'] = $o_dat->rowCount();

    // Store the source file in the context.
    $context['sandbox']['source_file'] = $o_dat;
  }
  // Process 5 entries per iteration.
  $limit = 5;

  // Assuming you have method getRows to get N number of entries starting from X entry.
  foreach ($o_dat->getRows($context['sandbox']['current_entry'], $limit) as $po_entry) {
    $context['message'] = "Processing: {$po_entry->s_name}";
    $o_node = _get_entry_node_by_id($ps_platform, $po_entry->s_id);
    $_SESSION['http_request_count']++;

    $context['sandbox']['progress']++;
    // Assuming you have number for entry within file.
    $context['sandbox']['current_entry'] = $po_entry->entry_number;
  }

  // Inform the batch engine that we are not finished,
  // and provide an estimation of the completion level we reached.
  if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
    $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
  }

}

```

So now instead of N queue items you would have only one item, that would get called recursively as long as `$context['finished'] < 1`.

For more information about `$context` variable please visit callback\_batch\_operation() page. It's preferable to use this variable to store information used across batch operation callbacks, rather than `$_SESSION`.

---
Tags: batch-operations
---


title: Drupal 8.5 REST 406 Not Acceptable

text:
# Question
Title: Drupal 8.5 REST 406 Not Acceptable
I had a REST resource for a custom entity working in 8.3, but when I try hitting it in 8.5, I get a 406 with `message": "Not acceptable format: json"` in the body.

Here's my config, with json clearly defined as the format:

`langcode: en
status: true
dependencies:
 module:
 - basic_auth
 - MY_MODULE
 - serialization
id: entity.MY_ENTITY
plugin_id: 'entity:MY_ENTITY'
granularity: resource
configuration:
 methods:
 - GET
 formats:
 - json
 authentication:
 - basic_auth`

I've tried stepping through code with Xdebug in PHPStorm, but not having much luck seeing where this is coming from.

# Answer
> 9 votes
You have to add this on the end of your endpoint URL:

`?_format=FORMAT`. So if you want JSON, its `?_format=json`.

This is a new change in 8.5.0 requiring this argument, but I could not locate in the changelogs exactly why it is now required otherwise a 406 is returned.

This same thing happened to all my REST endpoints until I added that.

---
Tags: 8
---


# Question
Title: jQuery conflict issues with client embed code
I am trying to use `jQuery.noConflict` so that I can use a 3rd party chat system that uses jQuery. This chat system loads in 1.72 while my current installation of drupal is using 1.12. After some hours of debugging and moving scripts around while trying to use noConflict(), I am at my wits end.

I believe the issue is that while trying to implement the 3rd party "click to chat" system for the client, it breaks IPE. This is being added via an embed field in a custom module I created. This embed field is being outputted via a twig variable in html.html.twig after

```
    {{ page_bottom }}
    <js-bottom-placeholder token="{{ placeholder_token|raw }}">
  </body>
  {{ embed|raw }} //Embed code here
</html>

```

My current error is as follows while trying to "edit" with the IPE.

```
jquery-ui.js:905 Uncaught TypeError: Cannot read property 'call' of undefined
    at a.(/web/anonymous function).(anonymous function)._trigger (https://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.js:905:38)
    at a.(/web/anonymous function).(anonymous function)._trigger (https://www.example.com/web/core/assets/vendor/jquery.ui/ui/widget-min.js?v=1.12.1:4:1094)
    at a.(/web/anonymous function).(anonymous function)._createWidget (https://www.example.com/web/core/assets/vendor/jquery.ui/ui/widget-min.js?v=1.12.1:4:3317)
    at new a.(/web/anonymous function).(anonymous function) (https://www.example.com/web/core/assets/vendor/jquery.ui/ui/widget-min.js?v=1.12.1:4:661)
    at HTMLDivElement.<anonymous> (widget-min.js?v=1.12.1:4)
    at Function.each (jquery.min.js?v=3.2.1:2)
    at r.fn.init.each (jquery.min.js?v=3.2.1:2)
    at r.fn.init.a.fn.(/franchise/anonymous function) [as draggable] (https://www.example.com/web/core/assets/vendor/jquery.ui/ui/widget-min.js?v=1.12.1:4:2374)
    at n.render (BlockView.js?v=8.4.5:95)
    at n.<anonymous> (LayoutView.js?v=8.4.5:146)

```

This currently renders the IPE completely broken. What would be the correct way to implement a 3rd party system that loads its own version of jquery, while not being able to change the source code of this 3rd party system?

This is what I have read/tried so far:

https://api.jquery.com/jquery.noconflict/

https://www.drupal.org/docs/8/api/javascript-api/javascript-api-overview

Similar but I also tried this:

https://stackoverflow.com/questions/2812359/mootools-and-jquery-conflict-despite-dollar-safe-mode

# Answer
> 1 votes
I was able to fix this conflict by only displaying this embed code to users who are not logged in. This resolved the conflicts with the in place editor.

In my twig file where I was outputting the embed code, I wrapped it in:

```
{% if not logged_in %}
  {{ embed|raw }}
{% endif %}

```

---
Tags: 8, theming, javascript
---


title: Is there a patch for SA-CORE-2018-002?

text:
# Question
Title: Is there a patch for SA-CORE-2018-002?
How can I apply patch for my Drupal 6 site which is working quite fine until now?

I've checked the patch in Drupal 7. It's using `sanitize()`. How do I add it in Drupal 6?

At the same time I'm working to have it upgraded to Drupal 8.

# Answer
Per the official the FAQ about SA-CORE-2018-002:

> **I manage a Drupal 6 site, is a fix available?**
>
> Yes, Drupal 6 is also affected and the Drupal 6 Long Term Support project has patches available.

The issue for this is \[core\] Add D6LTS patch for SA-CORE-2018-002. The issue has a patch from a security team member and further information.

**2018-03-30 update:**

Per a security team member in a recent comment:

> Please just upgrade Drupal core rather than patching!
>
> Note also the D6lts patch and corresponding github releases for that and Pressflow 6 were updated to fix a subtle flaw in the released security fix that was affecting a couple contrib modules including Organic Groups (og) for Drupal 6.
>
> https://github.com/d6lts/drupal/releases/tag/6.43
>
> https://github.com/pressflow/6/releases/tag/pressflow-6.43.124
> 3 votes

---
Tags: 6
---


# Question
Title: how can we limit the node view to a particular limit in drupal 7
I have a content type name **students list** and 100 nodes in this content type.

I have a user role named **alpha role**.

When a user belonging to alpha role logged in, he could see all the 100 nodes list with basic details and should only see any 10 nodes with full contact details one by one

how can we do this in drupal?

Thanks

# Answer
You can implement hook\_node\_access() in your custom module, and check how many of nodes from a certain content-type the user has visited.

For example:

```
<?php
function YOURMODULE_node_access($node, $op, $account) {
  $type = is_string($node) ? $node : $node->type;

  if (($type === 'page') && ($op === 'view')) {
    $view_limit = variable_get('YOURMODULE_limit', 10);
    $view_count = YOURMODULE_get_view_count($node, $account);
    if ($view_count > $view_limit) {
      return NODE_ACCESS_DENY;
    }
  }
}

function YOURMODULE_get_view_count($node, $account) {
  // Depending on your implementation
  // get the view count for specific node and the user.
  //
  return 10;
}

```

For getting the view count, you may want to consider enabling core module `Statistics`, it could carry the heavy lifting. Or you can create a logic based on sessions, or create a DB schema for your own node view counter logic.

However you get the count return it as an integer in `YOURMODULE_get_view_count()` custom function, then you can implement your access logic fairly easily for any content type, and for any role.
> 1 votes

---
Tags: views, theming, nodes, entities
---


title: sitemap for users not search engines

text:
# Question
Title: sitemap for users not search engines
I used simple XML sitemap module to create a sitemap for search engines but now I need one sitemap for visitors. Can I create this manually instead of using a module because the site already has too many modules? I was thinking to create a basic page and just add the links there one by one. Is this a good way?

# Answer
> 1 votes
Depends on how often your site changes and who makes the changes.

If it's a single person and that person can remember to add new pages to the site map then manual is probably OK.

If you have non-technical people adding pages to the site, chances are that they will not update the map just add it to the menu.

With a module, the sitemap can be automatically updated as the things change.

Remember changes can also include things like page or menu titles that feed into the site map.

# Answer
> 2 votes
There is a module that does what you want, and it isn't XML Sitemap but just Sitemap:

https://www.drupal.org/project/sitemap

> This module provides a site map that gives visitors an overview of your site. It can also display the RSS feeds for all blogs and categories.
>
> Drupal generates the RSS feeds automatically but few seems to be aware that they exist.
>
> The site map can display the following items:
>
> * A message to be displayed above the site map.
> * Any books.
> * Any menus that will be displayed fully expanded.
> * Any vocabularies, with all the terms expanded. Optionally with term depth, node counts, and RSS feeds.
> * A syndication block, the "more" link goes to the site map.

Then:

> because the site already has too many modules?

There is really no way to quantify this for you. There isn't necessarily a module *limit*, your limit is defined by the limits of your hosting space. The performance impact of adding the Sitemap module, vs spending hours doing it yourself (to reach the same point but with 10x the maintenance) is negligible, especially since you can cache it in Drupal and use things like Varnish or Memcache if your host supports it (if not, find an updated host!). You will be fine.

# Answer
> 1 votes
Easiest way perhaps using the Main menu block and displaying them at the sitemap page's content region.

If you already have the Menu Block installed, it'll give you more flexibility configuring how deep to expand the shown menus as well.

Then you can simply style the menu block with CSS.

---
Tags: navigation
---


title: Edit markup element permission

text:
# Question
Title: Edit markup element permission
I'm using webforms on Drupal 8.5.1 . I want to add some custom, arbitrary text to the form, so I chose to add a `markup` element. We want to have the text at the top of the form "Thank you for taking the time to fill out this survey. In order to serve you better..."

When the dialogue comes up, I see this:

From appearance and clicking, it seems like there is a missing textarea on the widget where I would enter the markup, right under the header "HTML markup".

I'm not sure if this is a problem with my install, my settings, or perhaps a bug.

I've looked at permissions and administrators have all webform permissions checked, and they are greyed out, so they can't be unselected. The account I'm using is an administrator account.

I am new to Drupal 8, and even more so its webforms. Is there something wrong in my settings?

# Answer
The missing editor is most likely a bug. You should see what is being logged in the browser's JS console.

@see https://drupal.org/project/webform/issues/2936147
> 1 votes

---
Tags: 8, webforms
---


title: $promotion->apply($order) doesn't work

text:
# Question
Title: $promotion->apply($order) doesn't work
I have a redemption form that I want to enter a coupon code and then an order should be created automatically, then the coupon code applied to the order as well.

The order gets created successfully but `$promotion->apply($order)` does not work.

As you can see in the image above, I have a promotion containing coupon code `Z-8FDA5A218B44` . In the condition section, this promotion is limited to a product called `Monthly`.

I want to create a redemption form in which when a user enters a coupon code, an order and an order item that contains my product (Monthly) will be automatically created. (picture below)

As you can see when I submit the redemption form with a coupon code, an order will be created, but I want to apply the coupon code to the order too.

Here's my code:

```
namespace Drupal\my_subscription\Form;

use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountProxy;
use Drupal\commerce_product\Plugin\Commerce\Condition\OrderItemProduct as OrderItemProductCondition;
use Drupal\commerce_order\Entity\Order;
use Drupal\commerce_product\Entity\ProductVariation;

/**
 * Class RedemptionForm.
 *
 * @package Drupal\my_subscription\Form
 */
class RedemptionForm extends FormBase {

  /**
   * Drupal\Core\Session\AccountProxy definition.
   *
   * @var \Drupal\Core\Session\AccountProxy
   */
  protected $currentUser;

  public function __construct(
    AccountProxy $current_user
  ) {
    $this->currentUser = $current_user;
  }

  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('current_user')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'meditation_redemption_form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $form['coupon_code'] = [
      '#type' => 'textfield',
      '#title' => t('Coupon code'),
      '#description' => t('Enter your coupon code to redeem a promotion.'),
    ];

    $form['submit'] = [
      '#type' => 'submit',
      '#value' => $this->t('Submit'),
    ];

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {
    $coupon_code = $form_state->getValue('coupon_code');
    /** @var \Drupal\commerce_promotion\CouponStorageInterface $coupon_storage */
    $coupon_storage = \Drupal::entityTypeManager()->getStorage('commerce_promotion_coupon');

    $coupon = $coupon_storage->loadByCode($coupon_code);
    if (empty($coupon)) {
      $form_state->setErrorByName('coupon_code', t('The provided coupon code is invalid.'));
      return;
    }
    else {
      $form_state->set('coupon', $coupon);
    }
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    /** @var \Drupal\commerce_promotion\Entity\Coupon $coupon */
    $coupon = $form_state->get('coupon');
    /** @var \Drupal\commerce_promotion\Entity\Promotion $promotion */
    $promotion = $coupon->getPromotion();

    $conditions = $promotion->getConditions();
    if ($conditions[0] instanceof OrderItemProductCondition) {
      $uid = $this->currentUser->id();

      $configuration = $conditions[0]->getConfiguration();
      $subscription_product_id = $configuration['products'][0]['product_id'];

      $subscription = ProductVariation::load($subscription_product_id);

      $order_item_storage = \Drupal::entityManager()->getStorage('commerce_order_item');

      $order_item = $order_item_storage->createFromPurchasableEntity($subscription, [
        'quantity' => 1,
      ]);

      /** @var \Drupal\commerce_order\Entity\Order $order */
      $order = Order::create([
        'type' => 'default',
      ]);
      $order->addItem($order_item);
      $order->setCustomerId($uid);
      $order->set('store_id', 1);
      $order->save();
      ///** @var  \Drupal\commerce_ORDER\OrderAssignment $order_assignment */
      //$order_assignment = \Drupal::service('commerce_order.order_assignment');
      //$order_assignment->assign($order, $account);

      if ($coupon->available($order) && $promotion->applies($order)) {
        $promotion->apply($order);
      }
    }

  }

}

```

# Answer
> 1 votes
Hi I'm maybe TLTTP but it appears that your implementation is right (assuming as you say it passes the **available** and **applies** checks). The problem I think is that you're not saving the order after the promotion gets applied.

```
...
if ($coupon->available($order) && $promotion->applies($order)) {
    $promotion->apply($order);
    $order->save();
}
...

```

Also as @matt-glaman suggests you should *refresh* the order so the final price gets updated.

```
...
if ($coupon->available($order) && $promotion->applies($order)) {
    $promotion->apply($order);
    // Recalculates total price of the order including any adjustment
    // to the order or it's order items.
    $order->recalculateTotalPrice();
    // Persist any changes applied to the order.
    $order->save();
}
...

```

---
Tags: 8, commerce
---


title: This page is not working

text:
# Question
Title: This page is not working
When I visit my site, I get an error:

> This page isn’t working my---site.com is currently unable to handle this request. HTTP ERROR 500

I have taken the below steps but no luck.

1. In shared hosting server, I have changed the php version from 5.6 to 7.0.
2. Renamed in sites/all the folder "modules" to "nomodules".
3. In settings.php file, added "ini\_set('memory\_limit', '128M');"
4. Renamed sites folder to "nosites"
5. Un commented RewriteBase / this line in .htaccess file.
6. Called hosting company and they tested php file and database access. All good in the server.

I tried all of the above one at a time. I get same error. How can I fix the page is not working error in drupal 7 site?

---

On home directory in shared hosting, I see logs folder. I dont see any apache folder. Once I click logs folder, I saw few zip files. I uploaded the latest one. It might be the one you are asking for. I personally never looked logged files so I do not know what to get out of this log file. I get the same error for other pages. When I visit robots.txt file page, I can see the content. Also uploaded for you to see.

I am not sure what else I could do to fix it. Please let me know if you need any additional info.

https://drive.google.com/open?id=1aQknx9NGz9-xmGSnXQ9vwGpAdvzw1Cwf

---

**Update 1** In cPanel metrics section, I see the below errors:

\[Thu Mar 29 10:29:55.504048 2018\] \[autoindex:error\] \[pid 1019784:tid 1401110643131018112\] \[client xxx.xx.xxx.xx AH01276: Cannot serve directory /home/kar2015/a.com/: No matching DirectoryIndex (index.php,index.html,index.htm) found, and server-generated directory index forbidden by Options directive

\[Thu Mar 29 10:19:52.133400 2018\] \[autoindex:error\] \[pid 109815:tid 14001164323507968\] \[client xxxxxxxx\] AH01276: Cannot serve directory /home/kar2015/a.com/: No matching DirectoryIndex (index.php,index.html,index.htm) found, and server-generated directory index forbidden by Options directive

---

**Update 2** index.php exists at the root directory.

Permission of index.php is set to 644

Code shows this:

```
<?php

/**
* @file
* The PHP page that serves all page requests on a Drupal installation.
*
* The routines here dispatch control to the appropriate handler, which then
* prints the appropriate page.
*
* All Drupal code is released under the GNU General Public License.
* See COPYRIGHT.txt and LICENSE.txt.
*/

/**
* Root directory of Drupal installation.
*/
define('DRUPAL_ROOT', getcwd());

require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
menu_execute_active_handler();

```

I just replaced the content by

```
<?php
echo "Hello world!";
?>

```

When I visit my page, it prints "Hello world". I guess problem is with the index.php. How can I fix it?

# Answer
> 0 votes
It seems that you *index.php* file is missing from the site root or at least where the web server is configured as your site root.

Make sure that you have your site correctly deployed at **/home/kar2015/a.com/** which seems your host root and that you have an *index.php* file in it and it's readable by the web server account (usually www-data) a proper permission should be 0644.

Hope it helps.

---
Tags: debugging
---


# Question
Title: How can I add Google Tag Manager's code to my website?
Is there any module to add some new things like Google Tag Manager's code to Drupal based website? for example you should install Google analytic module to add analytic to your site, is any equivalent for Google Tag Manager?

# Answer
> 5 votes
There is an officially released module (since early 2014): GoogleTagManager.

> Allow the non-technical stakeholders to manage the analytics for their website using the Google Tag Manager (GTM). This module allows you to trigger the insertion of tags and tracking systems onto the pages of the site.

# Answer
> 3 votes
You might be interested in:

https://drupal.org/project/gpt

> This module provides a way to serve DoubleClick's Google Publisher Tag (GPT) (Premium and Small Business) ads on Drupal.
>
> Benefits of GPT
>
> The new Google Publisher Tags have multiple benefits over Google Ad Manager (GAM) tags and the legacy DoubleClick for Publishers Dart tags.
>
> * Asynchronous
> * Ad loading does not block the page from rendering, improving page load time. Can be disabled if desired.
> * Google Publisher Console
> * Accessed by loading a page of your site with ?google\_console=1 appended to the URL page and using the keyboard shortcut Ctrl+F10 to toggle the console.
> * Single request mode
> * The browser sends a single request for retrieving all add units for the page, enabling advanced roadblocking and improving page load time.
> * Multiple instances of the same ad unit on a page
> * SSL support
> * Slot-level custom targeting
> * Refreshing ad slots on a page

# Answer
> 2 votes
There are two sandbox modules: GTM and Google Tag Manager, both are for Drupal 6, you can easily port them to Drupal 7.

# Answer
> 1 votes
you should use these two:

https://www.drupal.org/project/google\_tag

https://www.drupal.org/project/datalayer

First one installs GTM on your page, second one enables passing many variables and taxonomies to be passed to dataLayer. It also has an alter function, if you'd like to add some extra data (since the module is written in a general way and i.e. extracting taxonomies from json arrays on the GTM side can be complicated).

# Answer
> 1 votes
Installing Google tag manager is a bit complex, specially on CMS such as Drupal, here’s a complete tutorial for it at: https://www.cloudways.com/blog/install-google-tag-manager-drupal/ Its very easy to follow I hope others will find it usefull too.

---
Tags: 7, google-analytics
---


# Question
Title: Adding an existing node as a translation
I have many articles in original (English) language and they're all translated to 3 languages - however, the translations were created as new nodes (and not by clicking "Add translation" in the Translation tab).

Is it possible to somehow relate the translations with the original English article or do I have to manually redo it all by clicking "Add translation" in the Translate tab of each node and adding the translations?

# Answer
> 2 votes
You can do this in code by reading the field values from the three translated nodes and add them as translation to the english node:

```
$node_en->addTranslation($langcode1, $node1->toArray());
$node_en->addTranslation($langcode2, $node2->toArray());
$node_en->addTranslation($langcode3, $node3->toArray());
$node_en->save();

```

This is for demonstration only, you can loop through the languages and get the langcode from the node.

The problem is that at the moment the translated nodes and the english node have no connection in the database. If you have some data in the nodes that do match, you can do a entity query and loop through the results.

# Answer
> 1 votes
I created module to add this functionality. https://www.drupal.org/sandbox/lamp5/2956687

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


title: Hook after creating content

text:
# Question
Title: Hook after creating content
I want to add some specific treatment after creating the content.

Rules module is for similar cases but I look for a hook.

Is there a hook that triggers just after creating content (node)?

Thank you

# Answer
> 2 votes
You can implement `hook_node_presave()`, which is called after a node is created or updated, but before the node is saved in the database.

```
function mymodule_node_presave($node) {
  // $node->original contains the node object before the edits.
  if ($node->nid && $node->moderate && $node->original->moderate != $node->moderate) {
    $node->score = 0;
    $node->users = '';
    $node->votes = 0;
  }
}

```

---
Tags: 7, nodes, hooks
---


# Question
Title: Error running BrowserTest (Drupal\Core\Config\Schema\SchemaIncompleteException: No schema ...)
I am working on a module Rate Limiter and trying to improve the deprecated SimpleTest with BrowserTest. While doing so, I get the following error.

> C:\Project\Sites\devdesktop\drupal8\>.\vendor\bin\phpunit -c .\core\phpunit.xml.dist --filter testRateLimitConfigPageVisit .\modules\custom\rate\_limiter\tests\src\Functional\RateLimiterConfigFormTest.php PHPUnit 6.5.7 by Sebastian Bergmann and contributors.

```
Testing Drupal\Tests\rate_limiter\Functional\RateLimiterConfigFormTest
E                                                                   1 / 1 (100%)

Time: 56.75 seconds, Memory: 6.00MB

There was 1 error:

1) Drupal\Tests\rate_limiter\Functional\RateLimiterConfigFormTest::testRateLimitConfigPageVisit
Drupal\Core\Config\Schema\SchemaIncompleteException: No schema for rate_limiter.settings

C:\Project\Sites\devdesktop\drupal8\core\lib\Drupal\Core\Config\Development\ConfigSchemaChecker.php:88
C:\Project\Sites\devdesktop\drupal8\core\lib\Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher.php:111
C:\Project\Sites\devdesktop\drupal8\core\lib\Drupal\Core\Config\Config.php:227
C:\Project\Sites\devdesktop\drupal8\core\lib\Drupal\Core\Config\ConfigInstaller.php:334
C:\Project\Sites\devdesktop\drupal8\core\lib\Drupal\Core\Config\ConfigInstaller.php:134
C:\Project\Sites\devdesktop\drupal8\core\lib\Drupal\Core\ProxyClass\Config\ConfigInstaller.php:75
C:\Project\Sites\devdesktop\drupal8\core\lib\Drupal\Core\Extension\ModuleInstaller.php:268
C:\Project\Sites\devdesktop\drupal8\core\lib\Drupal\Core\ProxyClass\Extension\ModuleInstaller.php:83
C:\Project\Sites\devdesktop\drupal8\core\lib\Drupal\Core\Test\FunctionalTestSetupTrait.php:437
C:\Project\Sites\devdesktop\drupal8\core\tests\Drupal\Tests\BrowserTestBase.php:1026
C:\Project\Sites\devdesktop\drupal8\core\tests\Drupal\Tests\BrowserTestBase.php:490
C:\Project\Sites\devdesktop\drupal8\modules\custom\rate_limiter\tests\src\Functional\RateLimiterConfigFormTest.php:32

ERRORS!
Tests: 1, Assertions: 0, Errors: 1.

```

The Schema file is: https://github.com/aneek/rate\_limiter/blob/develop/config/install/rate\_limiter.settings.yml

And the Test File is: https://github.com/aneek/rate\_limiter/blob/develop/tests/src/Functional/RateLimiterConfigFormTest.php

What I am missing?

# Answer
> The Schema file is: https://github.com/aneek/rate\_limiter/blob/develop/config/install/rate\_limiter.settings.yml

No, that is not the schema file, that is the config file for which you need to create a configuration schema.

Tests by default enforce that your configuration has a schema, which is useful for supporting configuration translation and additional upcoming functionality like validation.

See Configuration schema/metadata for more information on how to create that.
> 4 votes

---
Tags: 8, testing
---


# Question
Title: user_login_block not displaying status messages
I am creating my own theme for my website, and am having an issue with the user\_login\_block form. I have a simple jQuery dropdown style content div in which I am outputting the form, and have no clue why it is not displaying status messages (invalid login attempts, ect..). When entering incorrect credentials, the page simply refreshes and nothing is displayed to the end user. I am new to Drupal, but not new to PHP. I have no idea what I could be doing wrong. My code is below, any help would be much appreciated.

hook\_form\_alter:

```
function dtn_form_alter(&$form, &$form_state, $form_id) {
    switch($form_id) {
        case 'user_login_block':
            $form['links']['#markup'] = '<ul class="dtn-user-login-menu-links"><li><a href="/user/password">' . t('Request new password') . '</a></li></ul>';
            $form['name']['#title'] = Null;
            $form['name']['#attributes'] = array('placeholder' => t('Username'));
            $form['pass']['#title'] = Null;
            $form['pass']['#attributes'] = array('placeholder' => t('Password'));
            break;
    }
}

```

Login Form Source:

```
$userLoginForm = drupal_get_form('user_login_block');

$output .= '<ul class="dtn-user-bar-content-list">';
$output .= '<li class="dtn-user-menu-login-link"><a class="dtn-user-menu-trigger-login" href="#">' . t('Login') . '</a>';
$output .= '<div class="dtn-user-menu-content">';
$output .= render($userLoginForm);
$output .= '</div>';
$output .= '</li>';
$output .= '<li class="dtn-user-menu-register">' . t('<a href="!url">Register</a>', ['!url' => url('user/register')]) . '</li>';
$output .= '</ul>';

$output = '<div class="dtn-user-bar-content">' . $output . '</div>';

return $output;

```

}

# Answer
> 1 votes
I think you are embedding Login Form directly in .tpl file. Either assign login block to some region or bring it through a variable from hook\_preproces\_page() function.

# Answer
> 0 votes
In Drupal 7, the messages the modules print with `drupal_set_message()` aren't rendered from any block but, as Jimajamma says, they are rendered from Drupal when rendering the page. The page template, which in Drupal 7 is the page.tpl.php file receives the HTML markup for the messages in the `$message` variable. The template file render those messages with code similar to the following.

```
<?php if ($breadcrumb): ?>
  <div id="breadcrumb"><?php print $breadcrumb; ?></div>
<?php endif; ?>

<?php print $messages; ?>

<div id="main-wrapper"><div id="main" class="clearfix">

```

The code before and after the line printing the messages can vary from theme. For example, the Bartik theme uses the following code.

```
  </div></div> <!-- /.section, /#header -->

  <?php if ($messages): ?>
    <div id="messages"><div class="section clearfix">
      <?php print $messages; ?>
    </div></div> <!-- /.section, /#messages -->
  <?php endif; ?>

  <?php if ($page['featured']): ?>
    <div id="featured"><div class="section clearfix">
      <?php print render($page['featured']); ?>
    </div></div> <!-- /.section, /#featured -->
  <?php endif; ?>

```

Without the `<?php print $messages; ?>` line, the messages will not be visible in the page. If you are using a custom theme, be sure to include it inside your page.tpl.php template.

# Answer
> 0 votes
Exactly. If you embed direct the user\_login\_block into any tpl files, it won't render any error messages for the first time as the error message will render after the tpl files was render.

It need to be declare in hook\_preprocess\_page() to make sure the error message is pass before any tpl files rendered.

---
Tags: blocks
---


# Question
Title: How to hide specific pages from users, but not the content?
I'm trying to hide a specific set of pages from anonymous users and I would like to return a 404 for them. To be more precise, the set of pages I'm trying to hide are ECK entity pages (info blocks I guess), taxonomy term pages and a few node types. But I would like to still have them visible in the pages they are part of.

To be more clear, let me give you an example : I would like to have `itinerary/gallery/1` hidden from anonymous users, but I would still like for the gallery itself to be visible in the blog pages it's embedded in.

I tried using the Rabbit Hole module and it works great for taxonomy terms and the node types, but not for the ECK stuff. I tried extending the module but it doesn't seem possible the way Rabbit Hole works unless I create an extension for each of them.

I also tried pulling a hook from `hook_entity_view()` but the problem with it is that it also triggers when the elements are loaded in the page, not just on their own pages. Does anyone have any idea how to do this?

# Answer
> 1 votes
You could use the Rules module to get this to work, by using the "**Drupal is initializing**" event. That will ensure that the rule gets triggered BEFORE the actual content is shown.

The links that you want to "intercept", should be formatted in some type of **regular expression**, which you then use as your Rules Condition. So that you have a rule that corresponds to "before showing the actual content of something that matches a specific path ...". After you get that part to work, your Rules Action should specify the actual redirect to be performed.

# Sample rule

Refer to the "Option 1" part of my answer to the question about "How to restrict access to a node via node/12 and allow access via a path like content/sometitle?", which contains this rule in export format:

```
{ "rules_check_url" : {
    "LABEL" : "Disallow node/* access",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules" ],
    "ON" : { "init" : [] },
    "IF" : [
      { "text_matches" : {
          "text" : [ "site:current-page:url" ],
          "match" : "node\/\\d+$",
          "operation" : "regex"
        }
      }
    ],
    "DO" : [
      { "drupal_message" : {
          "message" : "Sorry, URLs like [site:current-page:url] are not allowed around here ...",
          "type" : "error"
        }
      },
      { "redirect" : { "url" : "no_access" } }
    ]
  }
}

```

Here are some suggested tunings of the above sample, to make it work for your case also:

* machine name and label.
* replace the `node/*` by your path(s) (in the regular expression).
* possibly you may want to add an extra Rules Condition to only perform the Rules Actions for selected user roles (eg: only for user who are not administrators).
* replace the path in the action part of the rule by your target path, and check if you do want some type of error message to be shown (if not remove that part of the action).

---
Tags: 7, entities
---


# Question
Title: Custom Module Remote Fails Checksum with Drush
## Background

I have several proprietary Drupal modules that my company uses. We want to update these across all our sites. To that end, I've built an endpoint that produces code according to the (ill-documented) specifications required at https://www.drupal.org/node/542202#project%20status%20url

For those interested, the endpoint gets the project information from Bitbucket, where each core has a branch, then gets tags and parses out the tags as releases so it can get the newest one.

There's also some unzipping and re-zipping that goes on to put the returned .tar.gz in a format that Drupal accepts.

This works alright but there's a

## Problem

While the GUI for Drupal works fine to update the module from the custom remote, Drush fails. Running `drush up` gives me the expected prompts, recognizes the new version, downloads the file and then fails. The message:

`File {filename} is corrupt (wrong md5 checksum).`

The `mdhash` in my XML file is correct, according to the `md5` utility on MacOS. (It's calculated using PHP's `md5_file` utility). So, whenever I download the tar manually and check the hash, it's fine. But I cannot get drush to agree with me.

Any ideas? Thanks in advance.

# Answer
> 0 votes
## Answer

This isn't a good answer, but it works:

There is an *undocumented* drush flag `--no-md5` and if you pass that to `drush up` it will skip the md5 check and the update will succeed.

---
Tags: drush, updating, security, .info
---