A message is currently stored like:

<a href="/drupal/users/admin" class="user">admin</a> has updated Blog entry "<a href="/drupal/blog/sfd">sfd</a>"	

Now, if I decide to move my site from the subdirectory /drupal/ to a different subdirectory, or no subdirectory at all, the site will be loaded with busted links.

Perhaps you could use a token instead that's later processed with l().

Comments

Stalski’s picture

Status: Active » Needs work

I always override them with the method rebuildMessage because lot of streams can't be cached, and that's what that table is for ...
But indeed, it should not break things. Your sollution is not so bad at all. I will try to deal with this.

Stalski’s picture

Status: Needs work » Postponed

On the other hand, heartbeat streams are meant to be recent, so it would fade out to the past. You could also delete the messages.

It's rather a big change to implement this quickly.

mstef’s picture

I understand. I still strongly think you should consider bringing this in for future releases. There's a reason why l() exists.

Thanks

Stalski’s picture

indeed, that's why i always rebuild the message ;)
That's in heartbeat built in


function heartbeat_example_heartbeat_theme_alter(&$messages, HeartbeatAccess $stream) {

  foreach ($messages as $key => $message) {

    $messages[$key]->display_time = FALSE;

    if ($message->nid > 0) {

      $node = node_load($message->nid);

      // Catch normal story posts
      if ($node->type == 'story') {
        $messages[$key]->message = theme('heartbeat_content', $message, $node);
      }
    }
  }

}


function theme_heartbeat_content($message, $node) {

  $output = '';

  $user = heartbeat_user_load($message->uid);
  $output .= '<div class="icon-left-margin">';
  $output .= '<span class="avatar">'. l(theme('imagecache', 'tiny_picture', $user->picture), 'user/'. $user->uid, array('html' => TRUE)) .'</span>';
  $output .= '</div>';

  // If the message has to be shown anyway (inside the message)
  $output .= '<div class="heartbeat-indent">';
  $output .= $message->message;
  //$output .= $message->rebuild_message();
  $output .= '</div>';

  return $output;
}

So you use

$output .= $message->message;
or
$output .= $message->rebuild_message();

to override the cached version. So it's not like you are stuck ;)

Stalski’s picture

Assigned: Unassigned » Stalski
Priority: Normal » Minor
Status: Postponed » Closed (works as designed)

Hey,

I will not do this as it would be to big of a change. I will try to think about this in drupal 7.
However, there is a way to go around this. You could rebuild the message from code, using one of the hooks as mentioned above. This would be a way to rebuild the messages and even variables and invoke rebuild_message so your links could keep working.

Sorry if this has any inconvenient side-effects. If it is very important for you, i am willing to write it for you from specs.

mstef’s picture

Not that big of a deal (yet). I just noticed this and thought it would be good to report.

Stalski’s picture

Status: Closed (works as designed) » Active

Well, i fully understand the problem. the "yet" is the keyword why the status of this issue has changed :)

Perhaps you could use a token instead that's later processed with l().

The difficulty is that i see heartbeat_activity table as cached loggings, which you can rerender. On the other hand putting a placeholder for the basepath would be nice, but seems dirty.

So actually, as you represent the biggest number of heartbeat use cases, i am willing to implement this. In drupal7 certainly, drupal6 when we come to a understanding ;)

So options would be:

1/ always use the l function, which would be much slower as it will call drupal_lookup_path a lot more and that can be expensive. (it would also be a more difficult upgrade path)

2/ use a custom %basepath% placeholder in the loggings and replace it after fetching the messages.

What is your favorite?

mstef’s picture

This is your module. I trust your best judgement. There's no problem postponing this issue.

Stalski’s picture

Status: Active » Postponed

ok, postponed and 2 in drupal6
It will be re-evaluated for drupal7

Stalski’s picture

Version: 6.x-4.9 » 7.x-1.x-dev

I intented this to be a "cached log" and that's the way it works. If you specific want to use the message at runtime, you need to implement hook_heartbeat_theme_alter to do $message->rebuild_message($message).
I will target this for drupal7 by configuration. Use cached messages or generate dynamically at runtime.

Stalski’s picture

At the moment, messages are not writen with the variables in it. We build the activity message at runtime from the template and its arguments.
Now the other problem, variables containing links (which can change in time. E.g.: aliasses)
I don't find a good way to have to save an expression at log time. Especially using the rules UI, there is no way to "know" that we need a node title name and a node nid when seeing the variable "!title".

Anyone a tip to do this?

Stalski’s picture

Status: Postponed » Closed (fixed)

Fixed in drupal7

vamirbekyan’s picture

Stalski,
I have exactly the same issue with urls to nodes. ( Drupal v6 )
Can I rebuild messages if I use views to get message records? If so please give me a clue what api functions to use.
thank you in advance.

vamirbekyan’s picture

I found a work around with this code:

function my_view_preprocess_views_view_fields(&$vars) {
// Alter only zn_activity view.
if ($vars['view']->name != 'my_view') {
return;
}

if (!empty($vars['row']->variables['@node_title']) && (strpos($vars['row']->variables['@node_title'], 'node/') !== false)) {
// here we recalculate node links as at the time when rules culculate the same link aliases might not be there yet.
// also aliases can change so we need to recalculate the link literally always anyway
$vars['row']->variables['@node_title'] = l(strip_tags($vars['row']->variables['@node_title']), myfuncthat calculatesnodelinks($vars['row']->nid, $vars['row']->nid_target));

$data = array (
'hid' => $vars['row']->uaid,
'nid' => $vars['row']->nid,
'nid_target' => $vars['row']->nid_target,
'uid' => $vars['row']->uid,
'uid_target' => $vars['row']->uid_target,
'variables' => $vars['row']->variables,
);

$hba_message = new HeartbeatActivity($data, $vars['row']->template);
$vars['fields']['message']->content = $hba_message->rebuild_message();
}
}

Stalski’s picture

I am glad you found a workaround. This is and will be a very difficult issue.

Activity means hot messages at a point in time. So most of the time variables will mean something at the time activity occured. However links still need to work, and there is much more information needed (and context!) within heartbeat logging to be able to create links when streams are displayed.

I am sure such conversations will follow in the future, here or some other place.

Greetz,
Jochen

rooby’s picture

Priority: Minor » Normal
Status: Closed (fixed) » Active

You mention this is fixed in D7, can you elaborate on what was done?

In my D7 site I have activity logged to the heartbeat_activity table and in the variables column there are absolute urls. So anything that happens on my staging site for example, is broken once it gets to the live site.

Can you give some instructions for geting variables to be built at run time instead of stored in the database?

rooby’s picture

Activity means hot messages at a point in time.

In regards to this, I'm beginning to think that this module shouldn't be called an API but should be called facebook activity stream or something as it makes too many assumptions on how it will be used to be an API.

Stalski’s picture

Status: Active » Needs work

@rooby: that's not true. It is an api and its submodules are the ones taking assumptions. But you are correct that it takes a lot of assumptions, especially what is worked out by the people of facebook.
However, heartbeat.module is does not take assumptions.

About the user-generated links, the absolute urls are still a problem. I will make relative urls instead.
The actual problem in this issue is the fact that there is a in the database of heartbeat activity. I tried to have a work around for this but I've thrown it away again. It's hard and tedious task.
Any suggestions are welcome.

So this issue stays active untill at least the links are saved relative at log time

rooby’s picture

Relative links would be great. Although I guess there might be times when people need absolute but they would be rarer.
The ideal solution I guess is to store the non-aliased path, then run it through l() at view time (if that is feasible).
That way you handle relative and absolute paths and also path aliases.

I haven't actually looked in detail at the code yet but I will have to soon for a site I'm working on.

Stalski’s picture

Status: Needs work » Postponed

You don't need to look at the code imo.

The ideal solution I guess is to store the non-aliased path

I would be very glad if you had a way how to implement this. if people have a simple variable !title , but they want to have a link to it, there is no notion of that title being a node or a term or a profile title of a user, and so on ...
So I gave up on it :(

rooby’s picture

Assigned: Stalski » Unassigned

I would have thought if you are able to save the full url to the database then you would be able to save the relative path (again I don't know as I haven't actually looked at the code yet).

rooby’s picture

I will probably be investigating this in the next couple of days so I'll lete you know how I go.

Stalski’s picture

Cool, that would be great. Much appreciated in advance. (only tip: think of performance as well, since heartbeat is a community module and it always gets installed in sites that grow ...)

rooby’s picture

Sorry to be a pain, but I won't have any time for this now as I'm switching to a different module due to the requirements of the clients site.