3

I am parsing pdf's in a field for a custom content type in a cron job. I have a boolean on each node that determines whether their pdf has already been parsed. I grab the ones I need like so:

$query = \Drupal::entityQuery('node')
    ->condition('status',1)
    ->condition('type', 'issue')
    ->exists('field_pdf')
    ->condition('field_indexed',false)
    ->sort('created','ASC');
if($range > 0){
    $query->range(0,$range);
}

$issue_nids = $query->execute();
$issue_nodes = \Drupal::entityTypeManager()->getStorage('node')->loadMultiple($issue_nids);

foreach ($issue_nodes as $issue_node){
    //do my pdf parsing magic on field_pdf
    $node->field_indexed->value = true;
    $node->save();
}

This works fine but if the user replaces field_pdf and uploads a new one I want to make field_indexed false again so I know to reindex it. The problem is I don't really have a way of knowing whether the field changed.

I considered using a presave hook but I didn't see a way to compare the form state to what was currently on the node.

Is there a way I can detect when a field has changed when a node has saved?

1
  • 2
    Use a presave hook, you have access to $entity->original, which contains the original’s field values. Use those for comparison
    – Clive
    Aug 3, 2018 at 15:36

1 Answer 1

6

Clive is correct. $node->original does give access to the original node values. I was able to accomplish what I needed like so

function my_module_node_presave($node) {
    $type = $node->getType();
    if($type == 'issue'){
            if(isset($node->field_pdf->entity) && !isset($node->original->field_pdf->entity) || empty($node->original->field_pdf->entity) || $node->field_pdf->entity->id() != $node->original->field_pdf->entity->id()){
                $node->field_indexed->value = false;
            } else {
                $node->field_indexed->value = true;
            }
    }
2
  • 1
    You might be able to simplify that to $node->set('field_indexed', !$node->get('field_pdf')->equals($node->original->get('field_pdf'))). You could also do a hasField('field_pdf'), most of the time I prefer checking for the existence of a field over a node type check because that allows you to e.g. add another node type that should have the same functionality later on
    – Berdir
    Aug 3, 2018 at 21:58
  • 2
    Actually, you might want to keep the if () but remove the else.. only the process that actually indexes those nodes should set it to true again. Imagine a user uploads a new PDF, then saves, which sets it to false and then immediately edits and saves again to fix a typo, your current code would set it to indexed thn
    – Berdir
    Aug 3, 2018 at 21:59

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.