4

I am programming a new module in my Drupal 7 project. in my module hook_cron is override.

in my hook_cron function, I want to select a node type with specific filter for a cck field.

I am using EntityFieldQuery in order to run a query.

my specific content type is "order_status"

here us the first code of query.

$query->entityCondition('entity_type', 'node')
    ->propertyCondition('type', array('order_status'))
    ->propertyCondition('status', 1);
$result = $query->execute();
dpm($result);

this code works with no problem. it collects all nodes with "order_status" content type that are published. (status is 1)

but when I want to add a new cck filter to the query it doesn't work.

I have defined some cck fileds for my "order_status" content type.

one of them is field_order_status_cr_confirm type of this field is boolean (TRUE/FALSE or 1 | 0)

for adding a new filter to my above query I used this code.

->fieldCondition('field_order_status_cr_confirm','value',1,'=');

so my final query is

$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node')
    ->propertyCondition('type', array('order_status'))
    ->propertyCondition('status', 1)
    ->fieldCondition('field_order_status_cr_confirm','value',1,'=');
$result = $query->execute();
dpm($result);

but this code doesn't work. it returns nothing. also I changed value of the field_order_status_cr_confirm to 1 but it still returns no data.

Do you know what my problem is ?

here is the dpm function result for one node of "order_status" type. enter image description here

Please help me.

3 Answers 3

8

I have also encountered this kind of issue that running EntityFieldQuery does not work sometimes in the cron job.

It turns out that EntityFieldQuery will run access check.

Cron job is run as anonymous user role and it cannot access to order_status node.

To work around this issue you can add tag DANGEROUS_ACCESS_CHECK_OPT_OUT to bypass node access.

Here is the example:

$query->entityCondition('entity_type', 'node')
    ->propertyCondition('type', array('order_status'))
    ->propertyCondition('status', 1);
    ->addTag('DANGEROUS_ACCESS_CHECK_OPT_OUT');
$result = $query->execute();
6
  • I added this expression "->addTag('DANGEROUS_ACCESS_CHECK_OPT_OUT');" to my query builder but it seems there is no differences.
    – Mehrdad201
    Dec 3, 2013 at 20:28
  • Can you run this query to check if valid data exists? $sql = "SELECT COUNT(*) FROM {field_order_status_cr_confirm} order_status LEFT JOIN {node} n ON n.nid=order_status.entity_id AND order_status.entity_type='node' AND order_status.bundle='order_status' WHERE n.status = 1 AND order_status.field_order_status_cr_confirm=1"; $result = db_query($sql)->fetchField(); dpm($result); Dec 4, 2013 at 23:47
  • I will do that as soon as I can. this is very strange thing. When I want to see a node page in anonymous mode, I see restricted message. but when I run cron , I can see very thing . (in my cron, I used print_r function to print the result array)
    – Mehrdad201
    Dec 5, 2013 at 7:55
  • A cron job run as an anonymous user? Why? It's flushing cache meaning its accessing your DB. Why would it run as an anonymous user.
    – AlxVallejo
    Jun 6, 2014 at 22:25
  • I was having the same problem and this solved my issue. But still, why does cron run as an anonymous user? Dec 13, 2017 at 21:54
3

Another workaround is running the query as user 1:

$query->entityCondition('entity_type', 'node')
    ->propertyCondition('type', array('order_status'))
    ->propertyCondition('status', 1)
    ->addMetaData('account', user_load(1)); // <- Skip access checks!

$result = $query->execute();

See documentation at https://www.drupal.org/docs/7/creating-custom-modules/howtos/how-to-use-entityfieldquery.

0

I had to combine 2 changes to make my query work in hook_cron :

  1. apply entityCondition instead of propertyCondition on the type column
  2. use the addMetaData() method as previously mentioned

Code

  $query->entityCondition('entity_type', 'node')
    ->entityCondition('bundle', 'person')
    ->propertyCondition('title', '')
    ->range(0, 20)
    ->addMetaData('account', user_load(1));

instead of

  $query->entityCondition('entity_type', 'node')
    ->propertyCondition('type', 'person')
    ->propertyCondition('title', '')
    ->range(0, 20);

Apparenlty our production environment acted differently then our staging environment where the addMetaData() was sufficient to solve this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.