# Question
Title: How to check if a scheduled Rules action set has already been scheduled?
I'm using the Rules Scheduler (sub-module of the Rules module) to schedule an email reminder based on a date field set in the content type. So a user can request a reminder email on a specific date, to update that content.

However, if I invoke the Rules Action on node update, then I end up with lots of emails scheduled for that date.

How can I make sure that the rule is only scheduled once for the given date?

# Answer
The answer to this is simple.

In the action of the rule that calls the schedule component evaluation, in the Identifier section, set a unique value, such as: reminder-\[node:title\]-\[node:nid\]

This value will be a unique identifier of the scheduled task. Scheduled tasks with the same ID will simply be replaced. Problem solved.
> 2 votes

# Answer
My answer to "Rule to store user's last post date and scheduled rule based 30 day reminder" contains an illustration about how to delete scheduled tasks, using the "`schedule_delete`": the `schedule_delete` that is part of this rule is to ensure that previously "scheduled" reminders will get removed when updating the data field (so that it only triggers 1 reminder, and with the most recent date).

Here is a copy of the **Rules Action** included in that answer (which refers to the *Rules Component* that is also included in that answer):

```
..
        "DO" : [
          { "schedule_delete" : {
              "component" : "rules_send_email_notification",
              "task" : "[account:name]"
            }
          },
          { "data_set" : { "data" : [ "account:field-next-article" ], "value" : "+30 day" } },
          { "schedule" : {
              "component" : "rules_send_email_notification",
              "date" : {
                "select" : "account:field-next-article",
                "date_offset" : { "value" : 2592000 }
              },
              "identifier" : "[account:name]",
              "param_user_to_notify" : [ "account" ]
            }
          }
        ]
...

```

What is crucial in the context of this question here, is that you have to ensure that you give enough thought to the value you'll use for the `identifier` of the scheduled task.

In my sample the choice was that for each user, at any time, there can only be 1 scheduled task for each user. So using the account name as the key for that identifier is perfect ... to make it unique, and to know exactly which scheduled task should be deleted also.
> 0 votes

---
Tags: rules, emails
---


# Question
Title: Views: Show all terms of taxonomy with or without containing nodes
I have a view which shows all terms of a specific taxonomy (pages). My terms have a relationship with containing nodes. My nodes are grouped by taxonomy terms.

I get this result with no date filter:

```
taxonomy term 1
    - node 1 (2016-06)
    - node 2 (2016-07)

taxonomy term 2
    - node 3 (2016-06)

taxonomy term 3

taxonomy term 4

taxonomy term 5

taxonomy term 6
    - node 4 (2016-06)

```

**Problem**

I have an exposed date filter to get nodes for different months. But when I use this filter (2016-06), my terms with no matching nodes are not shown in my result.

```
taxonomy term 1
    - node 1 (2016-06)

taxonomy term 2
    - node 3 (2016-06)

taxonomy term 6
    - node 4 (2016-06)

```

This is the result I'm looking for, when I use my date filter (2016-06):

```
taxonomy term 1
    - node 1 (2016-06)

taxonomy term 2
    - node 3 (2016-06)

taxonomy term 3

taxonomy term 4

taxonomy term 5

taxonomy term 6
    - node 4 (2016-06)

```

So my question is:

How can I show all taxonomy terms in my view with or without containing nodes, if my filter is active?

---

## **UPDATE**

This is my generated SQL from views when my exposed filter is active. The second where condition removes my terms.

```
SELECT DISTINCT
    node_taxonomy_index.nid AS node_taxonomy_index_nid,
    taxonomy_term_data.name AS taxonomy_term_data_name,
    taxonomy_term_data.vid AS taxonomy_term_data_vid,
    taxonomy_term_data.tid AS tid,
    taxonomy_vocabulary.machine_name AS taxonomy_vocabulary_machine_name,
    'node' AS field_data_field_position_node_entity_type,
    'node' AS field_data_field_seite_node_entity_type,
    'node' AS field_data_field_sebepla_status_node_entity_type,
    'node' AS field_data_field_typ_node_entity_type,
    'node' AS field_data_field_ausgabenzeitraum_node_entity_type
FROM
    {taxonomy_term_data} taxonomy_term_data
LEFT JOIN {taxonomy_index} taxonomy_index
    ON taxonomy_term_data.tid = taxonomy_index.tid
LEFT JOIN {node} node_taxonomy_index
    ON taxonomy_index.nid = node_taxonomy_index.nid
LEFT JOIN {taxonomy_vocabulary} taxonomy_vocabulary
    ON taxonomy_term_data.vid = taxonomy_vocabulary.vid
LEFT JOIN {field_data_field_ausgabenzeitraum} node_taxonomy_index__field_data_field_ausgabenzeitraum
    ON node_taxonomy_index.nid = node_taxonomy_index__field_data_field_ausgabenzeitraum.entity_id AND
        (node_taxonomy_index__field_data_field_ausgabenzeitraum.entity_type = 'node' AND
        node_taxonomy_index__field_data_field_ausgabenzeitraum.deleted = '0')
WHERE
    (( (taxonomy_vocabulary.machine_name IN  ('sebepla_seiten')) AND
    (DATE_FORMAT(node_taxonomy_index__field_data_field_ausgabenzeitraum.field_ausgabenzeitraum_value, '%Y-%m') = '2016-06') ))

```

When I use following SQL, I get correct results:

```
SELECT DISTINCT
    node.nid AS node_taxonomy_index_nid,
    taxonomy_term_data.name AS taxonomy_term_data_name,
    taxonomy_term_data.vid AS taxonomy_term_data_vid,
    taxonomy_term_data.tid AS tid,
    taxonomy_vocabulary.machine_name AS taxonomy_vocabulary_machine_name,
    'node' AS field_data_field_position_node_entity_type,
    'node' AS field_data_field_seite_node_entity_type,
    'node' AS field_data_field_sebepla_status_node_entity_type,
    'node' AS field_data_field_typ_node_entity_type,
    'node' AS field_data_field_ausgabenzeitraum_node_entity_type
FROM
    taxonomy_term_data
LEFT JOIN taxonomy_index taxonomy_index
    ON taxonomy_term_data.tid = taxonomy_index.tid
LEFT JOIN
    (
        SELECT
            node.nid
        FROM
            field_data_field_ausgabenzeitraum node_taxonomy_index__field_data_field_ausgabenzeitraum,
            node
        WHERE
            node.nid = node_taxonomy_index__field_data_field_ausgabenzeitraum.entity_id AND
            node_taxonomy_index__field_data_field_ausgabenzeitraum.entity_type = 'node' AND
            node_taxonomy_index__field_data_field_ausgabenzeitraum.deleted = '0' AND
            DATE_FORMAT(node_taxonomy_index__field_data_field_ausgabenzeitraum.field_ausgabenzeitraum_value, '%Y-%m') = '2016-06'
    ) node ON taxonomy_index.nid = node.nid
LEFT JOIN
    taxonomy_vocabulary taxonomy_vocabulary
        ON taxonomy_term_data.vid = taxonomy_vocabulary.vid
WHERE (( (taxonomy_vocabulary.machine_name IN  ('sebepla_seiten')) ))

```

**Now my new question:**

How to implement this query in views? I know that **hook\_views\_query\_alter** is the key. If someone could explain how to write a left join select with my conditions I've used in views object query, it would help me a lot! :)

# Answer
From looking at your SQL, it looks like you're trying to build a `LEFT JOIN` off a subquery. This is one of those cases where you really have to get into in internals of views.

There're a few components you're looking at here:

1. Building a `db_select()` subquery that you're joining.
2. Utilizing `views_join()` to build the join to the view.
3. Using `views_plugin_query_default::add_table()` to insert your joined subquery table into the view.

An incomplete example would look something like this:

```
function mymodule_views_query_alter(&$view, &$query) {
  //$query->addJoin(j)

  // Build subquery to match expression
  $sub_query = db_select('field_data_field_ausgabenzeitraum', 'node_taxonomy_index__field_data_field_ausgabenzeitraum');
  $sub_query->fields('n', array('nid'));

  // INNER JOIN is the same as "SELECT * FROM table1, table2"
  $sub_query->addJoin('INNER', 'node', 'n');
  $sub_query->conditions('n.nid', 'node_taxonomy_index__field_data_field_ausgabenzeitraum.entity_id');
  // @TODO: Add Remaining Conditions & utilize addExpression() for DATE_FORMAT()

  // Build subquery JOIN.
  $join = new views_join();
  $join->type = 'LEFT';
  $join->definition = array('table formula' => $sub_query);
  $join->left_table = 'taxonomy_index';
  $join->left_field = 'nid';
  $join->field = 'nid';

  // Add the joined subquery table
  $query->add_table('node', NULL, $join, 'node');
}

```
> 2 votes

---
Tags: 7, views, nodes, taxonomy-terms
---


# Question
Title: Passing arbitrary data into a node prior to preprocessing
I am looking for a way of passing arbitrary data though `node_view()` to a preprocess function.

I am using the following code.

```
  $node = node_load(1);
  $node->mycustomdata = 'mydata'; // This is the data I want passed through.
  return node_view($node,  'teaser');

```

I want mycustomdata to be available to me inside my preprocess function so I can add it as a template variable.

```
function MYMODULE_preprocess_node(&$variables) {
  $node = $variables['node'];
  $variables['mycustomdata'] = $node->mycustomdata; //  Here is where I want to access the data.
}

```

How can I achieve this?

# Answer
> 0 votes
Node's in D8 work differently to D7. in D7 node was a stdClass object - basically used in the same way an array was assign a value to a key ($node-\>value). In D8 Node's are proper objects and can't do the same key/value. Instead, how about creating a field on the node and assigning the value to the field, save the node and then view it?

# Answer
> 0 votes
So it turns out this actually works, and the data does get passed through. Apologies for any time wasting.

---
Tags: nodes, 8, theming
---


# Question
Title: Only allow certain roles to publish content, other roles can save as unpublished?
I have a Content Admin and a Translator Roles.

Content Admin's can create, edit, delete, and publish content (this is working fine)

Translator's shouldn't be allowed to publish content, they should only be able to create and edit translations. (it should save as unpublished).

Anyone know how to achieve what I'm trying to do in Drupal 8? Or know if a module that does this has been ported to Drupal 8?

# Answer
You will need to alter insert / update node entity form:

1. Define a permission "Save unpublished content"
2. Make a hook\_form\_alter or hook\_form\_ENTITY\_TYPE\_form\_alter
3. Check if you are alter the exact entity types you need.
4. Hide all buttons you don't need (based on permission)
5. Add button ('save unpublished content') (based on persmission)
6. When submitting: call the default submission and add yours to set the status 0.

