0

I have the article node with two extra fields:

  • Taxonomy reference field field_verification_status with two possible values:
    • Valid (tid: 272)
    • Expired (tid: 271)
  • Date field (field_article_expiry_date)

When a user will create a new article, will set:

  • Taxonomy reference field field_verification_status = Valid (tid: 272)
  • Date field (field_article_expiry_date) = Any time in the future.

Now using Ultimate Cron Module, I want on every cron run, to:

  1. Check if the field_article_expiry_date value is less than current time (now)
  2. if above return true then change the field_verification_status value to Expired (tid: 271)

To accomplish the above, I have created a new module custom_cron_expired_articles and in the .module file I added the below codes:

<?php

use Drupal\node\Entity\Node;
use Drupal\taxonomy\Entity\Term;

/**
 * Implements hook_cron().
 */

// On "Cron Run" and "Every Half Hour":
    // Loop through all "Valid" articles with expiry date set to the past,
    // Change the status of each article to "Expired".

function custom_cron_expired_articles_cron() {

  // Get the "cron time" (Return Value is in UNIX Timestamp format)
    //$cron_time = \Drupal::time()->getCurrentTime();
    //date_default_timezone_set('GMT');

// Load all available expired nodes of type 'offer'.
  $storage = \Drupal::entityTypeManager()
    ->getStorage('node');
  $query = \Drupal::entityQuery('node')
      ->accessCheck(FALSE)
      ->condition('type', 'article')
      ->condition('field_verification_status', 272)    // Verification Status = Valid
      ->condition('field_article_expiry_date', strtotime($?????), '<=')  // Something is missing here
      //->range(0,50);
  $nids = $query->execute();

// Loop through all expired nodes.  
foreach ($nids as $nid) {

// Load the Node by its ID.
    $node = \Drupal\node\Entity\Node::load($nid);

    // Update the node.
    $node->field_verification_status->target_id = 271; // Verification Status = Expired

    // Save the updated node.
    $node->save();

// resetCache() in such a loop over all entities of one type avoids running out of memory.
\Drupal::entityManager()->getStorage('node')->resetCache(array($nid));
}
}

How to compare if the field_article_expiry_date is less than the current_time ? or by other words, how to load only the nodes with field_article_expiry_date less than the current_time?

Can somebody tell me what is the missing part ?

1

You store the value returned from \Drupal::entityTypeManager() ->getStorage('node') in $storage, but you don't use it. On the next line you use \Drupal::entityQuery(). (I don't recommend it, as it will be deprecated in Drupal 9; you should use the entity type manager.)

The code I would use is the following one.

  use Drupal\Core\Datetime\DrupalDateTime;

  // Build Drupal DateTime & set correct format for your query
  $curent_time = new DrupalDateTime('now');
  $curent_time = $curent_time->format('Y-m-d\TH:i:s');

  // Get Entity Manager to build your query
  $storage = \Drupal::entityTypeManager()
      ->getStorage('node');

  // Get all Nodes satisfing your conditions
  $nids = $storage->getQuery()
      ->condition('type', 'article')
      ->condition('field_verification_status', 272)
      ->condition('field_article_expiry_date', $curent_time, '<=')
      ->execute();

  // Load all Node entities according to their IDs
  $nodes = \Drupal\node\Entity\Node::loadMultiple($nids);

  // Do whatever you want with Nodes
  foreach ($nodes as $node) {
    // Do something
    $node->save();  
  }

See also

2
  • Does this piece of code at the end of foreach important ? \Drupal::entityManager()->getStorage('node')->resetCache(array($nid)); – user98752 Apr 17 '20 at 14:14
  • When you do this automatically, every time cron runs, I'd leave it there, so internal Node's cache will be cleared so you don't need to Clear Cache manually. – Patrick Star Apr 17 '20 at 14:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy