# Question
Title: Showing a node edit page with drupal_get_form() and hook_menu()
I am using drupal 7 and am stuck at a very basic problem. I would like to simply show the edit page to a known node id. I know there are similar posts but they either didn't work or I didn't understand theme. My module looks like this:

```
<?php
/*
 * Show the edid page to a specific nid.
 */

function control_center_menu() {
  $items = array();
  module_load_include('inc', 'node', 'node.pages');
  $nid = '4';
  $node = node_load($nid);
  $items['test/test'] = array(
    'title' => 'Edit this node',
    'description' => 'Edit this node.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('page_node_form', $node),
    'access callback' => TRUE,
  );
  return $items;
}

```

However, at test/test I get a bunch of errors:

```
Warning: call_user_func_array() expects parameter 1 to be a valid callback, function 'node_form' not found or invalid function name in drupal_retrieve_form() (line 795 of /home/christian/workspace/gigs/includes/form.inc).
Notice: Undefined index: #node in menu_form_node_form_alter() (line 629 of /home/christian/workspace/gigs/modules/menu/menu.module).
Notice: Trying to get property of non-object in menu_form_node_form_alter() (line 629 of /home/christian/workspace/gigs/modules/menu/menu.module).
Notice: Undefined index: #node in menu_form_node_form_alter() (line 630 of /home/christian/workspace/gigs/modules/menu/menu.module).
Notice: Trying to get property of non-object in menu_form_node_form_alter() (line 630 of /home/christian/workspace/gigs/modules/menu/menu.module).

```

And instead of the hole form I only get the Menu setting check box and the URL path settings.

What am I doing wrong? I tried hard to find a noob friendly copy past example but didn't find any... Thanks a lot in advance!

# Answer
> 7 votes
`hook_menu()` is only evaluated when the caches are rebuilt, so the call to `module_load_include()` won't be called when the path is actually visited.

That hook is only meant for declaring menu items, if there's any logic that needs to be added for a path it should happen in the access callback/page callback like so:

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

  $items['test/test'] = array(
    'title' => 'Edit this node',
    'description' => 'Edit this node.',
    'page callback' => 'control_center_test_callback',
    'page arguments' => array('page_node_form', $node),
    'access callback' => TRUE,
  );
  return $items;
}

function control_center_test_callback() {
  module_load_include('inc', 'node', 'node.pages');
  $nid = '4';
  $node = node_load($nid);

  return drupal_get_form('page_node_form', $node);
}

```

Since you're forwarding to a static node edit page though, it might be easier just to set the page callback to `drupal_goto()` and hardcode the URL:

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

  $items['test/test'] = array(
    'title' => 'Edit this node',
    'description' => 'Edit this node.',
    'page callback' => 'drupal_goto',
    'page arguments' => array('node/4/edit'),
    'access callback' => TRUE,
  );
  return $items;
}

```

# Answer
> 3 votes
You should define the menu callback as in the following code.

```
  $items['test/test'] = array(
    'title' => 'Edit this node',
    'description' => 'Edit this node.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('page_node_form', $node),
    'file path' => drupal_get_path('module', 'node'),
    'file' => 'node.pages.inc',
    'access callback' => TRUE,
  );

```

Remember that an implementation of `hook_menu()` is being invoked only when menus are rebuild, not each times a new page is requested to Drupal. As consequence of this, the form would get an updated node object only when your module is installed, or when the menus are being rebuilt; in other cases, the form will get a *static* copy of the node object, which doesn't reflect the actual node object.

It would be better to make test/test a path alias for node/4/edit. In that way, the form would get an updated node object every time.

# Answer
> 0 votes
I've used code as follow:

```
function mymodule_menu() {

  $items = array();

  $items['user/%user/firm'] = array(
    'title' => 'Firm',
    'page callback' => 'firm_callback',
    'page arguments' => array(1),
    'access callback' => 'user_check',
    'access arguments'  => array(1),
    'type' => MENU_LOCAL_TASK,
  );

  return $items;
}

function firm_callback($userobj) {
    ....

    if ( isset($node) ) { // existed node

        $form_state['build_info']['args'] = array($node);
        form_load_include($form_state, 'inc', 'node', 'node.pages');
        $form = drupal_build_form('firm_node_form', $form_state);
        return $form;

    } else { // new node

        module_load_include('inc', 'node', 'node.pages');
        $form = node_add('firm');
        return drupal_render($form);

    }
}

function mymodule_form_firm_node_form_alter(&$form, &$form_state, $form_id) {
  form_load_include($form_state, 'inc', 'node', 'node.pages');
}

```

---
Tags: forms, routes
---


# Question
Title: Drupal 8: Upload Validation form alterations ignored
I'm trying to ignore the auto down scaling of large images and replace the validation step with a hard check that the size matches the maximum size provided. I'm trying to do this through the HOOK\_form\_alter hook and while it appears to be affecting the form render array, the AJAX request seems to ignore my changes and run the default upload validation steps.

Here's what i'm doing: In the seven.theme file:

```
function seven_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  $imageForValidation = NULL;

  if (isset($form['field_name_here'])) {
    $imageForValidation = $form['field_name_here'];
  }

  if ($imageForValidation != NULL) {
    // Validate
    $imageForValidation['widget'][0]['#upload_validators']['myTheme_image_validator'] = array();
    unset($imageForValidation['widget'][0]['#upload_validators']['file_validate_image_resolution']);
  }

  return $form;
}

function myTheme_image_validator($file) {
  $errors = array();

  // This doesn't even get called.

  return $errors;
}

```

I've debugged with xdebug and the render array is indeed getting affected, but the result of uploading an image is always the same as the default setup. At the very least I expect the unset validator to not get run, but it still downscales.

Has anyone got round this issue before?

# Answer
Clive was spot on. Turns out I wasn't passing my variable by reference. I was thrown off by (what is now old hat in Drupal 8) returning the form variable at the end of the form\_alter hook.
> 0 votes

---
Tags: 8, forms
---


title: How to delete/hide "create new account"

text:
# Question
Title: How to delete/hide "create new account"
I have 2 roles on my site. I created 2 pages and corresponding links through which each of the roles will register.

I want to prevent users from using the default user registration menu ("create new account") by either deleting it or hiding it. Also i want to prevent users from being able to visit user/register.

Please how can i achieve this?

# Answer
> 3 votes
Use hook\_menu\_alter() to remove default registration page from menu system. Simply `unset($items['user/register']);` and clear menu cache.

# Answer
> 2 votes
I think, there is no need to use hooks or any module for it.

Follow below steps:
1) Go to `Account settings`(admin/config/people/accounts)
2) Under `REGISTRATION AND CANCELLATION` \> `Who can register accounts`
3) select `Administrators only`
4) Save configuration
5) Go and check

However, I would like to have feedback from community if I am missing some use-case here where its must to use module/hook.

# Answer
> 0 votes
The **easiest** option is to use Tab Tamer to hide any tabs you don't want.

> Tab Tamer is an administration utility that provides easy re-ordering, hiding, and deactivation of tabs and subtabs. You can also rename tab labels.

Then use `hook_menu_alter()` to either disable the path, or redirect any requests to another page.

# Answer
> 0 votes
You can add path alias in Pathauto (admin/config/search/path/add) ;)

```
Existing system path: any/page
Path alias: user/register

```

This is simplest solution, but has one disadvantage: the url in the browser is still user/register despite the fact that user is on other page.

# Answer
> 0 votes
Go to **Configuration** menu and **account setting**,
You can find **Who can register accounts?**
You select administator only..
That's all..

---
Tags: users
---


# Question
Title: Form api AJAX, reload js in #attached 3 times
I have a simple form api ajax which does nothing special. In the form I have a js file:

```
 $form['#attached']['library'][] = 'commerce/cart';

```

In the js file I put a log console:

```
function ($, Drupal) {
  Drupal.behaviors.cart = {
    attach: function (context, settings) {
      console.log('aaaa');
  }
});

```

The log console prints 3 times: "aaaa" after the ajax action is over. As if the file was loaded 3 times. If you load the page normally, without ajax, the script runs one time

# Answer
> 2 votes
> The log console prints 3 times: "aaaa" after the ajax action is over

That's correct, behaviours are re-attached after AJAX requests. That's actually the point of them - to ensure that Drupal modules can respond to changes in the DOM.

If you want to limit the effect of that, core provides `once()`. You'll need to add the once library separately, after which you can use, for example:

```
$(context)
  .find('input.myCustomBehavior')
  .once('myCustomBehavior')
  .addClass('processed');

```

See the JavaScript API overview for more information.

Of course you don't have to use `once`, if you don't need the complexity it offers you can just keep track of a boolean that determines whether or not your code should execute again.

---
Tags: 8, forms, javascript
---


# Question
Title: How to use select2 in form API drupal 7?
Hei please help me using select2 in drupal 7 I'trying to make custom module and form type is select using form API drupal 7

can anyone give an example using select2 module in custom form API

# Answer
> 0 votes
From what I recall, the select2 javascript needs to be #attached to a render node or otherwise included on the page, then the dom content loaded callback used to locate the HTML select items that should be modified. Something like:

```
function () {
  $('select').select2();
}

```

See https://select2.github.io/ for examples. Within Drupal, you should really use the Drupal 'behaviours' framework, so that the right thing happens when AJAX and other dynamic loading happens.

There is also the project https://www.drupal.org/project/select2 which may help!

---
Tags: 7
---


# Question
Title: Admin to Create User type Foo that can then Create User type Bar
I'm looking to build the following user structure in Drupal 8

**Admin**: They can create users of type Foo and Bar.

**Foo**: They can only create user type Bar.

**Bar**: They can only create content of a particular content type.

Is this achievable with any current module release? Here are some that I found that could help contribute to a solution:

I've seen profiles, but it has not got an official release yet.. and the feature set doesn't take care of my problem.

Rules, again not a full release but it can trigger events depending on a saved node/ submitted form etc..

Administer users by roles, sounds perfect, not tried and tested.. but noticed again the no official release.

Organic Groups. I don't need to entwine users and nodes (associating content with groups). Which is what I gathered when installing this module

The other option would be to create some custom code that is fired on the submission of a form to add a user via official drupal code... the only problem with this is making sure the code is correct and updated as new release of drupal is released for example. Would this be a good / stable approach?

Can anyone help point me in the direction of a solid solution?

Thanks in advance.

# Answer
@cwiggo Drupal doesn't really have a concept of a user 'type', just roles that a user can participate in, which I presume you know. You can of course layer 'types' on top of the provided structures using additional fields and tables. You've obviously looked at some of the candidates for helping with this, but have you considered Organic Groups, which might be closer?

