Hi,

I'm having headaches trying to find a solution to my problem using simplenews.

I want users (authentified as well as anonymous) to subscribe to custom alerts on content using taxonomy term lists.
To do that I created a Webform with the user email and the two term lists (1 selection only) used later as view argument, set up a Rule to subscribe the email to the unique newsletter of the site and to store the two terms selected in the source subscription (in that format : tid1/tid2), thinking that when inserting the view in the newsletter body I could find a way to retrieve these to trigger the inserted view with these arguments.

In the newsletter body, with the PHP code text format (and insert view replacement enabled), I tried to do the following (know it's not perfect code...) :

<?php 
   $arg = token_replace('[simplenews-subscriber:mail]'); 
   $result = db_query("SELECT s2.source FROM simplenews_subscriber s1, simplenews_subscription s2 WHERE s1.snid = s2.snid AND s1.mail = :mail", array(':mail' => $arg));
   $sourceArray = $result->fetchCol();
   $source = $sourceArray['0'];
?>

[view:simplenews_content=default=<?php print $source ; ?>] 

My idea was to use the subscriber email token to retrieve the term ids chosen by that user through the db_query direct query, then use it as the inserted view argument.
The problem is that token_replace is only executed at rendering and when executing the db_query it takes [simplenews-subscriber:mail] instead of its replacement ...@...

Can I load the subscriber or subscription object with code in my case (I heard that no variables where available in the newsletter body) ?
How can I access those saved values to use them as view arguments in the newsletter body ?

And, mostly, is there any better way to do what I'm trying to do ??
Thanks by advance, please help me getting outta this technical absurdity !

Comments

damienroussat’s picture

Could someone help me please or give me some hint to solve my problem ? That would be awesome thanks !!

berdir’s picture

Status: Active » Fixed

You can't use tokes in PHP code. Tokens are only replaced *after* the template is rendered, not before.

Quoting the documentation of that template:

 * - $simplenews_subscriber: The subscriber for which the newsletter is built.
 *   Note that depending on the used caching strategy, the generated body might
 *   be used for multiple subscribers. If you created personalized newsletters
 *   and can't use tokens for that, make sure to disable caching or write a
 *   custom caching strategy implemention.

So, using $simplenews_subscriber->mail (or better, ->snid, because you have that too) should work but make sure to read the notes about caching.

damienroussat’s picture

Thank you for your answer.
Still, I was talking about using the PHP code text format for inserting the view directly in the body - before template rendering. This, as you said, is not possible, right ?
Is the caching issue meaning that depending on your caching options, you may have trouble using a customized template ?
I tried adding a template to the template folder of my theme, deleted cache and refreshing theme_registry through the theme admin screen, but still any changes made to that custom folder where not taken into account. Or is it that the template only works for the email version, as I was testing with the online one ?

I think I'm a bit confused with all of that...
Could you lighten me a bit please ?

Thank you !!

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

pverrier’s picture

I confirm the simplenews token replacement occurs only after the filtering process.

Thus, the [simplenews-subscriber:...] token cannot be evaluated in php as you tried to do, and even if you use the Token Filter, it will not be processed, because when text filtering occurs, the token contextual object 'simplenews-subscriber' is unknown: this token will be replaced later, by this code located in simplenews/includes/simplenews.source.inc, class SimplenewsSourceNode, method getBodyWithFormat() (line 728 in 7.x-1.0):

protected function getBodyWithFormat($format) {
  ...
  $body = token_replace($body, $this->getTokenContext(), array('sanitize' => FALSE));

Here the 'simplenews-subscriber' object is provided as second argument for token_replace(), I didn't find a way to retrieve it elsewhere.

Therefore, I think the only way to insert values depending on the recipient (email, or - my need - a view with the recipient uid as a parameter), is to use the token mechanics and provide a 'simplenews-subscriber' or better, a 'simplenews-subscriber:user' token (because the value provided by the token relates to a user).

For instance, I created a custom module providing the result of a view through a custom token [simplenews-subscriber:user:MYMODULE-newsletter-registrations].


/**
 * Implements hook_token_info()
 */
function MYMODULE_token_info() {
  $types = array();  // no new token type
  // tokens for inserting parametrized views
  $tokens = array();
  $tokens['MYMODULE-newsletter-registrations'] = array(
    'name' => t('Insert view: Registrations'),
    'description' => t('Insert view: List of the registrations for the newsletter recipient.'),
  );
  return array(
    'types' => $types,
    'tokens' => array(
      'user' => $tokens,
    ),
  );
}

/**
 * Implements hook_tokens()
 */
function MYMODULE_tokens($type, $tokens, array $data = array(), array $options = array()) {
  $replacements = array();
  switch ($type) {
    case 'user':
      if (!isset($data['user'])) {
        return;
      }
      $subscriber = $data['user'];
      foreach ($tokens as $name => $original) {
        switch ($name) {
          case 'MYMODULE-newsletter-registrations':
            $replacements[$original] = MYMODULE__render_view('conferences','user_subscriptions',array($subscriber->uid));
            break;
        }
      }
  }
  return $replacements;
}

function MYMODULE__render_view($view_id,$display_id,$args=NULL,$hide_contextual_links=TRUE) {
  $view = views_get_view($view_id);
  if (!$view || !$view->access($display_id)) {
    return;
  }
  $view->hide_admin_links = $hide_contextual_links;
  return $view->preview($display_id, $args);
}

---
Note for users trying to insert a parametrized view with Insert View: it's also impossible, for the same reasons, the [simplenews-subscriber:...] token being unavailable during filtering. It's the reason why I went to the above solution.
See also issue #302612 'Dynamic Arguments?' of Insert Views.

pverrier’s picture

I just discovered the Views Send module, which is very much appropriate to send content dynamically computed for the recipient user...
It's a better solution for my needs than simplenews and my token hooks.