Save button is an UL with two LI elements: save published, save unpublished:
> 2 votes

---
Tags: 8, users
---


# Question
Title: How to limit the execution of a rule for sending an email to only run once in a day?
I have a rule that sends an email out to subscribers on the 28th of each month. The rule is executed when cron is run, I have cron set to automatically run once a day.

I also use linkchecker, which uses cron to check the links on the site. Right now I have to remember on the 28th of the month not to run cron for the linkchecker, otherwise my subscribers will get multiple emails that day for each time cron was run.

How can I limit the rule to only run once in any specific day, so that I don't have the potential to accidentally run cron manually and spam my subscribers?

# Answer
> 1 votes
Have a look at the "Rules Once per Day" module. Here is how it works (as per the comment in issue 2495775, from the module owner):

* You specify a **trigger hour** on the administration settings page for this module.
* The Rule trigger will then **run when cron tasks are first run after the start of that hour**. The actual run time will depend on your cron task timings.

So this is another way to understand/Read this:

* The "Event" will only be triggered when a cron job is run.
* And that event will only be triggered 1 time / day, i.e. "next time cron runs after the trigger hour has passed".

With that, you should be able to adapt your "*rule that sends an email*" to run ... ***once a day***, on any day, including the 28th of each month.

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


title: How make a virtual field for view?

text:
# Question
Title: How make a virtual field for view?
i want a vitual field for print value of sum in another entity :

My 2 custom entity content :

> commandes\_entity
>
> commandesLignes\_entity reference to commandes\_entity

In the commandes\_entity i have a view table who liste all my lines. i want to add a custom column who sum all the children in commandesLignes\_entity.

For that i make a field in .module :

```
function hook_views_data()
{

  $data['commandes_entity'] = array(

      'totalCommandeTTC' => array(
          'title' => t('Total Commande TTC'),
          'help' => t("Le total des commandes"),
          'field' => array(
              'id' => 'machine_name',
              'options callback' => 'Drupal\boutique\Controller\TestController::content',

          ),

          'sort' => array(
              'id' => 'standard',
          ),

      ),

  );

return $data;
}

```

This field is in my select field view, when i add it all is ok except one thing :

> SQLSTATE\[42S22\]: Column not found: 1054 Unknown column 'commandes\_entity.totalCommandeTTC' in 'field list': SELECT commandes\_entity.totalCommandeTTC AS commandes\_entity\_totalcommandettc, commandes\_entity.id AS id FROM {commandes\_entity} commandes\_entity WHERE (( (commandes\_entity.statut LIKE :db\_condition\_placeholder\_0 ESCAPE '\\') )) ORDER BY commandes\_entity.created DESC LIMIT 21 OFFSET 0; Array ( \[:db\_condition\_placeholder\_0\] =\> payer )

This field

> totalCommandeTTC

doesn't exist in my table, i want it virtual.

For now my callback just return 'test'.

Any idea for make this field really virtual ?

I try to move it to views group like this :

```
function boutique_views_data()
{

  $data['views'] = array(

      'totalCommandeTTC' => array(
          'title' => t('Total Commande TTC'),
          'help' => t("Le total des commandes"),
          'field' => array(
              'id' => 'machine_name',
              'options callback' => 'Drupal\boutique\Controller\TestController::content',

          ),

          'sort' => array(
              'id' => 'standard',
          ),

      ),

  );

return $data;
}

```

The field is in the Global group but SQL still try to get it into the commandes\_entity table.

# Answer
Thank to Clive for guide me :

This is how i make a virtual field :

First you need to create the handler for the field :

```
<?php

namespace Drupal\boutique\Plugin\views\field;

use Drupal\views\Plugin\views\field\FieldPluginBase;
use Drupal\views\Plugin\views\display\DisplayPluginBase;
use Drupal\views\ResultRow;
use Drupal\views\ViewExecutable;

/**
 * Field handler to present the path to the node.
 *
 * @ingroup views_field_handlers
 *
 * @ViewsField("totalCommandeTTC")
 */
class TotalTTC extends FieldPluginBase {

    /**
     * {@inheritdoc}
     */
    public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) {
        parent::init($view, $display, $options);

    }

    /**
     * {@inheritdoc}
     */
    public function query() {
        }

    /**
     * {@inheritdoc}
     */
    public function render(ResultRow $values) {
       return 'test';
    }

}

```

I remove the query for this handler.

Then in my module file, i use the hook\_views\_data :

```
function boutique_views_data()
{

  $data['commandes_entity'] = array(

      'totalCommandeTTC' => array(
          'title' => t('Total Commande TTC'),
          'help' => t("Le total TTC des commandes"),
          'field' => array(
              'id' => 'totalCommandeTTC',
          ),

      ),

  );

return $data;
}

```

And the result in views after add the field with views ui :

The field is Total commande TTC.
> 3 votes

---
Tags: 8, entities
---


title: Display taxonomy term from id

text:
# Question
Title: Display taxonomy term from id
I want to display taxonomy term from it's id. I have the following code that get's me id of this term but I don't how to convert this id into term name to display it.

```
function menu_custom_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  dpm($items);
  $element = array();
  foreach ($items as $delta => $item) {
    $element[$delta] =  l(check_plain($item['target_id']));
    }
  return array(
    0 => array(
      '#markup' => theme('item_list', array('items' => $item)),
    ),
  );
  return theme('item_list', array());
}

```

# Answer
To get the taxonomy term name from ID.

```
function menu_custom_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  dpm($items);
  $element = array();
  foreach ($items as $delta => $item) {
    $taxonomy = taxonomy_term_load($item['target_id']);
    $element[$delta] = $taxonomy->name;
  }
  return array(
    0 => array(
      '#markup' => theme('item_list', array('items' => $item)),
    ),
  );
  return theme('item_list', array());
}

```

`$taxonomy->name` will give you name of taxonomy term.

I hope this will help. Thanks
> 0 votes

---
Tags: taxonomy-terms
---


# Question
Title: Couldn't display body field on a view with Search Api
I have a view that I set it up with Search Api and Facet Api, I couldn't display the body field of indexed nodes.

I tried to add it to the Search Api index fields but it still the same result.

# Answer
There are 2 solutions to add body field:

* **Solution 1:**

1. Browse to search api index field configuration at `/admin/config/search/search_api/index/hone_and_strop/fields`
    2. Now add **The main body text** field from **Add related fields** list.
    3. Now do reindexing and you would be able to add body field into view.
* **Solution 2:**

1. Create view mode with body field in it.
    2. Now in view, use **Rendered entity** instead of fields.

> Note: You always need to do reindexing whenever you add or remove field form search api index field configuration.
> 3 votes

---
Tags: views, search
---


# Question
Title: Add element to form during (element) validation checks
I'm trying to make a module that offers an `#element_validate` function which will check the element for dodgy looking data and if this is detected, tell the user this looks invalid and add a 2nd element to the form which can then be used to validate the dodgy-looking data.

The problem I'm having is that:

1. To add an element you need the form to **rebuild**. (see code referenced in the comment below)
2. To trigger a rebuild the form **must have passed validation**

This means that:

1. the `#element_validate` function cannot use `form_error` \- else it would not be able to add the 2nd field. So I've had it instead set `$form_state['rebuild'] = TRUE` and issue a warning with `drupal_set_message()`.
2. adding the 2nd element will only happen when there are not any other validation errors on the form (since these would also prevent the form rebuilding) leading to a confusing situation for the user: they will see the warning asking them to complete the 2nd element that doesn't exist. They'll correct the other errors on the form re-submit and then get that back again, this time *with* the 2nd element, which they'll have to complete before their submission is accepted.

Is there a way around this? e.g. a way to force a rebuild of the form from validation?

# Answer
> 0 votes
Here's how I've got around this issue.

When defining the element, add in:

* `#pre_render`
* `#form_id`
* `#element_validate`

Here's the algorithm:

1. User completes normal form, entering something suspect.
2. The validation function picks up the suspect value and stores a note that this form (uses `#form_id`) and element has a suspect value on a global variable. It also uses `form_error()` to inform the user of the problem.
3. The `#pre_render` function is called for the element. This function does not get the `form` object at all, which is why we specifically added `#form_id` to the element. Using this we can check the global variable for this form and see whether suspect data was found. It was, so add another form element in asking for confirmation. This element is not part of the Form API, so as well as the usual (`'#type' => 'textfield'` etc. we need to explicitly set `'#name'`).
4. User confirms the data on the new form element and re-submits form.
5. The validation function notices the confirm data in `$form_state['input']` (it won't be in `values` because this element is not part of the Form API's form) and compares it to the submitted value. It matches, so it does not call `form_error()`.
6. Assuming no more errors, form submission continues.

I've also implemented a thing for storing the confirmed suspect value in a hidden field in case other fields fail verification, meaning the user only has to confirm the data once.

## Use case

My specific use case is an email validator module. Beyond the drupal sytax check it can lookup DNS records and then conduct an SMTP conversation with a server to see if mail is accepted. Some of the SMTP errors can be temporary and so we use this chance to tell the user *"hmmm. we got this error (user-friendly version of error goes here) - might be a temporary thing but can you double check your email?"* allowing them to complete the form while still helping them avoid typos.

My email\_validator module on github

---
Tags: 7, forms
---


title: Migrate data from CSV column header row

text:
# Question
Title: Migrate data from CSV column header row
I have a client CSV file that has Stores in the first column and Tasks in the cells across the header row. In each Task column, there is either an X, R, or blank (NULL). This is supposed to identify whether the Task is assigned to the Store in the first column, or a "rollover" task, or the task is not assigned to the store. Admittedly, this is a strange CSV format, but I am stuck with it.

The Tasks and Stores are already migrated. I am having a hard time trying to figure out how to tell my migrate class to iterate through the Tasks in the header row, and assign them (or not) to the Store(s) in the first column.

Any directions at this point is extremely appreciated.

See the image attached for reference.

# Answer
We ended up getting a better csv format after all from the client. We used a common territory code as the key. Then we have a separate csv for the tasks, assigned to the common territory.

```
TERR,STR,STR,STR,STR,STR,STR,STR,STR,STR,STR
AB01,954,959,981,6903,6905,8475,,,,
AB02,909,953,962,977,984,,,,,
AB03,6177,,,,,,,,,

```
> 0 votes

# Answer
I highly recommend looking into Feeds. It has a CSV importer where you can map the fields and headers to anything you want.
> 1 votes

---
Tags: 7, migrations
---


