# Question
Title: Ajax Form submit doesn't work second time
I'm loading the node/edit form in a block and I add ajax on submit.

I add the Ajax in the hook\_form\_alter.

```
$form['#prefix'] = '<div id="' . $form_wrapper . '">';
$form['#suffix'] = '</div>';
$form['actions']['submit']['#submit'][] = 'submitForm';
$form['actions']['submit']['#ajax'] = array(
  'callback' => 'my_ajax_callback',
  'wrapper' => $form_wrapper,
  'effect' => 'fade',
);

```

The SubmitForm:

```
function submitForm(array &$form, FormStateInterface $form_state){
  $input = $form_state->getUserInput();
  $form_state->setUserInput($input);
  $form_state->setRebuild(TRUE);
}

```

And the callback :

```
function my_ajax_callback(&$form, FormStateInterface $form_state, $form_id) {
   $form_state->setRebuild();
   return $form;
}

```

The first time works fine. The second time seems to work without any error but it doesn't submit my new data.

I checked this comment How can I implement AJAX form submission? but I don't know if I have to set the values to the form\_state. Also i use this callback for multiple content types. Should I check and set the value for each field? Is there a better way?

Thanks for your help!

------ EDIT -----

I added the submitForm function and now the second time I submit I get 'The content has either been modified by another user, or you have already submitted modifications. As a result, your changes cannot be saved.'.

Also, should I get/set each one of my fields or $input = $form\_state-\>getUserInput(); $form\_state-\>setUserInput($input); are enough?

-------- UPDATE ------

I managed to make it work for forms that I need to be empty after the ajax submit using the below code :

In hook\_form\_alter:

```
$form['wrapper'] = array(
    '#type' => 'container',
    '#attributes' => array('id' => $form_wrapper),
  );

$prefix = '<div id="' . $form_wrapper . '">';
$form['#prefix'] = $prefix;
$form['#suffix'] = '</div>';
$form['actions']['submit']['#submit'][] = 'Drupal\MY_MODULE\Plugin\Form\FormAlter::ajaxFormEntityFormSubmitEmptyForm';
$form['actions']['submit']['#ajax'] = array(
    'callback' => 'Drupal\MY_MODULE\Plugin\Form\FormAlter::ajaxFormEntityCallbackEmptyForm',
    'wrapper' => $form_wrapper,
    'effect' => 'fade',
);

```

And in the FormAlter.php :

```
/**
 * Rebuild the form - Empty form.
 */
 public static function ajaxFormEntityFormSubmitEmptyForm($form, &$form_state){
  $entity = $form_state->getBuildInfo()['callback_object']->getEntity();
  $entity_type = $entity->getEntityTypeId();
  $bundle = $entity->bundle();
  $new_entity = \Drupal::entityTypeManager()->getStorage($entity_type)->create(['type' => $bundle]);
  $form_state->getBuildInfo()['callback_object']->setEntity($new_entity);

  // Clear user input.
  $input = $form_state->getUserInput();
  $clean_keys = $form_state->getCleanValueKeys();
  $clean_keys[] = 'ajax_page_state';
  foreach ($input as $key => $item) {
    if (!in_array($key, $clean_keys) && substr($key, 0, 1) !== '_') {
      unset($input[$key]);
    }
  }

  $input['entity'] = $entity;
  $form_state->setUserInput($input);

  // Rebuild the form state values.
  $form_state->setRebuild();
  $form_state->setStorage([]);
}

/**
 * Ajax callback to handle just returns the form
 */
 public static function ajaxFormEntityCallbackEmptyForm(&$form, \Drupal\Core\Form\FormStateInterface $form_state) {
   if ($form_state->hasAnyErrors()) {
     return $form;
   }
   else {
     return $form;
    }
  }

```

Now I'm trying to do something similar but I want the form populated with the new values. So I created two new functions in FormAlter:

```
 /**
  * Rebuild the form.
  */
  public static function ajaxFormEntityFormSubmit($form, &$form_state) {
    $entity = $form_state->getBuildInfo()['callback_object']->getEntity();
    $entity_type = $entity->getEntityTypeId();
    $bundle = $entity->bundle();

    $new_entity = \Drupal::entityTypeManager()->getStorage($entity_type)->create(['type' => $bundle]);
    $form_state->getBuildInfo()['callback_object']->setEntity($new_entity);

    $input = $form_state->getUserInput();
    $input['entity'] = $entity;

    $form_state->setUserInput($input);
    if(!$form_state->hasValue('title')){
      $form_state->setValue('title',$entity->getTitle());
    }

    // Rebuild the form state values.
    $form_state->setRebuild(TRUE);
    $form_state->setStorage([]);
  }

 /**
  * Ajax callback to handle special ajax form entity magic.
  */
  public static function ajaxFormEntityCallback(&$form, \Drupal\Core\Form\FormStateInterface $form_state) {
  // If errors, returns the form with errors and messages.
  if ($form_state->hasAnyErrors()) {
    return $form;
  }
  // Else show the result.
  else {
    $userInputs = $form_state->getUserInput();
    $entity = $userInputs['entity'];
    $entity_type = $entity->getEntityTypeId();

    $response = new AjaxResponse();
    if ($entity_type == 'node') {
      $title = $entity->getTitle();
    }
    return $form;
  }
}

```

If I return the $form in the callback, the first time works fine but the second I'm getting two errors in the log:

> Drupal\Core\Database\IntegrityConstraintViolationException: SQLSTATE\[23000\]: Integrity constraint violation: 1048 Column 'title' cannot be null: INSERT INTO {node\_field\_data} (nid, vid, type, langcode, status, title, uid, created, changed, promote, sticky, revision\_translation\_affected, default\_langcode) VALUES (:db\_insert\_placeholder\_0, :db\_insert\_placeholder\_1, :db\_insert\_placeholder\_2, :db\_insert\_placeholder\_3, :db\_insert\_placeholder\_4, :db\_insert\_placeholder\_5, :db\_insert\_placeholder\_6, :db\_insert\_placeholder\_7, :db\_insert\_placeholder\_8, :db\_insert\_placeholder\_9, :db\_insert\_placeholder\_10, :db\_insert\_placeholder\_11, :db\_insert\_placeholder\_12); Array ( \[:db\_insert\_placeholder\_0\] =\> 201 \[:db\_insert\_placeholder\_1\] =\> 258 \[:db\_insert\_placeholder\_2\] =\> my\_estate\_details \[:db\_insert\_placeholder\_3\] =\> en \[:db\_insert\_placeholder\_4\] =\> 1 \[:db\_insert\_placeholder\_5\] =\> \[:db\_insert\_placeholder\_6\] =\> 5 \[:db\_insert\_placeholder\_7\] =\> 1500889059 \[:db\_insert\_placeholder\_8\] =\> 1500889066 \[:db\_insert\_placeholder\_9\] =\> 0 \[:db\_insert\_placeholder\_10\] =\> 0 \[:db\_insert\_placeholder\_11\] =\> 1 \[:db\_insert\_placeholder\_12\] =\> 1 ) in Drupal\Core\Database\Connection-\>handleQueryException()

And

> Drupal\Core\Entity\EntityStorageException: SQLSTATE\[23000\]: Integrity constraint violation: 1048 Column 'title' cannot be null: INSERT INTO {node\_field\_data} (nid, vid, type, langcode, status, title, uid, created, changed, promote, sticky, revision\_translation\_affected, default\_langcode) VALUES (:db\_insert\_placeholder\_0, :db\_insert\_placeholder\_1, :db\_insert\_placeholder\_2, :db\_insert\_placeholder\_3, :db\_insert\_placeholder\_4, :db\_insert\_placeholder\_5, :db\_insert\_placeholder\_6, :db\_insert\_placeholder\_7, :db\_insert\_placeholder\_8, :db\_insert\_placeholder\_9, :db\_insert\_placeholder\_10, :db\_insert\_placeholder\_11, :db\_insert\_placeholder\_12); Array ( \[:db\_insert\_placeholder\_0\] =\> 201 \[:db\_insert\_placeholder\_1\] =\> 258 \[:db\_insert\_placeholder\_2\] =\> my\_estate\_details \[:db\_insert\_placeholder\_3\] =\> en \[:db\_insert\_placeholder\_4\] =\> 1 \[:db\_insert\_placeholder\_5\] =\> \[:db\_insert\_placeholder\_6\] =\> 5 \[:db\_insert\_placeholder\_7\] =\> 1500889059 \[:db\_insert\_placeholder\_8\] =\> 1500889066 \[:db\_insert\_placeholder\_9\] =\> 0 \[:db\_insert\_placeholder\_10\] =\> 0 \[:db\_insert\_placeholder\_11\] =\> 1 \[:db\_insert\_placeholder\_12\] =\> 1 ) in Drupal\Core\Entity\Sql\SqlContentEntityStorage-\>save()

In case I return $response (which is what I prefer in order to be able to alter the message etc), the first time works fine but the second I get the message:

> The content has either been modified by another user, or you have already submitted modifications. As a result, your changes cannot be saved.'.

Apologies for the long message. Any idea/help will be helpful!

Thanks in advance.

# Answer
I managed to find the solution.

In my hook\_form\_alter :

```
$form['#attributes']['class'][] = $ajax_id;
$form['actions']['submit']['#submit'][] = 'Drupal\MY_MODULE\Plugin\Form\FormAlter::ajaxFormEntityFormSubmit';
$form['actions']['submit']['#ajax'] = array(
  'callback' => 'Drupal\MY_MODULE\Plugin\Form\FormAlter::ajaxFormEntityCallback',
  'wrapper' => $ajax_id,
  'effect' => 'fade',
);
$form['ajax_form_entity'] = [
  '#type' => 'hidden',
  '#value' => [
    'reload' => '.reload',
    'form_selector' => '.' . $ajax_id,
    'show_message' => TRUE,
  ]
];

public static function ajaxFormEntityFormSubmit($form, &$form_state) {
    $entity = $form_state->getBuildInfo()['callback_object']->getEntity();

    // Clear user input.
    $input = $form_state->getUserInput();
    // We should not clear the system items from the user input.
    $clean_keys = $form_state->getCleanValueKeys();
    $clean_keys[] = 'ajax_page_state';
    foreach ($input as $key => $item) {
      if (!in_array($key, $clean_keys) && substr($key, 0, 1) !== '_') {
        unset($input[$key]);
      }
    }

    // Store new entity for display in the AJAX callback.
    $input['entity'] = $entity;
    $form_state->setUserInput($input);

    // Rebuild the form state values.
    $form_state->setRebuild();
    $form_state->setStorage([]);
  }

```

And the callback:

```
public static function ajaxFormEntityCallback(&$form, \Drupal\Core\Form\FormStateInterface $form_state) {
    // If errors, returns the form with errors and messages.
    if ($form_state->hasAnyErrors()) {
      return $form;
    }
    // Else show the result.
    else {
      $userInputs = $form_state->getUserInput();
      $entity = $userInputs['entity'];
      $entity_type = $entity->getEntityTypeId();
      $configurations = $form_state->getValue('ajax_form_entity');

      $response = new AjaxResponse();

      // Get messages even if not shown.
      $status_messages = array('#type' => 'status_messages');
      $message = \Drupal::service('renderer')->renderRoot($status_messages);

      // Reload the form.
        $response->addCommand(new ReplaceCommand($configurations['form_selector'], $form));

      return $response;
    }
  }

```
> 0 votes

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


# Question
Title: What complications are there if I switch Mysql to MariaDB? Any Drush issues?
I have a heavy *Mysql* drupal 7 site and I was thinking about switching *Mysql* over to *Mariadb*, but I wasn't sure what issues I would run into. From what I'm reading *Mariadb* seems to be just a drop in replacement for *Mysql* and there doesn't seem much to fiddle with. I was wondering if *Mariadb* would affect drush commands?

# Answer
> 4 votes
Just wanted to chime in on this (albeit months late)... Have set up many Drupal sites in the past, decided to do things "better" this time and had MariaDB installed.

Everything works wonderfully (faster, cleaner, etc) with Drupal 7 EXCEPT for backup/restore :/ Always have to go directly into the db (whether through PHPMyAdmin, Heidi, or command line) and copy/export all of the tables.

Other than that, which there could be a number of reasons for happening, I highly recommend MariaDB. Less server resources used, D7 is much faster, etc etc.

# Answer
> 8 votes
As you say, Maria DB is a drop-in, completely transparent replacement for MySQL. Its releases coincide with the same major/minor version of MySQL so it's pretty much always in tandem as far as features are concerned. It reads the standard MySQL binary data files, uses the standard systen my.cnf, and even has a drop-in replacement for InnoDB.

The idea is that as far as your application is concerned it thinks it's connecting to a MySQL server. It uses MySQL drivers, issues full MySQL statements, and receives responses exactly as the MySQL server would send. Your app(s) won't know the difference.

I've been using Maria for a while now for Drupal sites (also using Drush extensively) and haven't had a single problem to date. If you're running \*nix upgrading is just a two minute job.

# Answer
> 0 votes
There are several issues to worry about. The Debian `unix_socket` *root access issue* is only one of them. I wonder that these issues are not discussed much. I assume many have their work flows and still stick with MySQL. That's why many of these issues are not well documented.

Related: MariaDB unix\_socket causes access issues under Debian - Drush can't login (A new post started to collect thoughts on this.)

---
Tags: 7, drush, database
---


title: Menu randomly does not display

text:
# Question
Title: Menu randomly does not display
Currently I maintain 10 different Drupal 7 web sites. They were designed and built by 3 different developers. These sites are running on 3 different platform types. Some are on a dedicated server, some on a VPS server and some on Pantheon. The dedicated and VPS servers are running Apache 2 and Pantheon uses Nginx. They are on various versions of the Drupal core, between 7.43 - 7.56.

All of these sites are experiencing the same issue, at some point the main navigation menu which displays on all the site pages just stops displaying. When this happens there are no errors in the Apache or Drupal logs.

On the dedicated server and the VPS servers clearing the Drupal cache (sometimes more than once) will bring the menus back. On the Pantheon servers, clearing the Drupal cache (even multiple times) does not work. The only way to do it is to clear the cache for the site in the Pantheon dashboard for that particular site.

The only common things between these sites are:

* There is nothing "special" about these menus. They were all designed using the standard Drupal utility in the Structure menu
* They are all sub-themed using the Drupal Bootstrap 3 as the base theme, currently at 7x-3.13

Google hasn't helped so I'm wondering if anyone has seen this error and if so, where I can start looking to correct the issue.

# Answer
The answer to this turned out to be unnecessary code.

The variable $primary\_nav is created when the Bootstrap theme is loaded. So when the cache is cleared it removes the initialized variable which then fails the If statement. The variable is initialized when the site is reloaded which I believe is what the Pantheon "Clear Caches" button does.

