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 Answer 1

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, 2020 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. Apr 17, 2020 at 14:18

Your Answer

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