title: Create a time range field

text:
# Question
Title: Create a time range field
I'm trying to make my own time range field widget, but I can't seem to make it work. I

* saw this question
* concluded that my skill level isn't high enough to implement
* offered bounty
* did not receive more details regarding implementing
* researched for half a day
* can't figure out how to implement a time range field

My current structure of my custom module time\_range is this:

```
time_range
  src
    Plugin
      Field
        FieldWidget
          TimeRangeWidget.php
  time_range.info.yml
  time_range.module

```

**time\_range.info.yml**:

```
name: 'Time Range'
type: module
description: 'Provides the ability to store start and end times.'
package: Custom
version: '8.0.0'
core: 8.x
project: 'drupal'
dependencies:
  - datetime
  - datetime_range

```

**time\_range.module**:

```
<?php

function time_range_field_widget_info() {
  return array(
    'daterange_time_only' => array(
      'label' => t('Time Range'),
      'field types' => array('datetime_range'),
      'settings' => array(
        'add_new_text' => 'Add new customer...', //Don't know which setting this is suppose to be
      ),
    ),
  );
}

```

**TimeRangeWidget.php**:

```
namespace Drupal\time_range\Plugin\Field\FieldWidget;

use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\datetime_range\Plugin\Field\FieldType\DateRangeItem;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Plugin implementation of the 'daterange_time_only' widget.
 *
 * @FieldWidget(
 *   id = "daterange_time_only",
 *   label = @Translation("Time range"),
 *   field_types = {
 *     "daterange"
 *   }
 * )
 */
class TimeRangeWidget extends DateRangeWidgetBase implements ContainerFactoryPluginInterface {

  /**
   * The date format storage.
   *
   * @var \Drupal\Core\Entity\EntityStorageInterface
   */
  protected $dateStorage;

  /**
   * {@inheritdoc}
   */
  public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, array $third_party_settings, EntityStorageInterface $date_storage) {
    parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $third_party_settings);

    $this->dateStorage = $date_storage;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $plugin_id,
      $plugin_definition,
      $configuration['field_definition'],
      $configuration['settings'],
      $configuration['third_party_settings'],
      $container->get('entity_type.manager')->getStorage('date_format')
    );
  }

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

    // Identify the type of date and time elements to use.
//    switch ($this->getFieldSetting('datetime_type')) {
//      case DateRangeItem::DATETIME_TYPE_DATE:
//      case DateRangeItem::DATETIME_TYPE_ALLDAY:
//        $date_type = 'date';
//        $time_type = 'none';
//        $date_format = $this->dateStorage->load('html_date')->getPattern();
//        $time_format = '';
//        break;
//
//      default:
//        $date_type = 'date';
//        $time_type = 'time';
//        $date_format = $this->dateStorage->load('html_date')->getPattern();
//        $time_format = $this->dateStorage->load('html_time')->getPattern();
//        break;
//    }

    $element['value'] += [
      '#date_date_format' => $date_format,
      '#date_date_element' => 'none',
      '#date_date_callbacks' => [],
      '#date_time_format' => $time_format,
      '#date_time_element' => $time_type,
      '#date_time_callbacks' => [],
    ];

    $element['end_value'] += [
      '#date_date_format' => $date_format,
      '#date_date_element' => 'none',
      '#date_date_callbacks' => [],
      '#date_time_format' => $time_format,
      '#date_time_element' => $time_type,
      '#date_time_callbacks' => [],
    ];

    return $element;
  }

}

```

However, the widget doesn't show.

# Answer
# Update: Time Range Module on drupal.org

(Old) Github here, with basic installation instruction in the README.md file.

My current structure of my custom module time\_range is this:

```
time_range
  src
    Plugin
      Field
        FieldWidget
          DateRangeWidgetBase.php
          TimeRangeWidget.php
          TimeRangeWidgetBase.php
  time_range.info.yml
  time_range.module

```

**time\_range.info.yml**:

```
name: 'Time Range'
type: module
description: 'Provides the ability to store start and end times.'
package: Custom
version: '8.0.0'
core: 8.x
project: 'drupal'
dependencies:
  - datetime
  - datetime_range

```

**time\_range.module**:

```
<?php

function time_range_field_widget_info() {
  return array(
    'daterange_time_only' => array(
      'label' => t('Time Range'),
      'field types' => array('datetime_range'),
      'settings' => array(
        'add_new_text' => 'Add new customer...',
      ),
    ),
  );
}

```

**DateRangeWidgetBase.php**

```
<?php

namespace Drupal\datetime_range\Plugin\Field\FieldWidget;

use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItem;
use Drupal\datetime\Plugin\Field\FieldWidget\DateTimeWidgetBase;
use Drupal\datetime_range\Plugin\Field\FieldType\DateRangeItem;

/**
 * Base class for the 'daterange_*' widgets.
 */
class DateRangeWidgetBase extends DateTimeWidgetBase {

  /**
   * {@inheritdoc}
   */
  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
    $element = parent::formElement($items, $delta, $element, $form, $form_state);
    $element['#element_validate'][] = [$this, 'validateStartEnd'];
    $element['value']['#title'] = $this->t('Start');

    $element['end_value'] = [
      '#title' => $this->t('End'),
    ] + $element['value'];

    if ($items[$delta]->start_date) {
      /** @var \Drupal\Core\Datetime\DrupalDateTime $start_date */
      $start_date = $items[$delta]->start_date;
      $element['value']['#default_value'] = $this->createDefaultValue($start_date, $element['value']['#date_timezone']);
    }

    if ($items[$delta]->end_date) {
      /** @var \Drupal\Core\Datetime\DrupalDateTime $end_date */
      $end_date = $items[$delta]->end_date;
      $element['end_value']['#default_value'] = $this->createDefaultValue($end_date, $element['end_value']['#date_timezone']);
    }

    return $element;
  }

  /**
   * {@inheritdoc}
   */
  public function massageFormValues(array $values, array $form, FormStateInterface $form_state) {
    // The widget form element type has transformed the value to a
    // DrupalDateTime object at this point. We need to convert it back to the
    // storage timezone and format.
    foreach ($values as &$item) {
      if (!empty($item['value']) && $item['value'] instanceof DrupalDateTime) {
        /** @var \Drupal\Core\Datetime\DrupalDateTime $start_date */
        $start_date = $item['value'];
        switch ($this->getFieldSetting('datetime_type')) {
          case DateRangeItem::DATETIME_TYPE_DATE:
            // If this is a date-only field, set it to the default time so the
            // timezone conversion can be reversed.
            datetime_date_default_time($start_date);
            $format = DATETIME_DATE_STORAGE_FORMAT;
            break;

          case DateRangeItem::DATETIME_TYPE_ALLDAY:
            // All day fields start at midnight on the starting date, but are
            // stored like datetime fields, so we need to adjust the time.
            // This function is called twice, so to prevent a double conversion
            // we need to explicitly set the timezone.
            $start_date->setTimeZone(timezone_open(drupal_get_user_timezone()));
            $start_date->setTime(0, 0, 0);
            $format = DATETIME_DATETIME_STORAGE_FORMAT;
            break;

          default:
            $format = DATETIME_DATETIME_STORAGE_FORMAT;
            break;
        }
        // Adjust the date for storage.
        $start_date->setTimezone(new \DateTimezone(DATETIME_STORAGE_TIMEZONE));
        $item['value'] = $start_date->format($format);
      }

      if (!empty($item['end_value']) && $item['end_value'] instanceof DrupalDateTime) {
        /** @var \Drupal\Core\Datetime\DrupalDateTime $end_date */
        $end_date = $item['end_value'];
        switch ($this->getFieldSetting('datetime_type')) {
          case DateRangeItem::DATETIME_TYPE_DATE:
            // If this is a date-only field, set it to the default time so the
            // timezone conversion can be reversed.
            datetime_date_default_time($end_date);
            $format = DATETIME_DATE_STORAGE_FORMAT;
            break;

          case DateRangeItem::DATETIME_TYPE_ALLDAY:
            // All day fields end at midnight on the end date, but are
            // stored like datetime fields, so we need to adjust the time.
            // This function is called twice, so to prevent a double conversion
            // we need to explicitly set the timezone.
            $end_date->setTimeZone(timezone_open(drupal_get_user_timezone()));
            $end_date->setTime(23, 59, 59);
            $format = DATETIME_DATETIME_STORAGE_FORMAT;
            break;

          default:
            $format = DATETIME_DATETIME_STORAGE_FORMAT;
            break;
        }
        // Adjust the date for storage.
        $end_date->setTimezone(new \DateTimezone(DATETIME_STORAGE_TIMEZONE));
        $item['end_value'] = $end_date->format($format);
      }
    }

    return $values;
  }

  /**
   * #element_validate callback to ensure that the start date <= the end date.
   *
   * @param array $element
   *   An associative array containing the properties and children of the
   *   generic form element.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the form.
   * @param array $complete_form
   *   The complete form structure.
   */
  public function validateStartEnd(array &$element, FormStateInterface $form_state, array &$complete_form) {
    $start_date = $element['value']['#value']['object'];
    $end_date = $element['end_value']['#value']['object'];

    if ($start_date instanceof DrupalDateTime && $end_date instanceof DrupalDateTime) {
      if ($start_date->format('U') !== $end_date->format('U')) {
        $interval = $start_date->diff($end_date);
        if ($interval->invert === 1) {
          $form_state->setError($element, $this->t('The @title end date cannot be before the start date', ['@title' => $element['#title']]));
        }
      }
    }
  }

  /**
   * Creates a date object for use as a default value.
   *
   * This will take a default value, apply the proper timezone for display in
   * a widget, and set the default time for date-only fields.
   *
   * @param \Drupal\Core\Datetime\DrupalDateTime $date
   *   The UTC default date.
   * @param string $timezone
   *   The timezone to apply.
   *
   * @return \Drupal\Core\Datetime\DrupalDateTime
   *   A date object for use as a default value in a field widget.
   */
  protected function createDefaultValue($date, $timezone) {
    // The date was created and verified during field_load(), so it is safe to
    // use without further inspection.
    if ($this->getFieldSetting('datetime_type') == DateTimeItem::DATETIME_TYPE_DATE) {
      // A date without time will pick up the current time, use the default
      // time.
      datetime_date_default_time($date);
    }
    $date->setTimezone(new \DateTimeZone($timezone));
    return $date;
  }

}

```

**TimeRangeWidget.php**:

```
<?php

namespace Drupal\time_range\Plugin\Field\FieldWidget;

use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\datetime_range\Plugin\Field\FieldType\DateRangeItem;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Plugin implementation of the 'daterange_time_only' widget.
 *
 * @FieldWidget(
 *   id = "daterange_time_only",
 *   label = @Translation("Time range"),
 *   field_types = {
 *     "daterange"
 *   }
 * )
 */
class TimeRangeWidget extends TimeRangeWidgetBase implements ContainerFactoryPluginInterface {

  /**
   * The date format storage.
   *
   * @var \Drupal\Core\Entity\EntityStorageInterface
   */
  protected $dateStorage;

  /**
   * {@inheritdoc}
   */
  public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, array $third_party_settings, EntityStorageInterface $date_storage) {
    parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $third_party_settings);

    $this->dateStorage = $date_storage;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $plugin_id,
      $plugin_definition,
      $configuration['field_definition'],
      $configuration['settings'],
      $configuration['third_party_settings'],
      $container->get('entity_type.manager')->getStorage('date_format')
    );
  }

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

    // Identify the type of date and time elements to use.
    switch ($this->getFieldSetting('datetime_type')) {
      case DateRangeItem::DATETIME_TYPE_DATE:
      case DateRangeItem::DATETIME_TYPE_ALLDAY:
        $date_type = 'date';
        $time_type = 'none';
        $date_format = $this->dateStorage->load('html_date')->getPattern();
        $time_format = '';
        break;

      default:
        $date_type = 'date';
        $time_type = 'time';
        $date_format = $this->dateStorage->load('html_date')->getPattern();
        $time_format = $this->dateStorage->load('html_time')->getPattern();
        break;
    }

    $element['value'] += [
      '#date_date_format' => $date_format,
      '#date_date_element' => 'none',
      '#date_date_callbacks' => [],
      '#date_time_format' => $time_format,
      '#date_time_element' => $time_type,
      '#date_time_callbacks' => [],
    ];

    $element['end_value'] += [
      '#date_date_format' => $date_format,
      '#date_date_element' => 'none',
      '#date_date_callbacks' => [],
      '#date_time_format' => $time_format,
      '#date_time_element' => $time_type,
      '#date_time_callbacks' => [],
    ];

    return $element;
  }

}

```

**TimeRangeWidgetBase.php**

```
<?php

namespace Drupal\time_range\Plugin\Field\FieldWidget;

use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItem;
use Drupal\datetime\Plugin\Field\FieldWidget\DateTimeWidgetBase;
use Drupal\datetime_range\Plugin\Field\FieldType\DateRangeItem;

/**
 * Base class for the 'daterange_*' widgets.
 */
class TimeRangeWidgetBase extends DateTimeWidgetBase {

  /**
   * {@inheritdoc}
   */
  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
    $element = parent::formElement($items, $delta, $element, $form, $form_state);
    $element['#element_validate'][] = [$this, 'validateStartEnd'];
    $element['value']['#title'] = $this->t('Start');

    $element['end_value'] = [
      '#title' => $this->t('End'),
    ] + $element['value'];

    if ($items[$delta]->start_date) {
      /** @var \Drupal\Core\Datetime\DrupalDateTime $start_date */
      $start_date = $items[$delta]->start_date;
      $element['value']['#default_value'] = $this->createDefaultValue($start_date, $element['value']['#date_timezone']);
    }

    if ($items[$delta]->end_date) {
      /** @var \Drupal\Core\Datetime\DrupalDateTime $end_date */
      $end_date = $items[$delta]->end_date;
      $element['end_value']['#default_value'] = $this->createDefaultValue($end_date, $element['end_value']['#date_timezone']);
    }

    return $element;
  }

  /**
   * {@inheritdoc}
   */
  public function massageFormValues(array $values, array $form, FormStateInterface $form_state) {
    // The widget form element type has transformed the value to a
    // DrupalDateTime object at this point. We need to convert it back to the
    // storage timezone and format.
    foreach ($values as &$item) {
      if (!empty($item['value']) && $item['value'] instanceof DrupalDateTime) {
        /** @var \Drupal\Core\Datetime\DrupalDateTime $start_date */
        $start_date = $item['value'];
        switch ($this->getFieldSetting('datetime_type')) {
          case DateRangeItem::DATETIME_TYPE_DATE:
            // If this is a date-only field, set it to the default time so the
            // timezone conversion can be reversed.
            datetime_date_default_time($start_date);
            $format = DATETIME_DATE_STORAGE_FORMAT;
            break;

          case DateRangeItem::DATETIME_TYPE_ALLDAY:
            // All day fields start at midnight on the starting date, but are
            // stored like datetime fields, so we need to adjust the time.
            // This function is called twice, so to prevent a double conversion
            // we need to explicitly set the timezone.
            $start_date->setTimeZone(timezone_open(drupal_get_user_timezone()));
            $start_date->setTime(0, 0, 0);
            $format = DATETIME_DATETIME_STORAGE_FORMAT;
            break;

          default:
            $format = DATETIME_DATETIME_STORAGE_FORMAT;
            break;
        }
        // Adjust the date for storage.
        $start_date->setTimezone(new \DateTimezone(DATETIME_STORAGE_TIMEZONE));
        $item['value'] = $start_date->format($format);
      }

      if (!empty($item['end_value']) && $item['end_value'] instanceof DrupalDateTime) {
        /** @var \Drupal\Core\Datetime\DrupalDateTime $end_date */
        $end_date = $item['end_value'];
        switch ($this->getFieldSetting('datetime_type')) {
          case DateRangeItem::DATETIME_TYPE_DATE:
            // If this is a date-only field, set it to the default time so the
            // timezone conversion can be reversed.
            datetime_date_default_time($end_date);
            $format = DATETIME_DATE_STORAGE_FORMAT;
            break;

          case DateRangeItem::DATETIME_TYPE_ALLDAY:
            // All day fields end at midnight on the end date, but are
            // stored like datetime fields, so we need to adjust the time.
            // This function is called twice, so to prevent a double conversion
            // we need to explicitly set the timezone.
            $end_date->setTimeZone(timezone_open(drupal_get_user_timezone()));
            $end_date->setTime(23, 59, 59);
            $format = DATETIME_DATETIME_STORAGE_FORMAT;
            break;

          default:
            $format = DATETIME_DATETIME_STORAGE_FORMAT;
            break;
        }
        // Adjust the date for storage.
        $end_date->setTimezone(new \DateTimezone(DATETIME_STORAGE_TIMEZONE));
        $item['end_value'] = $end_date->format($format);
      }
    }

    return $values;
  }

  /**
   * #element_validate callback to ensure that the start date <= the end date.
   *
   * @param array $element
   *   An associative array containing the properties and children of the
   *   generic form element.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the form.
   * @param array $complete_form
   *   The complete form structure.
   */
  public function validateStartEnd(array &$element, FormStateInterface $form_state, array &$complete_form) {
    $start_date = $element['value']['#value']['object'];
    $end_date = $element['end_value']['#value']['object'];

    if ($start_date instanceof DrupalDateTime && $end_date instanceof DrupalDateTime) {
      if ($start_date->format('U') !== $end_date->format('U')) {
        $interval = $start_date->diff($end_date);
        if ($interval->invert === 1) {
          $form_state->setError($element, $this->t('The @title end date cannot be before the start date', ['@title' => $element['#title']]));
        }
      }
    }
  }

  /**
   * Creates a date object for use as a default value.
   *
   * This will take a default value, apply the proper timezone for display in
   * a widget, and set the default time for date-only fields.
   *
   * @param \Drupal\Core\Datetime\DrupalDateTime $date
   *   The UTC default date.
   * @param string $timezone
   *   The timezone to apply.
   *
   * @return \Drupal\Core\Datetime\DrupalDateTime
   *   A date object for use as a default value in a field widget.
   */
  protected function createDefaultValue($date, $timezone) {
    // The date was created and verified during field_load(), so it is safe to
    // use without further inspection.
    if ($this->getFieldSetting('datetime_type') == DateTimeItem::DATETIME_TYPE_DATE) {
      // A date without time will pick up the current time, use the default
      // time.
      datetime_date_default_time($date);
    }
    $date->setTimezone(new \DateTimeZone($timezone));
    return $date;
  }

}

```

Now I just gotta find a how to remove the seconds from the field...

Note:

* You need to install Date Range
* Flush the Cache
* Enable the module
* Select Time Range in the Form display settings, not the field settings.
> 3 votes

---
Tags: 8, datetime
---


# Question
Title: Drush says it needs Composer, but Composer is already installed?
I've recently re-provisioned my development box, and went to run a drush command but was met with

> Unable to load autoload.php. Drush now requires Composer in order to install its dependencies and autoload classes. Please see README.md

I then tested to see if Composer was installed and found it was (version 1.0.3).

Would anyone know what I can do here?

# Answer
> 0 votes
There is a Drupal core isssue about this: Catch error(s) from composer install not being run and return friendly error.

**tl;dr**

Basically, you need to run `composer install` from inside your docroot.

---
Tags: 7, drush
---


title: Webform results don't download

text:
# Question
Title: Webform results don't download
We've been using our Drupal webforms for years. Suddenly today, if an authorized user or the admin tries to download the results, the resulting file is 0bytes. The data is definitely there. I am unsure how to even troubleshoot this problem.

The really odd thing is that my dev site is a near identical copy of the live site and it works on the dev site (but the results are outdated). Whatever changed on the live site would have been in the last couple weeks and I can't think of what may have caused it that I wouldn't have implemented on the dev site first.

Drupal 7.50 Commons, webform 7.x-1.0. Let me know what other information would be helpful to provide, thanks!

**Things I've Tried, to no avail:**

* downloaded the results into different formats
* downloaded results as regular staff and admin user
* downloaded only final and non-draft results

# Answer
I checked the permissions of the temporary files for our theme and sure enough, they were wrong. I am not sure what caused them to change, but they were set to root, whereas the dev site was set for www-data for both user and group. On our Debian server, Drupal uses the temporary files located at /tmp/example\_theme.

To fix:

`sudo chown -R www-data /var/example_theme`

`sudo chgrp -R www-data /var/example_theme`

That fixed this and many other problems we were having today.
> 1 votes

---
Tags: 7, webforms
---


title: How do I change the text of a link?

text:
# Question
Title: How do I change the text of a link?
How do I change the text of a link in Views?

Under 'Fields' I have Content:Title (the default)...and that's what I want. It links to the piece of content with the link being the Title of that document. But I want to change the link text to something else.

I tried clicking that field. It opens up a dialog. Under 'Rewrite Results' I selected 'Override the output of this field with custom text' and put in my custom text. But now instead of it being a link it's just static text. That's useless.

Replacement patterns don't have any links listed just {{title}} and {{ title\__value }} == Raw value

'Link to this content' is still checked at the top btw.

# Answer
In Fields add *Path* and \_Exclude from display. In your title, **uncheckmark** *Link to the Content*.

In rewrite results, checkmark *Override the output of this field with custom text* and put `<a href="{{ path }}">Custom Text</a>`. Alternatively, in rewrite results, checkmark *Output this field as a custom link*, for the path put `{{ path }}` and scroll down a bit to *Title text* and write your title here.
> 3 votes

---
Tags: views, 8
---


title: Get an image from an article/entity

text:
# Question
Title: Get an image from an article/entity
How do I easiest get an image (its path) from the article content type included in Drupal 8?

What I have is an entity. Using `$image = $node->fields['field_image']` gives me a hell of a structure, though.

Is there no easier way to get the image path? Also I cannot find the URL in this, what I get is some sort of target\_id (the file ID?).

# Answer
> 17 votes
Didn't see this before.

The shortest way to get the referenced entity for a single-value field is this:

```
$node->field_image->entity->url()

```

You can also specify the delta explicitly:

```
$node->field_image[0]->entity->url()

```

This works with a lot of ArrayAccess and \__get() magic.

See also the great cheat sheet at http://wizzlern.nl/drupal/drupal-8-entity-cheat-sheet. and https://www.drupal.org/node/1795854 and the other documentation pages there for more information (still very much work in progress).

# Answer
> 3 votes
What ended up working for me in D8 is:

```
$imageUrl = $node->get('field_image')->entity->uri->value;

```