Since the If statement was not necessary (we're not using Bootstrap menus) removing it cleared up the issue.
> 0 votes

# Answer
Last time I encountered such thing, it was on Drupal 8. The culprit was caching. In a gist, if the page was viewed by a user who doesn't have access to that menu and that result gets cached, the page will be served from cache (without that menu) until the cache is cleared. Might want to disable page caching, then block caching, in admin to verify this. If you have any other caching mechanisms, try disabling those too. A good indicator that this may be the case is the fact that you need to clear an external cache for one of your setups.

Another culprit would be template-side logic (`template.php` or directly on the templates themselves). Since you're using D7, it's relatively easy to sneak in PHP into templates. You might want to review your templates for this.

Lastly... there's JS and CSS. You might want to do a View Source to see if the markup is actually there, but just removed by JS or hidden by CSS. Due to Drupal's steep learning curve, it's very tempting to just do everything in JS and CSS. Also, if the menu is dynamically generated or enhanced by a script, a broken script might have interfered with that generation/enhancement.
> 2 votes

---
Tags: 7, theming
---


# Question
Title: Difficulty running tests, --group option not being respected
I am trying to run a `BrowserTestBase` based test in my own module, following the documentation on drupal.org.

No matter if I run the test from PHPStorm or command line, I get the same error:

```
vagrant@local:/var/www/mysite/docroot$ ../vendor/bin/phpunit -c core/phpunit.xml --group mymodule
PHP Fatal error:  Trait 'Drupal\Tests\facets\Functional\BlockTestTrait' not found in /var/www/mysite/docroot/modules/contrib/search_api_solr/tests/src/Functional/FacetsTest.php on line 20
PHP Stack trace:
PHP   1. {main}() /var/www/mysite/vendor/phpunit/phpunit/phpunit:0
PHP   2. PHPUnit_TextUI_Command::main() /var/www/mysite/vendor/phpunit/phpunit/phpunit:52
PHP   3. PHPUnit_TextUI_Command->run() /var/www/mysite/vendor/phpunit/phpunit/src/TextUI/Command.php:100
PHP   4. PHPUnit_TextUI_Command->handleArguments() /var/www/mysite/vendor/phpunit/phpunit/src/TextUI/Command.php:111
PHP   5. PHPUnit_Util_Configuration->getTestSuiteConfiguration() /var/www/mysite/vendor/phpunit/phpunit/src/TextUI/Command.php:649
PHP   6. PHPUnit_Util_Configuration->getTestSuite() /var/www/mysite/vendor/phpunit/phpunit/src/Util/Configuration.php:878
PHP   7. PHPUnit_Framework_TestSuite->addTestFile() /var/www/mysite/vendor/phpunit/phpunit/src/Util/Configuration.php:1000
PHP   8. ReflectionMethod->invoke() /var/www/mysite/vendor/phpunit/phpunit/src/Framework/TestSuite.php:353
PHP   9. Drupal\Tests\TestSuites\FunctionalTestSuite::suite() /var/www/mysite/vendor/phpunit/phpunit/src/Framework/TestSuite.php:353
PHP  10. Drupal\Tests\TestSuites\TestSuiteBase->addTestsBySuiteNamespace() /var/www/mysite/docroot/core/tests/TestSuites/FunctionalTestSuite.php:22
PHP  11. PHPUnit_Framework_TestSuite->addTestFiles() /var/www/mysite/docroot/core/tests/TestSuites/TestSuiteBase.php:55
PHP  12. PHPUnit_Framework_TestSuite->addTestFile() /var/www/mysite/vendor/phpunit/phpunit/src/Framework/TestSuite.php:384
PHP  13. PHPUnit_Util_Fileloader::checkAndLoad() /var/www/mysite/vendor/phpunit/phpunit/src/Framework/TestSuite.php:310
PHP  14. PHPUnit_Util_Fileloader::load() /var/www/mysite/vendor/phpunit/phpunit/src/Util/Fileloader.php:38
PHP  15. include_once() /var/www/mysite/vendor/phpunit/phpunit/src/Util/Fileloader.php:56

Fatal error: Trait 'Drupal\Tests\facets\Functional\BlockTestTrait' not found in /var/www/mysite/docroot/modules/contrib/search_api_solr/tests/src/Functional/FacetsTest.php on line 20

```

I am not requiring Search API Solr in my test, nor do I have a clue why it is running it. Even if I specify `--testsuite unit`, I get the same error.

Here is the test I am trying to run, with a basic test step:

```
namespace Drupal\Tests\mymodule\Functional;

use Drupal\Tests\BrowserTestBase;

/**
 * Class AuthenticationTest.
 *
 * @group mymodule
 */
class AuthenticationTest extends BrowserTestBase {

  /**
   * Required modules.
   *
   * @var array
   */
  protected static $modules = ['user', 'node'];

  public function setUp() {
    parent::setUp();

    // set config for netforum
  }

  /**
   * The superuser should not authenticate to Netforum.
   */
  public function testAdminUserUsesDrupalAuthentication() {
    $account = $this->drupalCreateUser(['administer site configuration']);
    $this->drupalLogin($account);
  }

}

```

I am not sure why it is even looking at the Search API Solr module, but the test in question does try to use several files that do not exist:

```
use Drupal\Tests\facets\Functional\BlockTestTrait;
use Drupal\Tests\facets\Functional\ExampleContentTrait;
use Drupal\Tests\facets\Functional\TestHelperTrait;

```

I assume these are a part of the Facets module, which I do not have.

edit: This might be my issue.

# Answer
> edit: This might be my issue.

Yes.

The error happens during test *discovery*, first it has to find all tests and then limit it based on the group.

The easiest workaround is simply to specifiy your module, then you don't even need the group. phpunit will only discover test in that folder, which will not just avoid this problem it will also be *much* faster.

```
$ ../vendor/bin/phpunit -c core/phpunit.xml modules/custom/mymodule

```
> 2 votes

---
Tags: 8, testing
---


# Question
Title: An admin-friendly approach to establishing a permissions relationship between a file group and a user
The need is that when a new client project begins, that the client be given a username and password and have access to a specific piece of content that, in turn, gives access to download files, specific to that client, that were uploaded previously.

The ideal would be for the admin to have only these steps:

* Create the project content
* Create the project user
* Bulk upload the files

This is a nontechnical admin, so the need is to avoid granular steps for creating accounts or setting up folders, permissions, etc.

The concern for 1. is restricting access to the 'project'. I'm thinking that hooking content access and simply comparing the project name to the username (both would be the same).

The approach for 2. concerns linking the files uploaded with FileZilla to the content. It would be great if all files could be uploaded to the same folder, and then admin then do one selection to link several to the content/user. The less-desired approach would be uploading each project's files to a new folder.

I don't know if filefield\_sources would created multiple instances of a file field so that each file would be listed when viewing the content, or whether it would need to be using something like IMCE to let the user browse, then download, from a folder that is linked to the username like the content access was.

Another thought is OG, but that might be overkill, and it's not ported yet.

# Answer
**The concern for 1** : you can use Permissions by field

> By adding fields of type Permissions by fields, you can manage access to the node hosting these field by referencing other entity and specifiy which access type you want to grant (none/standard permission, view, update, delete) for users which reference same entities (node, term, role or other users). You can also grant access to the node directly per user if needed.

**The approach for 2** : (without using Fillezilla, but only backoffice) You can use Plupload to upload to upload files (pdf, jpeg...) massively through a content type  .After, you can link "file" content type to a project with a field entity reference in your content type "project". Add a "permission field" in your content type "file" to restrict access.

I dont know if I answer your question correctly
> 1 votes

---
Tags: files
---


# Question
Title: The standard method for adding css classes to twig templates
What is the standard method for adding classes in twig template?
I'm going straightly to the main subject point:

**Scenario-1:**
I have some classes and I want to collect them in a group and add this group to the existing group that added before:
I try below code but it seems that something is wrong.

```
{%
  set classes = [
    'block',
    'block-' ~ configuration.provider|clean_class,
    'block-' ~ plugin_id|clean_class,
  ]
%}

{%
  set my-classes = [
    'class-name-1',
    'class-name-2',
    'class-name-3',
    'class-name-4',
  ]
%}
<div{{ attributes.addClass('classes my-classes') }}>

```

What tips should I consider for a class group name, For example, Is it important to follow `PHP` variables name convention, Can I use hyphen character in class group names?

**Scenario -2:**
I have few classes names and I want to add theme straightly to default added classes, like below:

`views-view-unformatted:`

```
<div {{ row.attributes.addClass(row_classes 'class-name-1 class-name-2') }}>

```

# Answer
Your variables `classes`and `my_classes` are arrays. You could merge them:

```
{{ attributes.addClass(classes, my_classes) }}

```

Or add them one by one:

```
{{ attributes.addClass(classes).addClass(my_classes) }}

```

Or merge an array constant directly:

```
{{ row.attributes.addClass(row_classes, ['class-name-1', 'class-name-2']) }}

```

Or single classes:

```
{{ row.attributes.addClass(row_classes, 'class-name-1', 'class-name-2') }}

```

According to the coding standards https://twig.symfony.com/doc/2.x/coding\_standards.html you should use underscores in variable names.
> 5 votes

---
Tags: theming, 8
---


# Question
Title: How to implement Page not found (404) for unpublished content?
On my site, some nodes are unpublished forever instead of being deleted. I'd like to return Page not found (404) for anonymous trying to access unpublished node pages instead of Access denied (403). It's not about displaying a different message to the user, but rather about returning the 404 error code (important for bots).

So I've added the following to my module:

```
function mymodule_init() {
global $user;

  $normal_path = current_path();
  $parts=explode('/', $normal_path);
  $nid_part = $parts[1];
  $node = node_load($nid_part);
  if (!isset($node)) {
    return;
  }
  if (($node->status == 0) &&
    ($node->nid == $nid_part) &&
    ($user->uid == 0)) {
    drupal_not_found();
  }
}

```

But I still get Access denied as anonymous user on unpublished pages. How to implement it?

# Answer
> 7 votes
You should be able to do it with Rules:

> The Rules module allows site administrators to define conditionally executed actions based on occurring events (known as reactive or ECA rules). It's a replacement with more features for the trigger module in core and the successor of the Drupal 5 workflow-ng module.

Using Rules...

Event: Content is being Viewed (by content type if you desire)

Condition: Content is Published, Negate

Event: Redirect to custom 404 page

This requires that you set up a custom 404 page, but most people do that anyways, and core takes care of everything else.

Specify 403 and 404 error pages for more info on setting up a custom 403 and 404 page

# Answer
> 2 votes
My solution was to allow access to unpublished nodes, but then return a 404 result before rendering the page. If you have other modules controlling or depending on `node_access()`, this solution may not be for you.

```
/**
 * Implements hook_node_access().
 *
 * Allow users to view unpublished nodes, but modify them later to return 404
 * in hook_view_node_alter().
 */
function MODULE_node_access($node, $op, $account) {
  if ($op == 'view') {
    return NODE_ACCESS_ALLOW;
  }

  return NODE_ACCESS_IGNORE;
}

/**
 * Implements hook_node_view_alter().
 *
 * Provide a 404 page for unpublished nodes.
 * Access is allowed through hook_node_access().
 */
function MODULE_node_view_alter(&$build) {
  $node = $build['#node'];
  if ($node->status == NODE_NOT_PUBLISHED) {
    drupal_not_found();
    drupal_exit();
  }
}

```

My use case was much more limited, and so I was able to limit `hook_node_access()` to only affect permissions for anonymous users, and then have `hook_node_view_alter()` ignore logged in users.
I also inlined code from `drupal_deliver_html_page()` in order to provide a custom 404 message instead of the site-wide page given by `drupal_not_found()`

# Answer
> 1 votes
1. Use the view\_unpublished module to grant access to unpublished nodes for anonymous users. - https://www.drupal.org/project/view\_unpublished
2. Add this to your module:

```
    /**
     * Implements hook_init().
     */
    function MYMODULE_init() {
      // For anon users, show a 404 for unpublished content instead of a 403.
      if(user_is_anonymous() && ($node = menu_get_object()) && $node->status == NODE_NOT_PUBLISHED) {
      drupal_not_found();
      drupal_exit();
      }
    }

```

# Answer
> 0 votes
I have used Hook\_preprocess to direct them to the 'page not found' page.

I was able to redirect them to the 404 page by the following code. hope this helps for someone in future.

This was written for a Drupal 6 site. I have slightly modified @camcam's code for drupal 6. you'll be able to use his code for drupal 7 and use drupal\_exit() for exit() method.

```
function Hook_preprocess_page(&$vars) {
  global $user;

  if ($vars['title'] == 'Access denied') {
    $normal_path = $_GET['q'];
    $parts=explode('/', $normal_path);
    $nid_part = $parts[1];
    $node = node_load($nid_part);

    if (!isset($node)) {
      return;
    }

    if (($node->status == 0) &&
      ($node->nid == $nid_part) &&
      ($user->uid == 0)) {
      drupal_not_found();
      exit();
    }
  }
}

```

cheers. this is my first post here.

# Answer
> 0 votes
I've always used this: https://www.drupal.org/project/unpublished\_404

It is currently unmaintained (and in the process of getting a new maintainer) due to a security issue, but there is a patch available in the Issues forum for this module.

https://www.drupal.org/node/2752665#comment-12157403

---
Tags: 7, hooks, users
---


title: Use template file from module

text:
# Question
Title: Use template file from module
I did this in my custom module:

```
/**
 * Implements hook_theme().
 */
function my_module_theme() {
  return [
    'my_module' => [
      'template' => 'my-module'
    ],
  ];
}

/**
 * Implements hook_theme_suggestions_HOOK_alter() for form templates.
 *
 * @param array $suggestions
 * @param array $variables
 */
function my_module_theme_suggestions_block_alter(array &$suggestions, array $variables) {
  // Block suggestion for specific block bundle.
  if (isset($variables['elements']['content']['#block_content'])) {
    $block_bundle = $variables['elements']['content']['#block_content']->bundle();

    if ($block_bundle = 'my_block_bundle') {
      array_splice($suggestions, 1, 0, 'my_module');
    }
  }
}

```

I already created this block bundle in the module, so I want to use my template from module (my-module.html.twig in my\_module/templates) for all blocks in this bundle, but with this code all my blocks in this bundle disappeared.

What I'm doing wrong here?

# Answer
I haven't checked the rest of the code but

```
if ($block_bundle = 'my_block_bundle') {

```

should be

```
if ($block_bundle == 'my_block_bundle') {

// you could also use
$suggestions[] = 'your_suggestion' // instead of the splice

```
> 0 votes

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


# Question
Title: Is it possible to display more than one node in a page?
I am trying to display two nodes in Drupalgap.

```
//page_callback
function tung_intro_page() {
  var display_page = '<body>' + '<div id="my_node_13"></div>';
  display_page += '<div id="my_node_3"></div>' + '</body>';
  return display_page;
}

function tung_intro_pageshow() {
//  drupalgap_alert('My pageshow event has been called!');
 try{
        var nid = 13;
        node_load(nid, {
        success:function(node){
         var title = node.title;
         var content = node.content;
         //var whole = html(title) + html(content);
         $('#' + 'my_node_' + nid).html(content).trigger('create');
          }
        });
        nid = 3;
        node_load(nid, {
        success:function(node){
         var title = node.title;
         var content = node.content;
         $('#' + 'my_node_' + nid).html(content).trigger('create');
          }
        });
  }
  catch (error) { console.log('tung_intro_pageshow - ' + error); }
}

```

This only shows the content of the last node. How can I show both the nodes?

# Answer
From our comment conversation...

Try this in your `pageshow` handler:

```
function tung_intro_pageshow() {

  // Load the fist node and inject it.
  var nid = 13;
  node_load(nid, {
    success:function(node) {

      var title = node.title;
      var content = node.content;
      $('#' + 'my_node_' + nid).html(content).trigger('create');

      // Load the second node node and inject it.
      nid = 3;
      node_load(nid, {
          success:function(node){

            var title = node.title;
            var content = node.content;
            $('#' + 'my_node_' + nid).html(content).trigger('create');

          }
      });

    }
  });
}

```

Not the most elegant solution, but a workaround nonetheless. A more ideal solution is dependent on the outcome of this: https://www.drupal.org/node/2601764
> 1 votes

---
Tags: javascript
---


title: NID in new created node title

text:
# Question
Title: NID in new created node title
I don't like second `node_save`. But I need `nid` for title.

```
$node = new stdClass();
$node->type = 'bill';
node_object_prepare($node);
$node->uid = $user->uid;
$node->field_body['und'][0]['value'] = $bodytxt;
$node = node_submit($node);
node_save($node);

$node->title = 'Bill # '.$node->nid;
node_save($node);

```

Is there more elegant way?

# Answer
> Is there more elegant way?

Not really - the NID doesn't exist until the node has been saved the first time, so there is no way around this if you want to save the node title.

However, you could just add the NID to the title when the node is loaded:

```
function hook_node_load(&$nodes, $types)
{
  foreach($nodes as $node)
  {
    if($node->type == 'my_type')
    {
      $nodes[$node->nid]->title = '#Bill ' . $node->nid;
    }
  }
}

```
> 2 votes

---
Tags: 7
---


title: Using Drupal Queue

text:
# Question
Title: Using Drupal Queue
I think I am close to getting a queue to work with the Drupal 7 Queue API. I have some code that returns a value to me that I want to retrieve on cron.

```
function ...{
  $guid_to_enqueue = $guid;
  //Add GUID into the queue so we can work with it on cron
  $queue = DrupalQueue::get('custom_application_guid_queue');
  $queue->createQueue();
  $queue->createItem($guid_to_enqueue);
}

```

I then have

```
function custom_application_cron_queue_info() {
  $queues[ 'custom_application_guid_queue' ] = array(
    'worker callback' => '_custom_application_guid_item',
    'time' => 30,
  );
  watchdog('custom_application_ques_on_cron',  '<pre>' . print_r($queues, TRUE) . '</pre>');
  return $queues;
}

```

I think the problem is when I try and use the callback. I am not sure how to iterate over my data that is in the queue. I know it is in the queue using Drush and if I use Watchdog() with $guid\_to\_enqueue I can see the right value in the variable.

```
function _custom_application_guid_item($queues) {
 foreach($queues as $quid_item) {
   watchdog('custom_application_guid_item_foreach', $quid_item);
 }
}

```

Any help with figuring out what I am doing wrong here is greatly appreciated. I have also tried getting the number of items in the queue but nothing is getting that far in my code.

I will add that I will rarely have more than two items in the queue if that changes anything.

Thanks, Josh

# Answer
Your queue worker callback takes a single queue item to process at a time, and you do not invoke it manually because you have setup cron to do it for you.

Drupal cron will try to process as many queue items within the `time` that you provided in `hook_cron_queue_info()`, and this should be first in, first out by the time the queue item was added and then by the primary key.

So in your cron queue worker callback you should expect the data that you enqueued.

```
function _custom_application_guid_item($guid_enqueued) {
  // Do something with $guid_enqueued
}

```
> 2 votes

---
Tags: queue
---


# Question
Title: How to add UniqueField constraint on integer field?
The title basically says it all. I have the following field definition in an Entity class:

```
$fields['code'] = BaseFieldDefinition::create('integer')
        ->setLabel(t('unique code'))
        ->setDescription(t('Some unique code'))
        ->addConstraint('UniqueField')
        ->setTranslatable(false)
        ->setRequired(true)
        ->setDisplayOptions('view', array(
            'label' => 'above',
            'weight' => 4,
        ))
        ->setDisplayOptions('form', array(
            'weight' => 4,
        ))
        ->setDisplayConfigurable('form', true)
        ->setDisplayConfigurable('view', true);

```

Creating a new entity in the UI works as expected as long as I do not set the code value to something already in the database. However, as soon as I try to create a new entity with an already existing value for code (thus triggering a constraint violation), I get the following error:

```
The website encountered an unexpected error. Please try again later.
TypeError: Argument 1 passed to Drupal\Core\Form\FormState::setError() must be of the type array, null given, called in /var/www/html/web/core/lib/Drupal/Core/Field/WidgetBase.php on line 454 in Drupal\Core\Form\FormState->setError() (line 1156 of core/lib/Drupal/Core/Form/FormState.php).

```

If I change the field definition to use a string instead everything works as expected:

```
$fields['code'] = BaseFieldDefinition::create('string')
        ->setLabel(t('unique code'))
        ->setDescription(t('Some unique code'))
        ->setSetting('max_length', 5)
        ->addConstraint('UniqueField')
        ->setTranslatable(false)
        ->setRequired(true)
        ->setDisplayOptions('view', array(
            'label' => 'above',
            'weight' => 4,
        ))
        ->setDisplayOptions('form', array(
            'weight' => 4,
        ))
        ->setDisplayConfigurable('form', true)
        ->setDisplayConfigurable('view', true);

```

So the question is how do I add a unique constraint for an integer field? Is there another validation class I can use, am I setting up my integer field definition wrong thus causing the error, or?

# Answer
This seems to be an open bug in core. I have filed a bug report containing a makeshift solution on Drupal.org: https://www.drupal.org/node/2784015/

Edit the file 'core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/NumberWidget.php' to let the errorElement function `return $element[0]['value']` instead of `$element['value']`. So far, I don't understand why it is happening.
> 0 votes

# Answer
It might be a core bug, I believe it should be fairly easy to overcome. The addConstraint method takes a second parameter with options:

```
public DataDefinition::addConstraint($constraint_name, $options = NULL)

```

This defaults to `NULL`, but according to the documentation can also be an array. Your error indicates that an array is expected. So you should be able to use this instead:

```
->addConstraint('UniqueField', [])

```
> 0 votes

---
Tags: 8, entities
---


# Question
Title: Is there any way to reuse the same file or image?
Is there any way to reuse the same file or image while uploading I just worry about having multiple/duplicate image files on the server - in time it could get full and slow down the server.

I have used FileField Sources module but I think its not compatible with drupal 8 its not showing configuration setup, any other alternative?

# Answer
> 3 votes
**The short answer is:** Yes!

And you also don't have to wait till 8.4 comes out (however that will make things easier).

I suggest you the following modules:

**How is it working?** (*in nutshell*):

Instead of using "image fields" you will have reference fields to media entities (Media Entity), which provides you the opportunity to use such an entity multiple times, also by other contents. Media Entity Image gives you just a predefined bundle to media entity, which is a nice to have. Media entity browser gives you a widget, which opens a modal, where you can select from existing media images, or upload a new one!

---

Drupal 8.4 will provide this as a core feature, which will make it more stable and easier to use. But until then: these three modules also do the job.

# Answer
> 1 votes
I got into this question while searching for a way to reuse the same image during *programmatic* creation of multiple nodes. It is not completely clear to me if the question is about creating nodes programmatically or from the Drupal backend, but I think it could be useful for someone if I post the solution I found to the programmatic use case too (you can skip this part and go to the manual solution if you are not interested to coding).

**Programmatic Solution**

1. assuming that you already have the image file on your local file system, you have to create an image object first:

`$imgUri = file_build_uri("import/default_image.jpg");
$imgFile = File::Create(['uri' => $imgUri]);
$imgFile->save();`

In the above code I assume that you have uploaded (e.g. via FTP) a file named "default\_image.jpg" to the subdirectory "import" in your public file system, but of course you can place it wherever you want and use the name you prefer, simply change the argument to "file\_build\_uri" accordingly.

2. for each node you want to create, if you now set the $imgFile object as the value of an image field the system will reuse the same image file. Find below a sample code for creating one node with a field image:

`use Drupal\node\Entity\Node;
...
$node = Node::create([
 'type' => 'article',
 'title' => 'Test article',
 'field_image' => $imgFile,
 ...
 ]);
$node->save();`

**Manual Solution**

Finally I would like to give a suggestion for the *manual* use case, that is if we need to upload the same file multiple times (e.g. in a node creation form) and do not want the system to create multiple copies of the same file on disk. In this case the solution that works for me is to:

1. store the image as a separate node, e.g. by creating a content type or taxonomy just for storing "default images"
2. instead of uploading the image to the target content type, we refer to the image stored at point 1 using an entity reference field. So basically we wouldn't have an image field at all in our target content type, and would replace it with an entity reference field which references one of the default images.

Needless to say the solution above is suitable for when you really have a ton of files to upload and want to avoid the disk being filled-in with duplicates of the same image. If you only have a bunch of images I think there is no better solution than the easiest one: accepting the duplications and living with them :)