# Question
Title: How to choose between classic SQL query and Drupal 8 technic?
I have a custom content entity (amap\_distributions\_inscriptions) linked to 2 entity\_reference 'datedistributionid' (which is basically the date of distribution plus other fields) and 'amapienid' (which is mainly the people who can attend to the distribution).

I want to create a form allowing people to enroll to the distribution, i.e. choose a date among all possible and their role.

In the past (a module I wrote for Drupal 6), I had a db\_query joining the three tables, sorting by date, name of the people, etc. I processed the result of the query with a `while ($record = db_fetch_object($result))` to build a tabular form with all dates and already enrolled people and so on.

What would be the "Drupal 8" way to do that?

I started with a

```
$storage = \Drupal::entityManager()->getStorage('amap_distributions_inscriptions');
$ids = \Drupal::entityQuery('amap_distributions_inscriptions')
  ->execute();
$inscriptions = $storage->loadMultiple($ids);
foreach ($inscriptions as $id=>$inscription) {my code here}

```

but I'm struggling with retrieving 'date distribution' and 'amapien', then sorting the results before starting to build the form rows...

Any guidance?

Trying to use @ssibal's advice, I assume I should write something like

```
$database = \Drupal::database();
$result = $database
  ->select('amap_distributions_dates', ???)
  ->fields('ddate', 'iid', 'pid', 'irole', 'nom', 'prenom')
  ->condition('dnumber', 0, '>')
  ->execute()

```

My D6 query ('amap\_distributions\_dates', 'amap\_distributions\_inscriptions' and 'association\_personnes' being the 3 tables):

```
$query = "
SELECT
    amap_distributions_dates.ddate,
    iid,
    amap_distributions_inscriptions.pid,
    irole,
    nom,
    prenom
FROM
    amap_distributions_dates
    LEFT JOIN amap_distributions_inscriptions ON amap_distributions_inscriptions.ddate = amap_distributions_dates.ddate
    LEFT JOIN association_personnes ON association_personnes.pid = amap_distributions_inscriptions.pid
WHERE
    dnumber > 0
ORDER BY
    amap_distributions_dates.ddate ASC,
    iid ASC,
    irole ASC,
    nom ASC,
    prenom ASC
";

```

# Answer
> 1 votes
Finally, this worked:

```
$database = \Drupal::database();
$query = $database->select('amap_distributions_dates', 'amdd');
$query->leftJoin('amap_distributions_inscriptions', 'amdi', 'amdi.datedistributionid = amdd.id');
$query->leftJoin('association_personne', 'ap', 'ap.id = amdi.amapienid');
$query->fields('amdd', ['id', 'datedistribution', 'nombreproduits'])
    ->fields('amdi', ['id', 'datedistributionid', 'amapienid', 'role'])
    ->fields('ap', ['id', 'nom', 'prenom'])
    ->condition('nombreproduits', 0, '>')
    ->orderBy('datedistribution', 'ASC')
    ->orderBy('role', 'ASC')
    ->orderBy('nom', 'ASC')
    ->orderBy('prenom', 'ASC');
$results = $query->execute()->fetchAllAssoc('id');
foreach ($results as $row) { some code here }

```

# Answer
> 0 votes
If you want more sophisticated query solution go for "database" service and the "select" method. You can have a much faster query and exactly what you need. It's the D8 equivalent of D7 db\_select().

Here is an example, how to add conditions, joins, and select fields. You should all the time check your database structure via phpmyadmin for example:

```
    $query = $this->database()->select('taxonomy_term_data', 'term');
    $query->innerJoin('taxonomy_term_field_data', 'term_data', 'term_data.tid = term.tid');
    $query->innerJoin('taxonomy_term__field_dst', 'name', 'name.entity_id = term.tid');
    $query->condition('term.vid', 'my_vocab', '=');
    $query->condition('term_data.name', $variable, '=');
    $query->condition('name.langcode', $this->getParameter('language'));
    $query->addField('name', 'field_destination_name_value', 'name');
    $result = $query->execute();

```

---
Tags: 8, entities
---


# Question
Title: How to sort taxonomy terms by their tid?
I'm using a custom module to print taxonomy terms as **filters** inside a View.

I want to sort the taxonomy terms by their tids not by their names.

The below is from the `custom-filter.tpl.php`:

```
<?php foreach($data as $tid => $name): ?>
<div data-filter=".filter-<?php print $tid; ?>" class="cbp-filter-item">
  <?php print $name; ?>
  <?php print $text_counter; ?>
</div>
<?php endforeach; ?>

```

**How can I sort the taxonomy terms by their tids?**

# Answer
Base on your code, I think the key for the `$data` is tid.

You can just add `<?php ksort($data);?>` before your foreach loop.
> 2 votes

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


# Question
Title: Make variables created in preprocess_page hook available to content type templates
I'm attempting to render a block plugin programmatically in a content type template. I understand how to render the block programmatically in a page template. like so

mytheme.theme

```
function mytheme_preprocess_page(&$variables){
    $myblock = \Drupal::service('plugin.manager.block')->createInstance('myblockid',[]);
    $variables['myblock'] = $myblock->build();

```

page.html.twig

```
<div class="my block">
{{ myblock }}
</div>

```

However in

node--contenttype.html.twig

```
<div class="my block">
{{ myblock }}
</div>

```

Produces nothing. Is there another hook I should be using? Or is there a better way to do this entirely?

# Answer
> 3 votes
I was able to accomplish this by placing the code into the preprocess node hook instead of the preprocess page. Like so

mytheme.theme

```
function mytheme_preprocess_node(&$variables){
    $myblock = \Drupal::service('plugin.manager.block')->createInstance('myblockid',[]);
    $variables['myblock'] = $myblock->build();

```

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


# Question
Title: How to display a Flag in a tpl file for different View modes?
There is no field in manage display of content type to display Flag link. There is a tpl file (**node--article--teaser.tpl.php**) for teaser mode displaying bookmark

```
<?php if (isset($content['links']['flag'])) : ?>
    <?php echo render($content['links']['flag']);?>
<?php endif; ?>

```

But for another mode this having View mode *teaser\_2\_col* and tpl file name **node--teaser-2-col.tpl.php**, `$content['links']` does not have a Flag element.

# Answer
> 2 votes
You actually *can* display a Flag link as a pseudofield, which can be ordered among other entity elements in the *Manage display* settings for an entity type. Go to `admin/structure/flags` and pick the Flag that you need. Next, check *Display link as field* in the section *Display in entity links*. You can now use the link in your template files by rendering the node and getting the right field (use Devel for this).

Alternatively, you can output a Flag link by using `flag_create_link($flag_name, $entity_id)`. In that case you don't need a pseudofield.

# Answer
> 0 votes
You can use flag\_create\_link() function to create the link and print it.

*Usage:*

If the flag was created for the content type, then the flag can be printed using:

```
<?php print flag_create_link('flag_machine_name', $node->nid); ?>

```

**Note:** The second argument is *the id of the entity for which the flag was created*.

---
Tags: 7, flags, entities
---


title: Writing alternative File Widget

text:
# Question
Title: Writing alternative File Widget
Okay, so I looked inside of the Managed File element and the FileWidget code and I am pretty overwhelmed. I don't think I need anything quite so complex, but it seems like there is so much that can be done with a file widget that I don't want to do things in a way that could cause problems in the future.

I have some javascript that will upload a file to a remote server and return a url, so I want to send that url to a custom controller and save it in Drupal. Is writing a file widget the right way to go here?

Any guidelines on where to go to find a good example of a file widget, or an explanation of how it works?

# Answer
> 2 votes
I've found that at the moment, there is no example more helpful than the Plupload module. It integrates with the Plupload\_widget module and extends the FileWidget from core and also has a lot of comments that I wish core would have included, explaining what the core file widget does.

---
Tags: 8
---


# Question
Title: multiple sites use one apache solr server
I am a beginner of using Apache Solr. I made a mistake two weeks ago. I link two of my sites to one Apache Solr server. One is dev site, another is live site. There are some different data between these two sites. But I forgot to set "read only" on dev site.

Right now, everything is messed up. The dev site data shows on live site. How can I fix this? I tried to fix, but still no luck.

My fix steps:

* Download Apache Solr Multiple Search on my dev site.
* Set Apache Solr Search index access as "Read only"
* Reindex all queue on my live site
* Wait two days
* Check the live site, still messy

I really appreciate if anyone could help.

# Answer
> 1 votes
apachesolr\_multisite allows you to tenant multiple Drupal sites in one Solr search core, allowing searching across sites, or on single sites, but it must be configured. Go to admin/config/search/apachesolr/settings, click "Edit" on the Solr search environment, and examine the settings at the bottom of the form:

These must be configured properly for your use case.

---
Tags: 7, search
---


# Question
Title: What is the programmatic equivalent of block save?
From `hook_save()`, I've updated the "pages" attribute of a block, adding a path to the list.

```
db_update('block')
    ->fields(array('pages' => $pages))
    ->condition('delta', $delta)
    ->execute();

```

I've used the database API, (maybe that's the problem?) instead of the block API, because I'm under the impression there is no support in Drupal 7 for this. (`hook_block_configure()` I think is just for changes to *default* block configuration.)

The problem I'm having is that the update to the block pages attribute is not reflected, even after clearing caches, until I go to block edit form and click on *Save*.

There's actually one thing in core's block module function block\_admin\_configure\_submit, and that is to pass the event along: module\_invoke($form\_state\['values'\]\['module'\], 'block\_save', $form\_state\['values'\]\['delta'\], $form\_state\['values'\]);

I'm not sure how go about structure $form\_state\['values'\]. Is there a way to do this with the block API?

With regard to Context, we're already using it; we could accomplish the same thing by writing to path to exclude to the context\['condition'\]\['path'\] attribute, (prefixing the path ~ to indicated "exclude"). This might be a better approach for us, but still would like to see the block code working.

# Answer
> 1 votes
The solution is to call drupal\_form\_submit. For example:

```
module_load_include('inc', 'block', 'block.admin');
$form_state = array();
$form_state['values']['module'] = 'block';
$form_state['values']['op'] = 'Save block';
drupal_form_submit('block_admin_configure', $form_state, 'block', $delta);

```

You can apply this solution to other forms: from the browser, inspect the submit button, and get the 'op' value and the form's machine name. In source, find the admin.inc that implements the form, and include that, and get the submit functions parameter signature; in this case, the 4th parameter is the form's delta value.

# Answer
> 0 votes
Although there's no really easy way to do this via code, there's a module for this specific need: Context. This module will allow you to create "Contexts" that have a certain condition (e.g. Path = /node/123) and a reaction to that condition (e.g. Place block X in region Y). These contexts are then exportable by Features. Features basically takes the configuration sitting in your database, and exports it into a "module". If you then enable this module anywhere else (e.g. on live server), then those contexts will activate on that server and the configuration gets carried over essentially.

To do this:

1. Download Context and Features modules
2. Enable `context`, `features` and `context_ui` modules
3. Go to Structure -\> Contexts and "Add Context"
4. Give it a name, and choose the conditions, then the reactions and save.
5. Go to Structure -\> Features and "Create Feature" on top right (on Seven)
6. Give it a name (e.g. myfeaturename), and then "check" the box next to your context from right hand side, then click "Download".
7. This will give you a tar.gz of your whole module code, you need to extract it to your sites/all/modules folder
8. Enable your feature either through "drush en myfeaturename", or through Structure -\> Features.

---
Tags: blocks
---


# Question
Title: How do I get the node ID for a node associated with my taxonomy term?
How do I get the node ID for a node associated with my taxonomy term with the Devel module?

# Answer
> 2 votes
Terms have a term ID number (tid) and nodes have a node id number (nid). Terms are applied to nodes so nodes can be associated to terms and vice versa.

Devel module can show the structure of a taxonomy term. To achieve this:

* Download and enable the devel.module
* Ensure you are logged in with a user who has the `Access developer information` permission
* Browse to the taxonomy term you want to inspect
* Click the Devel tab if it is visible
    + If it is not visible, that is likely either a permissions issue or a theme issue - to fix a theme issue you could try changing to a core theme like Bartik
* Then you should see some output like this:
* You can click tokens or Render or other sub-tabs as well
* This shows the tid and other values associated with the term, but not the nid of nodes associated with the term

---
Tags: 7, taxonomy-terms
---


# Question
Title: How do I avoid having to clear the cache when changing a module configuration parameter?
I have a simple configuration parameter for a custom module. I use this parameter to decide how to render a field using a custom render element:

```
class Jmol extends RenderElement {

/**
 * Define the available options for our new render element.
 */
public function getInfo() {
$class = get_class($this);

// Produce the default settings for our render element.
return [
  '#pre_render' => [
    [$class, 'preRenderJmol'],
  ],
  '#version' => NULL,
  '#theme' => NULL,
  '#id' => 'mydiv',
  '#info' => [],
  '#attached' => [
    'library' => [],
  ],
];
}

public static function preRenderJmol($element) {

// Examine the config file to see which library version to use.
$config = \Drupal::config('jmol.settings');
$version = $config->get('version');
// Look at the element to see which version the user would like to use.
// They may have changed it from the default.
if ($element['#version'] != NULL) {
  $version = $element['#version'];
}

// The twig template to use.
$theme = "";

// Add the correct library to any the user has already provided.
$library = $element['#attached']['library'];
if ($version == 'full') {
  $theme = 'jmol_full_template';
  $library[] = 'jmol/jmol_full';
}
elseif ($version == 'lite') {
  $theme = 'jmol_lite_template';
  $library[] = 'jmol/jmol_lite';
}

// Only add the theme if the user has not specified one.
if ($element['#theme'] == NULL) {
  $element['#theme'] = $theme;
}

// Add the info array to drupalSetting so the JS can access it.
$id = $element['#id'];
$drupalsettings['jmol'][$id] = [
  'info' => $element['#info'],
];

$element['#attached'] = [
  'drupalSettings' => $drupalsettings,
  'library' => $library,
];

return $element;
}

```

If I visit the module settings page and change the value of the "version" parameter, my module continues to behave the same until I clear the cache.

The submit portion of my configuration form is:

```
/**
 * {@inheritdoc}
 */
public function submitForm(array &$form, FormStateInterface $form_state) {
  $config = \Drupal::service('config.factory')->getEditable('jmol.settings');
  $config->set('version', $form_state->getValue('jmol_version'))
  ->save();

  parent::submitForm($form, $form_state);
}

```

Is there something else my submitForm function needs to do, or is there a different way I need to be reading the config parameter?

# Answer
> 8 votes
You need to set the cache tag to invalidate your output if the configuration changes. That's as easy as adding this to your render array:

```
$element['#cache']['tags'] = $config->getCacheTags();

```

---
Tags: 8
---


# Question
Title: More Stories appears when a user scrolls on a half page
More Article Box (More Stories) appears when a user scrolls on a single post at least 400px. The box appears in the right bottom corner and it can show one or more posts related with the current one.

Is there a module like this for Drupal 7?

# Answer
You can give the drupal infinite scroll module with views a try . Then tweak a bit to suit ur needs for scrolling
> 0 votes

---
Tags: 7, nodes
---


# Question
Title: Installed Boost module. How do you tell it is working on your site?
I just installed the Boost module on Drupal 7 and activated everything properly. How do I even tell if its working properly?

# Answer
> 2 votes
View the source code of the page as you're browsing as an anonymous user. Boost inserts some metadata about the cached page ("Page cached by...") as an HTML comment:

```
  // Add note to bottom of content if possible.
  if ($_boost['matched_header_info']['comment_start'] && $_boost['matched_header_info']['comment_end']) {
    $expire = $_boost['matched_header_info']['lifetime_max'];
    $cached_at = date('Y-m-d H:i:s', REQUEST_TIME);
    $expires_at = date('Y-m-d H:i:s', REQUEST_TIME + $expire);
    $note = "\n" . $_boost['matched_header_info']['comment_start'] . 'Page cached by Boost @ ' . $cached_at . ', expires @ ' . $expires_at . ', lifetime ' . format_interval($expire) . $_boost['matched_header_info']['comment_end'];
    $data .= $note;
  }

```

---
Tags: 7, caching
---


# Question
Title: Theme CSS overrides my CSS. How do I fix this?
Trying to customize this theme called Emon, but any theme styles I write bootstrap.css/template.css takes precedence even if we use identical selectors. I don't want to edit bootstrap.css/theme.css obviously, or use !important all over the place.

The theme offers a "Write your own CSS" section which has it at an inline-level, but it's not the easiest to maintain this way (though it's looking more attractive every minute). I saw libraries-override/extend, but wasn't able to accomplish what I want like this.

Again, I'm looking to tell Drupal to honor my stylesheet over the others without removing them. What is the right way to accomplish this?

# Answer
> 0 votes
Copy html.tpl file from your core module and place it in your themes folder ,look at the head element of your template then copy the path(link) of your CSS file and place it (at the last)after the themes CSS into the head tag.

---
Tags: theming, 8
---


# Question
Title: Error messages when running "drush verify-makefile" on a generated make file
When running the following command, Drush is printing a number of error messages:

```
drush verify-makefile

```

There is only one make file in document root and it was created with:

```
drush generate-makefile drupal-org.make

```

There were no errors printed with generating the make file. All that is said was:

```
Wrote .make file drupal-org.make                               [ok]

```

I am trying to publish a new Drupal distribution on drupal.org. The particular error messages I am receiving are:

```
The project-level attribute 'custom_download' on project 'datasets' is not allowed. [error]
The project-level attribute 'custom_download' on project 'operations' is not allowed. [error]
The project-level attribute 'custom_download' on project 'quadstat' is not allowed. [error]

```

My guess is that these modules are not published on drupal.org so they can not be included with the distribution. It seems related to this Drupal.org issue: #1427762

Before I went and created these modules on Drupal.org, I was hoping someone could confirm my theory.

Also the syntax generated for the make file seems to follow YAML (a Drupal 8 convention) even though my Drush version is 8.1.2 and my drupalorg\_drush version is 7.x-1.x-dev. My Drupal core distribution is 7.44.

I thought it may be helpful to include the make file too.

```
core: 7.44
api: 2
projects:
  admin_menu:
    version: 3.0-rc5
  ctools:
    version: '1.9'
  node_clone:
    version: '1.0'
  features:
    version: '2.10'
  field_group:
    version: '1.5'
  field_permissions:
    version: 1.0-beta2
  filefield_paths:
    version: 1.x-dev
  panels:
    version: '3.5'
  jquery_update:
    version: '2.7'
  libraries:
    version: '2.3'
  mathjax:
    version: '2.4'
  node_export:
    version: '3.1'
  nodeaccess:
    version: '1.4'
  text_with_summary:
    version: '1.0'
  uuid:
    version: 1.0-beta1
  views:
    version: '3.14'
  views_filters_populate:
    version: '1.1'
  shiny:
    version: '1.7'
  datasets:
    type: module
    custom_download: true
  operations:
    type: module
    custom_download: true
  quadstat:
    type: module
    custom_download: true
  libraries:
    SlickGrid:
      directory_name: SlickGrid
      custom_download: true
      type: library

```

There are some other unrelated error messages, but the ones I mentioned are the first that popup.

Thank you for any suggestions provided.

# Answer
EDIT: Not sure if the solution specified here is cosmetic but it did take care of the above question. I am not too familiar with Drupal project packaging.

This particular error was fixed with only making changes to the make file:

* I switched the colons defining Drupal core and the API versions to equals
* I changed the name for SlickGrid library to lowercase("slickgrid")

```
core = 7.44
api = 2

```

The rest of the make file still uses YAML convention. I wonder if that will cause problems down-the-road.
> 0 votes

---
Tags: drush
---


# Question
Title: How to reduce support request comments about a module on its official documentation pages?
When using the link `Add new comment` on any of the Community Documentation pages on Drupal.org, a message is shown near the top that looks like so:

> **Is your comment an addition, problem report, or example?** Instead of adding a comment, edit the page content directly. If you are unsure of the correct edits, add a comment here and then edit the page to update the page status. Once a solution for the page has been agreed upon, edit the page accordingly and read incorporating comments on how to remove the related comment(s).
>
> **Is your comment a question or request for support?** Take it to the forums. Questions are not answered here, and comments not providing useful information may be removed at any time.

If you wonder why that message is there, then go have a look at the comments below various community pages, such as the "Read documentation" links mentioned (within "Resources") on the project page from these contributed ***modules***:

Obviously, those comments don't comply with what's mentioned on Commenting on community documentation pages and API pages, i.e.:

> ... if you have a question about how to use a function or perform a task being described, please use the Forums or one of the other Support options, rather than adding a comment. And if you want to report a software bug, file an issue instead of adding a comment somewhere.

So what can people, who contribute to a contributed ***module***'s documentation via such Community pages, do to:

* **discourage** the creation of such comments?
* **cleanup** such comments?