As for using projects before stable release: my best suggestion is to dive in and help get a project over the line, perhaps by contacting the module maintainers and offering to help directly. There are however a lot of sites based on 'dev' modules; the maintainers just have to evaluate the code, the issue queue, and the overall risks/benefits and make a decision.
> 0 votes

---
Tags: 8, rules, users
---


# Question
Title: Can cookies safely be stored in the public filesystem (sites/default/files)?
One of my modules does some CURLing, and to do this it creates a cookie on the Drupal server. Where should I locate this? Where it will be nice and safe? Is there a convention? Is sites/default/files considered safe?

# Answer
The risk depends on the nature of the cookie. If these cookies contain session data, they could be used to take over you session, which is considered to be high risk.

Your public files folder (sites/default/files) has public read access, meaning that everybody can obtain a file (once they know its name) by going to example.com/sites/default/files/\[FILENAME\]. This is not safe and perhaps not the best solution for the type of cookies described above.

Instead, you can save it to the private filesystem. Instructions for Drupal 7 and 8 differ, so best to look up the instructions you need. The ultimate safe solution would be to move your private filesystem outside of your webroot (some tutorials create it as subfolder of sites/default/files). Safer would be to place it in a folder next to your public\_html/www folder or anywhere else on the filesystem, where it is not accessible from the internet.

If you configure it properly on SITE/admin/config/media/file-system, you can then use the streamwrapper `private://` to read and write the files.

If these cookies do not contain any data that could be considered to be sensitive, sites/default/files (or `public://`) should be good enough.
> 1 votes

# Answer
@Neograph734 is quite correct about public/private files.

Another option would be in a database field.

What should be considered is how to distinguish authorized cookie access (intended use) from unauthorized use. In other words, is php running with a Drupal-authenticated session before it needs to access the cookie? If so, private files, DB etc are useful, but if 'anyone' can cause the server's php to run the curl processing, how is safety ensured?
> 0 votes

---
Tags: cookies
---


# Question
Title: How to "flag" product that had already been purchased before "flaging feature" was added?
In reference to this question and answer: How to mark product if it has already been purchased by current user?

Now that I know how to "flag" the items in a way that lets me notify customer to avoid situation where customer buys two of the same product, remains one more question: How can I now mark or "flag" all the products, that had already been purchased before the flaging feature was added to the shop?

# Answer
If you can think of a way to create a view which contains 1 row for each product and the user who actually bought such product, and which wasn't flagged with this "already purchased" flag, then you can use such view as part of an actual solution for your question. In that case, you could get this to work by using the integration of VBO with the Rules module, as further detailed below.

# Step 1: Create a Rules Component

Create a (rather basic) Rules component to flag a product by a user. Here is a variation of such component in Rules Export format (which processes nodes instead of products):

```
{ "rules_flag_node_by_a_user" : {
    "LABEL" : "Flag node by a user",
    "PLUGIN" : "rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "flag", "rules" ],
    "USES VARIABLES" : {
      "flagging_user" : { "label" : "Flagging user", "type" : "user" },
      "flagged_node" : { "label" : "Node to be flagged", "type" : "node" }
    },
    "DO" : [
      { "flag_flagnode" : {
          "flag" : "your_flag",
          "node" : [ "flagged-node" ],
          "flagging_user" : [ "flagging_user" ],
          "permission_check" : "1"
        }
      },
      { "drupal_message" : { "message" : "Node flagged for user  [flagging-user:name] (uid=[flagging-user:uid])" } }
    ]
  }
}

```

This Rules Component uses a flag with machine name `your_flag`. After you edit that machine name to fit the name of your flag, you should be able to import this rule in your own site (using the Rules UI, which needs to be enabled). You can then adapt (or clone) it to make it work for your products instead of for nodes.

BTW: the Rules Action to display a message is just to see it at work while QA-testing this rule, feel free to remove that if you want.

# Step 2: Let VBO do the work

This step is pretty easy ... Just build an appropriate view (of all products that still need to be flagged) and transform it in a VBO view. The clue to what you want VBO to do as an operation is ... **Execute the Rules Component from Step 1**. Be aware: when creating that VBO view, you really need to create a view to "List Commerce Products".

If your Rules Component (= variation of the one in Step 1, where you flag products instead of nodes) cannot be selected as the VBO-action to be performed, then it might be because you need to change the order of the parameters used by the Rules Component: make the `flagged_node` (or `flagged_product` in your case) the very first parameter. This might be needed because it's a Rules Component with several parameters, and only the first one will be auto-populated by VBO. That might help to be able to select that Rules Component as your VBO action.

If you're not familiar with how to use VBO, have a look at the video about Using Rules components with VBO". If you want even more, then also watch the subsequent "Using Rules components with more than one parameter" video.

**Attention**: to process like 100.000 records at once is quite a challenge (memory requirements, etc). Therefor you might want to also watch the video about "More details about VBO settings" ... Before you are tempted to use VBO for processing them all at once ...

# Video tutorials

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

Happy VBO-ing while Rules-ing!
> 1 votes

---
Tags: 7, commerce, flags
---


# Question
Title: Drupal 8 Installation Symphony routing error
I am installing a second Drupal 8 site on an existing server configured to redirect a sub-domain to the new site. The Install was uneventful, but when I visit the site to confirm it is working I am met by:

```
The website encountered an unexpected error. Please try again later.

```

Inspecting the apache2 error.log i see the following:

```
Uncaught PHP Exception Symfony\\Component\\Routing\\Exception\\RouteNotFoundException:
"Route" search.view_node_search" does not exist." at
/var/www/html/subdomain/core/lib/Drupal/Core/Routing/RouteProvider.php line 187

```

I have double checked my rewrite module and it seems to be setup correctly for the sub-domain. I even tried re-setting it in the virtual host and the .htaccess file but no luck.

The directory for the sub-domain does differ in name to the actual site address, though I think this should not be a problem.

Can someone please explain what this means and how I fix it?

# Answer
Clearing cache at config/development/performance worked for me.
> 2 votes

---
Tags: installation, 8
---


# Question
Title: Use Url Argument in contextual filter for Block View
I have a View which uses contextual Filter to compare my URL last Argument with Taxonomy term. This Works when my view is Page but doesn't work in block mode. This is my View Below.

Attaching my view and Site Description along this. My Pdf Category View is placed as a block.  When I Preview by entering the brand name emax in the view, it give me proper results but it doesn't fetch from url(RAW Value from URL). Correct me if i failed to mention anything wrong.

# Answer
> -1 votes
I found the solution for this issue. I used PHP code by selecting "Provide Default" and Select PHP code as below to extract arguments from URL and provide a filter to your view.

```
$path = drupal_get_path_alias();
$path = explode("/", $path);
return $path[2] /* Since explode function return array of url arguments, select required arguments starting with 0.*/

```

---
Tags: views
---


# Question
Title: Migrate users from a custom application DB into Drupal
Is there a way (kind of best practice or tool) to import Users from a custom CMS into Drupal (with of course the all fields already set)? I think a JSON object with my all Users' data is the only way. Passwords are actually strings encrypted in md5 so all passwords should be regenerated by the Users (that's not a big problem). Someone suggested JSONdata.com but the URL is not reachable.

Thanks in advance for all welcome suggestions/remarks.

# Answer
> 2 votes
Yes. The Migrate module does exactly just that.

You just need to write a migration script, which is comprised of the source (there's a lot of plugins out of the box like MySQL, CSV, JSON), the destination (there's already a `User` class you can extend from), and the mapping (the mapping of source fields to destination fields).

Drupal will probably have a different hashing mechanism that your CMS, so the passwords probably cannot be reused. The values can be copied as is, and just force your users to reset their passwords. There's also the Force Password Change module for that.

---
Tags: database, importing-exporting
---


# Question
Title: Submission of dynamically generated input fields
I have created data entry form using Drupal 8 Webform (Yaml forms), Part of the form is table field which hosts dynamically generted textfields using jquery shown below:

```
 $(document).ready(function(){
    var input="";
    var column="";
    $(".add-row").click(function(){
    var new_row =jQuery('<tr>');
    input= jQuery('<input>').attr({type: 'text',name:'names[]'});
    column=jQuery('<td>').append(input);
    input= jQuery('<input>').attr({type: 'text',email:'emails[]'});
    column=jQuery('<td>').append(input);
    new_row.append(column);
        $("table tbody").append(new_row);
    });
});

```

However, to my surprise when I hit submit button of the form all other fields are submitted except the fields which have been generated dynamically on the table field.It seems Drupal 8 can not recognize the dynamically generated input fields

So my question how can I make Drupal 8 recognize my dynamically generated input fields. I want to see the data in these fields in the database. Please help. Your assistance will be greatly appreciated

# Answer
The WebformSubmissionStorage service uses the list of elements associated with the webform to properly store the data. You are going to have to create an Element and WebformElement plugin definition that defines the element type (ie multiple, composite, etc...) and then attach your JS as a library.
> 0 votes

---
Tags: 8, javascript, webforms
---


# Question
Title: Drupal Pager Error Causing WSOD When Viewing Term or Edit Term
I have recently been through the ordeal of updating D6 to D7. Things went better than I had previously encountered but I have a problem thats really holding me back and I can't work out how to sort it.

When I try to view a `taxonomy/term/` page or edit a term I get a WSOD. I managed to show the error which was:

> Fatal error: Call to a member function use\_pager() on a non-object in /home/oddeba/public\_html/onlinebanter.co.uk/sites/all/modules/views/includes/view.inc on line 690

Line 690:

```
    function init_pager() {
         if (empty($this->query->pager)) {
           $this->query->pager = $this->display_handler->get_plugin('pager');

        Line 690>>>  if ($this->query->pager->use_pager()) {
            $this->query->pager->set_current_page($this->current_page);
           }

```

Things are fine with Views disabled. I can for the life of me think how I needed a pager about my taxonomy before.

Could anyone suggest anything that could be causing it?

# Answer
If you ever run into a WSOD error, follow the directions here and it will generally tell you the file name and the line number that is causing the WSOD. Or, it will tell you that your server resources are too limited (out of memory).

Here are the instructions:

http://drupal.org/node/158043

Or just Google 'Drupal WSOD' and it's the first link on the SERP.
> 1 votes

# Answer
I just encountered this `use_pager()` problem again. This time with the `frontpage` view. I solved it by going to the view, opening the pager settings and choosing the same option again, then saving the view.
> 0 votes

---
Tags: views
---


# Question
Title: What is the goal of template_preprocess_page(&$variables)?
I am trying to modify the login and register page drupal 7 but i actually don't understand what is the goal of template\_preprocess\_page(&$variables) ... Someone can give me a better explanation of that ?

# Answer
> 2 votes
It is an entry point in your theme or module that allows you to modify or add template variables before the page (or applicable item) is rendered. This hook affects any page\*.tpl.php files.

Similarly, `template_preprocess_node` is the same, but for node templates.

Example:

I need to change existing variable `foo`:

```
function mytheme_preprocess_page(&$variables) {
  // $foo used to be 'Old Value'
  $variables['foo'] = 'New Value';
}

```

I need to add new variable:

```
function mytheme_preprocess_page(&$variables) {
  // $baz does not yet exist
  $variables['baz'] = 'Baz!';
}

```

These are injected into the template, then they can be rendered with `render` or printed:

`page.tpl.php`:

```
<?php print $foo; ?>
<?php print $baz; ?>

```

This is because `$variables` are passed by reference (note the **&** symbol) which allows you to modify the array.

---
Tags: theming, users
---


title: How to hard code to login as admin?

text:
# Question
Title: How to hard code to login as admin?
In the past, I developed a Drupal site in my localhost. After that, I uploaded to production site. Everything was OK.

Recently, my HDD was died. So, I lost my Drupal site source code. I downloaded my production site on localhost.

I cannot log in. I think the problem is cookies.

How can I force Drupal to get my login by adding some code lines?

# Answer
You have the possibility to edit the current password locally.

You should take a look at Resetting the administrator password with sql-query. It is possible with some commands and SQL queries to change the current password for your admin user (UID=1).
> 0 votes

---
Tags: 7, users
---


title: Access to block-system-main div

text:
# Question
Title: Access to block-system-main div
I have block with image so the easy way it's to create a content type. I have node--nodeName.tpl.php where I built correct DOM.

But this is slider, and all nodes embedded in one div with classes

> block-system-main block block-system

I have to initialize slider. For this I need unique parent class\id

This is beginning of my node--nodeName.tpl:

```
<div class="<?php print $classes . ' slick_hero ' . ' ' . $zebra; ?>">

```

# Answer
Looks like you're having a block of node teasers, and you want to initialize a slick slider on its items using vanilla JS, yes? There's a better way to do this, and that's to use the Slick module together with Slick Views.

1. Create a slick carousel view, configure it as a block and not a page.
2. Filter to the desired nodes
3. Configure to render the teaser displays
4. Configure the slider parameters.
5. On whatever block rendering mechanism you have (Block Layout, Context, Panels, whatever), position the view in the desired location.

All that and you never have to touch code or meddle with the template.
> 0 votes

---
Tags: nodes, blocks
---


# Question
Title: How to make an entity reference field required using states
I need to make an entity reference field in my form be required based on the state, the code below is working with other fields, but not my entity reference field.

```
$form['schedule_publish_date'] ['#states'] =  array(
 'required' => array(
  ':input[name="moderation_state[0]"]' => array('value' =>"published"),
 ),
);

```

this is the source code of the entity reference field. Am I putting in the wrong name for the form item?

```
<fieldset data-drupal-selector="edit-schedule-publish-date" id="edit-schedule-publish-date" class="js-form-item form-item js-form-wrapper form-wrapper">
  <legend>
<span class="fieldset-legend">Schedule Publish Date</span>

```

```
      </div>

```

the moderation state is not what I am having trouble reaching. It's the schedule publish date, which is an entity reference and doesnt become "required" when it should.

# Answer
> 1 votes
There isn't a specific form element with the moderation state, since they are added as action submit buttons, but you could add one like this:

```
  if (!empty($form['moderation_state']['widget'])) {
    $form['moderation_state_hidden'] = [
      '#type' => 'hidden',
      '#title' => 'moderation_state_hidden',
      '#value' => $form['moderation']['widget'][0]['#default_value'],
    ];
  }

```

Then you could refer to it in your states array like this:

```
$form['schedule_publish_date'] ['#states'] =  array(
 'required' => array(
  ':input[name="moderation_state_hidden"]' => array('value' =>"published"),
 ),
);

```

But using states doesn't really make sense because you can't change the moderation status of a hidden field or a non-ajax submit button.

So in that case, you could just update the form element to be required

```
  if (!empty($form['moderation_state']['widget']) && $form['moderation_state']['widget'][0]['#default_value'] == 'published') {
    $form['schedule_publish_date']['widget'][0]['target_id']['#required'] = TRUE;
  }

```

---
Tags: 8
---


title: Show if a user is logged-in or not

text:
# Question
Title: Show if a user is logged-in or not
I want to display an array of users of my site in a view.

How do I show if a user is logged-in or offline? I can not find anything to do that in sight.

# Answer
You can check $user-\>getLastAccessedTime() in a preprocess function and set this as a variable, for example the view at /admin/structure/views/view/who\_s\_online determines if someone is "online" by checking if last accessed time is within the last 15 minutes.

```
function mymodule_preprocess_views_view(&$variables) {

  if ($variables['view']->id() == 'my_example_view') {
    /** @var $account \Drupal\user\UserInterface */
    $account = <load up your user>

    if ($account->isAuthenticated() && time() - $account->lastAccessedTime() < 900) {
      $variables['online'] = ['#markup' => 'online'];
    }
    else {
      $variables['online'] = ['#markup' => 'not online'];
    }
  }
}

```

And then to use 'online', you'd need to use a custom template for views-view-my-example-view.html.twig.

If you want to check a bunch of users, it may make more sense to use a view mode and use the preprocess function for the view mode.

The main point of this answer isn't how to theme views, but how to determine "online" as best as possible using Drupal.
> 1 votes

# Answer
Probably not useful for 8, but in 7 you can take a look at `user.module` on lines 1428-1480 (version 7.56), and this chunk in particular appears to be responsible for generating this list:

```
 // Display a list of currently online users.
        $max_users = variable_get('user_block_max_list_count', 10);
        if ($authenticated_count && $max_users) {
          $items = db_query_range('SELECT u.uid, u.name, MAX(s.timestamp) AS max_timestamp FROM {users} u INNER JOIN {sessions} s ON u.uid = s.uid WHERE s.timestamp >= :interval AND s.uid > 0 GROUP BY u.uid, u.name ORDER BY max_timestamp DESC', 0, $max_users, array(':interval' => $interval))->fetchAll();
          $output .= theme('user_list', array('users' => $items));

```
> 0 votes

# Answer
I believe Drupal doesn't store an "online" status for users nor does it record logouts (Because it doesn't make sense. I can logout by deleting browser cookies and no one would know).

However, it does keep timestamps of last login (when the user last logged in) and last access (when the user accessed the site while logged in). You can probably create a view of users and their last access timestamp, filtering it down to the timestamps that fall within the past hour or something.
> 0 votes

# Answer
```
$db_conn = \Drupal::database();
$query = $db_conn->select('sessions', 'se');
$query->fields('se', ['uid']);
$result = $query->execute()->fetchAll(\PDO::FETCH_ASSOC);
$users = [];
foreach($result as $res){
  if($res['uid'] != 0){
    $users[$res['uid']] = $res['uid'];
  }
}

```

You can user this query and get all logged in users in array. But this will show only users with active session.
> 0 votes

---
Tags: views, users
---


# Question
Title: How to exclude an external js from a particular node?
How can we remove an external js from a particular node!

For Ex: Remove `http://cdn.jquerytools.org/1.2.6/jquery.tools.min.js` from home page.

# Answer
> 1 votes
If the script is added in a correct way(using Drupal API) you should be able to unset it as following:

***Drupal 7:***

```
/**
 * Implements HOOK_js_alter().
 *
 * @param $js
 */
function HOOK_js_alter(&$js) {

  $node = menu_get_object();
  if (!empty($node->nid) && $node->nid == XXX) {
    unset($js['your_path']);
  }

}

```

***Drupal 8:***

```
/**
 * Implements HOOK_page_attachments_alte().
 *
 * @param $attachments
 */
function HOOK_page_attachments_alter(&$attachments) {
  /** @var \Drupal\node\NodeInterface $source */
  $node = \Drupal::routeMatch()->getParameter('node');

  if ($node instanceof \Drupal\node\NodeInterface && $node->id() == XXX) {
    unset($attachments['your_js_path']);
  }
}

```

---
Tags: 7, javascript
---


# Question
Title: In Views, what is the difference between "Show Fields" and "Show Content" under Format?
In the Format section you have the option Show: Fields. That is the one I usually use. However, you also have Show:content. What is Show:content and how is it different? When would I want to use it instead of Show:fields?

# Answer
> 2 votes
`Show: content` will render the content as it is normally displayed if you access it at its URL. For example, selecting `Show: content` for a view displaying users will display each user's full profile. Selecting it for a view displaying nodes will render each node in its entirety.

`Show: fields`, by contrast, allows you to select (limit) which fields to display.

# Answer
> 0 votes
Show content will bring you the ability to choose a View Mode (say 'top\_view\_mode'). Then, you can create a template like thisone : nodes--article--top-view-mode.html.twig

From this template use {{ node.field\_name.value }}

---
Tags: 7, views
---


# Question
Title: Does cache-tag / cache context bubbling up mean core doesn't actually individually cache separate page components?
So I read that cache contexts and cache tags bubble up to the entire page they're in. Let's say I have a custom page template with 3 sections that are populated in the page's theme preprocess hook:

```
[A: The Current Time]
[B: The Logged in User Name / A link to login if not logged in]
[C: Node and Taxonomy data]

```

A and B are very simple and C is very complex and slow. The node/taxonomy data only changes when new content is added, so it also happens to update the least often and the one we'd want to cache the most. B is different between anonymous users and logged in users, and also unique to every user. A is the same for everyone but changes every minute.

Normally, I would have A with a max-age of 60 seconds, B with a 'user' context, and C with the node:id cache tags relevant to what it needs to show (which we invalidate when new content that affects those nodes is added).

It seems to me that including A and B severely limit the ability to cache C, because if the contexts bubble up then B will force the server to keep a cached copy of the page for every different user. And if the lowest max age bubbles up (not sure if this is a thing) then A will force the entire page to be invalidated every minute.

Does that mean that this specific scenario would force Drupal to clear the cache for C every minute? Does it depend on how the page is implemented?

# Answer
> 3 votes
The bubbling is for the cache\_tags and contexts, so it's related to when the cache on the parent item clears. The parent item will clear based on the children, as the parent has all the child cache tags. It doesn't mean that the children don't cache. They do, but they won't refresh at the same rate as the parent. The parent will potentially clear more often and then rebuild from the cached components.

---
Tags: 8, caching
---