Note that the latest modules for Drupal 8 which "automagically" resolve this problem are based exactly on this technique. So you can also download *Media Entity* for example and rely on it (along with the supporting *Media Entity Browser* and other useful sub-modules) to do the job for you.

---
Tags: 8
---


# Question
Title: How do I label of Field Group htab that has Hide as prefix?
I have a custom module that I have coded in a Horizontal tabs (htabs) group and a number of individual tabs (htab) to break up my node form. When I open the add form the tabs are showing with the label having a prefix of "Hide". For example one of my tabs I have assigned the label as "Log Entries". When the form is opened it is showing as "Hide Log Entries".

I don't want the prefix and can't seem to find how to turn it off. Any help would be appreciated.

# Answer
I have resolved my issue. I hade the collapse javascript included in my form alter function and it was adding in the "Hide" prefix to the labes.
> 0 votes

---
Tags: entities
---


# Question
Title: Field formatter only displays file name not link to file
I installed Drupal 8.3.5, no extra plugins or themes. I have added in the "base page" (structure/type) a field (file\_in) to upload files.

If I add a new page (node/add/page) and also load a file in file\_in (file2.txt), the new page displays me the link to the file.

Then I add a new field called file\_ext as entity reference (file type). If I add a new page (node/add/page) and put in file\_ext a reference to the file2.txt, I see the new page, but with only the label name of the file, not its link.

File module is enabled, version Drupal 8.3.5 (new and clean).

# Answer
> 1 votes
You should go to (*structure -\> content types -\> page -\> manage display*):

**/admin/structure/types/manage/page/display**

and set your fields format and its corresponding settings the way you prefer.

---

Further reading on the topic: here

Youtube tutorial: here

---
Tags: files
---


title: Sort commerce view by calculated price

text:
# Question
Title: Sort commerce view by calculated price
I use commerce, search api and facets. I have a "shop" view with indexed products. It works good and I can filter and sort the view using "search api" facets and "search api" sorts fields.
I can sort the view by an indexed field, like product base price which is a field of a product object. The problem is this base price could change due to rules (discounts, offers, etc), and then, the final price for the customer could be different. I need to sort the "shop" view by the final customer prices, but I don't know how to do it with this indexed view. Any sugestion? TIA

# Answer
Although I didn't find how to do it with views, I have found an alternative solution using views hooks.
First I have to unset the pager, because I need all records to sort. Only if it's this view and this sort criteria.

```
function MYMODULENAME_filters_views_pre_execute(&$view) {
  if (('shop' == $view->name) && ($view->exposed_raw_input['sort_by'] == 'field_product_commerce_price_amount_decimal_desc')) {
    $view->query->set_limit(NULL);
    $view->query->set_offset(NULL);
}}

```

After this, I reorder the $view-\>results as I need in another hook:

```
function MYMODULENAME_views_post_execute(&$view) {

    if (('shop' == $view->name) && ($view->exposed_raw_input['sort_by'] == 'field_product_commerce_price_amount_decimal_desc')) {

    $milista = array();
    foreach($view->result as $clave=>$valor) {
        $prdd = node_load($valor->entity);
        $producto = commerce_product_load($prdd->field_product['und'][0]['product_id']);
        $price = commerce_product_calculate_sell_price($producto);
        array_push($milista,array(0=>$clave, 1=>$valor->entity, 2=>$price['amount']));
    }

    if ($view->exposed_raw_input['sort_order']=='ASC') $ordenado = SortByKeyValue($milista, 2);
    else $ordenado = SortByKeyValue($milista, 2, SORT_DESC);

    $listafinal = array();
    foreach($ordenado as $datos) {
        array_push($listafinal, $view->result[$datos[0]]);
    }

    // Now, the pager
    $itemsperpage = 16;  // default items per page
    if ($view->exposed_raw_input['items_per_page']) $itemsperpage = $view->exposed_raw_input['items_per_page'];
    $page=1;
    if (isset($view->query->pager->current_page)) $page =  $view->query->pager->current_page;

    $indice = $itemsperpage * $page;

    if (($indice>sizeof($listafinal)) && ($itemsperpage!=0)) $indice = sizeof($listafinal) / $itemsperpage;

    $listafinal = array_slice($listafinal,$indice,$itemsperpage);

    // Lastly, I change the view results
    $view->result = $listafinal;
  }
}

```

To sort the array, I used the next functions:

```
function SortByKeyValue($data, $sortKey, $sort_flags=SORT_ASC)
{
    if (empty($data) or empty($sortKey)) return $data;

    $ordered = $data;

    if ($sort_flags==SORT_ASC) uasort($ordered,'cmpasc');
    else uasort($ordered,'cmpdesc');

    return $ordered;
}

function cmpasc($a, $b) {
    if ($a[2] == $b[2]) {
        return 0;
    }
    return ($a[2] < $b[2]) ? -1 : 1;
}

function cmpdesc($a, $b) {
    if ($a[2] == $b[2]) {
        return 0;
    }
    return ($a[2] > $b[2]) ? -1 : 1;
}

```

I hope this solution could help someone with my same use case.
> 0 votes

---
Tags: views, commerce, search
---


# Question
Title: How do I create a configuration sync folder?
I've inherited a Drupal 8 site but it has no config\_HASH folder with it which means that the majority of admin paths throw an exception.

How do I generate a new configuration folder based on the current site?