**Note**: I'm aware that there are ***modules*** (also in the top 10 of reported installs) that have a "Read Documentation"-link on their project page that is not somewhere on drupal.org, but that's not what my question is about (I don't want to consider links outside drupal.org).

# Answer
If you know of such Community documentation pages that are at risk (or already suffer) this problem, then perform these steps:

* For anything "valueable" in such comments, find a way to include them in the documentation pages themselves, or create an appropriate issue for it (so move it to where it belongs).
* Report such comments for removal (where appropriate indicate what you did in the prior step).
* Wait for all comments to be removed.
* Post your own (new!) comment to such page, which looks something like so (XYZ = machine name of the contributed module that the documentation relates, ABC = name of the module, 987654321 a node ID that fits for you):

+ **Subject**:
> Use XYZ issue queue for issues about ABC

+ **Comment**:

    Please do NOT add comments to this page or any of its childpages to report issues (feature requests, problems, etc) about the ABC module. Instead of adding such comments, please create an issue in the `<a href="/project/issues/XYZ">ABC issue queue</a>`.

    `<em class="marker"><strong>Note</strong></em>`: Refer to `<a href="/node/987654321">this page</a>` within these documentation pages of an example of various comments that do not belong there. The content of that page is very valuable community docu, but most of the comments below it do not add any value to that page (and are not compliant with the content of the yellow message you get when adding a comment).
* Occasionally go check (visit) those pages again. For any additional (new) comments: repeat the first 2 steps above.

For an illustration, have a look at this comment (Disclosure: I posted it) ... So far it seems to work ...

PS: Comments to improve / correct / extend the content of such community documentation pages are fine. After they got processed (via some type of edit of the page ere needed), they should get removed again (as in step 1 and 2).
> 1 votes

---
Tags: community-official-site
---


# Question
Title: How to track and display selected user activities in a site?
I wonder how to track and display user activities in a Drupal site. Examples of such activities are:

* posts.
* comments.
* page posts.

I've found some modules that track the users' activites all over the social media, but I need something much more local (within the site).

I was also thinking about using Views to create a block with this kind of filters, but I have never seen filters as specific as users. Is there a way to achieve this?

# Answer
There are a few modules that could help you out (quotes included are from their project pages):

* Activity:

> ... keeps track of the things people do on your site and provides mini-feeds of these activities in blocks, in a specialized table, and via RSS. The module is extensible so that any other module can integrate with it. The messages that are produced are customizable via the admin interface and are context sensitive.
* Heartbeat

> ... displays user activity on a website. This module is an API to log activity. The logged data contains message structures, attributes and variables. Once the activity messages exist in the database, they will be parsed and build into activity streams.
* User Activity

> ... calculates an activity index based on a user's logins, page impressions, created nodes and comments. The weight for each value is adjustable by an administrator. It provides an activity-o-meter on the user's profile page, a block with the most active users and an overview page of users sorted by activity.
* User Stats

> ... provides commonly requested user statistics for themers, IP address tracking and Views integration.

Which one(s) you choose really depend on what *exactly* you want to accomplish (use Views or not, display only post info or login stats, etc). I'm sure there are more out there that I am missing.

Activity stream modules (on Groups.Drupal.org) contains a **comparison** about the functionality and architecture of some activity modules.
> 16 votes

# Answer
For simple use cases, core provides the often overlooked Tracker module, which is what Drupal.org uses (although, if you're on Drupal 6, the Tracker2 contrib module is more performant, and made its way into Drupal 7).
> 8 votes

# Answer
The Goals module is a possible solution to answer this question. It can be used to incentivize anything on your site, such as voting, sharing content, creating relationships, etc.

**Goals** and **Tasks** are implemented using fieldable entities. So you can customize Goals via "Manage Fields" and/or "Manage display". And it integrates very well, out-of-the-box, with the Views module also.

Head over to the Goals video which includes:

* a general introduction to the module.
* a demonstration to install, configure and use it.
* samples of how it uses the Rules modules to do its magic (i.e. to track the progress of a user to achieve the various goals).

Using the **Goals Extras** sub-module it integrates with the User Points module also.

For more details, refer to its Community Documentation, which also includes a summary of what this module is really about, ie (quote from that page):

> **What is a "Goal"?**
>
> A "goal" is a set of one or more tasks a user must complete. A goal is a container for tasks. Once a user completes all tasks for a goal, the goal is automatically marked complete.
>
> By creating a number of goals that align with behaviors encouraged on a site, a gamification system can quickly be established which is easy to administer, highly customizable, and tailored to the needs of the site.
>
> **What is a "Task"?**
>
> A "task" is any action that site users must complete one or more times. In addition to simply counting the number of times an action is performed, administrators have the ability to place constraints on the timeframe in which an action is performed. Examples of tasks created by site administrators include:
>
> * A user "Likes" another user’s post.
> * A user contributes three posts of content within a week.
> * A user logs in to the site for three consecutive days.

Disclosure: I'm the maintainer of this module.
> 1 votes

---
Tags: 7, users
---


# Question
Title: How to programmatically insert and update Field Collection values?
I would like to insert and update Field Collection values. I'm using Drupal 8 with `field_collection 8.x-1.0-alpha1`.

# Setup

I have created a new content type `test_content_type` with the following fields:

* Title
* Body
*
* Test Field Collection
    + Machine name: `field_test_field_collection`
    + Type: `field collection`

The field collection `field_test_field_collection` has only one field:

* Example Text
    + Machine name: `field_text`
    + Type: `text`

# The Problem

I also created a node with values, for instance `Lorem Ipsum` as `field_text.value`, but I don't know how to read and define the value programmatically. I tried the following, which updates `body` but doesn't update `field_text`:

```
<?php

namespace Drupal\my_module\Controller;

use Drupal;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Entity\EntityStorageInterface;

class FieldCollectionTestController extends ControllerBase {
    /**
     * @return array
     */
    public function content() {
        $nodeId = 1402;

        /** @var EntityStorageInterface $entityStorage */
        $entityStorage = Drupal::entityTypeManager()->getStorage('node');
        $node = $entityStorage->load($nodeId);

        // Dump.
        {
            ob_start();
            var_dump($node->field_test_field_collection->field_text);
            $dump = ob_get_clean();
        }

        // Update node and field collection.
        {
            $exampleText = "Updated at " . time();

            $node->body = $exampleText;
            $node->field_test_field_collection->field_text = $exampleText;

            $node->save();
        }

        $response = [
            '#theme' => 'item_list',
            '#title' => 'Dumps',
            '#items' => [
                [
                    '#type' => 'markup',
                    '#markup' => $dump,
                ],
            ],
        ];

        return $response;
    }
}

```

The value of `$dump` is `null`.

# Question

How do you insert, update and delete Field Collections in Drupal 8?

# Answer
The following snippet (compatible with `field_collection 8.x-1.0-alpha1`) reuses an existing `FieldCollectionItem` or creates a new one on demand. The last few lines show how to modify fields inside the `FieldCollectionItem`.

If one has a field collection with a different name, then it should be enough to replace all occurrences of `field_test_field_collection` with the custom field collection's machine name.

```
<?php

// […]

$nodeId = 123;

/** @var EntityStorageInterface $entityStorage */
$entityStorage = Drupal::entityTypeManager()->getStorage('node');

$node = $entityStorage->load($nodeId);
$node->body = 'Body Update: ' . date('c');

/** @var Drupal\Core\Field\FieldItemList $fieldItemList */
$fieldItemList = $node->field_test_field_collection;

// Reuse existing Field Collection.
if (count($fieldItemList))
{
    /** @var \Drupal\field_collection\Plugin\Field\FieldType\FieldCollection $fieldCollection */
    $fieldCollection = $fieldItemList[0];
    $fieldCollectionItem = FieldCollectionItem::load($fieldCollection->value);
}

// Create new Field Collection.
else
{
    $fieldCollectionItem = FieldCollectionItem::create([
        'field_name' => 'field_test_field_collection',
    ]);

    $fieldCollectionItem->setHostEntity($node);

    $node->field_test_field_collection[] = [
        'field_collection_item' => $fieldCollectionItem,
    ];
}

$fieldCollectionItem->set('field_text', 'Last Update: ' . date('c'));

$node->save();

```

Deleting an existing collection is as simple as: `fieldCollectionItem->delete();`

Please have a look at the source code of the unit test class `Drupal\field_collection\Tests\FieldCollectionBasicTestCase` for more information.
> 4 votes

# Answer
Check the below link,

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

That may help you in your case.
> -2 votes

---
Tags: 8, entities
---


# Question
Title: Prevent Development modules from being added to configuration management
We have modules that are only used for local development like Stage File Proxy. How would I prevent these modules from being added to the configuration management?

# Answer
> 9 votes
From Dave Reid on Twitter

**Ignoring Development Modules**

If you have a certain list of modules that should only be enabled on the development or staging server, then this may be done with the built-in --skip-modules option in the config-export and config-import commands.

For example, if you want to enable the 'devel' module on development systems, but not on production server, you could define the following configuration settings in your drushrc.php file:

```
# $command_specific['config-export']['skip-modules'] = array('devel');
# $command_specific['config-import']['skip-modules'] = array('devel');

```

You may then use drush pm-enable to enable the devel module on the development machine, and subsequent imports of the configuration data will not cause it to be disabled again. Similarly, if you make changes to configuration on the development environment and export them, then the devel module will not be listed in the exports.

http://www.drush.org/en/master/config-exporting/#ignoring-development-modules

---
Tags: 8, configuration
---


# Question
Title: How do I get the number of nodes using terms from a vocabulary on the same line together the link to the term page?
I created a view of taxonomy terms, and then followed these steps to add the number of nodes using each term listed in the resulting view.

* As *Format*, I selected *HTML List* showing *Fields*
* As relationship, I added *Content using field\_blog\_category*, where *field\_blog\_category* is the field I added to a content type I created
* I checked *Use aggregration*
* I added *ID* (listed under the *Content* category) as new field
* I set *Aggregration type* to *Count* for the new field (by clicking on *Aggregration settings* for that field)

It works as expected, except the fields are not in the same line.

>

I checked the settings for both the fields, but I could not find a way to make them appear on the same line; even changing the settings for *Rewrite results* didn't help me.

Is it possible to have those two fields on the same line, without using *Table* as *Format*?

# Answer
Yes. By default, a HTML List View displays fields wrapped in a couple of `DIV`s, a block-level element. Hence, it displays each field on a new line. To disable this, use the **Style Settings** \> **Customize field and label wrapper HTML** checkbox for each field to use an element that isn't a block-level element (e.g. `SPAN`).
> 3 votes

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


# Question
Title: Why am i getting PDO exception while running the following test from console?
I am writing a module to return common parent of 2 revision in a linear entity. For example : After editing a node 5 times, we get a graph similar to 1-\>2-\>3-\>4-\>5 where 1 is the actual node and 5 is the last revision. I wrote a function which would return the common parent of 2 revision ID. It would return 3 for (4,5) and 2 for (3,4). The code is the following one.

```
namespace Drupal\conflict;

use Drupal\conflict\ConflictManagerInterface;
use Drupal\conflict\ConflictAncestorResolverInterface;

class ConflictManager implements ConflictManagerInterface {

    protected $resolvers = [];

    public function applies() {
        return TRUE;
    }

    public function addAncestorResolver(ConflictAncestorResolverInterface $resolver)
    {
        $this->resolvers[] = $resolver;
    }

    public function resolveLowestCommonAncestor($revision1, $revision2)
    {
        foreach ($this->resolvers as $resolver) {
            if ($resolver->applies()) {
                return $resolver->resolve($revision1, $revision2);
            }
        }
        echo "No revision found";
        return -1;
    }

    public function resolve($revision1, $revision2) {
        if ($revision1 < $revision2) {
            return $revision1-1;
        }
        return $revision2-1;
    }
}

```

To test the above written code, I have written a test case:

```
namespace Drupal\conflict\Tests;

use Drupal\Tests\UnitTestCase;
use Drupal\Core\Entity\Entity;
use Drupal\conflict;

class SimpleLcaTest extends UnitTestCase {

    public function basicTest() {
        $entity = EntityTest::create(['label' => 'revision 1']);
        $entity->save();
        $entity->label = 'revision 2';
        $entity->save();
        $entity->label = 'revision 3';
        $entity->save();

        $revision2 = entity_revision_load('entity_test', 2);
        $revision3 = entity_revision_load('entity_test', 3);

        $manager = Drupal::service('conflict.manager');
        $revisionLca = $manager->resolveLowestCommonAncestor($revision2, $revision3);
        $this->assertTrue($revisionLca->label() == 'revision 1');
     }
}

```

When I try to run test via console using run-test.sh, I get the following error:

> Exception 'PDOException' with message 'SQLSTATE\[23000\]: Integrity constraint violation: 1048 Column 'file' cannot be null

# Answer
You can't create and save entities in a unit test.

That's what kernel tests are for. You will also need to install the necessary entity schema then, make sure the necessary modules are enabled. One way to do that is to extend from EntityKernelTestBase.

Also, I strongly recommend to run the phpunit tests directly with phpunit, the error reporting is much better and it's faster as well.
> 5 votes

---
Tags: 8, testing
---


# Question
Title: UI.selectmenu from jQuery is not imported!
I have this function to add libraries from jQuery UI, but the *selectmen*, and *tooltip* seems to be missing! anyone know how to import them in Drupal 7.4?

```
function kalender_init() {
    $lib= array(
        'drupal.ajax', 'drupal.form',
        'drupal.autocomplete',
        'jquery', 'ui','ui.selectable',
        'ui.droppable','ui.draggable',
        'ui.sortable','ui.resizable',
        'ui.tabs','ui.dialog',
        'ui.datepicker','ui.autocomplete',
        'ui.button', 'ui.buttonset',
        'ui.selectmenu', 'ui.tooltip',
        'form'
    );
    foreach($lib as $l){
        drupal_add_library('system', $l);
    }
}

```

I need for the form over here:

```
foreach($result as $color){
    array_push($colors, $color->name);
}
foreach($colors as $color => $id){
    array_push($attr, array('class' => array('colors-list'), 'data-color' => $color) );
}
$form['gruppen']['checkbox'][$group->id]['color'] = array(
    '#type' => 'select',
    '#suffix' => '<div class="clear-both"></div></div>',
    '#default_value' => 0,
    '#options' => $colors,
    '#options_attributes' => $attr,
);

```

# Answer
Selectmenu Widget is added in jQuery UI 1.11, which is not supported by core and also jquery\_update module. There is an issue on Drupal.org.

Tabs Widget is added since jQuery UI 1.9, you can have it if you installed latest version of jquery\_update module with proper configuration.
> 0 votes

---
Tags: 7, javascript
---


title: Get single value field_view_field

text:
# Question
Title: Get single value field_view_field
I am using `field_view_field()` to render a product image. I have a condition where I want to display only one image for the product not other images of that product. How can I do this?

# Answer
> 0 votes
Use this inside your view template file:

```
print fields['your_field_name']->content;

```

---
Tags: 7, entities, media
---


# Question
Title: How to update field after ubercart checkout completion?
I have created a field (checkbox) in user profile edit form that is only visible to admin.

When the user completed their checkout process (after payment) that field which I created previously must be updated (I.e: checked).

I want to implement this functionality for letting admin know about who has purchased the subscription plan .

How could I do it by using rule or something else?

# Answer
> 0 votes
you can use the Rules module for the after checkout event then use some custom php code to update your field.

you might need to add Commerce Rules Extra module to get the checkout event in rules.

---
Tags: 7, rules, ubercart
---


# Question
Title: apply css for particular node and do not apply for particular node
I used the CSS injector module to replace the default CSS. I applied that CSS for paths like node/\*. How do I exclude node/add from that CSS (the one I created with the CSS injection module)?

# Answer
> 0 votes
This is the sort of thing that I'd do by code, but that's because that's just the way I roll.

In the template.php you will want something like:

```
function MYTHEME_preprocess_node($vars) {
  if (drupal_get_path_alias(current_path()) == 'node/add') {
    drupal_add_css(drupal_get_path('theme', 'MYTHEME') . "/css/foo.css");
  }
}

```

I hope this helps.. :)

# Answer
> 0 votes
If you want to give particular styling to a particular node (or content type) you can use the native class appears very high in the DOM. No modules needed.

You could hide a whole region using the module Content which is better than hiding it with display:none; ...

---
Tags: theming
---


title: Limiting access by role

text:
# Question
Title: Limiting access by role
So I basically have a custom module created and I just want to know how I can limit the users who can access the 2 forms I have by predefined roles -- the IT and Facilities roles that I have defined in Drupal (7) already so that only IT and Facilities people can access them..

I've been looking at access callback/access arguments but I'm not exactly sure what to use in my form definition/hook\_menu in order to limit access to just those two roles.

Here's my hook\_menu function:

```
//hook_menu
function ibbr_inv_menu(){
    //'Inventory Items' page
    $items['inventory_scan'] = array(
    'title' => 'Inventory Items',
    'page callback' => 'ibbr_inv_menu_page_callback',
    'access callback' => TRUE,
    'page arguments' => array(1, 2),
    'type'=> MENU_CALLBACK,
);
    //'Add new item' page
    $items['inventory_scan/add_item'] = array(
    'title' => 'Add new item',
    'page callback' => 'ibbr_inv_add_new_item_callback',
    'access callback' => TRUE,
    'page arguments' => array(1, 2),
    'type'=> MENU_CALLBACK,
);
return $items;
}//end hook

```

Thank you!

# Answer
Since you are setting `'access callback'` to `TRUE`, you are actually giving access to those routes to every user, including the anonymous users.
You could easily set the access callback to a function in your module `'access callback' => 'ibbr_inv_access_callback'` and check the roles the global `$user` variable has, but that would be a bad idea, since every time you need to give access to those routes to a new role, you would need to change the code of your access callback. Plus, since you are hard-coding the roles in your code, the module could not easily be adapted to different needs, such as sites using totally different roles.

The Drupal way is to assign permissions to the roles that should be able to access the routes you define, and use `user_permission()` as access callback for your routes. In this way, the code would check for the same permission, which could be given to new roles, or to totally different roles; any change in the roles having that permission would not reflect on your code, which would still work in any case.

As permission, you could use one that Drupal already use, or (if that is not restrictive enough) define a new permission.

```
function ibbr_inv_menu() {
  $items['inventory_scan'] = array(
    'title' => 'Inventory items',
    'page callback' => 'ibbr_inv_menu_page_callback',
    'access arguments' => array('administer inventory items'),
    'type'=> MENU_CALLBACK,
  );
  $items['inventory_scan/add_item'] = array(
    'title' => 'Add new item',
    'page callback' => 'ibbr_inv_add_new_item_callback',
    'access arguments' => array('administer inventory items'),
    'type'=> MENU_CALLBACK,
  );
  return $items;
}

function ibbr_inv_permission() {
  $permissions['administer inventory items'] = array(
    'title' => t('Administer inventory items'),
    'description' => t('Creates/deletes inventory items.'),
  );
  return $permissions;
}

```

To use a access callback that checks the roles the currently logged-in user has, I would use the following code. It's not the code I would use, but if you need to use such code for any reason, this is what I would suggest.

```
function ibbr_inv_menu() {
  $items['inventory_scan'] = array(
    'title' => 'Inventory Items',
    'page callback' => 'ibbr_inv_menu_page_callback',
    'access callback' => 'ibbr_inv_access_callback',
    'access arguments' => array('the role the user needs to have'),
    'type'=> MENU_CALLBACK,
  );
  $items['inventory_scan/add_item'] = array(
    'title' => 'Add new item',
    'page callback' => 'ibbr_inv_add_new_item_callback',
    'access callback' => 'ibbr_inv_access_callback',
    'access arguments' => array('the role the user needs to have'),
    'type'=> MENU_CALLBACK,
  );
  return $items;
}

function ibbr_inv_access_callback($role_name) {
  if ($role = user_role_load_by_name($role_name)) {
    return user_has_role($role->rid);
  }

  // The role doesn't exists; return FALSE as safe value.
  return FALSE;
}

```

The code works on Drupal 7.36 and higher, since it is using a function that previous versions didn't implement (`user_has_role()`).

As side note, since for inventory\_scan/add\_item you are using `array(1, 2)` as page arguments, the page callback would receive `'add_item'` as argument, which doesn't make much sense; it would make sense if you were using the same page callback for different routes, and you would use `'add_item'` to make the page callback know which action to perform.
In the same way, it doesn't make much sense to use `array(1, 2)` as page arguments for a route like inventory\_scan; if you are not visiting inventory\_scan/first\_value/second\_value, the page callback will not receive any arguments at all.
> 2 votes

# Answer
Drupal access control is build on permissions granted to roles. So in order to restrict access to users with at least one of two given roles, you actually need to restrict access to users with a role to which the correct permission has been granted.

When defining a menu entry with a `hook_menu()` implementation, you can specify the function used for access control with the `#access callback` property, and the arguments for this function with the `#access arguments` property. They work just like the `#page callback` and `#page arguments` ones. The default value for `#access callback` is the `user_access()` function which is exactly the function you need to use to check if the currently logged user has a given permission. Therefore, you only need to set the `#access arguments` property so the function will receive the permission. Access control is inherited in menu items, so children does not need to repeat the settings from their parents.

```
/**
 * Implements hook_menu().
 */
function ibbr_inv_menu(){
  $items = array();
  //'Inventory Items' page
  $items['inventory_scan'] = array(
    'title' => 'Inventory Items',
    'page callback' => 'ibbr_inv_menu_page_callback',
    'access arguments' => array('administer ibbr inventory'),
    'page arguments' => array(1, 2),
    'type'=> MENU_CALLBACK,
  );
  //'Add new item' page
  $items['inventory_scan/add_item'] = array(
    'title' => 'Add new item',
    'page callback' => 'ibbr_inv_add_new_item_callback',
    'page arguments' => array(1, 2),
    'type'=> MENU_CALLBACK,
  );
  return $items;
}

```

You also need to define the permission with an implementation of `hook_permission()`

```
/**
 * Implements hook_permission()
 */
function ibbr_inv_permission() {
  $permissions = array();
  $permissions['administer ibbr inventory'] = array(
    'title' => t('Administer IBBR iventory'),
    'description' => t('Perform administration tasks for inventory items.'),
  );
  return $permissions;
}

```

And of course, you need to grant that permissions to the relevant roles.
> 1 votes

---
Tags: 7, routes
---


# Question
Title: What function/method should I use for file_directory_path()?
In Drupal 6, I am using the following code.

```
$id = fileowner(file_directory_path());

```

What is the Drupal 8 equivalent of that code?

# Answer
> 1 votes
You can use the following code.

```
$real_path = \Drupal::service('file_system')->realpath(file_build_uri(''));

```

On my test site, it returns `'/Library/Server/Web/Data/Sites/avpnet/sites/default/files'`.

You can also pass a filename to `file_build_uri()`.

```
$real_path = \Drupal::service('file_system')->realpath(file_build_uri('file.jpeg'));

```

With this code, I get `'/Library/Server/Web/Data/Sites/avpnet/sites/default/files/file.jpeg'`.

# Answer
> 0 votes
You can use `\Drupal\Core\File\FileSystem::realpath()` to get the realpath of the file or `\Drupal\Core\File\FileSystem::dirname()`. As file\_directory\_path() is deprecated from Drupal 7. For more details please visit at drupal\_realpath and drupal\_dirname

---
Tags: 8
---


# Question
Title: How to avoid sending 2 emails at the same time?
I use Drupal 7 and I'm testing a function to automatically send email from a custom module.

I have 3 fields to check, and I have to send mail to a specific address.

I have write simple test code in a custom module:

```
function test_mail_node_presave($node) {
 if($node->type == 'rso') {
  if ($node->field_a['und'][0]['tid'] == '10'){
   mail('example1@mail.com', 'example2@mail.com', 'example text');
  }
 }
}

```

It works, but in any verification "field\_a" Drupal sends 2 equals email.

**Note**: I'd also be interested to know about any other technique that can achieve the same result.

# Answer
> 0 votes
You could get pretty close to what you're trying to do by simply (and only) using the Rules module. Some more details about this approach:

* Use Rules Event "***Before saving content***".
* Use as many Rules Conditions as needed, for any of your fields you want to validate.
* Use Rules Action "\**Send Mail".

For more details, Have a look at this rule (in Rules export format):

```
{ "rules_field_validations_before_saving_nodes" : {
    "LABEL" : "Field validations before saving nodes",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules" ],
    "ON" : { "node_presave--article" : { "bundle" : "article" } },
    "IF" : [
      { "entity_has_field" : { "entity" : [ "node" ], "field" : "field_optionlist" } },
      { "data_is" : { "data" : [ "node:field-optionlist" ], "value" : "C" } }
    ],
    "DO" : [
      { "mail" : {
          "to" : "example1@mail.com, example2@mail.com, example text",
          "subject" : "Subject of eMail triggered via Rules",
          "message" : "Message content of eMail triggered via Rules",
          "language" : [ "" ]
        }
      }
    ]
  }
}

```

Some more details to further explain the above above sample:

* The Rules event is "After saving new content", but as a sample I've limited it to content type "article" only (omit or adapt that extra verification as needed).
* In my case I have a selection list field with machine name `field_optionlist`.
* This field actually has 3 possible values, like so:
    + A (=Advanced).
    + B (=Basic).
    + C (=Custom).
* As a sample, I decided to add these Rules Conditions (validations), in the order specified:
    + a validation to ensure that this rule only applies for nodes that have a field with machine name `field_optionlist`.
    + a validation about attempts to save a node where "The selected value" of `field_optionlist` equals `Custom`.
* If all these Rules Conditions are satisfied, then the Rules Action will send an eMail (feel free to change the eMail subject/body to whatever you want).

If you want, you can use the Rules UI to import the above rule in your own site. But before doing so, make sure you have defined 2 similar fields (with machine names `field_optionlist` and `field_free_format_text`). As a variation, adapt the machine names to similar fields you already have (attention about `field-optionlist` versus `field_optionlist` though, same for the 2nd field, important!).

If you're not familiar (enough/yet) with Rules, checkout the 32 (!!!) great, and free, video tutorials Learn the Rules framework.

Voilà, the above solution depends on Rules, nothing but Rules ...

---
Tags: 7, emails
---


# Question
Title: How to fix error 'This site can’t be reached' for a site installed on Amazon?
I have just installed Drupal 8.1.3 on an Amazon instance using the instructions provided here.

I can connect via SSH (console) to my instance successfully.

However, when I try to browse my public DNS, I get:

```
This site can’t be reached

ec2-54-187-215-79.us-west-2.compute.amazonaws.com took too long to respond.

```

This is the first time I am performing this installation.

I have performed a DNS check and it says: `Delegation not found at parent`

I am wondering whether it is a Drupal related issue or not. How can I solve this?

# Answer
> 9 votes
It's because by default port 22 (SSH) comes open in your EC2 security group, but port 80 (HTTP) is not open.

You need to edit your security group. To get there, in your EC2 list, scroll all the way to the right and click on the blue security group name. You will be taken to your security group settings page, for inbound, add Custom TCP Rule of port 80

> **PS:** If you're going to use HTTPS might aswell open port 443 (HTTPS)

---
Tags: installation, 8
---


# Question
Title: How do I get the dynamic elements value?
I wrote code to display fields, but I can't get all the entered values.

```
function payroll_emp_form($form, &$form_submit) {
    for($i=1; $i<=2; $i++) {
     $form['foo_fieldset']['row_' . $i] = array(
       '#prefix' => '<tr>',
       '#suffix' => '</tr>',
     );
     $form['foo_fieldset']['row_' . $i]['names'] = array(
       '#markup' => $query_emp_result1->name,
       '#prefix' => '<td>',
       '#suffix' => '</td>',
     );

     $form['foo_fieldset']['row_' . $i]['accountno'] = array(
       '#type' => 'markup',
       '#markup' => $query_emp_result1->account_no,
       '#prefix' => '<td>',
       '#suffix' => '</td>',
     );

     $form['foo_fieldset']['row_' . $i]['perdaypay'] = array(
      '#type' => 'textfield',
      '#maxlength' =>2,
      '#size' => 10,
      '#required' => TRUE,
      '#prefix' => '<td>',
      '#suffix' => '</td>',
    );
  }

  $form['submit'] = array(
    '#value' => 'Submit',
    '#type' => 'submit',
    '#submit' => array('payroll_emp_form_submit'),
  );
  return $form;
}

function payroll_emp_form_submit($form, $form_state) {
  $accountno = $form_state['values']['foo_fieldset']['row_' . $a]['accountno'];
  $perdaypay = $form_state['values']['foo_fieldset']['row_' . $a]['perdaypay'];
}

```

What is wrong with my code?

# Answer
> 0 votes
Without using `'#tree'` and setting it to `TRUE`, `$form_state['values']` will just contain `$form_state['values']['perdaypay']`. `$form_state['values']` just contains the values submitted from the user; it doesn't contain markup as you expect.

To correct the first error, the code needs to be similar to the following one.

```
function payroll_emp_form($form, &$form_state) {
  $form['foo_fieldset'] = array(
    '#tree' => TRUE,
  );

  for ($i=1; $i<=2; $i++) {
    $form['foo_fieldset']["row_$i"] = array(
      '#prefix' => '<tr>',
      '#suffix' => '</tr>',
    );

    $form['foo_fieldset']["row_$i"]['names'] = array(
      '#markup' => $query_emp_result1->name,
      '#prefix' => '<td>',
      '#suffix' => '</td>',
    );

    $form['foo_fieldset']["row_$i"]['accountno'] = array(
      '#type' => 'markup',
      '#markup' => $query_emp_result1->account_no,
      '#prefix' => '<td>',
      '#suffix' => '</td>',
    );

    $form['foo_fieldset']["row_$i"]['perdaypay'] = array(
     '#type' => 'textfield',
     '#maxlength' =>2,
     '#size' => 10,
     '#required' => TRUE,
     '#prefix' => '<td>',
     '#suffix' => '</td>',
   );
 }

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

 return $form;
}

function payroll_emp_form_submit($form, &$form_state) {
  for ($i=1; $i<=2; $i++) {
    $perdaypay = $form_state['values']['foo_fieldset']["row_$i"]['perdaypay'];
    // Use $perdaypay.
  }
}

```

If then you wanted to be able to access `$form_state['values']['foo_fieldset']["row_$i"]['accountno']`, you should use the following, in the form.

```
 $form['foo_fieldset']["row_$i"]['accountno'] = array(
   '#type' => 'hidden',
   '#value' => $query_emp_result1->account_no;
   '#prefix' => "<td>{$query_emp_result1->account_no}",
   '#suffix' => '</td>',
 );

```

---
Tags: forms
---


title: How do I load the user object?

text:
# Question
Title: How do I load the user object?
I need to get the `global $user` object in Drupal 8. I did `$account = \Drupal::currentUser();` in the definition of `getSubscribedEvents()` (a static method) inside a class file.

I get the following error when running `drush cr`:

> exception
> \[error\] 'Drupal\Core\DependencyInjection\ContainerNotInitializedException' with message '\Drupal::$container is not initialized yet. \Drupal::setContainer() must be called with a real container.' in /Applications/MAMP/htdocs/drupal-8.0.x-dev/core/lib/Drupal.php:129

What is wrong in my code?

# Answer
> 2 votes
Here is my whole piece of code which works fine now:

Inside my\_module.service.yml

```
services:
  myModule.event_subscriber:
    class: Drupal\my_module\EventSubscriber\MymoduleSubscriber

    tags:
      - {name: event_subscriber}

```

Inside MymoduleSubscriber.php

```
<?php

namespace Drupal\my_module\EventSubscriber;

use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class myModule implements EventSubscriberInterface {

  public function xyz(GetResponseEvent $event) {
    $user_id = $this->accountProxy->id();
    if($user_id) {
    }
  }
  /**
   * {@inheritdoc}
   */
  static function getSubscribedEvents() {
    $events[KernelEvents::REQUEST][] = array('xyz');
    return $events;

  }

  public function __construct() {
    $user = \Drupal::currentUser();
    $this->accountProxy = $user;
  }

}

```

# Answer
> 10 votes
Since you are using a `getSubscribedEvents()` static method, I get you are implementing an event subscriber. In this case, you don't access `\Drupal::currentUser()` (and any static method returning a service that `\Drupal` exposes) in that method since it would be getting called too early, when Drupal has not yet initialized the dependency container.
That static method is supposed to return a static array describing the events to which the module wants to subscribe; the methods used to subscribe to the events will eventually take a different action basing on the user currently logged-in, and the user permissions that user account has.

Event subscribers are services, and as such they get their dependency injected. Instead of using `\Drupal::currentUser()`, you define @current\_user as one of the arguments of your service, which is what the authentication\_subscriber service does.

```
class: Drupal\Core\EventSubscriber\AuthenticationSubscriber
arguments:
  - '@authentication'
  - '@current_user'
tags:
  - { name: event_subscriber }

```

If you look at `AuthenticationSubscriber::__construct()`, you will see how it gets the current user object.

```
public function __construct(AuthenticationProviderInterface $authentication_provider, AccountProxyInterface $account_proxy) {
  $this->authenticationProvider = $authentication_provider;
  $this->filter = ($authentication_provider instanceof AuthenticationProviderFilterInterface) ? $authentication_provider : NULL;
  $this->challengeProvider = ($authentication_provider instanceof AuthenticationProviderChallengeInterface) ? $authentication_provider : NULL;
  $this->accountProxy = $account_proxy;
}

```

In your case, I would use the following code.

### mymodule.services.yml

```
services:
  mymodule.eventsubscriber:
    class: Drupal\mymodule\EventSubscriber\MyModuleSubscriber
    arguments:
      - '@current_user'
    tags:
      - { name: event_subscriber }

```

### src/EventSubscriber/MyModuleSubscriber.php

```
namespace Drupal\mymodule\EventSubscriber;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class MymoduleSubscriber implements EventSubscriberInterface {

  /**
   * {@inheritdoc}
   */
  static function getSubscribedEvents() {
    // Return the array describing the events to which you subscribe.
  }

  public function __construct(AccountProxyInterface $account_proxy) {
    $this->accountProxy = $account_proxy;
  }

}

```

Notice that @current\_user is an instance of `AccountProxyInterface`, so for example, you can check the user has some user permissions with `$this->accountProxy->hasPermission()`.

# Answer
> 10 votes
You can not get the current user in getSubscribedEvents()

That is not possible and not needed. There is no container at this point.

The only thing you may do in there is returned a list of events you want to register to. This information is then stored in the compiled container and must be identical for all requests, it must not be conditional.

Any logic needs to be inside the methods you register there.

# Answer
> 2 votes
You have to use namespace for load the current user object.

```
// Load the current user.
$user = \Drupal\user\Entity\User::load(\Drupal::currentUser()->id());

// get field data from that user

$email = $user->get('mail')->value;
$name = $user->get('name')->value;

```

---
Tags: users, 8
---


# Question
Title: How do I limit the access basing on the user role?
How do I use an access callback to limit the access basing on the user role?

For example, in my site I have the following roles:

1. Administrator
2. Authenticate User
3. Anonymous user
4. Teacher

I want to make a particular page available only to the users who have the *Teacher* role. How can I achieve this?

```
function form_test_menu() {
  $items['programme_reg'] = array(
    'title' => 'Approved Programmes Registration',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('form_test_form'),
    'access callback' => 'user_access',
    'access arguments' => array('Teaching')
  );

  return $items;
}

```

My code is not working.

# Answer
user\_access function takes permission name as an argument you can not pass user role name to it.

Here is how you can achieve this:

```
function MYMODULE_menu() {
  $items = array();

  $items['programme_reg'] = array(
    'title' => 'Approved Programmes Registration',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('MYMODULE_form_test_form'),
    'access callback' => '_MYMODULE_check_user_role',
  );

  return $items;
}

function _MYMODULE_check_user_role() {
  $account = $GLOBALS['user'];

  // Assuming that RID 4 is Teacher.
  // You can also check for role name in $account->roles array.
  return (isset($account->roles[4]) ? TRUE : FALSE);
}

```

Assuming that user role **Teacher** has Role ID as 4, you can check and return TRUE/FALSE in your own custom access callback. You can also check using Role Name instead of Role ID, see **here** for more details.
> 0 votes

# Answer
You have to implement hook\_permission

e.g.,

```
function MyModule_permission() {
  return array(
    'teaching' => array(
      'title' => t('Teaching my module'),
      'description' => t('Perform teaching tasks for my module.'),
    ),
  );
}
function form_test_menu() {
    $items['programme_reg'] = array(
        'title' => 'Approved Programmes Registration',
        'page callback' => 'drupal_get_form',
        'page arguments' => array('form_test_form'),
        'access callback' => 'user_access',
        'access arguments' => array('teaching'),
    );
    return $items;
}

```

After that, you can give access from permission page to any role
> 0 votes

# Answer
The code is wrong because the access callback used (`user_access()`) accepts a user permission string as argument, not a role name. To check the role the currently logged in user has, you need your own access callback. I would rather user permissions, since this would permit me not to alter the code in my module, in the case I need to check for more roles.

If I were asked to check for roles, I would use the following code, which runs on Drupal 7.36 and higher.

```
function form_test_menu() {
  $items['programme_reg'] = array(
    'title' => 'Approved Programmes Registration',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('form_test_form'),
    'access callback' => 'form_test_check_role',
    'access arguments' => array('Teaching')
  );

  return $items;
}

function form_test_check_role($role_name) {
  if ($role = user_role_load_by_name($role_name)) {
    return user_has_role($role->rid);
  }

  // The role doesn't exists; return FALSE as safe value.
  return FALSE;
}

```
> 0 votes

---
Tags: 7, users, routes
---


# Question
Title: How do I get the login form submitted values in hook_user_login()?
Since `hook_user_login()` in Drupal 8 has only 1 arg, how can I get the values submitted in the form? In other words, what is the equivalent of `$edit['input]['element_name']` I would use in Drupal 7?

# Answer
> 0 votes
If you need values from the submitted form, you should use `hook_form_alter()` to add a new form submission handler to the form, and get the submitted values when the form is submitted. `hook_user_login()` has never meant to be used to do anything on form values, but merely to inform modules that a user has been logged in.
Actually, you could not even know which form has been submitted because `hook_user_login()` is invoked from `user_login_finalize()`, which is called from the following methods:

---
Tags: 8, hooks
---


# Question
Title: Ensure registered users can publish nodes only after paying some money
Is there a way to charge registered users who publish a node in a Drupal 8 site?

If I'm not wrong, the pricing process should be easier as Web services are now part of the core in Drupal 8.

Pricing should be through Paypal.

# Answer
The pre-existing solutions ( Commerce Node Checkout, UC Node Checkout, Pay-per-node) for this problem haven't been ported into D8.

If one of the pre-existing solutions covers your use case well, you could help port it to D8 (Commerce 2.x is likely to have a stable release this year). Otherwise, you're looking at some sort of custom solution involving involving modifying the node form workflow and PayPal integration.
> 2 votes

---
Tags: 8, payment-gateways
---


# Question
Title: How to access current amount of earned userpoints in a Rules Condition?
I have no access from Rules to \[points\] field or any userpoints field (User points module).

I have enabled: Rules, Rules scheduled, Rules\_ui, Userpoints, Userponints\_rules\_integration, Userpoints\_role (from userpoints\_contrib),

I have done un/installed several times one by one modules mentioned with clear cache and cron in between and nothing, no access to userponits fields.

My event is "before saving content", in the **Rules Conditions** I have "`User has a role-->auth-user`", also in **Rules Conditions** I have "`content is of type-->My custom contentype`" in that order (I have changed that order with no results).

I need to update userponits field value before (preferred) or after a node is saved.

I tried also via Rules Components with an element "`User has a role-->auth-user`", same thing: ***no access to Userpoints fields***.

I have another rule applied and reacting on Rules Event: “After saving a new user account” and there YES I have access to those fields.

Any ideas? Reference module? Do I have to implement a hook in template file to load current user? Do I need a custom module? I've seen all the node.one screencasts about Rules several times. And I have read many post in here, and (think) I’ve done everything right, but no success.

Any suggestions?

In case that your suggestions are: hook or module (I’m not a skilled programmer) please submit some code within.

# Answer
> 1 votes
There doesn't seem to be some Rules Condition related to the current total user points for a user. Except by using custom PHP code as in this example (which you could use in a Rules Conditionn *Execute custom PHP code* condition, e.g. to do some type of comparison):

```
global $user;
$current_points = userpoints_get_current_points($user->uid, 'all');
if ($current_points < 0) {return TRUE;}

```

However, there is a Rules Action "***Load user points of a user***", whereas you can ask for either a specific category, or for all categories together. This Rules Action provides a Rules variable (for which you can specify its name and description) which contains the amount of user points for the requested category. You can then use this variable in subsequent Rules Actions.

If you then want to use that variable within a Rules Condition, you have 2 ways of doing so:

* Include the condition in a Rules Component, whereas you trigger the execution of that Rules Component via a Rules Action following the "Load user points of a user" (and passing the variable containing the amount of user points as a variable for the Rules Component).
* Use the Conditional Rules module, so that you can specify Rules Conditions within Rules Actions.

Here is a basic example that displays a message about the current total user points for a user, after the user performed an update of some node (= the Rules Event, which you can change to any Rules event that you want):

```
{ "rules_display_userpoints_after_updating_content" : {
    "LABEL" : "Display userpoints after updating content",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "userpoints_rules", "rules" ],
    "ON" : { "node_update" : [] },
    "DO" : [
      { "userpoints_rules_get_current_points" : {
          "USING" : { "user" : [ "site:current-user" ], "tid" : "all" },
          "PROVIDE" : { "loaded_points" : { "total_points" : "Number of points in all categories together" } }
        }
      },
      { "drupal_message" : { "message" : "You now have [total-points:value] points" } }
    ]
  }
}

```

Use the Rules UI to import the above rule in your own site if you want.

---
Tags: 7, rules, userpoints
---