# Question
Title: Remove uploaded files before the 6 hours cron?
I have a custom Content Entity in wich definition there is a 'file' field. The file widget works fine.
The 'Browse' button allows to select a file and uploads it to the proper server directory and the 'file\_managed' and 'file\_usage' tables are updated accordingly.
If I delete the entity, 'file\_usage' record is deleted and in 'file\_managed' table, the record has its status field set to '0'.
What I understood is that cron job removes all files in the directory with status = '0' after 6 hours.
My question is: how to have the file removed just after the submission of the delete form?

# Answer
> 3 votes
`file_cron()` contains the code that delete managed files. To adapt it to delete those files with their status set to 0, this is what I would use.

```
$file_storage = \Drupal::entityTypeManager()->getStorage('file');
$fids = Drupal::entityQuery('file')->condition('status', 0)->execute();
$files = $file_storage->loadMultiple($fids);

foreach ($files as $file) {
  $references = \Drupal::service('file.usage')->listUsage($file);
  if (empty($references) && file_exists($file->getFileUri())) {
    $file->delete();
  }
}

```

This code returns you all the files matching those conditions. You can also use the following code to get them in batches of 100 per time.

```
$file_storage = \Drupal::entityTypeManager()->getStorage('file');
$fids = Drupal::entityQuery('file')->condition('status', 0)->range(0, 100)->execute();
$files = $file_storage->loadMultiple($fids);

foreach ($files as $file) {
  $references = \Drupal::service('file.usage')->listUsage($file);
  if (empty($references) && file_exists($file->getFileUri())) {
    $file->delete();
  }
}

```

I didn't check, but it is probable you can also filter the returned file entities by the bundle using them.

---
Tags: 8, files
---


# Question
Title: Can you create a view to display all files within a certain directory?
I have a Node Type A that is referred to by a bunch of other nodes. Within the nodes that are referring to Node Type A, there are various and separate CCK file fields. I have configured all of these files to be saved in a directory that is named with the title of each Node Type A (with the FileField Paths module)...so all of the corresponding files for a Type A node are in one place. I need to create a view that displays all of the files from the referring nodes in a sortable table. The problem that I'm running into, is that I have to add each separate CCK file field from an assortment of different node types to the view, which generates empty fields in the rows ouput.

So can I build a view that pulls the files from a specific directory on the server?

# Answer
> 0 votes
As Jim Kirkpatrick said, you want to create a new View selecting "Files".

Then in the Filters you enter the path you want to view (you could also use attributes, if you have very many node types, it would be faster but requires you to enter the node type in the view path... although you can later hide that using URL aliases.)

Note that only works for files that appear in the Drupal Core file upload table. Any other file is not known by the system and thus won't just show up in the view.

# Answer
> 2 votes
Only tools I've seen dealing with showing file are more like this...

http://drupal.org/project/elfinder

http://drupal.org/project/webfm

http://drupal.org/project/manager

http://drupal.org/project/filebrowser

You can create a view of all attachments to nodes, but that's not what you want either.

# Answer
> 1 votes
In Drupal 7 you can create a view of files, with path as one of the available filters.

In Drupal 6 the Table Wizard and the Data allow you to pull database tables in to views, so it's an extra step but perhaps you could create a table to maintain a list of files and their paths then use one of these modules to create a view.

# Answer
> 0 votes
Look at the Style Settings/Theme Information on your view and dive into the Row style output template for your view. You most probably can throw some php code in there to skip the empty fields...

