This is my use case. We have a Drupal 8 installation that we used as decoupled, so one external API retrieve all content and them indexed. So, this external API update indexed content when Changed date is updated. But, if the content is missing it doesnt do nothing. The content is removed from index only when content is unpublished.

I was thinking in deny users to delete content, and add an state or a field value to notify that the node need to be deleted in external index. Then a while delete content with a cron.

  • I don't really understand.. but it sounds like you need a reconciler task running independent of the indexer (perhaps after that task) that checks if the local IDs in your index still exist in Drupal, else, wipe it from the index. – Kevin Jan 7 '19 at 20:23
  • What about implementing hook_entity_delete() to store deleted ids in a variable that will be read by the external API to delete indexed content (and for each deleted indexed content , delete the id in the variable) or if the external API can be triggered to delete a content by its id, directly trigger it from the hook_entity_delete() – izus Jan 7 '19 at 20:31

The plan was prevent users to delete content, then unpublished content, save.. then index will remove content after a while. Time later we can remove unpublished content.

What I did

  1. Remove permission to delete for all roles(without admin). So no body can delete content directly.

  2. I enabled Content Moderation (core) module. Here I added a State "To Delete"(unpublished) to all CTs. So we add the option to erase a content later.

  3. When external index check content unpublished and erase it.

  4. I added a cron that check content with State "To Delete" that have more than 1 week without been updated. Then we delete those nodes.

    function MODULE_cron() {
      $nids_to_delete = getIdsByModerationState('to_delete');
      // @todo verify if empty array
      // @todo verify default language
      $query = \Drupal::entityQuery('node')
        ->condition('nid', $nids_to_delete, 'IN')
        ->condition('changed', strtotime('-1 week'), '<=')
        ->condition('status', NOT_PUBLISHED);
      $nids = $query->execute();
      // @todo test entity_delete_multiple('node', $array);
      foreach ($nids as $nid) {
        $node = Node::load($nid);
    function getIdsByModerationState($moderation_state) {
      $query = \Drupal::database()->select('content_moderation_state_field_data', 'ms');
      $query->join('node_field_revision', 'nf', 'nf.nid=ms.content_entity_id AND nf.vid=ms.content_entity_revision_id AND nf.langcode=ms.langcode');
      $results = $query->execute()->fetchAllAssoc('content_entity_id');
      $array_result = array_keys($results);
      return $array_result;
|improve this answer|||||
  • I don’t get what this has to do with an external index. – Kevin Jan 11 '19 at 1:31
  • Hi @kevin continually the external index check Drupal API checking content. If content is published it add it to this own. If it is unpublished it is erased. Thanks for your comments! – Carlos Jan 11 '19 at 1:38

Your Answer

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

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