How to mark a node as read per user? I'm wondering what the best solution is to mark a node as read per user.

The below scenario is what I am trying to achieve:


Admin creates a node which requires to be read and confirmed and flags user a+b.
User a+b receives an email staying there is a new content that requires them to read it.
User a goes to the page and reads the content and clicks "I confirm I have read this" which cannot be reversed by user a.
When admin views the page they can see that user a has confirmed read but user b hasn't.


My first initial thoughts was to use a combination of Flag, Views and Rules.

Any suggestions?
Using the Flag, Views and Rules modules (as in your question) is indeed a way to get this to work. But assuming you have way more then just 2 (= a+b) users, you probably also want to add the Views Bulk Operations (VBO) module to this. Read on for more details ...


  
  Admin creates a node which requires to be read and confirmed and flags user a+b
  


Use Flag to create a (1st) flag to flag your nodes, and which at first will be used by the admin to set the flag for "user a+b" (as in your question), as further detailed below. The labels for this flag could be something like this:


to flag: "Confirmation outstanding".
to unflag: "Confirmed".


To actually set the flag for user a+b (imagine you have dozens ...), you should create an appropriate view (using Views) to create a list of such user a+b. And use Views Bulk Operations (VBO) to transform that view, so that the "operation" to be performed by that VBO-list is to execute a Rules Component (created with Rules).

If you're not familiar with how to do so, have a look at the video about Using Rules components with VBO". You may also want to watch the subsequent "Using Rules components with more than one parameter" video.

The actual Rules Component to be used by this VBO list, is simply a rule to flag a node by a single user. The trick here is the value to use as flagging user: it should use the uid as contained in the VBO list row being processed (so not the current uid, which would be the admin using the VBO list).


  
  User a+b receives an email staying there is a new content that requires them to read it.
  


Just enhance (extend) the Rules Component from the previous step to add an additional action, which is to also send an eMail to each user being processed. Tune the subject and body of the eMail to fit your needs.


  
  User a goes to the page and reads the content and clicks "I confirm I have read this" which cannot be reversed by user a
  


Use Flag to create a (2nd) flag with labels for this flag that could be something like so:


to flag: "I confirm I have read this".
to unflag: "I already confirmed to have read this".


When user a visits this page, all that's needed is that user a clicks the link which says "I confirm I have read this". After user a flagged it like so, the (1st) flag set for the node by user a needs to be removed (= unflagged). That's something you can do with a 2nd rule, which looks like so:


Rules Event = after flagging (with 2nd flag).
Rules Action = unflag (with 1st flag)).


However, after user a flagged the node (with the 2nd flag), the link to unflag it again will be shown. But you don't want user a to be able anymore to unflag it again. To prevent that to happen, a possible solution is to create a 3rd rule to either disallow such attempt to unflag, or to capture such attempt and automatically flag it again. Another approach could be via a custom template, which will simply hide the unflag link.


  
  When admin views the page they can see that user a has confirmed read but user b hasn't.
  


Create a Views block to list all users who have not flagged the node anymore with the 1st flag (these would be your users like a). And a similar block to list all users who have still flagged the node with the 1st flag (these would be your users like b).

Note: the above approach is entirely entity based, and may be considered as a possible alternative to some of the facilities provided by the Legal module (your question might be about similar functionality).