# Answer
> 0 votes
From another drupal.stackexchange answer, this module called **Filebrowser** looks like an ideal solution (I've yet to test) for discrete folder listing of files. From the Filebrowser project page:

> You will create one node (node type dir\_listing) for each each Directory Listing (DL). Node settings are used to control access and other features of the DL. These settings can vary per node and per user.
>
> This module offers the following features:
>
> Private downloads so that files (such as PHP files) can be downloaded. File blacklists so that specific files can be removed from directory listings. Node-based. All features available to nodes, such as path aliasing and access control can be applied to directory listings. Settings to limit exploration of subdirectories

The latest Filebrowser version 7.x-4.0-rc1 can do multiple file uploads (drag and drop) if the Plupload module along with the Plupload library dependency (ie extract zip file into library folder at sites/all/libraries/plupload) are available. Looks like it offers file meta-information options as well.

The .info file for Filebrowser *does not have a Views dependency* so it is likely Views contextual filters or Views relationships needs tweaking, or alternately some type of views enhancement module such as the popular EVA - Entity Views Attachment, or block or entity reference module possibly with Context module, could be needed to solve the display/view/layout in cases like this question. Also, depending on the roles/permissions that Filebrowser does, or may not have, coded into this module with its content type, ACL (Access Control Lists) with Content Access might be additional modules for privacy of the custom file listings/nodes.

Kudos to the community developers for this module, that is showing active development activity at the time of this answer. Try to contribute back folks!

---
Tags: views, files
---


# Question
Title: How to keep password form populated ever if the validation fails on registration
On the registration page when the validations for profile fields fail, the page is refreshed with error messages. The problem is that then the password form is cleared even if the user has already entered an acceptable password. Is there any way to keep the password populated even if the page is refreshed after the validation fails?

# Answer
The password form field is always cleared out when re-submitting the form after a validation handler reports an error.
There isn't a workaround to that, as the password form field is not using the "#default\_value" property that usually other fields would use to pre-populate the fields with a value that is then edited from users. If you use the "#value" (supposing that would have any effect for the password form field) then that value would override the value entered from the users.
> 0 votes

# Answer
I realise this post is old but I had a similar frustration. You can have the password fields not clear on validation by using client side validation.

https://www.drupal.org/project/clientside\_validation
> 0 votes

---
Tags: users
---


# Question
Title: Filter Taxonomy Widget Options by Entity Reference
I have two content types, Lesson Plan and Course. When creating a Lesson Plan, users select a Course (Entity Reference). Later, they choose course goals (Term Reference) that the Lesson Plan meets. I'd like to filter the list of course goals by the earlier selection, Course. Each Course has a number of course goals (Term Reference).

Is this possible? I've tried using Term / Entity Reference Views, but can't figure out how to pass the selected Course as an argument and have the term list update (AJAX).

# Answer
> 0 votes
It is possible and can be implemented using Simple Hierarchical Select. From the modules page-

> Simple hierarchical select defines a new form widget for taxonomy fields to select a term by "browsing" through the vocabularies hierarchy.

Expose the view filters (course and course goals) in your case after you set the field type to simple hierarchical select. This guide might be helpful.

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


# Question
Title: How do i create a field for a content type from a content type? Like a list for add multiples values from a content type, inside another
It is simply as a **1 to many** relationship between content and I need to manage multiple content within another.

I do not know if there is any plugin or library or method that allows me to. Please I need help. Thanks in advance

# Answer
> 0 votes
It is as simple as use the module Entity Reference. You'll have a new field type to reference a node (or multiple) into an other node.

---
Tags: entities
---


# Question
Title: How to use AJAX for an exposed filter form of a Views block?
I have a View, in a block, assigned to a region. I have enabled Ajax for the view. Pagination works with Ajax. Exposed filters do not. Exposed filters "submit".

I am definitely willing to cut corners at this point, so if there's a method that can be done with a simple JS function I will do that.

I believe that the problem is related to using the exposed form as a block. When "exposed form in block" is set to "no" ajax filtering does work.

update/solved: I disable "exposed form in block" which I was using to change the position the filters. I then edited the view's template to get the position where I wanted it. so this is "solved" but I am not sure why it didn't work before.

# Answer
> 4 votes
You must install the Better Exposed Filters module:

> What else can I do with BEF?
>
> * Add help text for each exposed filter
> * Tame long lists with scrollable checkbox/radio button lists or select all/none links
> * ***Provide instant feedback by updating the View using AJAX whenever an exposed filter is changed***
> * Use the jQuery Slider widget for greater-than, less-than or in-between types of filters

You can read more about this in Views exposed filters without "Apply" button

# Answer
> 3 votes
Exposed form as a block doesn't work out of the box with a block view.

There is an add-on module that does allow this configuration: Views Block Exposed Filter Blocks

---
Tags: blocks, ajax, views
---


# Question
Title: Ajax form in block, how do I reliably load the include file?
It is an ajax form, so as soon as the ajax runs there is a 500 error with 'Fatal error: Call to undefined function, yhivebooking\_form\_validate() in ...

It is an ajax callback, but goes through /system/ajax which isn't a menu item and therefore, I can't load the include.

```
/**
* Implements hook_block_view()
*
* @param string $delta
* @return array
*/
function yhivebook_block_view($delta = '') {
  $block = array();

switch ($delta) {
 case 'yogahive_book' :
  module_load_include('inc', 'yhivebook', 'yhivebook_booking_form');
  $block['subject'] = t('Book a class with a YogaHive pass');
  $block['content'] = drupal_get_form('yhivebook_booking_form');
}

return $block;
}

```

# Answer
> 1 votes
You need to use form\_load\_include() in your form definition. So at the top of the function yhivebook\_booking\_form(), add the following:

```
form_load_include($form_state, 'inc', 'yhivebook', 'yhivebook_booking_form');

```

---
Tags: forms, ajax
---


title: Missing node_reference warning

text:
# Question
Title: Missing node_reference warning
> User warning: The following module is missing from the file system: node\_reference. For information about how to fix this, see the documentation page. in trigger\_error() (line 1138 of /\[localdevetc/drupalrootetc\]/docroot/includes/bootstrap.inc). =\>

This error usually occurs when module files are removed without a module being disabled and uninstalled first. Typically it's corrected by simply re-downloading the module files and then uninstalling it. The problem is that there doesn't seem to be a module called node\_reference for Drupal 7. I tried `drush dl node_reference` and got:

> No release history was found for the requested project (node\_reference).
> Could not download requested project(s).

Any ideas?

# Answer
node\_reference is just a sub-module of the References module; that's why you can't download it using Drush. Instead, download the References module.

```
drush dl references

```
> 0 votes

---
Tags: 7
---


title: Sporadic permissions issue

text:
# Question
Title: Sporadic permissions issue
We are running a Drupal 8 site with 400 or so pages of content.

We have a number of "resource pages" were views generate links to content by topic area. Here is an example of one of those pages.

In general everything is working as intended, however, sporadically we have an issue with clean URLs and the link to content in those views. Specifically, index.php is added to the link presented only to anonymous users. For example, website/mypage becomes website/index.php/mypage, or even website/index.php/index.php/mypage.

This problem never occurs for logged in users, only anonymous users. It is also not consistent. It may happen to 2-3 of the links in a single view, or several across the views on the same page but generally will not affect the entire site or page. It may not happen for weeks and then 4-5 times in 24 hours. In the last few days it appears to be happening every few hours.

It appears to mostly only happen on resource pages (they are a content type) like the one I linked above. We have also some times observed it occurring on other menu links. These links usually still work however...

We have been unable to find a reason for it. Clearing the site cache a few times does fix the issue but it is somewhat unacceptable that this happens regularly.

The views on those specific pages do make use of relationships and aggregation to generate their content. Several also use re-write rules to generate custom link text. The issue appears to affect both types of views on those pages.

Can anyone suggest what the cause of such an issue could be or give any ideas as to how to stop it occurring?

# Answer
How this gets started is hard to tell. But once it does it spreads quickly. When a user clicks on a link with /index.php the page will include /index.php in the base url, which then is used for all links generated on this page. The same is the case for search bots, once they hit a link with /index.php they will crawl the whole site with it.

To stop this, redirect the unclean urls. You could use this core patch or Redirect, but as long as the core patch is not committed and the module is not released, you can do this in .htaccess. Place these two lines at the top of the rewrite rules:

```
# Various rewrite rules.
<IfModule mod_rewrite.c>
  RewriteEngine on

  RewriteCond %{THE_REQUEST} "^[A-Z]{3,9}\ /index\.php(.+)\sHTTP" [NC]
  RewriteRule "^" "%1" [R=301,NE,L]

```
> 4 votes

---
Tags: 8, users, uri
---


# Question
Title: How to create audit trails/order revisions?
I've been working with Drupal Commerce for a few months now. As a non-profit, our organization hosts an e-commerce/e-learning site. We're a smaller organization with approx 20 staff users and \<20,000 regular customers.

How do others handle creating audit trails/order revisions within Drupal Commerce? There are quite a few modules out there, but I have yet to find the right combination. Currently, we've added Line Item Revisions module and use the Order revisioning built into Drupal Commerce.

Here are some concerns I'm attempting to address:

1. How did the order end up in the current state (who and why)?
2. What was recently changed (line items, status, owner, coupons, etc. who and why also)
3. How do you identify who deleted records, specifically financial records? Secondly, how to you log what the deleted records originally entailed?

As a non-profit, we're audited annually and when staff can accidentally delete payments/orders/etc for money already collected or products already delivered, we lose any history of how it all happened. I'm hoping I'm not the only one who has this question and some of the more tenured users here can point me in a direction.

# Answer
> 3 votes
IMO the Message module would be a perfect fit to answer this question. Using this module, you can create your own custom "*Events logging*" (to register things that happened in a site).

Specific to this question here, I'd create an appropriate set of so called "Message types" that fit your needs (the "*concerns you're attempting to address*", as in your question, seem to require multiple Message types). Some of the actual data you probably want to be included in one or more of them:

* username ("***who***" did something).
* event date ("***when***" did something happen).
* any data about the actual orders you want to track, such as the order id (of course), etc.

You could even track how those data looked like before and after they got updated, a kind of "light" revisioning (only for those attributes you want to know about).

About *Message types*: think of them as equivalent to Content types, whereas you create messages (instead of nodes) of a specific Message type (instead of Content type).

### Rules integration

A really interesting facility of the Message module is its perfect integration with the Rules module. Have a look at the answer to "How to implement a follow author (or user) function?" for way more details on that.

In your case, you'd simply create a (rather basic) custom rule which uses:

* a Rules Event like "Before saving a new order", of "After updating an existing order" (or variations of these events).
* a Rules Action to "Create a message" (of a selected Message type).

That's really it ...

### Example included in Commerce Kickstart

A great sample of this can be found in Commerce Kickstart, which uses the Commerce Message module, to create such "*Events logging*". In that case in the format of an Order History, as shown in this screenprint (from this module's project page).

### More info about the Message module

The Message module is an amazing module, it is fully entity based, which implies that it perfectly (out of the box) integrates with modules such as Views and Rules.

For more details about the Message module, refer to some interesting Use Cases detailed within its Community Documentation. And/or checkout the video introduction "Your Drupal site can talk" (if you want you can fast forward to about 03:30 where it really starts).

### Learn from examples

There is ***not a lot of documentation about the Message module*** (which is what makes it a hidden Drupal gem). A possible way to get started with it, and to get an idea of the kind of things it can be used for, is to have a look at the answers to:

### Replacement tokens

Because of the nature of your question, it seems you'll have quite a few of custom data to be included in your custom messages (= log records to be created). Most of them will NOT be supported out of the (message) box.

However, there is a pretty amazing technique you can take advantage of, i.e. the "replacement tokens" used by the Message module. For an in depth tutorial about how to use this technique, refer to "What's the purpose of "Replacement tokens" of a Message type?". Here are some examples where this technique is used:

# Answer
> 3 votes
I'm assuming you're using Drupal 7 here but one of the most effective ways to do is to handle it the same way that Commerce Kickstart does: with the Message stack.

There is a Commerce Message module exposes some of the common events, you'll just need to create a view and tie it into your order page or figure out some other way of handling things.

---
Tags: 7, commerce
---


# Question
Title: Where do I add HTML content into a block?
I have created a custom block, but there is no option to add content or any body part.

>

How do I add content to a block?

# Answer
I think you first want to define the fields of a block content type. You'll find this at this url:

```
www.mysite.com/admin/structure/block/block-content/types

```

In the admin UI this is not so easy to find like the node content type at the top level of the admin structure. The block content types are two or three levels deeper in the block layout. To access above link make sure you have the *Custom Block* module enabled.
> 2 votes

# Answer
You may want to take a look at Drupal 8 custom block with html and javascript

I am able to get it working with the response provided by @Aram Boyajyan
> 0 votes

# Answer
To add a custom block, you need to enable *Custom Block* module which allows the creation of custom blocks through the user interface. Then in *Structure*, *Block layout*, when placing a block, you should have access to the new option *Add custom block* which should allow you to create blocks with HTML content (at the first time, you'd have to create a new block type for it).
> 0 votes

---
Tags: blocks, 8
---


# Question
Title: How to rebuild derived plugins after new entities are installed?
I have a problem with a stale plugin-derivatives cache in a kernel test:

```
  protected function setUp() {
    parent::setUp();
    $this->installConfig(['my_module', 'my_module_test']);
  }

```

The `my_module_test` module installs new entities that *should* produce derived plugins, but when my test class tries to instantiate these plugins, they are not found.

It works if I explicitly call `$this->container->get('{my_plugin_manager}')->clearCachedDefinitions()` after `installConfig()`, so it's definitely a stale plugin cache. But I'm worried this problem might happen elsewhere. Is there some way to tag the plugin cache with `{my_entity_type}_list` so it gets invalidated by new entities? Or do I simply need to invalidate it explicitly whenever I do something that creates new entities?

# Answer
> 2 votes
Yes you should do that.

Module install is not really a problem as all plugins are invalidated then anyway, but entities can also be changed in the UI.

See \Drupal\block\_content\Entity\BlockContent::postSave() for an example that does that in core.

---
Tags: 8, caching, testing, plugins
---


# Question
Title: Set the default value for a password field on a custom form
I have created a custom user register form. I want to set the default value for the password, and confirm the password fields.
My point is that, whenever form error occurs, the password fields get cleared. Users don't need to type the password again and again.

# Answer
If you are using password as form element type for the password, it does not support the *#default\_value* property. The password field is cleared when there is a validation error.
> 0 votes

---
Tags: users
---


# Question
Title: How do I call $form_state->getValue() to get as value in an array?
I created a form for a block plugin. I'm attempting to save the values to the form after submitting. However, I'm having trouble saving the values that are in an array.

```
public function blockForm($form, FormStateInterface $form_state) {
  $form['plugins_string_text'] = array(
    '#type' => 'text_format',
    '#title' => $this->t('Block contents'),
    '#format' => 'full_html',
    '#description' => $this->t('This text will appear in the block.'),
    '#default_value' => $this->configuration['plugins_string_text-submit'],
  );

  $form['header']['margin-top'] = array(
    '#type' => 'textfield',
    '#title' => t('Margin Top (pixels)'),
    '#default_value' => $this->configuration['header']['margin-top-submit'],
  );

  $form['header']['margin-bottom'] = array(
    '#type' => 'textfield',
    '#title' => t('Margin Bottom (pixels)'),
    '#default_value' => $this->configuration['header']['margin-bottom-submit'],
  );

  $form['header']['margin-left'] = array(
    '#type' => 'textfield',
    '#title' => t('Margin Left (pixels)'),
    '#default_value' => $this->configuration['header']['margin-left-submit'],
  );

  $form['header']['margin-right'] = array(
    '#type' => 'textfield',
    '#title' => t('Margin Right (pixels)'),
    '#default_value' => $this->configuration['header']['margin-right-submit'],
  );
}

public function blockSubmit($form, FormStateInterface $form_state) {
  $this->configuration['plugins_string_text-submit']  = $form_state->getValue('plugins_string_text');
  $this->configuration['header']['margin-top-submit'] = $form_state->getValue('header','margin-top');
  $this->configuration['header']['margin-bottom-submit'] = $form_state->getValue('header','margin-bottom');
  $this->configuration['header']['margin-right-submit'] = $form_state->getValue('header','margin-right');
  $this->configuration['header']['margin-left-submit'] = $form_state->getValue('header','margin-left');
}

```

This is properly saved.

```
$this->configuration['plugins_string_text-submit']  = $form_state->getValue('plugins_string_text');

```

However, each of the following lines displays the entirety of the 'header' array instead of the individual values.

```
$this->configuration['header']['margin-top-submit'] = $form_state->getValue('header','margin-top');
$this->configuration['header']['margin-bottom-submit'] = $form_state->getValue('header','margin-bottom');
$this->configuration['header']['margin-right-submit'] = $form_state->getValue('header','margin-right');
$this->configuration['header']['margin-left-submit'] = $form_state->getValue('header','margin-left');

```

How do I call `$form_state->getValue()` to get the value of an element in an array?

# Answer
> 24 votes
Put the keys in an array, for example:

```
$this->configuration['header']['margin-top-submit'] = $form_state->getValue(['header','margin-top']);

```

# Answer
> 6 votes
This worked for me in drupal 8 after many hours of testing. I hope it helps.

```
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
    $is_live = $form_state->getValue('settings')['is_live '];
}

```

---
Tags: 8, forms
---


# Question
Title: How to get hook_form_FORM_ID_alter field value in hook_ENTITY_TYPE_presave
I am adding one field dynamically by using hook\_form\_FORM\_ID\_alter.

```
/**
 * Implement hook_form_FORM_ID_alter
 * @param $form
 * @param \Drupal\Core\Form\FormStateInterface $form_state
 * @param $form_id
 */
function hook_form_FORM_ID_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
    // Modification for the form with the given form ID goes here. For example, if
    // FORM_ID is "user_register_form" this code would run only on the user
    // registration form.

    $form['platforms'] = array(
        '#type' => 'textfield',
        '#title' => 'Add Platforms',
        '#required'=>True,
    );
}

```

"platform" field is added dynamically here, now I want this field value in hook\_ENTITY\_TYPE\_presave.

```
/**
 * Implement hook_ENTITY_TYPE_presave
 *
 * @param \Drupal\node\NodeInterface $node
 */
function hook_ENTITY_TYPE_presave(\Drupal\node\NodeInterface $node){
    if($node->bundle()=='platform'){
        $field_platforms = $node->get('platforms')->getValue();// Here how to get platform field value.
   }
}

```

I am not getting any idea how do this any help very appriciate.

# Answer
> 2 votes
The form field you've added is not a node field.

If you want the field to be accessible in the node, then add it to the content type. In this case you don't need a form alter hook, because the entity fields are added to the form automatically. You can create multiple form modes with and without the field and select them dynamically, for example with Form mode manager.

If you don't want the field to be stored in the node, but want to do something else with the user input, then add a custom submit handler in the form alter hook to process the field value.

---
Tags: 8, entities, hooks
---


# Question
Title: Why is #attached library load not working, but drupal_add_library works?
This question is specific to D7: I'm trying to load in jQuery UI modal into the theme. I've put the following in my `THEMENAME_preprocess_html`:

```
$variables['page']['content']['#attached']['library'][] = array('system', 'ui.dialog');

```

This isn't loading the library at all.

DPM-ing the `$variables` array after the above line shows that it's all added correctly (There's even other stuff in there like, addthis.js):

Direct link: https://i.stack.imgur.com/6iC3h.png

Obviously all caches were cleared. At this point the console shows an error that `dialog is not defined`. But as soon as I add this (in the same function, just below the `#attached` line):

```
drupal_add_library('system', 'ui.dialog');

```

then the dialog modal opens and starts playing nicely. Am I doing something wrong with #attached? I'm really puzzled as to why one's working and the other doesn't. Ideally I'd like to use `#attached` in the cases where the variables array gets cached and the preprocess doesn't get called.

# Answer
> 3 votes
Because the render array has already been rendered before the preprocess functions, '#attached' is not supported in preprocess functions until Drupal 8.

The issue where it was added is https://www.drupal.org/node/2346369

The related Drupal 8 change record is https://www.drupal.org/node/2352319 \- this also shows the supported way of doing it in Drupal 7.

Using drupal\_add\_library() will work, but it will not be cached, so you will take a performance hit. You are better off adding it to the #attached array at a different step in the process.

---
Tags: 7, javascript
---


# Question
Title: Dynamic Page Cache not working for my controller?
I have a module that defines route /x and assigns it the controller ViewNodes::show. This takes no parameters and the show method simply returns a nearly blank render array:

```
[
'#theme' => 'view_nodes',
'#cache' => ['tags' => ['node_list'], 'max-age' => Cache::PERMANENT, 'bin' => 'render'],
'#pre_render' => [[$this, 'buildNodeListView']]
];

```

The buildNodeListView then takes care of doing all the expensive logic and SQL queries to build the array. This all works fine and the page displays as expected, but devel's WebProfiler shows the SQL queries for building the render array are still being executed even when they should have been cached. This suggests buildNodeListView is always being called, which means #pre\_render is always being called, which means the render array is always a miss. Am I mistaken here?

The route shows up under "bin dynamic\_page\_cache" and is always marked as MISS. And in the HTTP headers, there's always X-DRUPAL-DYNAMIC-CACHE: UNCACHEABLE

Is there something I'm doing wrong, or things I should check to further debug this? My settings.local.php has

```
//$settings['cache']['bins']['dynamic_page_cache'] = 'cache.backend.null';

```

and

```
 //$settings['cache']['bins']['render'] = 'cache.backend.null';

```

They're both commented out so the caching should be enabled. The Dynamic Page Cache module is also enabled. And my routes do not have the "no\_cache" option.

# Answer
You need cache keys

```
'#cache' => ['keys' => ['key1', 'key2', ...], ...]

```

and this is not the dynamic page cache, it is the standard render cache which will take care of this.
> 1 votes

---
Tags: 8, caching
---


# Question
Title: Cannot log in site despite having credentials from settings.php
Ubuntu 16.04, Drupal 8 managed through ISPConfig 3.1

I'm trying to log in at `mysite.com/index.php/user/login` and I get bad username or password. I have copied and pasted from the `settings.php` file and everything.

This is a box that was setup for me by someone else who, when asked for the credentials, directed me to just get them from `settings.php`.

The only thing I can think of is that I'm somehow getting a site-login instead? But it's a fresh Drupal 8 install with no config. Is there any other source for the password or alternate password for it?

I've tried going through ISPConfig and changing the database password there but it just breaks the whole site:

> “The website encountered an unexpected error. Please try again later.”

So I just revert to the snapshot.

# Answer
Okay I see what happened now.

I was trying to login to Drupal and not to the database, but I was getting the DB password from settings.php.

On the Drupal sites I setup in the past I used the database user and password as the Site Maintenance Account’s credentials, so I’m used to them always correlating. Since someone else set this one up they put the user and pw to something different. It's probably a security hole to do it the way I was doing it so I guess I need to fix that.
> 0 votes

---
Tags: 8, configuration
---


# Question
Title: Image field in field collection not working
I have an image field inside a field collection (set to unlimited). After selecting the file to upload and clicking Upload the field reverts back to 'No file selected'.

There is nothing in the Drupal or Apache logs and there are no JS errors.

Even stranger, this works on my local dev environment but not on staging server. I have set PHP config to mirror local but again, still not working.

Image field appears to work okay when not in a field collection.

Absolutely no idea what this could be?! Only other difference I can see is PHP version on local is 5.6 and on staging is 5.5 but not sure why this would cause a problem.

EDIT: This is a field collection inside a field collection. An image field nested in a field collection does work.

# Answer
> 0 votes
1) Check if your web-server has read/write access to sites/default/files(typically uploaded files go here).

2) Other reason might be the file you're trying to upload is bigger than allowed. Increase max-allowed upload file-size in **.htaccess** file