# Answer
To generate a new config folder do the following:

In settings.php add the following line:

```
$config_directories['sync'] = 'dest/to/config-sync';

```

This is relative to your docroot or index.php file. My permission were set in a way that drupal could create this directory but you may have to create your own. Next you will want to populate your sync directory with active config. Run

```
drush cex -y

```

Now your active config can be version controlled and deployed to your other environments. Remember to make a **database backup first** before importing config.
> 1 votes

---
Tags: 8, configuration
---


title: Fill table with data on submit

text:
# Question
Title: Fill table with data on submit
I created a submit button in my config form.

```
$form['actions']['find_users']  = array(
        '#type' => 'submit',
        '#value' => t('Find users'),
        '#submit' => array('::find_users'),
      );

```

When I press on submit button, I need to create a table and fill it with the all users of my forum.

First, I created this function:

```
function find_users(array &$form, FormStateInterface $form_state) {
        $header = [
                    'username' => t('username'),
                    'registered' => t('registered'),
                      'email' => t('e-mail'),
                    'ip' => t('ip'),
                      'last_visit' => t('last visit'),
                  ];

                  $form['table'] = array(
                    '#type' => 'tableselect',
                    '#header' => $header,
                    '#empty' => t('No users found'),
                  );
    }

```

But when I press on my submit button, table doesn't create. What should I do?

**For example**, I need to fill table with just the first record from users\_field\_data table (limit 1).

# Answer
You're missing `#options` property in your `tableselect` element, e.g.

```
$form['table'] = array(
  '#type' => 'tableselect',
  '#header' => $header,
  '#options' => $options,
  '#multiple' => FALSE,
);

```

See: Adding checkboxes to a table.
> 0 votes

---
Tags: forms
---


# Question
Title: Views relationship between user and custom created entity
I've an custom entity type : "*card*", witch has a property named "*owner*", an `entity_reference` to the owner of the card.

My custom entity is pretty basic and has been created trough Drupal Console.

If I create a view on *Cards* I can use the relationship to get the "owner" fields and properties accessible.

But if on a *Users* based view, the reverse relationship is not present : I can't access card information's from the owner.

Am-I missing something ? Do I have to set up this *reverse relationship* somewhere ?

Thanks in advance !

# Answer
> 4 votes
Ok ! finally found out !

I had to use the hook\_views\_data\_alter to put the relationship on the user :

```
/**
 * Implements hook_views_data_alter().
 */
function MYMODULE_views_data_alter(array &$data) {
  $data['users_field_data']['cards'] = [
    'title' => t("Users cards"),
    'help' => t("Link the users to their cards"),
    'relationship' => [
      'group' => t('Cards'),
      'label' => t("User cards"),
      'base' => 'cards', // database table
      'base field' => 'owner', //database field to join on
      'relationship field' => 'uid',
      'id' => 'cards',
    ],
  ];
}

```

---
Tags: 8, views
---


# Question
Title: Views contextual filter - Contains search with taxonomy field
I am searching with taxonomy terms, is there a way to do the search with anything that contains what i am searching for will be returned?

For example if i search `Amer` nothing will return, but i would like `America` to return in the results. I know that there is an option when you are just searching by a field, but i don't see it for taxonomy. Does anyone have any ideas??

**---EDIT---**

I do have the search set as an exposed filter too...

# Answer
As per my understanding exposed filter works for this requirement. So maybe you can try combining contextual filter with exposed filter.

You can use the Views Filter Harmonizer module for that. Here is a quote about it (from its project page):

> Views Filter Harmonizer solves an operational foible with the Views module regarding filtering.
>
> Normally, when a Views field has been assigned both an exposed filter and a contextual filter, then both filters get applied to the View's results set -- **always**. This is not configurable behaviour. It's hard-coded.
>
> As a consequence, contradictory search clauses easily occur, causing a counter-intuitive user experience with some White Screens of Disillusionment. Since the contextual filter sets the "bounds" for the page, any filtering by the visitor through the exposed filter on that page can only narrow down the results set, not broaden it. In other words the exposed filter appears not to be working properly.
>
> This small module allows you to have a contextual filter argument apply only when there is no corresponding regular (exposed) filter value present.
>
> This is most common on initial page load. After that the contextual filters will silently retreat and let the exposed filter values as selected by the visitor do their thing without interfering.
>
> This means that you can take advantage of friendly URLs using contextual arguments instead of ugly and verbose query parameters. Put the URLs anywhere on your site, in emails and in newsletters to take visitors to tailored Views pages. Having arrived there, visitors may then further filter these pages to their heart's content using the View's regular filters you exposed. And they won't experience any odd behaviour.
> 0 votes

# Answer
This might help: https://www.drupal.org/project/views\_argument\_substitutions

> Contextual Filters allow a View to be filtered based on arguments passed via URL or other embedded method (e.g. the View Reference module), but contextual filters are inflexible compared with normal filters (which allow for "contains," "begins with," "ends with," etc.).
>
> This module allows **contextual filter arguments to be used as replacement tokens** in filters and table arguments, so that passed-in arguments (such as from URLs or View Reference fields) can be used as values in normal View filters.
> 0 votes

---
Tags: 7, views
---


# Question
Title: How to eMail webforms to 2 alternating email adresses?
I got a Drupal 7 site with a working webform in it. Now I got 2 email addresses to send the mails to, we want to send them like so:

* Send 1st email to emailadress A.
* Send 2th email to emailadress B.
* Send 3th email to emailadress A again.
* Send 4th email to emailadress B again
* ... and so on.

Can someone help me how to do this or push me in the right direction?

I was thinking about something with the Rules module.

# Answer
> 2 votes
### 1. Userids with those eMail IDs

Assume that some userid exist for a user named X, with emailadress A, and similarly user Y for emailadress B.

### 2. Enable the Webform Rules module

Use the Webform Rules module to transform your Webform question to a Rules question. Some details about it (from its project page):

> This module adds rules integration on webforms.
>
> Did you ever want to react on webform submission using rules but couldn't find the proper event?
>
> Webform Rules makes it possible to catch webform submissions by rules and do whatever you'd like to do with it (meaning: do whatever rules let you do with it).

To get you going, have a look at this example rule (in Rules export format):

```
{ "rules_process_submitted_webform" : {
    "LABEL" : "Process submitted webform",
    "PLUGIN" : "reaction rule",
    "ACTIVE" : false,
    "OWNER" : "rules",
    "REQUIRES" : [ "rules", "webform_rules" ],
    "ON" : { "webform_rules_submit" : [] },
    "DO" : [
      { "mail" : {
          "to" : "[site:mail]",
          "subject" : "A new webform submission has occurred",
          "message" : "A new webform submission has occurred (with form-id \u0022[form-id:value]\u0022). It was submitted by the user with id = [user:id], name = [user:name] and eMail Id = [user:mail] ...",
          "language" : [ "" ]
        }
      }
    ]
  }
}

```

I intentionally did not include any Rules Conditions here, just to illustrate that by using this Rules Event (= a form is submitted), you do have access to a limited set of tokens related to the user who submitted the webform, such as `[user:id]`, `[user:name]` and `[user:mail]`.

### 3. Enable the Flag module

Use the Flag to create a flag for flagging users. Its purpose is to (automatically) indicate which of both users (X or Y) should receive the ***next*** eMail, i.e the next eMail should go to the user who is flagged at the time of the webform submission.

### 4. Create 2 custom rules

**a) Send an eMail to user X**

Create a 1st custom rule like so:

* Rules Event: a form is submitted
* Rules Condition: if user X is flagged
* Rules Actions:
    + Send an eMail to user X.
    + Unflag user X.
    + Flag user Y.

Note: you probably have to use "*switch to direct input mode*" multiple times (to be able to enter the `uid` of user X or Y).

**b) Send an eMail to user Y**

Create a 2nd custom rule like so:

* Rules Event: a form is submitted
* Rules Condition: if user Y is flagged
* Rules Actions:
    + Send an eMail to user Y.
    + Unflag user Y.
    + Flag user X.

Note: you probably have to use "*switch to direct input mode*" multiple times (to be able to enter the `uid` of user X or Y).

### 5. Perform an initial flagging of a single user

Decide which user (X or Y) should receive the very first eMail, and flag that user. After doing so, next time a webform is submitted the process to send those eMails will start. And as long as you don't flag either one, nothing will happen (as per the implemented Rules logic in step 4 ...).

Note: If you ever want to stop the process, just unflag the user (X or Y) that is flagged.

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


# Question
Title: Fast method to locate occurrences of SQL queries via code?
I'm reviewing some SQL queries made throughout a few modules, but to do that, I've been reading every line of code manually, which is time consuming.

Is there a term or phrase I could CTRL+F for to find out where the queries are occurring directly? Any packages I should be on the look for?

# Answer
> 1 votes
Try CTRL+F-ing for these:

1. `db_query`
2. `->query(`
3. `\Drupal\Core\Database\Connection::query()`
4. `\Drupal\Core\Database\Connection::defaultOptions()`

# Answer
> 1 votes
Try the Webprofiler module (part of Devel).

Enable the module and check the saved profiles by the Webprofiler module via `/admin/reports/profiler/list`. Select the `Database` option on the left and you should see the executed queries.

---
Tags: 8, database
---


# Question
Title: How do I set some script in the <head> section on a page?
I solved some question on field type generation and learned how to render my custom field. Now, I need to use an accessible audioplayer to play my songs. In my custom field formatter view function I set item\_output to render this custom field in an unordered list. Each item of this list is a link that calls a javascript function that plays automatically the song. Unfortunately, to use this player, I must set some script in header section of my page, and style css for this player. So, I need to set these scripts on ly in a page that displays this field. There is a way? Maybe in $element array returned from field formatter view function? I hope you can understand me, my english is very bad!

# Answer
The function drupal\_add\_js can solve your probleme. You can try this in custom module:

```
function my_module_init() {
     drupal_add_js(drupal_get_path('theme', 'MYTHEME') .'/my_file.js',
        array('type' => 'file', 'scope' => 'header', 'weight' => 1000)
      );
}

```

Look at this documention for use this function in diffrent way.
> 1 votes

---
Tags: 7, javascript
---


title: Test fails with custom configuration

text:
# Question
Title: Test fails with custom configuration
After creating a custom configuration for my module "module\_name.settings.yml" simpletest fails with this message:

> InvalidArgumentException: Invalid database prefix: in Drupal\Core\Test\TestDatabase-\>\__construct() (line 81 of /path/to/installation/core/lib/Drupal/Core/Test/TestDatabase.php)

I reinstalled my module and everything works. I load the configuration with the following code.

```
$config = \Drupal::config('module_name.settings');
$base = $config->get('module_name.variable');

```

Still, I can't run my tests. If I remove the content from my configuration, tests run again. I'm using Drupal 8.3.4, Apache 2.4.18, PHP 7.0.8, and MariaDB 10.1.25.

# Answer
Since your module provides a settings.yml file, it must also provide a mymodule.schema.yml file describing the config object that stores the settings.

The real error pertains to something along these lines, and not a database error:

```
The test did not complete due to a fatal error.
Exception Uncaught e ConfigSchemaCheck   86 Drupal\Core\Config\Testing\ConfigSc
    Drupal\Core\Config\Schema\SchemaIncompleteException: No schema for
    MODULENAME.settings in
    Drupal\Core\Config\Testing\ConfigSchemaChecker->onConfigSave() (line 86
    of
    /var/www/docroot/core/lib/Drupal/Core/Config/Testing/ConfigSchemaChecker.php).

```

By providing a schema.yml file, clearing cache and re-running the tests this should resolve itself.

Related:

You have to be careful of this one, because any contrib module that provides a settings.yml without a matching schema will throw the same error. It is confusing because you can install the module in your main application, but when you install it with a test, it will error out.

It will be easy to narrow down which ones, because it will be one that is listed in your required modules var (`protected static $modules = [...]`) which is how I stumbled upon the Menu Breadcrumb issue I mentioned.
> 3 votes

---
Tags: testing
---


# Question
Title: How can I create block for my custom form?
I create a custom form module. Now I want show my form in a block. How can I do this ?

Note: I create MymoduleBlock.php in /modules/my-module/src/Plugin/Block path with this code but not work:

```
<?php

namespace Drupal\my-module\Plugin\Block;

use Drupal\Core\Form\FormInterface;
use Drupal\Core\Block\BlockBase;

class MymoduleBlock extends BlockBase {
  public function build() {
    $form = \Drupal::formBuilder()->getForm('Drupal\my-module\Form\MymoduleForm');
    return $form;
   }
}

```

# Answer
The code in `MymoduleBlock::build()` is correct, and it is what Drupal core does in `UserLoginBlock::build()`.

```
  $form = \Drupal::formBuilder()->getForm('Drupal\user\Form\UserLoginForm');
  unset($form['name']['#attributes']['autofocus']);
  // When unsetting field descriptions, also unset aria-describedby attributes
  // to avoid introducing an accessibility bug.
  // @todo Do this automatically in https://www.drupal.org/node/2547063.
  unset($form['name']['#description']);
  unset($form['name']['#attributes']['aria-describedby']);
  unset($form['pass']['#description']);
  unset($form['pass']['#attributes']['aria-describedby']);
  $form['name']['#size'] = 15;
  $form['pass']['#size'] = 15;

```

What the block definition is missing is the annotation (the comment before the class) which allows Drupal to identify that class as plugin. See what Block API says. (Emphasis is mine.)

> Blocks are a combination of a configuration entity and a **plugin**. The configuration entity stores placement information (theme, region, weight) and any other configuration that is specific to the block. The **block plugin** does the work of rendering the block's content for display.
>
> Block plugins use **the annotations** defined by `\Drupal\Core\Block\Annotation\Block`. See the Annotations topic for more information about annotations.

In the block class I used as example, the annotation is the following one.

```
/*
 * @Block(
 *   id = "user_login_block",
 *   admin_label = @Translation("User login"),
 *   category = @Translation("Forms")
 * )
 */

```

Also, the machine name of module should not contain hyphens, which aren't allowed in PHP functions. That creates problems when you implement hooks, since the hook name is derived from the machine name of the module. For example, the implementation of `hook_page_attachments()` for your module would be `my-module_page_attachments()`, which is not an acceptable PHP function name.
If you think your module is not going to implement hooks, keep in mind that the majority of modules implements at least hook\_update\_N(), for which is also preferable not using capital letters in the module machine name.
> 6 votes

# Answer
Provided that you are posting all your code you are missing annotations in your Block class. Annotations are used by Drupal 8 to register plugins.

Check out this link to get started on custom blocks:

https://www.drupal.org/docs/8/creating-custom-modules/create-a-custom-block

Don't forget to clear your cache after creating your block plugin.

P.S. I see that you named your module 'my-module'. Dashes are not allowed in module names, use underscores. For more information about module naming please see: https://www.drupal.org/docs/8/creating-custom-modules/naming-and-placing-your-drupal-8-module
> 1 votes

---
Tags: 8, forms, blocks
---


title: Generate image URL from FID

text:
# Question
Title: Generate image URL from FID
I have a custom form in Drupal 8, which has a image upload field. I am storing the file ID of that uploaded image. Now I need to generate the URL of that image.

How can I achieve this?

# Answer
> 22 votes
Get the image file src (url)

```
$fid = 1;//The file ID
$file = \Drupal\file\Entity\File::load($fid);
$path = $file->getFileUri();

```

OR

```
$path = 'public://images/image.jpg';
$url = \Drupal\image\Entity\ImageStyle::load('medium')->buildUrl($file->getFileUri());

```

# Answer
> 1 votes
This way you can get your stored image file using fid in your custom module

```
$myconfig = \Drupal::config('yourmodule.settings');
$fid = $myconfig->get('image');

foreach ($fid as $key => $value) {
  $fid1 = $value;
}

$file = \Drupal\file\Entity\File::load($fid1);
$path = $file->getFileUri();

```

---
Tags: 8, media
---


# Question
Title: How can I add superscript character in a textfield
I am looking for a way to use superscript characters in a Drupal textfield. When I copy and paste from a Word document, Drupal changes it to plain text.

Expected Result: **m2**

Actual Result: **m2**

What’s the correct way to use the superscript in fields? How can I enable special character support?

# Answer
Solution for me. Instead of using a feature WYSIWYG, which make it kind of confusing on endless fields, I’ve decided to use Unicode superscripts.
> 1 votes

# Answer
On a vanilla drupal 7 site you can set the text format of the field to full HTML and use standard HTML to render the superscript.

For the paste from word functionality, I would recommend adding the WYSIWYG module and following the instructions to get a proper editor like ckeditor. Will be a world of difference.
> 0 votes

---
Tags: 7, entities
---


# Question
Title: Error after adding second CSS to ckeditor_stylesheets in mytheme.info.yml
Per https://www.drupal.org/node/2717985 and https://www.drupal.org/node/2589827

I added a second stylesheet to my functioning D8 site in `mytheme.info.yml`. File exists in same css dir as style.css which is loaded into ckeditor and working fine.

```
ckeditor_stylesheets:
- css/style.css
- css/ckeditor_specific.css

```

The whole contents of new CSS is

```
.fcx-inner-accordion-content {
    display:block;
}

```

Which is intended to show some normally hidden content for edits.

When the cache was flushed after the addition of the one line to the yml the site died with "The website encountered an unexpected error. Please try again later."

Repeat flushes got same error and removing the one line and flushing brought site back up.

What am I doing wrong?

# Answer
> 1 votes
I was committing a very foolish sin when I did not think to check the logs when error occurred. Thank you to @kiamlaluno for pointing this out.

Log of the error says quite clearly " YAML file cannot contain tabs as indentation" My editor was indenting with tabs automatically though the original stylesheet entry in YAML was indented with spaces.

Once removed all worked as intended.

---
Tags: theming, wysiwyg
---


# Question
Title: phpunit test: drupalGet a public node returns 404
Simply trying to get a node.

```
$this->drupalGet('node/25250');
$this->assertSession()->statusCodeEquals(200);

```

But this returns 404. I can browse to that node anonymously. Why is it returning 404?

# Answer
> 3 votes
BrowserTestBase do not run against your installation, they do a new installation and then run against that.

There is no content, no modules, pretty much nothing there by default, everything you need to need to create and install.

If you're looking for a way to run tests against your installation, you might be able to override the set up and tear down process. Or look at using behat: http://behat-drupal-extension.readthedocs.io/en/latest/intro.html

---
Tags: 8, testing
---


title: File always save with underscore

text:
# Question
Title: File always save with underscore
I have a custom form where admin users upload a CSV file. Everything is working fine, but the file is saved with an underscore. For example, I upload **callLog4127\_Lorem\_20170701.csv** but the file is saved as **callLog4127\_Lorem\_20170701\_1.csv**.

I checked the database, but I don't find any reference to callLog4127\_Lorem\_20170701. I also deleted the temp folder, and ran cron, but I am still getting the same problem.

It happens just with this file; when I upload another file it's working correctly, which means the filename is not changed.

This is my form validation handler. Is there anything wrong with it that could cause the behavior I am seeing?

```
function upload_rtap_validate($form, &$form_state) {
  $file = file_save_upload('calllogrtap_file', array(
    'file_validate_extensions' => array('csv'), // Validate extensions.
    'public://mrtap/', FILE_EXISTS_REPLACE
  ));

  if ($file) {
    $file = file_move($file, 'public://mrtap/', FILE_EXISTS_REPLACE);
    $file->status = 1;
    file_save($file);
    $form_state['storage']['filename'] = $file->uri;
  }
}

```

If I print the content of `$file` with `print_r($file)`, after `file_save_upload()`, I get the following.

```
stdClass Object(
  [uid] => 1
  [status] => 0
  [filename] => callLog4127_GentleDental_20170701.csv
  [uri] => temporary://callLog4127_GentleDental_20170701_4.csv
  [filemime] => text/csv
  [filesize] => 48429
  [source] => calllogrtap_file
  [destination] => temporary://callLog4127_GentleDental_20170701_4.csv
  [timestamp] => 1501309335
  [fid] => 235
 )

```

# Answer
The main error is that you aren't passing the last two arguments of `file_save_upload()` to that function, since you are putting them in the array you pass as second argument. The code you are using is the following one; see the comments I added.

```
  $file = file_save_upload('calllogrtap_file', array(
    // First line of the array
    'file_validate_extensions' => array('csv'),
    'public://mrtap/', FILE_EXISTS_REPLACE
    // Last line of the array
  ));

```

As you aren't passing the last two arguments to `file_save_upload()`, the function is using the default values for those parameters, which are:

* `$destination = FALSE`
* `$replace = FILE_EXISTS_RENAME`

The first values is making Drupal save the uploaded file in temporary://; the second value is telling Drupal to rename the file if there is already a file with that name.

The function call should be the following one.

```
  $file = file_save_upload('calllogrtap_file', array('file_validate_extensions' => array('csv')), 'public://mrtap/', FILE_EXISTS_REPLACE);

```

If you change the code in this way, then the following code line is not necessary, since the uploaded file is already moved in public://mrtap/ from the call to `file_save_upload()`.

```
$file = file_move($file, 'public://mrtap/', FILE_EXISTS_REPLACE);

```

If *filename* is the ID of the form element for uploading the file, the following code probably needs to be changed.

```
$form_state['storage']['filename'] = $file->uri;

```

Probably, the correct line is the following one.

```
$form_state['values']['filename'] = $file;

```

I would also keep the code to validate the user input in `upload_rtap_validate()`, and the code saving the file as managed file in `upload_rtap_submit()`.
For example, see the code used from the form handlers for `system_theme_settings()`, `system_theme_settings_validate()` and `system_theme_settings_submit()`. (I replaced the comments with mine.)

```
  // system_theme_settings_validate()
  $file = file_save_upload('logo_upload', $validators);
  if (isset($file)) {
    // The user upload the logo file.
    if ($file) {
      // The uploaded file passed the validation in $validators.
      $form_state['values']['logo_upload'] = $file;
    }
    else {
      // The file upload failed.
      form_set_error('logo_upload', t('The logo could not be uploaded.'));
    }
  }

```

