Question

Is there a module which can check if an user has read a node? For example, I have this node:

  1. Node order 1
  2. Node order 2 (locked)
  3. Node order 3 (locked)
  4. Node order 4 (locked)

If the user read 'node order 1' or marked as read with a button, he has access to 'node order 2'. If 'node order 2' has marked as read, he has access to 'node order 3'.

It's all user based. It's similar to an e-learning structure, but I don't like heavy modules like: course or opigno for just this functionality.

Can I do something like this with rules or an other lightweight module? I saw the flag module, but I don't know if it possible to do something like this with that module?

Was it helpful?

Solution

I'd say you can use hook_ENTITY_TYPE_view to store the uid and the nid of the user into a custom table. That would solve the easy part, I believe.

You'd may start by something similar to

function yourmodule_node_view(array &$build, \Drupal\Core\Entity\EntityInterface $entity, 
        \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display, $view_mode) {

  $bundle = $entity->bundle();
  if($bundle == 'your_content_type') {
    $uid = \Drupal::currentUser()->id(); // get current user's ID
    $nid = $entity->get('nid');
    [...] // insert into custom table, etc
  }
}

For the long-term, complex solution regarding performance, that's a huge discussion. If your node list is just a simple queue that unlocks next node if previous has been read, then maybe storing just the current nid would work for you. If you need the history per user, then, as mentioned, some different solutions could do the trick. Other approach could be to do database sharding, for instance creating 1 table per node so table_read_nid_1 would just contain the users who actually have read this node and can unlock the second. table_read_nid_2 would contain the next and so on. Don't be afraid of sharding, lots of big companies use it daily! :)

Licensed under: CC-BY-SA with attribution
Not affiliated with drupal.stackexchange
scroll top