```
php_value upload_max_filesize  "20M"

```

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


# Question
Title: How do I add a variant programmatically?
I have many sites in an installation that have many Panels pages. Many of them need a HTTP Response (404) variant added to them, which I would like to do programmatically.

Assume I have the page already via:

```
$page = page_manager_page_load($pageName);

```

Modifying something in the page is easy. Make the change then call `page_manager_page_save($page);`

It seemed the easiest way to accomplish adding a variant was to take an exported variant and import it. This is what the clone function does.

Here is an exported variant:

```
$handler = new stdClass();
$handler->disabled = FALSE; /* Edit this to true to make a default handler disabled initially */
$handler->api_version = 1;
$handler->name = 'page_bes_homepage__http_response_0ab6f1a9-9c98-459c-b4d3-10f63ddace56';
$handler->task = 'page';
$handler->subtask = '';
$handler->handler = 'http_response';
$handler->weight = 1;
$handler->conf = array(
  'title' => '404 Error',
  'contexts' => array(),
  'relationships' => array(),
  'code' => '404',
  'destination' => '',
  'name' => '',
);

```

It doesn't appear necessary to set the subtask or provide a new name since the `page_manager_handler_add_to_page()` appears to handle that (though at first I set those myself; didn't help).

Attempting to add and save via:

```
page_manager_handler_add_to_page($page, $handler);
page_manager_page_save($page);

```

doesn't work. Some code in page\_manager.module had me think that the failure might might be because of ctools caching so I tried this:

```
page_manager_save_page_cache($page);
page_manager_clear_page_cache($pageName);
page_manager_page_save($page);

```

and that doesn't work either. Scouring the web for an example of this has not turned up anything in code snippets, tutorials or books and ctools doesn't provide this level of documentation.

How does one add a variant programmatically? Note that I do not want this in Features and I do not want this stored in code via the ctools api. I just want to run through a list of Panels pages programmatically and add a variant.

# Answer
You can try this:

I found how to store manually created variants in code for custom pages (e.g. '/node/%node/test')

```
function MODULE_default_page_manager_pages() {
  // Copy exported page code here.

  $pages['UNIQUE_PAGE_ID_HERE'] = $page;

  return $pages;
}

```

Putting everthing in a file called 'MODULE.pages\_default.inc' in your MODULE's main folder, and link that file with my MODULE.module via

```
/**
 * Implement hook_ctools_plugin_api().
 *
 * If you do this, CTools will pick up default panels pages in
 * MODULE.pages_default.inc
 */
function MODULE_ctools_plugin_api($module, $api) {
  if ($module == 'page_manager' && $api == 'pages_default') {
    return array('version' => 1);
  }
}

```

Source: https://www.drupal.org/node/579036
> 1 votes

---
Tags: panels
---


# Question
Title: What is the equivalent of hook_property_info_alter()?
In Drupal 7, The Entity API module uses `hook_entity_property_info()` and `hook_entity_property_info_alter()` which allowed us to add custom properties. (Not everything is a field.)

I can't find anything related to Drupal 8. The only thing I find is how to add it on a custom entity. How should I add properties to an existing entity/bundle?

# Answer
I suppose you want hook\_entity\_base\_field\_info(). By using a computed field based on a class, you can get a behavior similar to properties.

```
function hook_entity_base_field_info(\Drupal\Core\Entity\EntityTypeInterface $entity_type) {
  if ($entity_type->id() == 'node') {
    $fields = [];
    $fields['mymodule_text'] = BaseFieldDefinition::create('string')
      ->setLabel(t('The text'))
      ->setDescription(t('A text property added by mymodule.'))
      ->setComputed(TRUE)
      ->setClass('\Drupal\mymodule\EntityComputedText');

    return $fields;
  }
}

```

I have copied a snippet from Drupal commerce, where a payment gateway reference is appended to a commerce\_order entity (commerce\_payment module altering an entity from commerce\_order module).

```
/**
 * Implements hook_entity_base_field_info().
 */
function commerce_payment_entity_base_field_info(EntityTypeInterface $entity_type) {
  if ($entity_type->id() === 'commerce_order') {
    $fields['payment_gateway'] = BaseFieldDefinition::create('entity_reference')
      ->setLabel(t('Payment gateway'))
      ->setDescription(t('The payment gateway.'))
      ->setRequired(TRUE)
      ->setSetting('target_type', 'commerce_payment_gateway');

    $fields['payment_method'] = BaseFieldDefinition::create('entity_reference')
      ->setLabel(t('Payment method'))
      ->setDescription(t('The payment method.'))
      ->setRequired(TRUE)
      ->setSetting('target_type', 'commerce_payment_method');

    return $fields;
  }
}

```

