Upon further inspection, when simplenews_token_values() loads the $account object, that object does not have an 'snid' property. Furthermore, what of anonymous subscriptions?

The section of concern is illustrated here:

<?php

/**
 * Implementation of hook_token_value().
 */
function simplenews_token_values($type, $object = NULL, $options = array()) {
  $values = array();
  switch ($type) {
    case 'all':
    case 'simplenews':
      $account = $object['account'];
      $node = $object['node'];
      $language = isset($account->language) ? $account->language : language_default();
      $langcode = $language->language;
      $urlargs = array('absolute' => TRUE, 'language' => $language);

      // Build tokens for 'simplenews' only.
      $values['simplenews-receiver-name']       = !empty($account->name) ? check_plain($account->name) : check_plain(variable_get('anonymous', 'Anonymous'));

      $values['simplenews-newsletter-url'] = url('node/' . $node->nid, $urlargs);
      // Try to switch to translation if possible.
      if ($node->tnid) {
        $translations = translation_node_get_translations($node->tnid);
        $node_translated = $translations[$langcode];
        if ($node_translated) {
          $values['simplenews-newsletter-url'] = url('node/' . $node_translated->nid, $urlargs);
        }
      }
      // Intentionally fall through (no break).
    case 'simplenews_subscription':
      $account = $object['account'];
      $newsletter = $object['newsletter'];
      $node = $object['node'];
      $language = isset($account->language) ? $account->language : language_default();
      $urlargs = array('absolute' => TRUE, 'language' => $language);

      // Build hash for (un)subscribe URL.
      $hash = '';
      if (isset($account->snid) && isset($newsletter->tid)) { //THIS DOESN'T WORK
        $hash = _simplenews_generate_hash($account->mail, $account->snid, $newsletter->tid);
      }



?>

What worked for me:

<?php
/**
 * Implementation of hook_token_value().
 */
function simplenews_token_values($type, $object = NULL, $options = array()) {
  $values = array();
  switch ($type) {
    case 'all':
    case 'simplenews':
      $account = $object['account'];
      $node = $object['node'];
      $language = isset($account->language) ? $account->language : language_default();
      $langcode = $language->language;
      $urlargs = array('absolute' => TRUE, 'language' => $language);

      // Build tokens for 'simplenews' only.
      $values['simplenews-receiver-name']       = !empty($account->name) ? check_plain($account->name) : check_plain(variable_get('anonymous', 'Anonymous'));

      $values['simplenews-newsletter-url'] = url('node/' . $node->nid, $urlargs);
      // Try to switch to translation if possible.
      if ($node->tnid) {
        $translations = translation_node_get_translations($node->tnid);
        $node_translated = $translations[$langcode];
        if ($node_translated) {
          $values['simplenews-newsletter-url'] = url('node/' . $node_translated->nid, $urlargs);
        }
      }
      // Intentionally fall through (no break).
    case 'simplenews_subscription':
      //CH20110328: Debug the missing hash
      watchdog('simplenews', "DEBUG: object <pre>".print_r($object, true)."</pre>");
      $account = $object['account'];
      $subscription = simplenews_get_subscription($account); //HACKED: CH20110328
      $newsletter = $object['newsletter'];
      $node = $object['node'];
      $language = isset($account->language) ? $account->language : language_default();
      $urlargs = array('absolute' => TRUE, 'language' => $language);

      // Build hash for (un)subscribe URL.
      $hash = '';
      if (isset($subscription->snid) && isset($newsletter->tid)) { //HACKED: CH20110328
        $hash = _simplenews_generate_hash($subscription->mail, $subscription->snid, $newsletter->tid);
      }

?>

Note the use of $subscription instead of $account in the "hacked" lines. It may also be better to load the $subscription->mail into the [simplenews-receiver-mail] token, instead of the $account->mail.

I'm not making a patch for this, as I've already hacked other parts of this code and don't have time at the moment.

Comments

simon georges’s picture

Hi,

Can you explain how to reproduce this ? By using the 6.x-2.x-dev, even when subscribing anonymously, the unsubscribe hashes are ok in the sent mails. What is the problem exactly ?

simon georges’s picture

Status: Active » Postponed (maintainer needs more info)
simon georges’s picture

Status: Postponed (maintainer needs more info) » Closed (cannot reproduce)

No answer in more than 6 months, closing. Please reopen if you still have the issue.

lavamind’s picture

I'm experiencing this issue. However, in my case, when sending out email, the hash is OK. The problem appears when viewing the node : $account->snid isn't set.

lavamind’s picture

Status: Closed (cannot reproduce) » Active