```
  // system_theme_settings_submit()
  // If the user uploaded a new logo, save it to a permanent location.
  if (!empty($values['logo_upload'])) {
    $file = $values['logo_upload'];
    unset($values['logo_upload']);
    $filename = file_unmanaged_copy($file->uri);
    $values['default_logo'] = 0;
    $values['logo_path'] = $filename;
    $values['toggle_logo'] = 1;
  }

```

In your case, you could use `file_copy()` instead of `file_unmanaged_copy()`, or `file_save()` as your code is doing.
> 0 votes

---
Tags: 7, forms, files
---


# Question
Title: Problem with dependency injection (File::load and \Drupal::service)
In order to make a managed\_file field permanent I did this in my module configuration form:

```
<?php

namespace Drupal\my_module\Form;

use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;

/**
 * Class MymoduleSettings.
 */
class MymoduleSettings extends ConfigFormBase {

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

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $config                    = $this->config('my_module.settings');
    $form['my_module_title'] = [
      '#type'          => 'textfield',
      '#title'         => $this->t('Title'),
      '#description'   => $this->t("Enter the title"),
      '#maxlength'     => 64,
      '#size'          => 64,
      '#required'      => TRUE,
      '#default_value' => $config->get('my_module_title'),
    ];
    $form['mymodule_icon']   = [
      '#type'              => 'managed_file',
      '#title'             => $this->t('Icon'),
      '#description'       => $this->t("Upload the image file for the icon"),
      '#upload_location'   => 'public://',
      '#upload_validators' => [
        'file_validate_extensions' => ['gif png jpg jpeg'],
      ],
      '#default_value'     => $config->get('my_module_icon'),
    ];
    return parent::buildForm($form, $form_state);
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    parent::submitForm($form, $form_state);

    $this->config('my_module.settings')
      ->set('my_module_title', $form_state->getValue('my_module_title'))
      ->set('my_module_icon', $form_state->getValue('my_module_icon'))
      ->save();

    // First we just grab the file ID for the icon we uploaded, if any.
    $icon_field = $form_state->getValue('my_module_icon');
    $file_id    = empty($icon_field) ? FALSE : reset($icon_field);

    if (!empty($file_id)) {
      // Make this a permanent file so that cron doesn't delete it later.
      $file         = File::load($file_id);
      $file->status = FILE_STATUS_PERMANENT;
      $file->save();
      $file_usage = \Drupal::service('file.usage');
      $file_usage->add($file, 'my_module', 'file', $file_id);
    }
  }

  /**
   * {@inheritdoc}
   */
  protected function getEditableConfigNames() {
    return [
      'my_module.settings',
    ];
  }

}

```

but I'm getting warning to use dependency injection principle in this case:

```
File::load calls should be avoided in classes, use dependency injection instead

```

and

```
\Drupal calls should be avoided in classes, use dependency injection instead

```

I looked through Dependency Injection for a Form but still not sure that I really get it.

Can someone explain me what I need to do in this particular case so I can get a better view on this issue and figure it out?

# Answer
If you are extending FormBase you can use `create` to inject dependencies. In this case what I think you want is the `entity_type.manager` service and `file.usage`.

```
  /**
   * Class constructor.
   */
  public function __construct(EntityTypeManagerInterface $entity_type_manager, FileUsageInterface $file_usage) {
    $this->entityTypeManager = $entity_type_manager;
    $this->fileUsage = $file_usage;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('entity_type.manager'),
      $container->get('file.usage')
    );
  }

```

See this docs page for more examples.

The `create` method sends arguments to the constructor, and then you set those to instance variables, and voila, there are your dependencies. Be sure to update your file with the necessary `use` statements and declare your protected members (`entityTypeManager` and `fileUsage`) at the top of the form class.

Therefore, you can remove the static ::service call and use:

`$this->fileUsage->add()...`

Also, the reason I am passing entity type manager service, is because you would replace File::load with:

`$this->entityTypeManager->getStorage('file')->load($id)`;

If you need more than that object returns, you may need to use a different service but I don't know that off the top of my head.
> 11 votes

---
Tags: 8, forms, files, dependency-injection
---


# Question
Title: How to combine four text fields into one column in a view?
I have four text fields in my Content Type:

First Name Middle Name Last/Business Name (required) Generation

I want to combine these into one column in my view. I want the display format to be: LastName, FirstName MiddleName Generation

So only the last name is followed by a comma. The first name and middle name and generation only have spaces between them. I go to the Drupal view table settings and set the "Column" for all four fields to "Last/Business Name." But here's where I'm stuck: I know that there is a "Separator" field, but if I set it to a comma the format will be LastName, FirstName, MiddleName, Generation and that's not what I want.

# Answer
> 2 votes
**TL;DR:** Add the four fields, hide them from the view. Add a custom text field, use it to custom-render the earlier four.

What you need to do is add the four fields into your view. For each, click and check the Exclude From View setting. Then add a fifth field, a Custom Text field, and arrange it so that it comes after the four fields earlier. Click on it to edit, and configure it to output the fields earlier using token replacements.

---
Tags: 7, views
---


title: Display Node edit under edit tab

text:
# Question
Title: Display Node edit under edit tab
I would like to know whether the "node edit form" (admin form) can be displayed under the edit tab itself using `MENU_LOCAL_TASK`?

# Answer
I suggest hide default edit tab and create a tab set with Quick Tabs module.I mean bypass default drupal menu tab( or hide it completely ) and create your own . this module help you to create a `quicktab set` that click on each item don't need page getting refresh.

> The Quick Tabs module allows you to create blocks of tabbed content, specifically views, blocks, nodes\* and other quicktabs\*. You can create a block on your site containing multiple tabs with corresponding content. Clicking on the tabs makes the corresponding content display instantly, using jQuery. With the 6.x-2.x branch, this can be done in either ajax or non-ajax mode:
>
> ```
> if you choose ajax mode for your Quick Tabs block (and this is chosen on an individual QT basis), only the content of the active tab
>
> ```
>
> will be loaded on page load and the content of the other tabs will be loaded via ajax on tab click (this is good for performance if you are loading, for example, several large views) in non-ajax mode the tab content is just hidden / shown on tab-click. This latter method is an ideal way to do something like the Most Popular / Most Emailed stories tabs you see on many news websites, where it is used more as a space-saving device in your sidebar. If however, you want a QT block as the main content of your entire page, then the chances are that ajax mode will be more appropriate.
>
> Once created, the Quick Tabs blocks show up in your block listing, ready to be configured and enabled like other blocks. Multiple Quick Tabs blocks can be placed on a single page.
>
> For theming of the tabs, several styles have been provided for you to choose from (in the 7.x-3.x branch this functionality comes in a separate submodule, Quicktabs Tabstyles), along with the default option of no style, if you prefer to add your own theming instead.
> 1 votes

# Answer
For D7, use Advanced Form Blocks (AFB) for specific nodes, but not all/any nodes. Works also for new nodes of any chosen content type.
> 0 votes

---
Tags: hooks
---


# Question
Title: How do you add "Rating Field" to a content type?
I know that there are many rating or voting module like:

etc for drupal 7, I haven't found any modules for Drupal 8. How can I create a simple 5 star rating widget in Drupal 8?

Ideally I would like a solution, that doesn't require much coding, but can be achieved using existing modules and configuration.

# Answer
> 2 votes
If you're willing to try a D8 module which has an alfa release, then the Votingapi Widgets module might help. Some details from its project page:

> A flexible field based Voting System based on https://www.drupal.org/project/votingapi .
>
> You need Drupal Version \>= 8.2.3. (Multiple form instances on a page)

And a screenprint about it (also from its project page):

**disclaimer**: alfa status, and only a few installs ... use it at your own risk ...

# Answer
> 5 votes
**Do it yourself version:**

You also can add a custom field, integers, with min 1 and max 5 values. After this you only need to theme the display of the field, in a twig template maybe.

For achieving the star effect, there are plenty of solutions for that on google (css / js perspective).

One of them is to use field type List (integer) and in options use this values (so there will be select/radios with stars shown, but stored as a integer):

```
1|★
2|★★
3|★★★
4|★★★★
5|★★★★★

```

# Answer
> 2 votes
The are several modules for this rating feature, but very few has the Drupal 8 version. You can use Voting API for D8. Do no know some other feature you need, may this work.

# Answer
> 1 votes
For Drupal 8 you can use the Like Button module.

> Add a Like button to Drupal content and comments!
> Get instant statistics and insights! Sort content by likes!

Another useful module for Drupal 8 is the Vote Up/Down module.

> Allows votes on some drupal entities and provides the base for implementing votes on other entities.

---
Tags: entities, 8, rating
---


title: Limit comment length

text:
# Question
Title: Limit comment length
I'm trying to put a max number of characters that users can enter when they comment on an article, but what seems to be a simple task actually seems pretty hard to do. I found a module and several code snippets, but they are all for Drupal 7 and under. Ideally, they would also be a character countdown so that users know when they are about to reach the limit.

How shall I proceed?

# Answer
> 2 votes
In D8 the fields of a comment can be configured in a comment type where you can define a field with a maximal number of characters. For a character countdown you need some javascript code or use a field module like Maxlength.

---
Tags: 8, comments
---


# Question
Title: How to define theme variations for entities
In Drupal we can define theme settings that can for instance allow us to create "theme variations".

For instance allow a user to choose a color-scheme, or even define individual colors, sizes, ...

But what if you want to be able to, when creating content, decide what variation is used on that content-page/entity/field?

One way would be to implement a pseudo-field that adds one or more select-box's to all entity forms. That would then populate it's information by reading the theme's info file.

In Drupal 7, I would do something like:

```
/**
 * @param bool $rebuild
 * @return array<
 *  $entityType:Array<
 *    $bundle:Array<Options>
 *  >
 * >
 */
function _ema_entity_variation_info($rebuild=true) {
  $cid = 'ema_entity_variation_info';

  if (!$rebuild) {
    $variations = &drupal_static(__FUNCTION__);
    if (isset($variations)) {
      return $variations;
    }
    if ($cache = cache_get($cid)) {
      $variations = $cache->data;
      return $variations;
    }
  }

  $variations = array();

  $themes = list_themes();
  foreach ($themes as $theme_key => $theme) {
    if ($theme->status && isset($theme->info['variations'])) {
      $variations += $theme->info['variations'];
    }
  }

  cache_set($cid, $variations);

  return $variations;
}

/**
 * Implements hook_entity_property_info_alter().
 */
function ema_entity_variation_entity_property_info_alter(&$info) {
  $variations = _ema_entity_variation_info();

  foreach ($variations as $entity_type => $variation_info) {
    if (!isset($info[$entity_type])) { continue; }

    foreach ($variation_info as $bundle => $bundle_variations) {
      if (!isset($info[$entity_type]['bundles'][$bundle])) { continue; }

      $properties = &$info[$entity_type]['bundles'][$bundle]['properties'];
      foreach($bundle_variations as $variation_name => $variation_options) {
        $properties['variation_'.$variation_name] = array(
          'type' => 'token',
          'label' => t('Variation'),
          'description' => t('Provides variations'),
          'setter callback' => 'entity_property_verbatim_set',
        );
      }
    }
  }
}

/**
 * Implements hook_field_attach_form().
 */
function ema_entity_variation_field_attach_form($entity_type, $entity, &$form, &$form_state, $langcode) {
  //stupid user profiles, comments, ...
  if (!isset($entity->type)) {
    return;
  }
  $variations = ema_entity_variation_get_variations($entity_type, $entity->type);
  if ($variations) {
    $form['variation'] = array(
      '#type' => 'fieldset',
      '#title' => t('Variation'),
      '#collapsible' => TRUE,
      '#collapsed' => TRUE,
      '#group' => 'additional_settings'
    );
    foreach ($variations as $label => $options) {
      $form['variation']['variation_'.$label] = array(
        '#type' => 'select',
        '#title' => $label,
        '#options' => $options,
        '#default_value' => isset($entity->variations[$label]) ? $entity->variations[$label] : NULL
      );
    }
  }
}

```

