-1

My question has a half answer here but not completed for my case.

This is the piece of code I am talking about:

<?php

function mymodule_cron() {
  $storage_handler = \Drupal::entityTypeManager()
    ->getStorage('node');
  $query = \Drupal::entityQuery('node')
    ->accessCheck(FALSE)
    ->condition('created', strtotime('-2 year'), '<=')
    ->range(0,50);
  $result = $query->execute();
  if (!empty($result)) {
    $nids = array_keys($result);
    $nodes = $storage_handler->loadMultiple($nids);
    $storage_handler->delete($nodes);
  }
}

On one of my projects, cron is scheduled to run every 5 minutes.

I want when:

  1. Cron Run and
  2. at the end of the day so time is 00:00 (midnight) or between 23:45 - 00:00

to programmatically delete arbitrary only 50 nodes from my site that meet the below conditions:

  1. of type: article (if any) and
  2. node creation time is more than 2 years old.

The above code will:

  1. Delete 50 nodes at once. (GOOD)
  2. Which have node creation time more than 2 years old. (GOOD)
  3. Delete all nodes of any type (NOT GOOD)
  4. Will Run on every cron run (NOT GOOD)

So... how to alter the above code to:

  1. Run only on Cron and the end of the day is reached so time of the day is 00:00 (midnight) or between 23:45 - 00:00 ?

  2. Delete only nodes of type: article (if any) ?

If someone has a better idea on how to implement what I need, please do share it here!

UPDATE #2:

I have found the below code is working as expected:

 $result = \Drupal::entityQuery('node')
      ->accessCheck(FALSE)
      ->condition('type', 'article')
      ->condition('created', strtotime('-2 month'), '<=')
      ->range(0,50)
      ->execute();      
  entity_delete_multiple('node', $result);

can please someone check if this is the right way to delete a bunch of nodes or there is a different better method ?

closed as too broad by Clive Apr 28 at 13:09

Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 1
    Please remember to keep it to one distinct question per post, otherwise it’s by definition too broad for a question here. Also make sure you add details of what you’ve tried yourself, and where those attempts are going wrong, as we don’t write tutorials here. Thanks – Clive Apr 28 at 13:10
  • 1
    Writing tests would be a good way to narrow down what the issue might be with your code. – Kevin Apr 28 at 18:09
  • Also, once the question has been answered, it cannot be changed, if the change invalidates the given answers. If a user posts an answer suggesting to use some code, you cannot edit the question saying that the same code doesn't work. If the answer doesn't work for you, just comment on that answer saying it doesn't work for you. – kiamlaluno Apr 28 at 18:25
  • @Clive you flagged the question as too broad, I cannot understand how you find such question as too broad... the question is well detailed with a proposed code and all I asked for is a help push on how to do it in the right way !!! can you please remove the too broad flag from the question ! Thank you – Elie Masaad Apr 28 at 22:03
2

Delete only nodes of type: article (if any) ?

add the condition ->condition('type', 'article') to your query. your cron hook will be like:

/**
 * Implements hook_cron().
 */
function mymodule_cron() {
  // Delete 5O node of type articles.
  _mymodule_delete_nodes_of_type_before_while('article','-2 year', 50);
  // Delete 30 node of type page.
  _mymodule_delete_nodes_of_type_before_while('page','-1 year', 30);
}

/**
 * Helper function to delete nodes created before a while.
 *
 * @param $bundle
 * @param string $time
 * @param int $range
 * 
 */
function _mymodule_delete_nodes_of_type_before_while($bundle, $time = '-2 year', $range = 50){
  $storage_handler = \Drupal::entityTypeManager()
    ->getStorage('node');
  $query = \Drupal::entityQuery('node')
    ->accessCheck(FALSE)
    // Get only nodes of type article.
    ->condition('type', $bundle)
    ->condition('created', strtotime($time), '<=')
    ->range(0, $range);
  $result = $query->execute();
  if (!empty($result)) {
    $nids = array_keys($result);
    $nodes = $storage_handler->loadMultiple($nids);
    $storage_handler->delete($nodes);
  }
}

Run only on Cron and the end of the day is reached so time of the day is 00:00 (midnight) or between 23:45 - 00:00 ?

You can use one of contrib module to scheduled your cron i use to work with elysia cron for d7 it's very useful, but is not usable yet for D8.
You can use ultimate_cron for this it has a pre-release version for D8.
Here is a very good article explain hook_cron, it's limitations and how to overcome all these limitations.

After install ultimate_cron module go to admin/config/system/cron/jobs and find your cron with the name of your module: enter image description here Then edited it and set running Every 1 day. enter image description here enter image description here

  • Thank you so much, more easier than I thought... I already use the ultimate cron module... but one more question please: Say on the same cron run, I want to delete 50 nodes of type article with 2 years old and delete 30 nodes of type page with 1 year old. Is it doable ? I have to create ankther module with almkst sane code as above or I have to include another function in the same .module file. Thank you – Elie Masaad Apr 28 at 11:44
  • You are so welcome, i'm glad that help, you can use a helper function as i suggest in the edit. good luck . – berramou Apr 28 at 12:09
  • The code mentioned in the comment below is not working for me! 1) I created 5 articles from 1 year ago 2) added to custom module, your code in mymodule.module 3) cc all caches 4) manually run cron but articles not deleted... So for debugging, I have added \Drupal::messenger()->addMessage(t('Cron Succeeded')); message below $storage_handler->delete($nodes); in order to check if the module and cron are working... After manually running cron, The message is displayed but yet the articles are not deleted – Elie Masaad Apr 28 at 18:54

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