4

I am using a user flag, Visits, to track each user's visits to other user's profiles.

When a user visits another user's profile, a rule is triggered that automatically flags the visited user on behalf of the visiting user.

Flagging the user on the first visit is no problem. But on the second visit and thereafter, I want to update the flag that was flagged on the first visit. To do this, I made the following rule:

  • Event: User account page is viewed
  • Condition 1: NOT [account] is [site:current-user]
  • Condition 2: User is flagged ([account] on behalf of [site:current-user])
  • Actions-> How do I fetch and update the flag?

This rule is triggered correctly; however, I don't know how to get the previous flag (the flag applied when the user visited the profile for the first time) in order to update it.

My question: how can I fetch the previously applied flag in rules so that I can update the timestamp and re-save it?

What I tried

Flag provides a rules action Fetch user flagged by user, but this does not help because this returns an array of users, not the flagging, which is what I want to update.

I can add the Unflag a node action and then the Flag a node action, but this will destroy my previous flag and replace it with a new one; since I want to track referer information over time, this is not a good solution.

Since I'm using Flag 3.x in which flags are entities, I tried using the Fetch entity by property action in Rules to fetch the flagging, but in this case the only property I can choose to select is the value of the Referer field, which is not helpful. There seems to be no way to fetch the flag by its endpoints.

Why I'm doing this

This flag has a computed field, Referer, which stores the value of $_SERVER['HTTP_REFERER'] upon flagging.

When a user visits the profile of a user for the second time, I want to update this flag by updating the timestamp of the flagging and adding the new referer information to the flag.

  • I am going to assume Flag 3.x where flags are now entities. If so, is there another path or action through Rules outside of Flag that could operate upon this entity? – Jimajamma Nov 7 '13 at 14:27
  • @Jimajamma Yes, I'm using Flag 3.x. Good point, since flags are entities, it may be possible to use the entity integration in Rules. – Patrick Kenny Nov 8 '13 at 3:05
  • 1
    The limitation with flag is it can only be flagged and unflagged (if flagged). So, its boolean on/off. I gave up using flag in such situations and looked for VotingApi. Specially the voting plusOne module (drupal.org/project/plus1). I am not sure if it has rules integration, if it has then it'd solve your problem. – user12947 Nov 8 '13 at 13:40
  • Why don't you simply unflag the visited user and flag him/her again afterwards? In that way, you don't have to mess around with timestamps of the old flag. – Jeroen Mar 24 '16 at 12:18
2

My question: how can I fetch the previously applied flag in rules so that I can update the timestamp and re-save it?

Some good news but mostly bad.

If you add an extra text field to the flag and add an extra rule to set its data value to [flagged_uid]-[flagger_uid] when a flag is created, it seems that you can then fetch the flagging using that field as the Property and [account_uid]-[current-user_uid].

I say seems because while the rule runs without errors and I know my logic is right, I can't do anything to the fetched flagging to prove I've actually fetched it. I get an error when trying to delete it because "Rules doesn't have info about deleting a flagging" and saving it doesn't change the timestamp.

It just feels like it's not fully integrated. Even if you added a date field, I'm not sure Rules could access it on user view.


I guess I would either create a custom rules action to finish the rule or go with a fully fledged Field Collections solution.

1

You could add a count field to the flag entity (a numeric field). Every time a user visits a profile, grab the flag and +1 to the count field.

Unfortunately I would not be able to answer how you get this flag via the rules UI.

You could create a custom rule (in code), or a user view hook (hook_user_view). Within this hook, load the flag and update the count value.

The below code is an example of the idea, I havent tried it myself. If it doesn't work, try a different flag load and save method. (if no other better method is found you could even resort to a database query to load and update the flag).

HOOK_user_view($account, $view_mode, $langcode){
  if ($view_mode == 'profile') {

    // Get user id's
    global $user;
    $viewing_uid = $user->uid;
    $viewed_uid = $account->uid;

    // If we are not viewing our own profile
    if ($viewing_uid != $viewed_uid) {

      // Load the flag contents // Remember to check entity name, and field names
      $flag_entity = entity_load('user_flag', FALSE, array('uid' => $viewing_uid, 'content_id' => $viewed_uid));

      // Update the count
      $flag_entity->count = $flag_entity->count + 1;

      // re-save the entity
      $return = entity_save('user_flag', $flag_entity);
    }
  }
}

As a side note: If you have a problem displaying the flag contents on page/profile views, you could also use a load/view hook to override what is displayed. As its an entity however, the field should be available via the entity view mode or views.

I hope this helps.

  • I was hoping to do this in Rules, but based on your example I tried to do it in code. However, I wasn't able to load the flag via entity_load(). It seems that EntityFieldQuery() is preferred to entity_load() anyway: "Instead, it is preferable to use EntityFieldQuery to retrieve a list of entity IDs loadable by this function." api.drupal.org/api/drupal/includes!common.inc/function/… – Patrick Kenny Nov 9 '13 at 10:33

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.