(yes I know It's not perfect and only works with a single theme, but it got the job done).

This would allow a drupal themer (not everyone is full-stack) to easily define "variations" for all entity types/bundles in his info file:

```
variations[node][basic_page][content_align][left] = Left
variations[node][basic_page][content_align][center] = Center

```

And then in his theme add a class:

```
/**
 * Implements hook_preprocess_entity
 */
function THEME_preprocess_node(&$vars) {
  if (isset($vars['elements']['#entity']) && isset($vars['elements']['#entity']->variations)) {
    foreach ($vars['elements']['#entity']->variations as $variation_name => $value) {
      $vars['classes_array'][] = drupal_html_class($variation_name).'--'.drupal_html_class($value);
    }
  }
}

```

This however feels oh so wrong and I'm now looking into how this could be done "the drupal 8 way".

* I looked into plugins, but themes can't implement plugins (?), atleast my plugin manager is not finding them.
* I looked into reading the info file (using theme handled and such), but this just feels wrong (or is my gut feeling off here?)
* I can only move all the form logic into the theme if it is also used for the admin, this is however hardly ever the case. And I want to support multiple themes and being able to select the variations on a per theme basis.

Anyone has any idea's where I should look into?

# Answer
Assuming I'm understanding the problem correctly, you want to select a variation of the theme on content creation. This looks like a job for Panels and Page Manager (a Ctools submodule).

Enable both modules then do the following:

1. Create a field on your entity to signal the mechanism what to use.
2. Create the layouts using Drupal's built-in layout API.
3. In `Structure -> Pages`, Enable the `node/%` custom page so that Page Manager can custom render nodes.
4. Click Edit on `node/%` and create a "variant". A variant is a set of configurations used by Page Manager to render a page.
    * Define selection criteria. Use the field in step 1 to determine when this variant takes effect.
    * Define layout. Select a layout created from step 2 to use on this variant.
    * Define content. Position content in the layout.

There will be a bit of coding needed for creating the layouts. But other than that, everything else is pretty much admin duty, selecting which layout to use when. Layouts can also define their own CSS.
> 3 votes

# Answer
Why do you need a generic code based solution? Why a pseudo field instead of a real field? You need storage for your data anyway.

Just create a field in the UI, provide values like

```
two_columns|Two columns
three_columns|Three columns

```

And then implement hook\_theme\_suggestions\_HOOK\_alter() and define suggestions based on the selected value.
> 2 votes

---
Tags: 8, entities
---


# Question
Title: Facet filter in Views wrongly returns "No results"
I'm running into a strange behavior with Search API and Facets API, and I hope someone can point what I'm doing wrong.

I am working in Drupal 7 with Views, Search API, Database Search (search\_api\_db), Facets API, and Search Facets (search\_api\_facetapi). My view is working fine otherwise: exposed filters and facet filters work fine in isolation.

The problem happens when I search using an exposed filter, and then try to narrow it with a facet filter.

First step: I search using a exposed filter (see image 1). I get 606 results which display fine.

Then I try to narrow clicking "2" in the facet "Filter by level". The field level is an Integer, and is indexed by Search API as an Integer. Weirdly, I supposedly get 33 results (the View says "Displaying 1 - 20 of 33") but NOTHING gets displayed in the View body (the View says "No results"). Still, the pager at the bottom correctly indicates that there are 2 pages.

Any help will be appreciated.

PS: The field "Composer" is indexed as Fullsearch.

# Answer
I figured out what the problem was. I was using `Indexed Node: Composer` for the exposed filter instead of `Search: Fulltext search` (the field composer was indexed as a fulltext index).
> 0 votes

---
Tags: 7, search
---


# Question
Title: "[node:flag-vote-count]" displays the token name, not the number
I have a problem in the Flag module with the *\[node:flag-vote-count\]* token. I googled for a solution, but I couldn't find one.

On my content page, the Flag module displays the token name (i.e. *\[node:flag-vote-count\]*) on the node creation preview page, instead of a number.

I am putting the token on the Flag -\> Edit -\> "Flag link text" field. Meaning inside the flag itself. *\[node:title\]* is working perfectly fine there.

Someone can help me here?

# Answer
> 0 votes
OK , so I solve it.

The \[node:flag-vote-count\] is really not working. But you can look for another count token for the flag you created, under the TOKEN REPLACEMENT -\> nodes.

Good luck :)

# Answer
> 0 votes
It's works fine:

If i have name variable of flag: **'bookmarks'**

I most replace this **\[node:flag-vote-count\]** to this **\[node:flag-bookmarks-count\]**

If your name variable for example like this: **'bookmarks\_this'**,

you need write toke like so: **\[node:flag-bookmarks-this-count\]**

# Answer
> 0 votes
When a single token is not replace, it means that none of the modules implementing tags gave a value for the token you are using.

Looking at flag.tokens.inc, which contains the code for listing and generating the Flag module tokens, I notice it is using the following code to generate the token you are trying to use.

```
  // We only provide tokens on entity types if we have token module's helper
  // methods available.
  if (isset($data[$type]) && module_exists('token')) {
    $entity_type = token_get_entity_mapping('token', $type);
    if ($entity_type && in_array($entity_type, flag_get_types())) {
      $flags = flag_get_flags($entity_type);
      $object = $data[$type];
      foreach ($flags as $flag) {
        foreach ($tokens as $name => $original) {
          $flag_count_token = 'flag-' . str_replace('_', '-', $flag->name) . '-count';
          $flag_link_token = 'flag-' . str_replace('_', '-', $flag->name) . '-link';
          if ($name == $flag_count_token) {
            $replacements[$original] = $flag->get_count($flag->get_entity_id($object));
          }
          elseif ($name == $flag_link_token) {
            $replacements[$original] = flag_create_link($flag->name, $flag->get_entity_id($object));
          }
        }
      }
    }
  }

```

To see that token, you need to have the Token module installed, since flag.info doesn't require it as dependency, if not for executing the tests. You also need to use the correct flag name, which means that if you are using *\[node:flag-vote-count\]*, but the flag name is bookmarks, you are using the wrong token name, which should instead be *\[node:flag-bookmarks-count\]*.

I didn't test it, but probably you would get back the token name if the node doesn't have any value for that flag.

---
Tags: tokens, flags
---


title: Remove subject field from comments

text:
# Question
Title: Remove subject field from comments
Is it possible to remove the subject field on comment forms? I find it to be kind of useless and redundant, since the subject of the comment is usually the title of the article being read, at least for me anyway.

# Answer
> 32 votes
You can turn it off in the UI at `admin/structure/types/manage/type-name` with the "Allow comment title" checkbox:

# Answer
> 2 votes
There I have found some solutions to this question.

**Option 1:**

How to disable comment titles in Drupal 7. This is so easy and good tutorial to simply hide the subject(title) of comment through user interface.

**Option 2:**

You can also use the *hook\_preprocess\_comment()* in `template.php` file of your current active theme. This is really cool snippet, you can also some other options ie. comment-reply, comment-delete or comment-edit etc.

```
function bartik_preprocess_comment(&$vars) {
  $vars['submitted'] = $vars['created'] . ' — ' . $vars['author'];
  switch( $vars['node']->type ){
    case 'macine-name-of-node-type':
      $vars['title'] =FALSE;
    break;
  }
}

```

# Answer
> -2 votes
```
//get comment by node id
$comment->nid = $nid;
//get form by form name
$form = drupal_get_form('comment_form', $comment);
//hide subject in form
hide($form['subject']);
//check comment form
print render($form);

```

---
Tags: 7, forms, comments
---


# Question
Title: Is `watchdog-show string` broken in 7.56?
On a test instance, `drush watchdog-show` shows, among three other entries, a message starting with "Notice: Undefined property:". However, both of the following commands print nothing at all:

```
drush watchdog-show "Notice"
drush watchdog-show "Undefined property"

```

`drush watchdog-show ":"` does print the message, but also other irrelevant message. So how do I search watchdog messages like it says in the documentation:

> drush watchdog-show "cron run succesful" Show a listing of most recent 10 messages containing the string "cron run succesful".

?

# Answer
> 1 votes
No. Or maybe yes - broken for all versions of Drush. The problem is that Drush only searches the message column of the watchdog table, not the variables column too. A watchdog entry is built-up by a message - format string - where a variable can be inserted. If the text you are looking for is in the variable part, Drush won't find it.

Yes, this is very annoying. There is a related Drush bug - see https://github.com/drush-ops/drush/issues/408 Maybe you should comment and ask for re-opening?

---
Tags: drush, log-messages
---


# Question
Title: How to display only some terms of a specific vocabulary in Views
I have a taxonomy vocabulary (Drupal 7) called "Categories", with 6 terms: a, b, c, d, e, f

I can't see a way to create a view that will show just terms b, d, e (i.e. any sub-set of the full term list).

This seems like something that should be easy to do. Hopefully it is and I am just missing something, though an hour of searching has turned up nothing...

Any suggestions?

# Answer
This can be achieve through View,

1. Create a view based on the Taxonomy (Strucutre-\>view-\>View settings)
2. Choose Page or Block View.
3. Select the desire fields in the field section
4. Add the taxonomy vocabulary ( categories) and Add term in Filter criteria, and select the Drop down, select the select the hirarchy.

Then it will show the term what you want to filter, select the b,d,e terms over there

And then, b,d and e terms only will be shown in View.
> 1 votes

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


# Question
Title: How to pass negative values to config-set
It seems that we can't set negative values with config-set:

```
drush cset block.block.myblock_name weight '-1' --format=string -y

```

doesn't work

# Answer
> 6 votes
The (ugly) work-around is:

```
echo '-1' | drush cset block.block.myblock_name weight - -y

```

You don't need to specify that format is string as that is the default.

This seems to be a general problem with Drush commands; values starting with a dash is interpreted as arguments. See bug report for similar issue with vset - https://github.com/drush-ops/drush/issues/378

---
Tags: drush, configuration
---


# Question
Title: Display multiple values in entity reference view
I have created an entity reference view to display the values of a multi value field in Drupal 8.

The field is a date field.

In the view I have set the "Multiple Field Settings" so the date field values will be shown in separate rows.

When I preview the view, I can all of the date values shown is separate rows as expected.

I then create an entity reference field and select the view as its reference type /view.

The problem is, when I then view this field, I am only shown a single value instead of all the dates as seperate rows.

How do I setup a multi value field so I can select from all of its values in an entity reference field?

Thanks in advance.

# Answer
Try to use Entity Reference Views Select module. For me it worked when I had the same issue.
> 2 votes

---
Tags: 8, entities, views
---