Using `kint($node->get('field_image')->entity)` and looking through the array was very helpful

Then in my twig file I used:

```
<img class="top-article-image" src="{{ file_url(imageUrl) }}" />

```

# Answer
> 1 votes
So my solution was to use the method "referencedEntities()" found in the nodeobject. This gave me an array of File-objects which I could iterate through and use the method "url()" from the file objects to retrieve a valid path.

# Answer
> 0 votes
If your node has more than one image you can use this to get a array of the image urls (helpful for making slideshow modules among alot of other useful things)

```
$allImagesFound = false;
$imageUrls = array();
$numberOfImages = 0;
while(!$allImagesFound)
{
    //make sure we are not calling a null value, if so then we have found all images
    if($node->get('your_image_field_name')[$numberOfImages] != null) {
        $imageUrls[] = $node->get('your_image_field_name')[$numberOfImages]->entity->url();
        $numberOfImages++;
    } else {
        $allImagesFound = true;
        break;
    }
}

```

The imageUrls array will hold all the urls for any images associated with the nodes field. Hope this helps.

---
Tags: entities, 8, media
---


title: Rule action seems to fire unexpectedly

text:
# Question
Title: Rule action seems to fire unexpectedly
I've got a problem with a rule that fires when I think it shouldn't.

**Background**:

My Article content type uses the Node Expire and Node Expire Extras modules to control automatic Article expiration. I have the following “expiration” rule defined:

```
{ "rules_expired_content" : {
    "LABEL" : "Expired Content",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules", "node_expire" ],
    "ON" : { "node_expired" : [] },
    "DO" : [ { "node_unpublish" : { "node" : [ "node" ] } } ]
  }
}

```

The rule sets the Article to “unpublished”.

My users asked that I provide a way to selectively control if an email is sent when an article is **updated**. To that end, I added a field (radio button) to the Article content type called “Send email” (*field\_send\_email*). The field defaults to “Yes”. I wrote two rules: when content is saved and when content is updated. The rule for saving content seems to work flawlessly. Here's the rule for updating the content:

```
{ "rules_updated_article_email_notification_cloned_" : {
    "LABEL" : "Updated Article Email Notification",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "TAGS" : [ "Email" ],
    "REQUIRES" : [ "rules", "node_expire", "php", "mimemail" ],
    "ON" : { "node_update--article" : { "bundle" : "article" } },
    "IF" : [
      { "data_is" : { "data" : [ "node:field-send-email" ], "value" : "1" } },
      { "AND" : [ { "NOT node_expire_rules_expired_check" : { "node" : [ "node" ] } } ] }
    ],
    "DO" : [
      { "mimemail_to_users_of_role" : {
          "key" : "xxxxxxxxxxxxxxxxxx",
          "roles" : { "value" : { "4" : "4" } },
          "active" : "1",
          "from_mail" : [ "node:author:mail" ],
          "subject" : "An article has been updated: [node:title]",
          "body" : "[node:body]",
          "attachments" : "\u003C?php\r\nforeach($node-\u003Efield_file_attachments[\u0027und\u0027] as $file) {\r\n  echo  drupal_realpath(file_load($file[\u0027fid\u0027])-\u003Euri);\r\necho (\u0022\\n\u0022);}\r\n?\u003E",
          "language_user" : "1",
          "language" : [ "" ]
        }
      }
    ]
  }
}

```

**Problem**:

When cron runs, it fires the rule that detects that an Article has expired. That changes the state of the Article to “unpublished”. Changing the state forces the above updated Article rule to fire. Today, December 31st, a series of emails was sent out unexpectedly. I know it has something to do with the Updated Article rule, but, I am at a loss to pinpoint the cause. I checked the system log and noticed the following line that looked suspicious:

> Notice: Undefined property: stdClass::$expired in node\_expire\_rules\_expired\_check() (line 98 of /XXXX/XXXX/public\_html/XXXXX/sites/all/modules/node\_expire/node\_expire.rules.inc).

I did not find any reported problems with the Node expire module and the above message.

I also ran some localhost tests and the code appeared to run correctly although I'm not sure I'm simulating an expired node correctly by forcing it from Cron.

I've turned on Rules debug so that it will show in the system log for future issues with Articles. However, if anyone can shed some light on this, I'd greatly appreciate it.

**UPDATE**: I have since found that this bug is inconsistent. I had one article that was unpublished and had the problem, and, another that did not. The only difference seems to be that the one with the problem was also originally promoted to the front page.

**UPDATE 2**: I'm not getting any response on the Drupal Node Expire page. If anyone knows of an alternative mechanism to implement Node expiration without using the above mentioned modules, I'd love to hear.

# Answer
> 1 votes
Your problem is `node_unpublish` will be saving the node, triggering the second rule on `node_update--article` thereby actioning `mimemail_to_users_of_role`

Looks like you'll need to add a condition to make sure the email should be sent. For example, you could check the updated node is not being set to "unpublished"

```
"IF" : [ { "data_is" : { "data" : [ "node:status" ], "value" : "1" } } ],

```

---
Tags: 7, rules
---


# Question
Title: How to get selected term ID from drop down while ajaxing?
I can't get name or ID from selected drop down during ajaxing. I was trying with code below:

```
if(isset($form_state['values']['submitted']['company_name'])){
    $company_ID = $form_state['values']['submitted']['company_name'];
    $form['submitted']['company_name']['#value'] = $company_ID;
}

```

Why is `$company_ID` empty?

# Answer
I wasted too much time on this tiny task. However, I have done what I wanted.

Actually, I had to add `$form_state['rebuild'] = TRUE;` in my `callback_function`.

```
if(isset($form_state['values']['submitted']['company_name'])){
    $array_id[0] = $form_state['input']['company_name']; //$form_state['input']['company_name'] array holding the number I wanted.
    $company_ID = $array_id[0];
    $form['submitted']['company_name']['#value'] = $company_ID;
}

```
> 0 votes

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


# Question
Title: Problem with showing custom html.twig content
im making a custom menu for the homepage. My issue is that whenever I change **block--system-menu-block.html.twig** to something else that it suggest in the debugging like for example: **block--system-menu-block--main.html.twig** or **block--hoofdnavigatie.html.twig** it's not showing up anymore. I've cleared cache, switched themes, but nothing works. It does show up in the dubugging tool that firefox has but theres 0 content in it.. Am I doing something wrong \>?

# Answer
I've tried this on my site and used main navigation and it worked. block--mainnavigation.html.twig

What you can check:

1. Of course check if you have some typo in file name, or try with default navigation to see if it works.
2. https://www.drupal.org/node/2598914 Try to disable Twig cache while you are developing.
3. Try to use cache rebuild with Drush https://drushcommands.com/drush-8x/cache/cache-rebuild/

I don't think that you are doing something wrong, problem is with caching I believe.
> 1 votes

---
Tags: 8, navigation
---


# Question
Title: run drupal2drupal that is configured in UI via drush
Is there any way to run a drupal to drupal import with the Migrate module that is configured in the UI via drush ?

# Answer
> 0 votes
`drush help --filter=migrate` provides a complete list of relevant commands.

**Examples**

`drush migrate-import Article` Import new articles

`drush migrate-import Article --update` Import new items, and also update previously-imported items

See official Drupal.org documentation for more info: https://www.drupal.org/node/1561820

---
Tags: 7, migrations
---


# Question
Title: Render an entity in a string and return it through an AJAX callback in a custom form
I use the code snippet from: render a drupal 8 entity in a string

```
$node = \Drupal::entityManager()->getStorage('node')->load($nodeid);
$view_builder = \Drupal::entityManager()->getViewBuilder('node');
$renderarray = $view_builder->view($node, 'full');
$html = \Drupal::service('renderer')->renderRoot($renderarray);

```

It works in a normal controller class without problems. But I did not get it to work in an Ajax Callback in a Custom Form.

The $html = \Drupal::service('renderer')-\>renderPlain($build); returns nothing.

Where ist the problem? Here is the reduced code of my test form:

```
<?php

namespace Drupal\mymodule\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;

class SearchApiPageBlockForm extends FormBase {

  public function getFormId() {
    return 'search_api_page_block_form';
  }

  public function buildForm(array $form, FormStateInterface $form_state, $args = array()) {

    $form['form']['actions'] = array('#type' => 'actions',);
    $form['form']['actions']['submit'] = array(
      '#type' => 'submit',
      '#value' => $this->t('TESTBUTTON!'),
      '#ajax' => array(
        'callback' => '::myAjaxCallback',
      ),
    );

    return $form;
  }

  public function submitForm(array &$form, FormStateInterface $form_state) {
  }

  public function myAjaxCallback(array &$form, FormStateInterface $form_state) {

    $view_builder = \Drupal::entityTypeManager()->getViewBuilder('comment');
    $storage = \Drupal::entityTypeManager()->getStorage('comment');
    $node = $storage->load(103); //cid 103 already exists
    $build = $view_builder->view($node);

    dpm('before rendering'); // -> dpm output is: 'before rendering'

    $html = \Drupal::service('renderer')->renderPlain($build);

    dpm($html);// -> dpm has no output
    dpm('after rendering');// -> dpm has no output

    }

}

```

My goal is, to return the html of an entity via the

```
$response->addCommand(new HtmlCommand('#testtmp_message', $output));

```

UPDATE: Content of build: dpm(build)

# Answer
> 0 votes
The code in my question is OK. The problem was caused by a conflict by calling the form from `hook_preprocess_field()`. I changed the hook, and I am calling the form from `template_preprocess_block()` and the AJAX callback of the entity gets fine.

4k4 put me on the right track. Thank you.

---
Tags: theming, 8, forms, entities, ajax
---


# Question
Title: How to wrap Drupal "$messages" in a div?
How can I wrap $messages in a div using template.php file?

This is my code:

```
function THEME_status_messages($variables) {
  $display = $variables['display'];
  $output = '';

  $status_heading = array(
    'status' => t('Status message'),
    'error' => t('Error message'),
    'warning' => t('Warning message'),
  );
  foreach (drupal_get_messages($display) as $type => $messages) {
    $output .= "<div class=\"message $type\"><a class=\"message-close\"></a>\n";
    if (!empty($status_heading[$type])) {
      $output .= '<h2 class="element-invisible">' . $status_heading[$type] . "</h2>\n";
    }
    if (count($messages) > 1) {
      $output .= "<ul>\n";
      foreach ($messages as $message) {
      $output .= '<li>' . $message . "</li>\n";
    }
    $output .= "</ul>\n";
    }
    else {
      $output .= reset($messages);
    }
    $output .= "</div>\n";
    }
    return $output;
}

```

I need to wrap so the result it's this:

```
<div id="messages">
  <div class="message warning">
    <a class="message-close"></a>
  </div>
  <div class="message error">
    <a class="message-close"></a>
  </div>
</div>

```

I'm not interested to in doing it in page.tpl.php like this because it will leave an empty div if there's no messages:

```
<div id="messages"><?php print render($page['messages']); ?></div>

```

So far I wasn't able to output the #messages div, every time I try something I break everything or nothing happens.

Thank you.

# Answer
> 0 votes
Change this:

```
return $output;

```

To this:

```
return '<div id="messages">' . $output . '</div>';

```

---
Tags: 7, status-messages
---


# Question
Title: how to subtract 2 months from current month?
I have used this :

> $date = date("Y-m", strtotime("-2 months"));

and it is gives "2016-12" but what i needed is "2016-11".

# Answer
> 2 votes
I have used :

> $fdate = date('Y-m', strtotime('first day of -2 month'));

# Answer
> 1 votes
If you try to change format to dmY for example: echo date("dmY", strtotime("-2 months")); You will see that result is 01122016.

You can check comments from this question also: https://stackoverflow.com/questions/10586615/current-date-2-months

And you can check solution here: https://stackoverflow.com/questions/9058523/php-date-and-strtotime-return-wrong-months-on-31st

Pass second parameter.

---
Tags: 7, datetime
---


title: How to render a field from loadtree

text:
# Question
Title: How to render a field from loadtree
Here is my code:

```
   $terms = array(

  \Drupal::service('entity_type.manager')
      ->getStorage("taxonomy_term")
      ->loadTree('faq', $parent = 0, $max_depth = 1, $load_entities = TRUE)

```

);

and when i'm using kint, i can see the first level of my vocabulary.

How can i render the field\_question\_tag in twig?

# Answer
> 2 votes
I Changed how to build my form,

```
public function buildForm(array $form, FormStateInterface $form_state) {
  $terms = \Drupal::service('entity_type.manager')
      ->getStorage("taxonomy_term")
      ->loadTree('faq', $parent = 0, $max_depth = 1, $load_entities = TRUE);
  $terms_select = array();
  foreach ($terms as $term){

      $question = $term->get('field_question_faq')->getValue();

      $terms_select[] =  $question[0]['value']);

  }

```

and then everything was fine!!

Thx to Vikram8888

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


title: How to store user meta data?

text:
# Question
Title: How to store user meta data?
I've seen that it was possible to store custom meta data in Drupal 7 but I didn't find the equivalent for Drupal 8 ?

https://martsie.github.io/2015/03/04/drupal-how-to-use-user-data/

The data that I need to store is temporary user data that might differ from each users and it's not needed to put it as field (no sql query needed).

# Answer
> 11 votes
You can use the user.data service

```
\Drupal::service('user.data')->set('mymodule', $uid, 'some_key', 'some_value');

```

You can then retrieve it with the same service:

```
$some_key = \Drupal::service('user.data')->get('mymodule', $uid, 'some_key');

```

---
Tags: 8, users, entities, database
---


# Question
Title: Howto override a function in privatemsg.module?
There is a function in the module private message that I want to override. What is the right way to do this?

This is the function:

```
/**
* Format an array of user objects.
*
* @param $part_array
*   Array with user objects, for example the one returned by
*   _privatemsg_generate_user_array.
*
* @param $limit
*   Limit the number of user objects which should be displayed.
* @param $no_text
*   When TRUE, don't display the Participants/From text.
* @return
*   String with formatted user objects, like user1, user2.
*/
function _privatemsg_format_participants($part_array, $limit = NULL,$no_text = FALSE) {
 global $user;
 if (count($part_array) > 0) {
$to = array();
$limited = FALSE;
foreach ($part_array as $account) {

  // Directly address the current user.
  if (isset($account->type) && in_array($account->type, array('hidden', 'user')) && $account->recipient == $user->uid) {
    array_unshift($to, $no_text ? t('You') : t('you'));
    array_shift($to, $no_text ? t('You') : t('you'));
    continue;
  }

  // Don't display recipients with type hidden.
  if (isset($account->type) && $account->type == 'hidden') {
    continue;
  }
  if (is_int($limit) && count($to) >= $limit) {
    $limited = TRUE;
    break;
  }
  $to[] = privatemsg_recipient_format($account);
}

$limit_string = '';
if ($limited) {
  $limit_string = t(' and others');
}

if ($no_text) {
  return implode(', ', $to) . $limit_string;
}

$last = array_pop($to);
if (count($to) == 0) { // Only one participant
  return t("From !last", array('!last' => $last));
}
else { // Multiple participants..
  $participants = implode(', ', $to);
  return t('Between !participants and !last', array('!participants' => $participants, '!last' => $last));
}
  }
  return '';
}

```

I like to remove this part from the code:

```
// Directly address the current user.
  if (isset($account->type) && in_array($account->type, array('hidden', 'user')) && $account->recipient == $user->uid) {
    array_unshift($to, $no_text ? t('You') : t('you'));
    array_shift($to, $no_text ? t('You') : t('you'));
    continue;
  }

```

# Answer
The `_privatemsg_format_participants()` function is called from `template_preprocess_privatemsg_recipients()` function, which is a template preprocess hook. You can simply override `template_preprocess_privatemsg_recipients()` into your module's `.module` file or theme's `template.php` file. Check the example below:

```
/**
 * Implementation of hook_preprocess_privatemsg_recipients().
 */
function [MODULE/THEME_NAME]_preprocess_privatemsg_recipients(&$vars) {
  $vars['participants'] = ''; // assign a default empty value
  if (isset($vars['thread']['participants'])) {
    $vars['participants'] = _[MODULE_NAME]_format_participants($vars['thread']['participants']);
  }
}

/**
 * Format an array of user objects.
 *
 * @param $part_array
 *   Array with user objects, for example the one returned by
 *   _privatemsg_generate_user_array.
 *
 * @param $limit
 *   Limit the number of user objects which should be displayed.
 * @param $no_text
 *   When TRUE, don't display the Participants/From text.
 * @return
 *   String with formatted user objects, like user1, user2.
 */
function _[MODULE_NAME]_format_participants($part_array, $limit = NULL, $no_text = FALSE) {
  global $user;
  if (count($part_array) > 0) {
    $to = array();
    $limited = FALSE;
    foreach ($part_array as $account) {

      // Directly address the current user.
      if (isset($account->type) && in_array($account->type, array('hidden', 'user')) && $account->recipient == $user->uid) {
        array_unshift($to, $no_text ? t('You') : t('you'));
        array_shift($to, $no_text ? t('You') : t('you'));
        continue;
      }

      // Don't display recipients with type hidden.
      if (isset($account->type) && $account->type == 'hidden') {
        continue;
      }
      if (is_int($limit) && count($to) >= $limit) {
        $limited = TRUE;
        break;
      }
      $to[] = privatemsg_recipient_format($account);
    }

    $limit_string = '';
    if ($limited) {
      $limit_string = t(' and others');
    }

    if ($no_text) {
      return implode(', ', $to) . $limit_string;
    }

    $last = array_pop($to);
    if (count($to) == 0) { // Only one participant
      return t("From !last", array('!last' => $last));
    }
    else { // Multiple participants..
      $participants = implode(', ', $to);
      return t('Between !participants and !last', array('!participants' => $participants, '!last' => $last));
    }
  }
  return '';
}

```

**Note: Make sure to change \[MODULE\_NAME\] with your module/theme name.**
> 1 votes

---
Tags: 7, privatemsg
---


title: How to send HTML email

text:
# Question
Title: How to send HTML email
I am creating a simple module which will be sending HTML emails to users for deals in our website.

I have searched a lot, but I can't find a solution proper solution for Drupal. Now I can send mails but plain text.

What is a step-by-step procedure to send HTML emails in Drupal 7?

```
function example_form_submit( $form,&$form_state) {
    $friend_email=$form_state['values']['friend_email'];
    $mailto =$friend_email;  //gift to a friend
    $mailfrom ='no-reply@example.com';
    $subject = "another message for  HTML email from example.com";
    $body="<h2 style='font-size:28px;color:red;'>Hello EMAIL, i here i want to be <b>bolded</b></h2>";
    if (drupal_mail('example', 'send_gift', $mailto, language_default(),$params,$mailfrom,TRUE)) {
        drupal_set_message(t('Your gift was sent successfully!!!'));
    }
    else {
        drupal_set_message(t('<font color="red">Error occured while sending your mail!!!</font>'));
    }

/****hook_mail*/
function example_mail($key,&$message,$params) {
    $language = $message['language'];
    switch ($key) {
        case 'send_gift':
            $message['subject']=t($params['subject'], $var, $language->language);
            $message['body'][]=$params['body'];
            $message['headers']['Content-Type'] = 'text/html; charset=UTF-8; format=flowed';
        break;
    }
}

```

# Answer
Like geoff mentioned one option would be to use the Mime Mail module, but you can also enable your custom module to send HTML e-mails with some extra code. In short you'd need to alter the `mail_system` variable and write your own implementation of `MailSystemInterface`. An example of that is the following code.

Inside 'mymodule.install':

```
function mymodule_enable() {
  $current = variable_get('mail_system', array('default-system' => 'DefaultMailSystem'));
  $addition = array('mymodule' => 'MymoduleMailSystem');
  variable_set('mail_system', array_merge($current, $addition));
}

function mymodule_disable() {
  $mail_system = variable_get('mail_system', array('default-system' => 'DefaultMailSystem'));
  unset($mail_system['mymodule']);
  variable_set('mail_system', $mail_system);
}

```

Inside 'mymodule.module':

```
class MymoduleMailSystem extends DefaultMailSystem {
  public function format(array $message) {
    $message['body'] = implode("\n\n", $message['body']);
    $message['body'] = drupal_wrap_mail($message['body']);
    return $message;
  }
}

```

You'd have to replace mymodule instances with your actual module's name then disable and re-enable your module to get the variable changed after which things should be working. For a complete example you can check out my answer here. Additionally this page on drupal.org is from where I originally got all the information from.
> 23 votes

# Answer
Mime Mail module is almost certainly what you are looking for.

> This is a Mime Mail component module (for use by other modules).
>
> * It permits users to receive HTML email and can be used by other modules. The mail functionality accepts an HTML message body, mime-endcodes it and sends it.
> * If the HTML has embedded graphics, these graphics are MIME-encoded and included as a message attachment.
> * Adopts your site's style by automatically including your theme's stylesheet files in a themeable HTML message format
> * If the recipient's preference is available and they prefer plaintext, the HTML will be converted to plain text and sent as-is. Otherwise, the email will be sent in themeable HTML with a plaintext alternative.
> * Allows you to theme messages with a specific mailkey.
> * Converts CSS styles into inline style attributes.
> * Provides simple system actions and Rules actions to send HTML email with embedded images and attachments.
> 7 votes

# Answer
None of the above answers worked for me, so here is my take on the original question.

First of all, install and enable the Mime Mail module. You can read the README.txt for complete instructions on how to use it. I'll give you the short version.

You need to enable Mime Mail for your module. You can do this using `hook_enable` or `hook_update_N` in `example.install`:

```
function example_enable() {
  mailsystem_set(array(
    'example_send_gift' => 'MimeMailSystem',
  ));
}

```

When you go to `admin/config/system/mailsystem` you will see that a new entry has been added for your module:

> Example module (send\_gift key) class
>
> MimeMailSystem

Now you don't need to specificy any `text/html` headers anymore, Mime Mail takes care of this. So you don't need this:

```
$message['headers']['Content-Type'] = ...

```

If you want, you can add `$message['plaintext']` to your mail for a non-HTML alternative, but this is not required.

That's it!
> 4 votes

# Answer
You might also want to look at the Swift Mailer module. It lets you send HTML e-mails with both inline and regular attachments (such as images or files). Furthermore, it is also capable of automatically generating plain text versions based on the HTML e-mail.

You can have a look at it http://www.drupal.org/project/swiftmailer

For the record: I'm the author and maintainer of the module.
> 3 votes