By using `->setReadOnly(TRUE);` or `->setComputed(TRUE)`, you can probably hide them from regular forms, making them behave like properties.
> 4 votes

---
Tags: 8, entities
---


title: REST API and date field format

text:
# Question
Title: REST API and date field format
I have an angular front end with D8 backend. I am populating a content type that has a Date field. I am successfully creating the content-type with the all its fields including the Date field. The format I am sending via POST looks like `2017-07-07`. It gets saved and I can even retrieve the data.

The problem is when I edit or view the node via drupal admin, the date field is empty. If I devel the node, the value I sent is set on the field. It just will not display via in drupal. What format should I be sending the date field so it will save and populate the form.

In JS, I am sending the date like so:

```
var start = new Date();
var params = {
  start: {value: start.getFullYear() + '-' + (start.getMonth() + 1) + '-' + start.getDate()}
};
$http.post(API + 'entity/node', params); //etc

```

# Answer
To set a Date Field via REST in Drupal 8, you can do this:

```
// Build the JSON payload.
var node = {
  "type":[{"target_id":"article"}],
  "title":[{"value":"Hello World"}],
  "field_start":[{"value":"2017-07-21T18:11:11"}]
};

// Then POST the payload to Drupal...
$http.post('https://example.com/entity/node', node);

```
> 1 votes

---
Tags: entities, 8
---


# Question
Title: Page Manager on a variant of the node url
I have overriden the default `/node/%node` layout using panels and the page manager, now I need to add some different content when the URL is `/node/%node/step2`.

I have added a variant, and on the selection rules I added the URL path on `/node/*/step2`. I also tried different URL paths like `/node/%node/step2` or even `*/step2`.

But if I go to that URL it doesn't show up, and returns me a 404. This seems odd since that, if no other variant would be found (like my new `/node/%node/step2`), the default `/node/%node` page should be shown instead of a 404.

So my question is: why am I receiving a 404 instead of my "step2" variant, or even the default node page?

I'm using Page Manager 7.x-1.12.

# Answer
> 1 votes
I don't know if this is the only way to do it but I just add custom pages at `/admin/structure/pages` like:

```
/node/%node/admin

```

I guess there are some benefits to doing it separately instead of as a variant of the main `/node/%node` because now your selection rules etc. are easy to manage for different content types, for example.

Your arguments page should look like this:

---
Tags: 7, panels, chaos-tool-suite
---


# Question
Title: Changing Page Title of Access Denied Page
I have an odd request that appears to only be "solved" (aka not really) through changing the includes/common.inc file.

The instructions are something like...

> 1 Go to INCLUDES Folder 2. and make a copy of the file common.inc 3. use copy to make change. 4. edit the file with a text editor (not WORDPAD) 5. and go to "function drupal\_access\_denied()" 6. go to the 3th "IF" instruction
>
> and if you want change the TITLE of the "ACCESS DENIED" page
>
> change default (t('Access denied')) to something like: (t('Welcome Visitor'))

Obviously it's a stupid and wasteful move to just go through changing a core file, so I was wondering... another answer mentioned adding something to the theme template.php file or the local.module file. If I wanted to change just the text for the page title of the default "Access Denied" references, how would I go about doing that without going into editing the core files?

And due to an odd way a module around the site was built, the custom 404 page idea just won't work, which is why I need the workaround the way I described it.

Thanks ahead of time!

Matt

# Answer
In Drupal 7 You can use GUI.

* Step 1: First create a page and add whatever message you want.
* Step 2: Customize the page alias as you see fit. Copy that URL.
* Step 3: Go to admin/config/system/site-information and then go to the field set for "Error Pages" and put in your custom page alias for the 403 page.
> 0 votes

---
Tags: theming
---


# Question
Title: How do I bypass cart and go straight to checkout?
I know that you can easily achieve this functionality in Drupal 7 with the Rules module or using the Commerce Checkout Express module.

Since Rules and Commerce are not that much integrated yet, I am not sure we can achieve this that easily, in Drupal 8.

Can I implement this feature using just rules? If the answer is *no*, how can I do it, programmatically?

# Answer
If you use the last development version of commerce, and look for file `commerce\modules\cart\src\Form\AddToCartForm.php` which lives under the `Drupal\commerce_cart\Form` namespace, you can see that cart\_id was set, and it is the order ID too.

```
$form_state->set('cart_id', $cart->id());

```

Therefore, in `hook_form_alter()`, we can get the order ID (the cart ID).

```
$order_id = $form_state->get('cart_id');

```

The complete code would be this.

```
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;

/**
 * Implements hook_form_alter().
 */
function <MY_MODULE>_form_alter(&$form, FormStateInterface $form_state, $form_id) {
    // Add to cart form id for product 5 is: commerce_order_item_add_to_cart_form_commerce_product_5
    // Then it's enough to check $form_id contains the string 'commerce_order_item_add_to_cart_form_commerce'
    if(strpos($form_id, 'commerce_order_item_add_to_cart_form_commerce') !== false) {
        $form['actions']['submit']['#submit'][] = '_redirect_to_checkout';
    }
}

// Callback for form submission
// @see hook_form_alter().
function _redirect_to_checkout(&$form, FormStateInterface $form_state) {
  /** @var \Drupal\commerce_order\Entity\OrderInterface $cart_id */
  $cart_id = $form_state->get('cart_id');

  $url = Url::fromRoute('commerce_checkout.form',
    ['commerce_order' => $cart_id]
  );

  $form_state->setRedirectUrl($url);
}

```
> 6 votes

---
Tags: 8, commerce, rules
---


title: How to stop a loop in rules?

text:
# Question
Title: How to stop a loop in rules?
I'm using Conditional Rules module, there some conditions inside the loop I need to break out of. However, there's no action in rules for stopping/terminating the loop.

I tried a custom rules where I tried the following but it does not work:

```
function my_module_break_rules_loop() {
  return FALSE;
}
function my_module_break_rules_loop() {
  return 0;
}
function my_module_break_rules_loop() {
  break;
}

```

The break works but display with this error message:

> PHP Fatal error: Cannot break/continue 1 level in

Any one know how to stop/terminate the loop?

# Answer
> 2 votes
Install Conditional Rules so that you can add "conditions" between " rule actions". After that you can create a variable which iterates and use that to stop after the third elements.

# Answer
> 0 votes
You ought to filter the array before handling it over to the foreach. You could do this by implementing a rule component that takes two parameters:

1. The new (filtered) list.
2. The item you are considering.

Put this component within a foreach loop. That would likely be another component.

If the parameter meets your criteria, then append it to the list. If not, do nothing. The result is that you then have your filtered list.

Now you can do your foreach.

Another possibility is to put a rule component within your loop that only runs if some passed in function works. Basically, a while loop.

---
Tags: 7, rules
---


title: sharing code in custom module

text:
# Question
Title: sharing code in custom module
I have a small module that basically contains a controller and a block plugin. I cannot figure out how to include a class in both of them

The files are located in sites/all/modules/my\_module. That directory contais

```
$ ls -R
.:
config/  my_module.info.yml       my_module.links.menu.yml  src/
css/     my_module.libraries.yml  my_module.routing.yml

./config:
install/

./config/install:
my_module.settings.yml

./css:
hello_block-layout.css

./src:
Controller/  Plugin/  Utils.php

./src/Controller:
MyController.php*

./src/Plugin:
Block/

./src/Plugin/Block:
MyBlock.php

```

The problem is the namespaces: MyController.php has namespace Drupal\my\_module\Controller and MyBlock.php has namespace Drupal\my\_module\Plugin\Block

I can use the class definition in Utils.php for one of the two, if I insert a require\_once in the file (with the *whole path*, use of .. seems not to be working) AND I use the same namespace in it.

So if MyController.php starts with

```
<?php
namespace Drupal\my_module\Controller;
use Drupal\Core\Controller\ControllerBase;

require_once '/home/rdgon/public_html/sites/all/modules/my_module/src/Utils.php';

```

and MyBlock.php starts with

```
<?php
namespace Drupal\my_module\Plugin\Block;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Block\BlockPluginInterface;

require_once '/home/rdgon/public_html/sites/all/modules/my_module/src/Utils.php';

```

and Utils.php starts with

```
<?php
namespace Drupal\my_module\Controller;

```

then the class is used by correctly by the controller. But then MyBlock.php complains about not finding the class, because the namespaces don't match.

My question: is it possible to share (include) a class definition by several components of a module? What location should I use for the shared code and what is the proper way to include it? (using the full path of the file cannot be the way to go)

thanks in advance, Ruud

# Answer
If you want the class declared in `my_module/src/Utils.php` to be made available to *any* PHP script, add this at the top of that script file:

```
use Drupal\my_module\Utils;

```

This of course assumes that you're following the correct PSR-4 standards for naming: make sure that mymodule/src/Utils.php exists, and contains one single class named `Utils`, with `namespace Drupal\my_module` at the top.

See PSR-4 namespaces and autoloading in Drupal 8 for a more in-depth explanation.
> 2 votes

---
Tags: 8
---


# Question
Title: How to make all render caches update on a configuration override?
**Short version:**

I am using a configuration override to override the site name. Changes are reflected in the HTML title, but not in the system branding block. Drupal keeps serving this block from the render cache.

**Long version:**

I am using a configuration override service that implements ConfigFactoryOverrideInterface, which overrides configs on demand. Slightly simplified, it looks like this:

```
class MyConfigOverride implements ConfigFactoryOverrideInterface {

  /**
   * {@inheritdoc}
   */
  public function loadOverrides($names) {
    $overrides = [];

    if ($override_required) {
      if (in_array('system.site', $names)) {
        $overrides['system.site']['name'] = 'My name';
      }
    }
    return $overrides;
  }

  /**
   * {@inheritdoc}
   */
  public function getCacheSuffix() {
    return 'MyConfigOverride';
  }

  /**
   * {@inheritdoc}
   */
  public function getCacheableMetadata($name) {
    $metadata = new CacheableMetadata();

    if ($name === 'system.site') {
      $my_entity = MyEntity::Load(1);
      if ($override_required && !empty($my_entity)) {
        // Append entity cache metadata (cache tags and context).
        $metadata->addCacheableDependency($my_entity);
      }
    }
    return $metadata;
  }

  /**
   * {@inheritdoc}
   */
  public function createConfigObject($name, $collection = StorageInterface::DEFAULT_COLLECTION) {
    return NULL;
  }

}

```