# Answer
You are not sending proper HTML , you are only including H1 tags and B tags, you probably need to include Full HTML tags as well starting from
`<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">`
> 2 votes

---
Tags: 7, emails
---


# Question
Title: Should I save temporary data in $form_state or in my form class?
As far as I can see, there are two ways of storing temporary data when working with complex forms in Drupal 8.

1. `$form_state->set('key', 'value')`. The value ends up in $form\_state\['storage'\]\['value'\], and I can use it other places because it is passed around from function to function.
2. Make a non-static property inside `class MyForm extends FormBase`. The value is also accessible everywhere I need it, since all of the form functions are in one class.

After browsing through a lot of core `EntityForm` code today, it seems that both are used! Is any of the above necessarily "better" or more in line with "The Drupal Way"?

Related question: It seems that there is a `1:1` mapping between an instance of `MyForm` and the `$form_state` variable. Why then, is `$form_state` not implemented as a non-static class property? Then it wouldn't be necessary to pass it from function to function. The same can be asked of the `$form` variable.

# Answer
While the storage in `$form_state` can be cached, the class property can't. So if you build a multistep form you would need to use the first option.

And a validate or submit function is not necessarily in the same class or in no class at all if it is defined in a hook. This also answers the related question.
> 10 votes

---
Tags: forms, 8
---


title: Unknown engine type outputformat

text:
# Question
Title: Unknown engine type outputformat
Hello I've just updated Drupal (to version 7.53) and now in Drush when I try launch the commands: "drush @theflyingeye.org up" (to update my website) or "drush @theflyingeye.org cc" (to clean chache) or "drush @theflyingeye.org dl view" (to download a basic module, view for example) I can just get this answer: "Unknown engine type outputformat"

If I digit:

```
"drush status" (after "su aegir")
I can get:
"PHP configuration     :  /etc/php5/cli/php.ini
 Drush version         :  5.10.0
 Drush configuration   :  /var/aegir/.drush/drushrc.php
 Drush alias files     :  /var/aegir/.drush/server_master.alias.drushrc.php
                          /var/aegir/.drush/theflyingeye.org.alias.drushrc.php
                          /var/aegir/.drush/server_localhost.alias.drushrc.php

```

Do you have any advise please to fix this problem?

# Answer
Start with upgrading to Drush 8 ... see http://drush.org/en/master/install
> 0 votes

---
Tags: 7, drush, aegir
---


title: Infinite Scroll - Issue with first load

text:
# Question
Title: Infinite Scroll - Issue with first load
I created a view that displays all the products of my website's database.

First of all, my view looks like this. As you can see I am using Responsive Grid as my layout format.  Because of the fact that I chose to work with Responsive Grid, I implemented some code to identify the content selectors to Infinite Scroll.

```
  case 'responsive_grid':
    $content_selector = '.view-content > div';
    $items_selector = '.views-row';
    break;

```

I am overriding the output of this view using a template file. The reason is that for every 12 blocks of content I have to display a banner for a product category. You can see the snippet bellow.

```
<?php if (!empty($title)) : ?>
  <h3><?php print $title; ?></h3>
<?php endif; ?>
  <div class="<?php print $classes; ?>">
<?php if ($options['alignment'] == 'vertical') : ?>
<?php foreach ($columns as $column_id => $column) : ?>
  <div class="<?php print trim($column_classes[$column_id]); ?>">
  <?php foreach ($column as $item_id => $item) : ?>
    <div class="<?php print trim($item['classes']); ?>">
      <?php print $item['content']; ?>
    </div>
  <?php endforeach; ?>
  </div>
<?php endforeach; ?>
<?php else : ?>
  <?php foreach ($rows as $row_id => $row) : ?>
    <div class="<?php print trim($row_classes[$row_id]); ?>">
  <?php foreach ($row as $item_id => $item) : ?>
    <div class="<?php print trim($item['classes']); ?>">
      <?php print $item['content']; ?>
    </div>
  <?php endforeach; ?>
  </div>
  <?php endforeach; ?>
<?php endif; ?>
</div>
<?php if ($row_id % 1 == 0 && $row_id !=0): ?>
      <div>
        <?php print views_embed_view('display_random_snippet_home_1', 'block'); ?>
      </div>
<?php endif; ?>

```

Although everything appears to be working as designed I have an issue when the Infinite Scroll module loads the first page (always counting from 0.) As you are able to see bellow, when the pager is initiated it loads 12 products pushing down the category block and creating a mess. Also, you can notice that after the first initiation everything works as planned.

You can see the issue reproduced here: http://giphy.com/gifs/l0Ex99XrcsBjynBcY

Or you can reproduce it yourself: mygadgeto.com/infinite

Hope we find a way out of this.

# Answer
It seems like it is a pure markup error. I should have the statement placed in my main markup. Updated template looks like the snippet bellow.

```
<?php if (!empty($title)) : ?>
  <h3><?php print $title; ?></h3>
<?php endif; ?>
  <div class="<?php print $classes; ?>">
<?php if ($options['alignment'] == 'vertical') : ?>
<?php foreach ($columns as $column_id => $column) : ?>
  <div class="<?php print trim($column_classes[$column_id]); ?>">
  <?php foreach ($column as $item_id => $item) : ?>
    <div class="<?php print trim($item['classes']); ?>">
      <?php print $item['content']; ?>
    </div>
  <?php endforeach; ?>
  </div>
<?php endforeach; ?>
<?php else : ?>
  <?php foreach ($rows as $row_id => $row) : ?>
    <div class="<?php print trim($row_classes[$row_id]); ?>">
  <?php foreach ($row as $item_id => $item) : ?>
    <div class="<?php print trim($item['classes']); ?>">
      <?php print $item['content']; ?>
    </div>
  <?php endforeach; ?>
  </div>
  <?php endforeach; ?>
<?php endif; ?>
<?php if ($row_id % 2 == 0 && $row_id !=0): ?>
      <div>
        <?php print views_embed_view('display_random_snippet_home_1', 'block'); ?>
      </div>
<?php endif; ?>
</div>

```
> 1 votes

---
Tags: views, theming
---


# Question
Title: How to allow users to add images to an existing node?
How to allow users to add images to an existing node without giving them access to the whole node edit page. In Drupal 7 i used the Block Upload Module but it's buggy in the drupal 8 version. Do you have any approaches to get this functionality?

# Answer
In D8 you can use a form mode for this to assign a reduced node edit page to a specific user role.

See https://www.drupal.org/project/form\_mode\_control
> 1 votes

---
Tags: 8
---


# Question
Title: Adding an image to a media bundle's field
I am trying to add create a piece of new media with the following code. When visiting the media overview screen the media item is listed along with a thumbnail however when you edit the media item the file is not attached, although the file exists in the files area?

```
use Drupal\Core\Language\Language;
use Drupal\media_entity\Entity\Media;

$data =     file_get_contents("https://homepages.cae.wisc.edu/~ece533/images/airplane.png");
$file = file_save_data($data, 'public://plane.jpg',  FILE_EXISTS_RENAME);

$image_media = Media::create([
  'bundle' => 'image',
  'uid' => '1',
  'langcode' => Language::LANGCODE_DEFAULT,
  'status' => Media::PUBLISHED,
  'field_image' => [
    'target_id' => $file->id() ,
    'alt' => t('this is the alt text'),
    'title' => t('this is an image'),
  ],
]);
$image_media->save();

```

# Answer
Unless you have a default language setup, Language::LANGCODE\_DEFAULT will resolve to x-default.

Either:

* Set a default language
* Set the property manually, e.g, 'en' rather than Language::LANGCODE\_DEFAULT
* Remove the line entirely
> 1 votes

---
Tags: entities, media
---


# Question
Title: 'Unexpected Error' when attempting to edit or delete variant with page manager and panels
I'm using page manager 8.x-1.0-alpha24 with panels. This issue seems to crop up randomly, but when I attempt to edit variants on certain pages I receive the dreaded 'unexpected error' page. I even receive this error when attempting to delete the variant. Whenever I encounter it I end up having to resolve it by creating a new page in the page manager and apply the same settings but this isn't always an option. This is also currently running on the /node/{node} page, which I'm not sure I can delete. In the error log I receive this warning:

> Message Warning: Invalid argument supplied for foreach() in Drupal\Component\Utility\NestedArray::mergeDeepArray() (line 327 of /var/www/mydev.dev/http/web/core/lib/Drupal/Component/Utility/NestedArray.php) #0 /var/www/mydev.dev/http/web/core/includes/bootstrap.inc(548): \_drupal\_error\_handler\_real(2, 'Invalid argumen...', '/var/www/aaep.o...', 327, Array) #1 /var/www/mydev.dev/http/web/core/lib/Drupal/Component/Utility/NestedArray.php(327): \_drupal\_error\_handler(2, 'Invalid argumen...', '/var/www/aaep.o...', 327, Array) #2 /var/www/mydev.dev/http/web/core/lib/Drupal/Component/Utility/NestedArray.php(295): Drupal\Component\Utility\NestedArray::mergeDeepArray(Array) #3 /var/www/mydev.dev/http/web/core/lib/Drupal/Core/Block/BlockBase.php(76): Drupal\Component\Utility\NestedArray::mergeDeep(Array, NULL, Array) #4 /var/www/mydev.dev/http/web/core/lib/Drupal/Core/Plugin/DefaultLazyPluginCollection.php(162): Drupal\Core\Block\BlockBase-\>setConfiguration(Array) #5 /var/www/mydev.dev/http/web/core/lib/Drupal/Core/Plugin/DefaultLazyPluginCollection.php(135): Drupal\Core\Plugin\DefaultLazyPluginCollection-\>setInstanceConfiguration('16e9261f-a1ac-4...', Array) #6 /var/www/mydev.dev/http/web/modules/contrib/ctools/src/Plugin/DisplayVariant/BlockDisplayVariant.php(160): Drupal\Core\Plugin\DefaultLazyPluginCollection-\>setConfiguration(Array) #7 /var/www/mydev.dev/http/web/modules/contrib/panels/src/Plugin/DisplayVariant/PanelsDisplayVariant.php(471): Drupal\ctools\Plugin\DisplayVariant\BlockDisplayVariant-\>setConfiguration(Array) #8 /var/www/mydev.dev/http/web/core/lib/Drupal/Core/Display/VariantBase.php(30): Drupal\panels\Plugin\DisplayVariant\PanelsDisplayVariant-\>setConfiguration(Array) #9 /var/www/mydev.dev/http/web/modules/contrib/ctools/src/Plugin/DisplayVariant/BlockDisplayVariant.php(103): Drupal\Core\Display\VariantBase-\>\__construct(Array, 'panels\_variant', Array) #10 /var/www/mydev.dev/http/web/modules/contrib/panels/src/Plugin/DisplayVariant/PanelsDisplayVariant.php(106): Drupal\ctools\Plugin\DisplayVariant\BlockDisplayVariant-\>\__construct(Array, 'panels\_variant', Array, Object(Drupal\Core\Plugin\Context\ContextHandler), Object(Drupal\Core\Session\AccountProxy), Object(Drupal\Component\Uuid\Php), Object(Drupal\token\Token), Object(Drupal\Core\Block\BlockManager), Object(Drupal\Core\Condition\ConditionManager)) #11 /var/www/mydev.dev/http/web/modules/contrib/panels/src/Plugin/DisplayVariant/PanelsDisplayVariant.php(126): Drupal\panels\Plugin\DisplayVariant\PanelsDisplayVariant-\>\__construct(Array, 'panels\_variant', Array, Object(Drupal\Core\Plugin\Context\ContextHandler), Object(Drupal\Core\Session\AccountProxy), Object(Drupal\Component\Uuid\Php), Object(Drupal\token\Token), Object(Drupal\Core\Block\BlockManager), Object(Drupal\Core\Condition\ConditionManager), Object(Drupal\Core\Extension\ModuleHandler), Object(Drupal\panels\Plugin\DisplayBuilder\DisplayBuilderManager), Object(Drupal\layout\_plugin\Plugin\Layout\LayoutPluginManager)) #12 /var/www/mydev.dev/http/web/core/lib/Drupal/Core/Plugin/Factory/ContainerFactory.php(21): Drupal\panels\Plugin\DisplayVariant\PanelsDisplayVariant::create(Object(Drupal\Core\DependencyInjection\Container), Array, 'panels\_variant', Array) #13 /var/www/mydev.dev/http/web/core/lib/Drupal/Component/Plugin/PluginManagerBase.php(84): Drupal\Core\Plugin\Factory\ContainerFactory-\>createInstance('panels\_variant', Array) #14 /var/www/mydev.dev/http/web/core/lib/Drupal/Core/Plugin/DefaultSingleLazyPluginCollection.php(65): Drupal\Component\Plugin\PluginManagerBase-\>createInstance('panels\_variant', Array) #15 /var/www/mydev.dev/http/web/core/lib/Drupal/Component/Plugin/LazyPluginCollection.php(80): Drupal\Core\Plugin\DefaultSingleLazyPluginCollection-\>initializePlugin('panels\_variant') #16 /var/www/mydev.dev/http/web/modules/contrib/page\_manager/src/Entity/PageVariant.php(235): Drupal\Component\Plugin\LazyPluginCollection-\>get('panels\_variant') #17 /var/www/mydev.dev/http/web/modules/contrib/page\_manager/page\_manager\_ui/src/Wizard/PageEditWizard.php(94): Drupal\page\_manager\Entity\PageVariant-\>getVariantPlugin() #18 /var/www/mydev.dev/http/web/modules/contrib/page\_manager/page\_manager\_ui/src/Wizard/PageEditWizard.php(54): Drupal\page\_manager\_ui\Wizard\PageEditWizard-\>getVariantOperations(Object(Drupal\page\_manager\Entity\PageVariant), Array) #19 /var/www/mydev.dev/http/web/modules/contrib/ctools/src/Wizard/FormWizardBase.php(165): Drupal\page\_manager\_ui\Wizard\PageEditWizard-\>getOperations(Array) #20 /var/www/mydev.dev/http/web/modules/contrib/ctools/src/Wizard/FormWizardBase.php(251): Drupal\ctools\Wizard\FormWizardBase-\>getOperation(Array) #21 \[internal function\]: Drupal\ctools\Wizard\FormWizardBase-\>buildForm(Array, Object(Drupal\Core\Form\FormState)) #22 /var/www/mydev.dev/http/web/core/lib/Drupal/Core/Form/FormBuilder.php(514): call\_user\_func\_array(Array, Array) #23 /var/www/mydev.dev/http/web/core/lib/Drupal/Core/Form/FormBuilder.php(271): Drupal\Core\Form\FormBuilder-\>retrieveForm('page\_manage\_var...', Object(Drupal\Core\Form\FormState)) #24 /var/www/mydev.dev/http/web/modules/contrib/ctools/src/Wizard/WizardFactory.php(45): Drupal\Core\Form\FormBuilder-\>buildForm(Object(Drupal\page\_manager\_ui\Wizard\PageEditWizard), Object(Drupal\Core\Form\FormState)) #25 /var/www/mydev.dev/http/web/modules/contrib/ctools/src/Controller/WizardFormController.php(84): Drupal\ctools\Wizard\WizardFactory-\>getWizardForm(Object(Drupal\page\_manager\_ui\Wizard\PageEditWizard), Array, false) #26 \[internal function\]: Drupal\ctools\Controller\WizardFormController-\>getContentResult(Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\Routing\RouteMatch)) #27 /var/www/mydev.dev/http/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call\_user\_func\_array(Array, Array) #28 /var/www/mydev.dev/http/web/core/lib/Drupal/Core/Render/Renderer.php(574): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber-\>Drupal\Core\EventSubscriber{closure}() #29 /var/www/mydev.dev/http/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(124): Drupal\Core\Render\Renderer-\>executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure)) #30 /var/www/mydev.dev/http/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber-\>wrapControllerExecutionInRenderContext(Array, Array) #31 \[internal function\]: Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber-\>Drupal\Core\EventSubscriber{closure}() #32 /var/www/mydev.dev/http/vendor/symfony/http-kernel/HttpKernel.php(144): call\_user\_func\_array(Object(Closure), Array) #33 /var/www/mydev.dev/http/vendor/symfony/http-kernel/HttpKernel.php(64): Symfony\Component\HttpKernel\HttpKernel-\>handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1) #34 /var/www/mydev.dev/http/web/core/lib/Drupal/Core/StackMiddleware/Session.php(57): Symfony\Component\HttpKernel\HttpKernel-\>handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #35 /var/www/mydev.dev/http/web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(47): Drupal\Core\StackMiddleware\Session-\>handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #36 /var/www/mydev.dev/http/web/core/modules/page\_cache/src/StackMiddleware/PageCache.php(99): Drupal\Core\StackMiddleware\KernelPreHandle-\>handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #37 /var/www/mydev.dev/http/web/core/modules/page\_cache/src/StackMiddleware/PageCache.php(78): Drupal\page\_cache\StackMiddleware\PageCache-\>pass(Object(Symfony\Component\HttpFoundation\Request), 1, true) #38 /var/www/mydev.dev/http/web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(47): Drupal\page\_cache\StackMiddleware\PageCache-\>handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #39 /var/www/mydev.dev/http/web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(50): Drupal\Core\StackMiddleware\ReverseProxyMiddleware-\>handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #40 /var/www/mydev.dev/http/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware-\>handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #41 /var/www/mydev.dev/http/web/core/lib/Drupal/Core/DrupalKernel.php(652): Stack\StackedHttpKernel-\>handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #42 /var/www/mydev.dev/http/web/index.php(19): Drupal\Core\DrupalKernel-\>handle(Object(Symfony\Component\HttpFoundation\Request)) #43 {main}.

However I'm having trouble making sense of the error message. I make custom modules but I can't see any mention of them in the error message. So I'm having trouble making sense of it. At line 327 of NestedArray.php I do see that it needs an array and I'm assuming it didn't get that, but I'm not sure what else to do with that information. Is there a proper way to troubleshoot this? Or is this a known issue?

Even if there isn't a clear answer, is there a good method for troubleshooting issues for this yet?

UPDATE: I was able to temporarily get it to work by applying this patch https://www.drupal.org/node/2831521 to ctools. And returning to the latest version of page\_manager But after some time it broke once again. And gave me the error I was getting in the very beginning.

UPDATE 2: I turned on logging with backtrace information and got a better error message

> The website encountered an unexpected error. Please try again later. Drupal\Core\Database\DatabaseExceptionWrapper: SQLSTATE\[HY000\]: General error: 2006 MySQL server has gone away: INSERT INTO {watchdog} (uid, type, message, variables, severity, link, location, referer, hostname, timestamp) VALUES (:db\_insert\_placeholder\_0, :db\_insert\_placeholder\_1, :db\_insert\_placeholder\_2, :db\_insert\_placeholder\_3, :db\_insert\_placeholder\_4, :db\_insert\_placeholder\_5, :db\_insert\_placeholder\_6, :db\_insert\_placeholder\_7, :db\_insert\_placeholder\_8, :db\_insert\_placeholder\_9); Array ( \[:db\_insert\_placeholder\_0\] =\> 54 \[:db\_insert\_placeholder\_1\] =\> php \[:db\_insert\_placeholder\_2\] =\> %type: @message in %function (line %line of %file). \[:db\_insert\_placeholder\_3\] =\> a:6:{s:5:"%type";s:45:"Drupal\Core\Database\DatabaseExceptionWrapper";s:8:"@message";s:4810210:"SQLSTATE\[HY000\]: General error: 2006 MySQL server has gone away: UPDATE {key\_value\_expire} SET value=:db\_update\_placeholder\_0, expire=:db\_update\_placeholder\_1 WHERE ( (name = :db\_condition\_placeholder\_0) AND (collection = :db\_condition\_placeholder\_1) ); Array ( \[:db\_update\_placeholder\_0\] =\> O:8:"stdClass":3:{s:5:"owner";s:2:"54";s:4:"data";a:6:{s:4:"page";O:31:"Drupal\page\_manager\Entity\Page":24:{s:5:"\*id";s:9:"node\_view";s:8:"\*label";s:9:"Node view";s:14:"\*description";s:0:"";s:7:"\*path";s:12:"/node/{node}";s:11:"\*variants";a:15:{s:26:"node\_view-panels\_variant-3";O:38:"Drupal\page\_manager\Entity\PageVariant":27:{s:5:"\*id";s:26:"node\_view-panels\_variant-3";s:8:"\*label";s:9:"Get A DVM";s:9:"\*weight";i:0;s:7:"\*uuid";s:36:"ace4efd4-dadc-43a9-afbb-6703c4b4cc9c";s:10:"\*variant";s:14:"panels\_variant";s:19:"\*variant\_settings";a:11:{s:6:"blocks";a:5:{s:36:"c88ac011-7207-4268-a4f8-548eebadd7bc";a:9:{s:2:"id";s:7:"getadvm";s:5:"label";s:9:"Get a DVM";s:8:"provider";s:12

And then a huge list of values of the settings in each block plugin. Huge as in a 5MB text file of errors. I checked the max post size though and it was 200MB.

My guess is that the SQL query is just too gigantic? Either way it's submitting the info of every single variant instead of just one.

# Answer
> 2 votes
Your current error is this:

```
General error: 2006 MySQL server has gone away

```

You can try to fix this in two ways:

1. `my.ini`

Open your `my.ini` file and locate max\_allowed\_packet. By default this is 1M. Setting it to 16M and restart your MySQL server. If the problem persists, try setting it to 512M and restart your MySQL server.

2. `MySQL prompt`

Enter your MySQL prompt, log in as user root or as a user with the SUPER privilege. Run the following command:

```
SET GLOBAL max_allowed_packet = 1024 * 1024 * 512;

```

This method doesn't require you to restart the server.

# Answer
> 1 votes
I had a similar issue with the `The "" plugin does not exist` problem. I solved it by simply uninstalling and reinstalling page manager and panels after having a similar issue in my workflow. I would try that first.

---
Tags: 8, panels, debugging
---


title: export drupal2drupal migrate settings

text:
# Question
Title: export drupal2drupal migrate settings
I am using the drupal2drupal UI for a D7 to D7 migration. Is there anyway I can export the setting for the migration including the connection string and the field mappings so that we can repeat the exact migration on another server without having to repeat the UI setup?

# Answer
There is a feature request for the Migrate module: Export migration configuration as code. Beware that this is highly experimental! Here is the summary of the issue:

1. Apply this patch to the Migrate module and be sure to clear cache. This patch makes your configuration exportable as a Feature.
2. You can now create a new Feature on the source site and select your configuration inside the Migrate fieldgroup. Check all options that apply and download/export your Feature.
3. Copy the Feature to your target site, enable it and then revert it to copy all your settings.
> 0 votes

---
Tags: 7, migrations
---


# Question
Title: Drupal Form Ajax not updating form on first click
```
function _ajax_ticket_info($form,&$form_state)
{
    $subscriber = $form['info']['ticket']['subscribe'];
    _ticket_subscribe($subscriber['#value'],$subscriber['#name']);

    // Dunno if this is needed or not
    $form_state['rebuild'] = TRUE;

    return $form;
}
function _ticket_info($form,&$form_state,$node) {

    $is_subscribed = _ticket_is_subscribed($node->nid);
    $subscriber_count = count(_ticketsys_get_subscribers($node));

    $form = [
        '#prefix' => "<div id='ticket-info-form'>",
        '#suffix' => '</div>',
    ];
    // other form fields here not that important
    // just focusing on my problem
    $form['info']['ticket']['subscribe'] = [
    '#type' => 'button',
    '#value' => $is_subscribed,
    '#name' => $node->nid,
    '#id' => 'ticket-subscribe',
    '#ajax' => [
        'callback' => '_ajax_ticket_info',
        'wrapper' => 'ticket-info-form',
        'effect' => 'fade',
    ],
];
return $form;
}

```

So the problem is i'm using that code to update my form without reloading the page and when i do that it only executes the replacement on the second time i clicked the button $form\['info'\]\['ticket'\]\['subscribe'\] and i notice using inspect element on chrome that the form id and other form fields have --2 on their ids and increasing every time i click the Subscribe button

Any ideas whats wrong here. I really need to fix this thanks

# Answer
> 1 votes
Try changing the button type to "submit", and specifying a custom submit handler:

```
$form['info']['ticket']['subscribe'] = [
    '#type' => 'submit',
    '#submit' => [['ticket_submit_handler']]
    '#ajax' => [
        'callback' => 'ticket_ajax_callback',
        'wrapper' => 'ticket-info-form',
    ],

    // ...
];

```

In the submit handler:

* Change any variables in form\_state storage that need to persist.
* Tell the form to rebuild itself (instead of doing a redirect after submission), in order to keep the form state.
* Do other stuff.

e.g.

```
function ticket_submit_handler(&$form, &$form_state) {
    $form_state['storage'][] = ;
    $form_state['rebuild'] = TRUE;
    // ...
}

```

In the AJAX callback:

* Return the part of the form that will replace the 'wrapper'. In your case, it seems to be the entire form.
* Don't do anything else here.

e.g.

```
function ticket_ajax_callback(&$form, &$form_state) {
    return $form;
}

```

AFAIK, when the user clicks your AJAX button, the following functions will run, in order:

1. Form validation (if any).
2. `ticket_submit_handler`
3. Form builder, to rebuild the entire form, even if we only need a part.
4. `ticket_ajax_callback`, which returns a part of the form, which is sent to the browser.

For more information, see the example code in the Drupal 7 documentation.

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


# Question
Title: Remove lingering configuration data in block plugin
I built a custom block plugin but after updating it there are configuration items that I no longer need. But removing the part that saves the configuration data in blockSubmit submit function doesn't actually remove the configuration data that existed before.

My original blockSubmit function was as follows

```
public function blockSubmit($form, FormStateInterface $form_state) {
        $this->configuration['row']       = $form_state->getValue('row');
        $this->configuration['columns']   = $form_state->getValue('columns');
}

```

But now I only want to store $this-\>configuration\['columns'\] like below

```
public function blockSubmit($form, FormStateInterface $form_state) {
        $this->configuration['columns']   = $form_state->getValue('columns');
}

```

Is there a way to delete the configuration data in $this-\>configuration\['row'\] ? I don't mind it being a work around since I'm only going to be using it once. I wouldn't mind doing something like delete($this-\>configuration\['row'\]); in the build function so it's removed when you visit a page that contains it.

Is there a way to remove this lingering configuration data in this block plugin?

# Answer
There are several options.

You can unset the configuration 'row' in submit:

```
unset($this->configuration['row']);

```

You can load each block, remove the item from settings and save it. See https://drupal.stackexchange.com/a/224362/47547 how to load blocks. You can do this in an update hook.

You can export the configuration, remove the lines you don't want from the yaml files and import the configuration again. This would be the best option for a site owner who wants to clean up a single drupal installation.
> 1 votes

---
Tags: 8, blocks
---


# Question
Title: How to restrict Drupal commerce Shipping only for two provinces
we have a drupal commerece site http://floristerianoe.com, that need only to deliver (commerce shipping) in Madrid and Guadalajara (only two privinces in Spain) and we can´t find the option to do this, we only find the option to restrict contry, but we need this for province or city. Thanks in advence.

# Answer
> 0 votes
If you are using the Address Field module, you definitely have Madrid and Guadalajara as options. Thereafter, you need to use rules and add conditions. I'm not sure how your shipping works but I would use the Flat Rate module to create components, such as 0-5km, which costs a set amount. Create a flat rate, give it a name: perhaps 0-5 km, and a price then add conditions. Select "Order address component comparison". Province will be available. Your operator is "equals" and then you add your values, Madrid and Guadalajara.

Here is a screenshot of a rule that restricts shipping costs being applied to a certain country, within weight parameters and restricts it to a particular product but it is possible to select a province instead of a country

Here is a screenshot of the components, I selected province here to show that it is available

---
Tags: commerce
---


# Question
Title: buildForm runs before ajax button's submit handler on first click
First of all, here is some working example code for the classic "Add more" AJAX button (complete module available as a gist):

```
public function buildForm(array $form, FormStateInterface $form_state) {

  if (!$form_state->get('number_of_fields')) {
    $form_state->set('number_of_fields', 1);
  }

  $form['#tree'] = TRUE;
  $form['container'] = [
    '#type' => 'container',
    '#id' => 'replace-me',
  ];

  for ($i = 0; $i < $form_state->get('number_of_fields'); $i++) {
    $form['container'][$i] = [
      'my_text' => [
        '#type' => 'textfield',
        '#title' => $this->t('Any text'),
      ],
    ];
  }

  $form['add'] = [
    '#type' => 'submit',
    '#value' => t('Add another'),
    '#submit' => [[$this, 'addTextFieldCallback']],
    '#ajax' => [
      'callback' => [$this, 'ajaxReplaceMeCallback'],
      'wrapper' => 'replace-me',
    ],
  ];

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

  return $form;
}

public function addTextFieldCallback(array &$form, FormStateInterface $form_state) {
  $form_state->set('number_of_fields', $form_state->get('number_of_fields') + 1);
  $form_state->setRebuild();
}

public function ajaxReplaceMeCallback(array &$form, FormStateInterface $form_state) {
  return $form['container'];
}

```

Now I want to save more things in the form storage. For example, I would want to generate a unique id for the container, so I can include my form more than once per page:

```
if (!$form_state->get('unique_id')) {
  $form_state->set('unique_id', Html::getUniqueId('replace-me'));
}

// ...

$form['container'] = [
  '#type' => 'container',
  '#id' => $form_state->get('unique_id'),
];

// ...

$form['add'] = [
  '#type' => 'submit',
  '#value' => t('Add another'),
  '#submit' => [[$this, 'addTextFieldCallback']],
  '#ajax' => [
    'callback' => [$this, 'ajaxReplaceMeCallback'],
    'wrapper' => $form_state->get('unique_id'),
  ],
];

```

However, this does not work. Using `xdebug` and `phpstorm`, I found out why:

When I load the page containing the form, `buildForm` runs. It generates a unique ID. First time round, the ID is `replace-me`. All good.

The first time I click on "Add another", the following functions run, in this order:

* `buildForm`
* `validateForm`
* `addTextFieldCallback`
* `buildForm`
* `ajaxReplaceMeCallback`

The first time `buildForm` runs, `$form_state->getStorage()` is empty, which is unexpected! Consequently, a new ID is generated, e.g. `replace-me--62or3gVN0K0`. This means that the AJAX won't find the right node to replace next time, since the button still points to the old ID, `replace-me`.

The second time I click on "Add another", the following functions run, in this order:

* `validateForm`
* `addTextFieldCallback`
* `buildForm`
* `ajaxReplaceMeCallback`

This time, it works as expected, and the ID stays the same, but functionality is broken because the ID shouldn't have changed in the first place.

Questions:

* Is this normal behaviour, or have I discovered a D8 bug?
* What am I doing wrong?
* Why would `buildForm` run twice on the first click?

# Answer
> 2 votes
Yes, this the normal behavior. In D7 and earlier in Drupal 8, having a form with at least one #ajax element forced the form to be stored in "cache", which quickly resulted in a huge amount of data there (we had GB of data in key\_value\_expire in an very early D8 site and it was growing almost faster than we could keep deleting it)

Now this only happens on the first Ajax request, when the form actually needs to start storing data.

The only thing you can do is depend your key on something that is more or less stable, you're possibly editing something that has an ID or you have a loop displaying multiple forms, then you can pass in an index. In Simplenews where we display multiple forms in blocks and we generate a unique Id (or allow the user to provide one) that we can then use to identify the forms.

Note that you need a unique form\_id anyway to be able to use the same form more than once per page, see Generate unique form ID based on context.

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


# Question
Title: How to change relative path in hyperlinks?
I have developed site on localhost in XAMPP, in the folder C:\xampp\htdocs\drupLC

Then everything uploaded to the server.

And now all (or many of them) hyperlinks looks like

> example.com/**drupLC**/user
>
> example.com/**drupLC**/admin (etc).

How can I get rid of **drupLC** from all hyperlinks? Because my site is not usable.

# Answer
> 1 votes
You may need to:

1. Check the setting for `RewriteBase` in .htaccess (e.g make `RewriteBase /`)
2. Check the `$base_url` setting is correct (Should be automatic in D8).
3. Clear all caches ( Admin \> Config \> Development \> Performance \> Clear cache )

If you have inline links in body content with incorrect URLs, that's a different story, but the above may help with the standard stuff.

---
Tags: 8, deployment
---


# Question
Title: Pasting text from GoogleDocs into D7 Body field causes imagestyle error?
Super strange - I'm copying and pasting text from a GoogleDoc into a D7 article post. When I do this and publish my article, it drops onto the main page into a slider that I've created via a View. This works seamlessly usually, however when I paste the text from the googledoc, it actually distorts my entire main page - seemingly stripping the image styles from my other article posts in the slider, thus, ruining my slider? Any idea why this is and how I can fix it?

# Answer
You may have better luck exporting the Google Doc to "RTF" format first then copy + pasting that format into the article body.

You could also try the "Paste without formatting" option, such as `Ctrl+Alt+Shift+V` or `Ctrl+Shift+V` but would need to re-add the formatting (headings etc..) with that approach.

There may also be some WYSIWYG toolbar options to paste with various formatting options (paste from word, paste as plain text etc..)
> 0 votes

---
Tags: 7
---


# Question
Title: Possible to use drush to list overrides for all features?
I believe that drush features-diff will list the overrides for a specific feature and that drush features-list will list all features. Is it possible to list all of the overrides for all features, perhaps by piping the results of drush fl to drush fd?

If so, how would one pick up the second field from drush fl to pipe to drush fd? Or, is there a better way to do this?

# Answer
In the current version of Drush, you can show a list of all features and their override state with (both short and long versions of commands shown, with and without the "-y" flag to skip confirmation questions):

```
$ drush features-list
$ drush fl

```

If you want to show only the overridden features:

```
$ drush features-list | grep -E "Overridden|Needs"
$ drush fl | grep -E "Overridden|Needs"

```

To show everything that has been overridden for all features:

```
$ drush features-diff-all
$ drush fda -y

```

To update all features to their currently overridden state:

```
$ drush features-update-all
$ drush fua -y

```

To revert all features to their default state:

```
$ drush features-revert-all
$ drush fra -y

```
> 6 votes

# Answer
Just to share or whatever -- I use it all the time, and I would've loved to come across this tip when I was a noob , so...

I run:

```
drush fl | grep -E "Overridden|Needs"

```

...And, I added an alias to my `drushrc.php` to make it even quicker to call upon:

```
$options['shell-aliases']['flovr'] = '!drush fl | grep -E "Overridden|Needs"';

```

That's all, hope it helps someone! (Also, "first time / long time," so if I've done wrong here, please be gentle :) )
> 2 votes

# Answer
I think what you are missing is `xargs` (available on Mac and Linux, at least). Also, the magic numbers in your `cut` command are not reliable; use `sed` instead. It is hard to tell, but I think that drush is outputting tabs as well as spaces, hence the `[:space:]` character class in the following:

```
$ drush fd | grep -E 'Overridden[[:space:]]+$' \
| sed -E 's/[[:space:]]*Enabled[[:space:]]*Overridden[[:space:]]*//' \
| sed -E 's/.*[[:space:]]//' \
| xargs drush fd

```
> 1 votes

# Answer
I'm sure it's possible by piping the results of `drush fd` or `drush fl` to `grep`, which could be used to extract the feature name, then piping that to `drush fd`, but that is no simple task.

If you're using git, another option is, on a clean working directory, run `drush fua` and then `git diff`. You can then run `git reset --hard HEAD` to get back to where you were. A workaround, but possibly simpler.
> 0 votes

# Answer
If you'd like to show the code difference for all enabled features not in their default state, use `fda` command:

```
drush features-diff-all --force

```

> `--force` Bypass the confirmations. This is useful if you want to output all of the diffs to a log file.

---

Other option is to use Features Diff module for that.

> This is a simple modules used to view the diffs of a single or all features modules.

---

To list all *Overriden* feature modules by parsing the output of feature-list, the syntax can be:

```
drush fl --status=enabled | grep -o "\S\+\s\+Enabled.\+" | grep "Overridden"

```

To have both *Overridden* and *Needs review*, use: `grep -e "Overridden" -e "Needs review"` instead.

To get the list of modules, filter by: `cut -d' ' -f1`.

For longer name of modules, increase `COLUMNS` variable as names can be cut off.

So to pipe all features into feature-diff (`fd`), feature-revert (`fr`), feature-update (`fu`) or features cleanup (`fcf`), e.g.

```
COLUMNS=100 drush fl --status=enabled | grep -o "\S\+\s\+Enabled.\+" | grep -e "Overridden" -e "Needs review" | tee | cut -d' ' -f1 | xargs -t drush fcf

```

For running it in parallel (to speed it up), add `-P4 -L4` into `xargs`.
> 0 votes

---
Tags: drush, features
---


# Question
Title: Have Google Analytics code still run on force download
When you click on a download link (my\_download/download/agent/%/week/%) that I have set up dynamically for each user it runs some logic and downloads a file.

I was thinking that I could just check Google Analytics to see how many people downloaded the file but the data is not there. Does anyone have any idea to have it force download like I have set up and run Google Analtyics?

```
/**
 * Implements hook_menu().
 */
function my_module_menu() {
  $items['my_download/download/agent/%/week/%'] = array(
    'title' => 'Download',
    'description' => 'Download File.',
    'page arguments' => array(3, 5),
    'page callback' => 'my_module_file_download',
  );

  return $items;
}

/**
 * Download file.
 *
 * @param string $agent_id
 *   Agent number.
 * @param string $date
 *   Date string.
 *
 * @return string
 *   Force file to download or give error.
 */
function ea_email_requote_agent_file_download($agent_id, $date) {
  $file_name = my_module_agent_file_name($agent_id, $date);
  $file = "/mypath/$date/$file_name";

  if (file_exists($file)) {
    // Transfer to browser download.
    drupal_add_http_header('Pragma', 'public');
    drupal_add_http_header('Expires', '0');
    drupal_add_http_header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0');
    drupal_add_http_header('Cache-Control', 'private');
    drupal_add_http_header('Content-Type', 'text/csv');
    drupal_add_http_header('Content-Disposition', 'attachment; filename="' . $file_name . '";');

    readfile($file);
    drupal_exit();
  }
  else {
    drupal_set_message('File has not been loaded yet.', 'error');
    return '';
  }
}

```

# Answer
For that kind of thing, you can use the GA "event tracking" to track the click event for the file download.

> Events are user interactions with content that can be tracked independently from a web page or a screen load. Downloads, mobile ad clicks, gadgets, Flash elements, AJAX embedded elements, and video plays are all examples of actions you might want to track as Events.

The GA module provides some click event tracking for files by default in the config, else you can check here for more info on adding such a feature:

https://developers.google.com/analytics/devguides/collection/analyticsjs/events
> 2 votes

---
Tags: 7
---


# Question
Title: How to make https links available to anonymous when new article is published?
When content/article is created the content is accessible first on the http link and then later the httpS link. There is usually a delay of at least 5mns for anonymous to access it.

http://example.com/item-just-published vs https://example.com/item-just-published

The cache settings have been modified for the content type to refresh cache on update and insert but it seems to affect the http links only not httpS. This is a problem as some time sensitive items don't get to the audience in a timely matter using httpS links.

example.com/admin/config/development/performance

example.com/admin/config/system/expire

How to make httpS links available as soon as it is published to anonymous?

# Answer
Assuming both secure and non-secure websites are in fact the same Drupal instance, there are a few possibilities which may cause the issue you are experiencing:

1. **Web server; configuration differences in secure non-secure sites.**
Compare both website settings. Only difference should be SSL specific settings, rest should be same or inheriting settings from other's. if necessary, refer to web server's official documentation.
2. **Web server; misconfiguration in redirect rules**
From your comments it's clear that both websites are actually available. Still there could be redirect rules needs correcting.
3. **HTTP or HTTPS version of the site has an external caching system**
Check if there is caching system or proxy enabled for either of the sites. i.e. Varnish, Redis, CloudFlare.

Please provide some more details about the webserver (Apache, nginx, IIS, etc), and currently installed caching and performance related modules.

Also, you can consider serving the site only on HTTPS, to avoid penalties from search engines for duplicate content.
> 2 votes

---
Tags: 7, navigation
---


# Question
Title: Custom Fieldable panels pane template rendering the Field collection items
I am using Fieldable Panels Panes (FPP). I created a custom FPP and I am using Field Collection items into my custom FPP.

I want to customize the rendering of Field collection item fields in my FPP template file.

For example: fieldable-panels-pane--my\_custom.tpl.php is my tpl file, where I am unable to customize my\_field\_collection\_items fields seperately by using some classes.

Is there a way to customize these fields and render the output in desired way?

# Answer
> 0 votes
I found the answer. Actually, by using `$elements` in `.tpl` file, we get all variables and also all fields as an array. You can use it to render the output you want to.

---
Tags: 7, entities
---


title: How to alter node links

text:
# Question
Title: How to alter node links
I have few existing node nodes which contains link `<a href="/some/link/here">Click here</a>`. Now I want to update all links to `<a href="/updated/some/link/here">`. Is there any way to do this in Drupal8 via code.

# Answer
> 0 votes
You can load all those nodes by nid with

```
node_load_multiple(array $nids = NULL, $reset = FALSE);

```

Loop over all nodes and then find and replace by using

```
str_replace('original link', 'new link', $node->field_you_want_to_change);

```

And then saving the node using

```
$node->save()

```

# Answer
> 0 votes
You can alter the content of your node, without changing it in the DB, with

hook\_ENTITY\_TYPE\_view\_alter() or hook\_ENTITY\_TYPE\_view

Both these hooks allow you to alter the content of your entity before it is rendered. In combo with Fons' answer you can then replace your old link with the new one.

---
Tags: 8
---


# Question
Title: One view per taxonomy vocabulary without a contrib module?
What do I need to set in a D8 view, to have one view per taxonomy vocabulary without any contrib module?

# Answer
> 1 votes
Drupal 8 already uses the (now-builtin) Views for listing pages of content belonging to a certain taxonomy term.

That's a single view for all taxonomy terms:

You can edit the view and make necessary changes you need http://example.com/admin/structure/views/view/taxonomy\_term

# Answer
> 0 votes
I don't know why anyone would have a "without a contrib module" requirement.

You can either do this with Page Manager, or you can write a custom module that alters the route and then dynamically calls a different view. Drupal 8 doesn't provide a feature to do this without additional modules/code

---
Tags: 8
---


# Question
Title: Which module creates the "Article" and "Basic page" content types?
By Default we have two content types: *Article* and *Basic page*.

Which module creates those content types?

# Answer
@Wim Mostrey was right.

In Drupal 7, the default configuration for modules (e.g. content types, field configuration, views) required custom PHP code to install and keep updated. In Drupal 8, these are stored with the configuration system in plain text YAML files, for example core/profiles/standard/config/install/node.type.article.yml.

### References
> 2 votes

---
Tags: 8, entities
---


# Question
Title: Programmatically update node image field (using URI of the image) and get URL in twig
I am trying to update a node image field programmatically. I currently loading the node like this:

```
$node = Node::Load(1);

```

have the URI if the image that I want to set. I have tried this but no luck:

```
$node->set('field_image_head', array('#uri' => $imageUri));

```
1. How do I now update the node image with an image URI?
2. The twig will need to get the URL from the image field like so
`{{ file_url(node.field_image_head.entity.fileuri}}`

# Answer
> 16 votes
You have to create a file for the image first before you can add it to the node.

```
use Drupal\node\Entity\Node;
use Drupal\file\Entity\File;

  $node = Node::load(1);
  $uri = 'public://image.jpg';

  // check first if the file exists for the uri
  $files = \Drupal::entityTypeManager()
    ->getStorage('file')
    ->loadByProperties(['uri' => $uri]);
  $file = reset($files);

  // if not create a file
  if (!$file) {
    $file = File::create([
      'uri' => $uri,
    ]);
    $file->save();
  }

  $node->field_image[] = [
    'target_id' => $file->id(),
    'alt' => 'Alt text',
    'title' => 'Title',
  ];

  $node->save();

```

---
Tags: nodes, 8, media
---


# Question
Title: How to detect the region of a block programatically
I need to create a custom submit handler when blocks that are assigned to a certain region are saved (whether an existing or a new block)

I am using :

```
function MY_MODULE_NAME_form_alter(&$form, $form_state, $form_id) {
  if ($form['#id'] == 'block-admin-configure'){

    //If the block being saved is in region "Header" then do something
  }

```

Can someone tell me what to replace my commented line with please ?

# Answer
> 1 votes
You can implement hook\_block\_save($delta = '', $edit = array()) to execute your custom code.

---
Tags: 7, blocks, theming
---