However, as soon as this override kicks in, the render cache for the System branding block does not get updated with the new site name. This is because the SystemBrandingBlock class does implement `getCacheTags()` in which it merges the system.site cache tags (see below), but it does not implement `getCacheContexts()` (which my module uses since I serve a variation of the page).

```
/**
 * {@inheritdoc}
 */
public function getCacheTags() {
  return Cache::mergeTags(
    parent::getCacheTags(),
    $this->configFactory->get('system.site')->getCacheTags()
  );

}

```

I have tried to overcome this by adding additional 'empty' cache metadata to my class for the cases where the override does not apply.

```
  /**
   * {@inheritdoc}
   */
  public function getCacheableMetadata($name) {
    $metadata = new CacheableMetadata();

    if ($name === 'system.site') {
      $my_entity = MyEntity::Load(1);
      if ($override_required && !empty($my_entity)) {
        // Append entity cache metadata.
        $metadata->addCacheableDependency($my_entity);
      }
      else {
        // Append 'empty' cache metadata.
        $metadata->addCacheContexts(['mycachecontext']);
        $metadata->addCacheTags(['myentity', 'myentity:0']);
      }
    }
    return $metadata;
  }

```

Since the block does not inherit the cache contexts of `system.site` and I do not update or otherwise invalidate any of the provided cache tags ('myentity', 'myentity:0'), the render cache still persists. I can append cache context to the system branding block in a `hook_block_build_BASE_BLOCK_ID_alter` implementation, but I'd prefer not to implement such specific exceptions as they will never cover all situations.

I am somewhat hoping for a hook to update all renderable elements (blocks?) and append cache contexts to those that inherit cache tags provided by `system.site`. But I am open to alternative solutions as well.

How can I make any block or other entity in the render cache, that is depending on the `system.site` config aware of the config override?

# Answer
> 3 votes
> In the meantime I have come up with this approach, but I am still open to other solutions.

I have found a solution in a pre\_render callback for the blocks, by deconstruction the cacheable metadata, searching it for a `system.site` tag and append my own context and tags (if required).

```
/**
 * Implements hook_block_view_alter().
 */
functionmymodule_block_view_alter(array &$build, \Drupal\Core\Block\BlockPluginInterface $block) {
  $build['#pre_render'][] = 'mymodule_block_view_pre_render';
}

/**
 * #pre_render callback: Sets my module cache tags.
 */
function mymodule_block_view_pre_render(array $build) {
  $cacheable_metadata = CacheableMetadata::createFromRenderArray($build);
  $tags = $cacheable_metadata->getCacheTags();

  if (in_array('config:system.site', $tags)) {
    // Always add a cache context, so we have a variant without overrides as well.
    $cacheable_metadata->addCacheContexts(['mycontext']);

    if ($entity = MyEntity::Load(1)) {
      $cacheable_metadata->addCacheableDependency($entity );
    }
  }

  $cacheable_metadata->applyTo($build);

  return $build;
}

```

---
Tags: 8, blocks, caching, configuration
---


# Question
Title: How to add selected users to OG Group from field selection when creating group
I have an OG and a field that lists users with checkboxes. Is there a way using Rules, to add the selected users as group members when group is saved/updated?

# Answer
> 1 votes
This is the rule I created to solved it:

1. After updating/adding existing content of type
2. Entity has field Parameter: Entity: \[node\], Field: FIELD WITH UNAMES
3. Crete a LOOP
4. (In Loop) Subscribe user to group -- Parameter: User: \[list-item\], Group: \[site:og-context--node\]

Here is an export of my rule:

```
{ "rules_watch_list_group_add" : {
  "LABEL" : "Watch List Group Add",
  "PLUGIN" : "reaction rule",
  "OWNER" : "rules",
  "REQUIRES" : [ "rules", "og" ]
  "ON" : { "node_insert" : [], "node_update" : [] },
  "IF" : [
    { "entity_has_field" : { "entity" : [ "node" ], "field" : "field_watch_list" } }
  ],
  "DO" : [
    { "LOOP" : {
        "USING" : { "list" : [ "node:field-watch-list" ] },
        "ITEM" : { "list_item" : "Current list item" },
        "DO" : [
          { "og_subcribe_user" : { "user" : [ "list-item" ], "group" : [ "site:og-context--node" ] } }
          ]
        }
      }
    ]
  }
}

```

---
Tags: rules, organic-groups
---


# Question
Title: Using rules to populate a field with the output of pdfprevew
I have a field (public\_files) that accepts file uploads to which I have applied the pdfpreview module which provides a field formatter that will provide the generated image for pdf files. I have another field for cover images.

This setup is working well, and I basically default to the cover image field, and fallback to the pdf preview version of the first file if the cover image hasn't been provided. A problem arises for a section of the site where I only want to list items that have cover images. There is a complicated bug in drupal that prevents me from doing the filtering in views to only items that have a cover image or for which the first file is a pdf file.

To alleviate this, what I'd like to do is use rules to automatically populate the cover image field with the generated cover whenever there is a generated cover image, and the cover image field is empty.

Sorry for the long preamble, here is the question:

**Is there any way to get at the pdf preview image and populate an image field with it in rules?**

# Answer
From your question, I seem to understand that this is your ***goal*** (= quote from your question):

> ... use rules to automatically populate the cover image field with the generated cover whenever there is a generated cover image, and the cover image field is empty.

There seem to be at least 3 ways to achieve *that* goal, as further detailed below ...

# Solution 1

This solution elaborates on one of your comments, which is like so:

> I was thinking at node view, might be a good time just to be sure that the preview had had a chance to be saved. I'd then need a condition to check whether the cover field already has a value and one to see if either there is a pdfpreview available or if the first file in the field is a pdf.

This could indeed work, but the crucial Rules challenge here is that there is no such event like "***BEFORE***" a node is being viewed. Because the "clue" about what Rules EVent "Content is viewed" actually means, seems to be like so:

* The event ***Content is viewed*** is what it is: the user has (already) started viewing the content.
* The (system) event ***Drupal is initializing*** is what you should use instead (possible combined with other Events and/or Actions), if you want to trigger some Rules "Action(s)" ***BEFORE*** the user can start viewing (= looking at) the content.

For more details, and a working sample (in Rules 'export format'), refer to How to specify a Rules event like "Content is 'going to be' viewed"?

**My advice**: only use this if all other options (solutions) fail. Read on for what IMO is a better solution.

# Solution 2

This solution elaborates on one of your comments, which is like so:

> ... at node create and node update may be a much better time, if pdf preview has had a chance to do what it does by the time those events fire ...

Using this approach, you'll run into another Rules challenge ... I.e what's detailed in issue # 430274, about an event which is a variation of your event here, and somehow explains that "after saving something" actually happens "before saving something". This is not a bug, but simply how the Rules module works.

**My advice**: using this solution is a kind of risky, because of that above mentioned Rules challenge. Read on for what IMO is a better solution.

# Solution 3

A possible compromise to avoid the kind of issues described in Solution 2, is to implement what needs to be done into a Rules Component, so that your original Rule "schedules the execution" (using the Rules Scheduler sub-module) of that Rules component. For example after only a few seconds or minutes if your cron job runs frequent enough (otherwise it'll be next time cron runs). This compromise will ensure that, at the time the Rules component is executed, the entity is for sure saved (so *that* can't be the reason anymore then why things don't work as expected). Read on for how you can get this to work ...

### Step 1 - Create a Rules Component

Have a look at this Rules Component, in Rules export format:

```
{ "rules_populate_an_output_field_with_an_input_field" : {
    "LABEL" : "Populate an output field with an input field",
    "PLUGIN" : "rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules" ],
    "USES VARIABLES" : { "node_to_update" : { "label" : "Node to be updated", "type" : "node" } },
    "IF" : [
      { "entity_has_field" : { "entity" : [ "node-to-update" ], "field" : "field_image" } },
      { "NOT data_is_empty" : { "data" : [ "node-to-update:field-image" ] } },
      { "entity_has_field" : { "entity" : [ "node-to-update" ], "field" : "field_cover_image" } },
      { "data_is_empty" : { "data" : [ "node-to-update:field-cover-image" ] } }
    ],
    "DO" : [
      { "data_set" : {
          "data" : [ "node-to-update:field-cover-image" ],
          "value" : [ "node-to-update:field-image" ]
        }
      },
      { "entity_save" : { "data" : [ "node-to-update" ], "immediate" : "1" } }
    ]
  }
}

```

This Rules Component used a "node" (the node to be updated) as a parameter.

This is what the Rules Conditions in the above Rules Component are about:

* It uses a parameter "Node to be updated".
* It processes the fields with machine names `field_cover_image` and `field_image` (adapt the machine names to fit your own field names, prior to trying to import this Rules Component in your own site).
* It has a rules condition "Entity has field" (twice) to make those fields available for subsequent processing.
* It has a Rules Condition for each of both fields to check that their initial value (before the Rules Component's actions will be triggered), to match your requirement like "*... populate the cover image field with the generated cover whenever there is a generated cover image, and the cover image field is empty...*".

This is what the Rules Actions in the above Rules Component do:

* Set the value of field `field_cover_image` equal to the value of field `field_image`.
* Save the node (to ensure the updated value actually gets saved ...).

### Step 2 - Create a Rule to schedule the Rules Component

This one is pretty easy, here is a rule (in Rules export format) that will "*schedule*" the execution of the Rules Component from the previous step:

```
{ "rules_schedule_image_population" : {
    "LABEL" : "Schedule image population",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules", "rules_scheduler" ],
    "ON" : { "node_insert" : [], "node_update" : [] },
    "IF" : [
      { "entity_has_field" : { "entity" : [ "node" ], "field" : "field_cover_image" } }
    ],
    "DO" : [
      { "schedule" : {
          "component" : "rules_populate_an_output_field_with_an_input_field",
          "date" : "+1 min",
          "identifier" : "Schedule-image-population-[node:nid]",
          "param_node_to_update" : [ "node" ]
        }
      }
    ]
  }
}

```

The rule uses as Rules Event "After creating a new node", or "After updating an existing node".

To avoid wasting resources, we only want to trigger the Rules Action for nodes that do have that `field_cover_image` field we want to populate (hence the Rules Condition).

And all this rule has to do (as Rules Action), is to schedule the execution of the Rules Component from the previous step. Adapt the delay to fit your needs (I've set it to just 1 min).

**My advice**: go for solution 3 (tested in my own setup, works like a charm ...)

***`Easy, no`***?
> 0 votes

---
Tags: 7, rules
---