[mod] Customizing confirmation emails with custom attributes

3rd party code for phpList

[mod] Customizing confirmation emails with custom attributes

Postby H2B2 » 2:06am, Fri 24 Mar, 2006

Hi,

I ran into some problems customizing my confirmation emails and could use some help.

I would like the confirmation emails to include the firstname of a user by using the placeholder [FIRSTNAME], like this:

Dear [FIRSTNAME],

Almost welcome to our newsletter(s) ...

Someone, hopefully you, has subscribed your email address to the following newsletters:

[LISTS]

etc.



For some reason the [FIRSTNAME] placeholder doesn't work and just displays [FIRSTNAME] instead of the user's name. That's strange because the [LISTS] placeholder does work...

My subscription form has 2 input fields:
email
firstname => which is attribute1

And 2 selection boxes for list subscriptions.

Any help would be appreciated!
Last edited by H2B2 on 7:28am, Fri 29 Feb, 2008, edited 1 time in total.
H2B2
Moderator
 
Posts: 7188
Joined: 1:51am, Wed 15 Mar, 2006

Postby Totto » 9:45pm, Fri 24 Mar, 2006

Look at this thread - it explains how to be able to add user attributes placeholders in your emails. Hope that helps!
To all forum users: Search the forums when you got a question first! Your question may have already been asked many times before and also many times answered. The search feature is your best friend on any forums of this kind!
Totto
PL Master
 
Posts: 370
Joined: 11:20pm, Tue 31 Jan, 2006

Postby H2B2 » 11:16pm, Sun 26 Mar, 2006

Thanks for pointing out this thread. I'll take a look and see how far i get in solving this problem.

Cheers!
H2B2
Moderator
 
Posts: 7188
Joined: 1:51am, Wed 15 Mar, 2006

Postby H2B2 » 9:32pm, Wed 24 May, 2006

Well, it appears most placeholders do not work in the confirmation mails. The placeholders [LISTS], [CONFIRMATIONURL], etc. are some of the exceptions.

A bug report has been filed (http://mantis.phplist.com/view.php?id=3288) and hopefully this problem will be resolved in release 2.11.

Still, most -if not all- placeholders do work in list messages to subscribers.
H2B2
Moderator
 
Posts: 7188
Joined: 1:51am, Wed 15 Mar, 2006

Postby H2B2 » 12:44am, Tue 05 Dec, 2006

I ran some tests to check which placeholders would work with specific system messages. These are my test results for Phplist 2.10.3 :

Message they receive when they subscribe
Message they receive when they confirm their subscription


Working
confirmationurl: [CONFIRMATIONURL]
preferencesurl: [PREFERENCESURL]
subscribeurl: [SUBSCRIBEURL]
unsubscribeurl: [UNSUBSCRIBEURL]
lists: [LISTS]
domain: [DOMAIN]
website: [WEBSITE]

Not working
1. all custom placeholders: e.g. [FIRSTNAME]
2. built-in placeholders:
Email: [EMAIL]
forward: [FORWARD]
forwardform: [FORWARDFORM]
forwardurl: [FORWARDURL]
listowner: [LISTOWNER]
preferences: [PREFERENCES]
signature: [SIGNATURE]
subscribe: [SUBSCRIBE]
userid: [USERID]
usertrack: [USERTRACK]
userdata: [USERDATA]
unsubscribe: [UNSUBSCRIBE]


Message that is sent when users change their information

Working
confirmationurl: [CONFIRMATIONURL]
preferencesurl: [PREFERENCESURL]
subscribeurl: [SUBSCRIBEURL]
unsubscribeurl: [UNSUBSCRIBEURL]
lists: [LISTS]
userdata: [USERDATA]

Not working
1. all custom placeholders: e.g. [FIRSTNAME]
2. built-in placeholders:
Email: [EMAIL]
forward: [FORWARD]
forwardform: [FORWARDFORM]
forwardurl: [FORWARDURL]
listowner: [LISTOWNER]
preferences: [PREFERENCES]
signature: [SIGNATURE]
subscribe: [SUBSCRIBE]
userid: [USERID]
usertrack: [USERTRACK]
unsubscribe: [UNSUBSCRIBE]
domain: [DOMAIN]
website: [WEBSITE]


Message users receive when they unsubscribe

Working
confirmationurl: [CONFIRMATIONURL]
preferencesurl: [PREFERENCESURL]
subscribeurl: [SUBSCRIBEURL]
unsubscribeurl: [UNSUBSCRIBEURL]
lists: [LISTS] (will state "All newsletters" instead of listing all lists)

Not working
1. all custom placeholders: e.g. [FIRSTNAME]
2. built-in placeholders:
Email: [EMAIL]
forward: [FORWARD]
forwardform: [FORWARDFORM]
forwardurl: [FORWARDURL]
listowner: [LISTOWNER]
preferences: [PREFERENCES]
signature: [SIGNATURE]
subscribe: [SUBSCRIBE]
userid: [USERID]
usertrack: [USERTRACK]
Userdata: [USERDATA]
unsubscribe: [UNSUBSCRIBE]
domain: [DOMAIN]
website: [WEBSITE]
H2B2
Moderator
 
Posts: 7188
Joined: 1:51am, Wed 15 Mar, 2006

Postby rjc » 12:46am, Tue 12 Dec, 2006

Hi Guys,

I have come up with a solution to the problem of Placeholders not being processed in System Emails (eg subscribe etc - See Issue 3288). I'm just new to phplist, but was disappointed that the first email a user receives after registering weren't able to be personalised... :( A bit of a letdown, as personalisation was the reason I went with phplist :?

This is what I did. First, I created two functions in the file admin/commonlib/lib/userlib.php. The first processes Custom Placeholders (user-defined), the second some System-defined Placeholders:

Before the ending ?>, add:

function RJC_ReplaceCustomPlaceholders($systemmessage = '',$userid = 0) {
/* Function to replace Custom Placeholders with the proper values from the database (See Issue 3288) */
/* PS: Made so that placeholders are replaced in System Messages (eg Subscribe/Unsubscribe emails) */

/* Function works successfully. I guess it needs some sort of check to make sure parameters are supplied???
(to avoid a crash if $systemmessage or $userid are not supplied)
Someone should check for insecurities/inefficiencies as I don't know php well */

$rjc_user_att = getUserAttributeValues('',$userid);
while (list($att_name,$att_value) = each ($rjc_user_att)) {
if (eregi("\[".$att_name."\]",$systemmessage))
$systemmessage = eregi_replace("\[".$att_name."\]",$att_value,$systemmessage);
}
return $systemmessage;
}

function RJC_ReplaceBuiltinPlaceholders($systemmessage = '',$userid = 0) {
/* Function to replace Builtin Placeholders with the proper values from the database
PS: Made so that placeholders are replaced in System Messages (eg Subscribe/Unsubscribe emails)
(See Issue 3288):
*/

$systemmessage = ereg_replace('\[DOMAIN\]', getConfig("domain"), $systemmessage);
$systemmessage = ereg_replace('\[WEBSITE\]', getConfig("website"), $systemmessage);

return $systemmessage;
}


(As an aside, I have shortened the second procedure above to only those ones which successfully work. I show the full one below with all my comments and the placeholders which don't work. Someone eslse may have more success).

Then I modifed the following:

In index.php:

After:
$confirmationmessage = ereg_replace('\[LISTS\]', $lists, getUserConfig("confirmationmessage:$spage",$userdata["id"]));

Add:
// RJC ADDED - Includes User Placeholders in System Emails when a user Confirms their Subscription
$confirmationmessage = RJC_ReplaceCustomPlaceholders($confirmationmessage,$userdata["id"]);
$confirmationmessage = RJC_ReplaceBuiltinPlaceholders($confirmationmessage,$userdata["id"]);
// END RJC ADDED

After:
$unsubscribemessage = ereg_replace("\[LISTS\]", $lists,getUserConfig("unsubscribemessage",$userid));
Add:
// RJC ADDED - Includes User Placeholders in System Emails when a user Unsubscribes
$unsubscribemessage = RJC_ReplaceCustomPlaceholders($unsubscribemessage,$userid);
$unsubscribemessage = RJC_ReplaceBuiltinPlaceholders($unsubscribemessage,$userid);
// END RJC ADDED


In admin/subscribelib2.php:

After:
$subscribemessage = ereg_replace('\[LISTS\]', $lists, getUserConfig("subscribemessage:$id",$userid));

Add:
// RJC ADDED - Includes User Placeholders in System Emails when a user Subscribes
$subscribemessage = RJC_ReplaceCustomPlaceholders($subscribemessage,$userid);
$subscribemessage = RJC_ReplaceBuiltinPlaceholders($subscribemessage,$userid);
// END RJC ADDED


Before:
print '<title>'.$GLOBALS["strPreferencesTitle"].'</title>';

Add:
// RJC MODIFIED - Includes User Placeholders in System Emails when a user updates personal data
$message = RJC_ReplaceCustomPlaceholders($message,$userid);
$message = RJC_ReplaceBuiltinPlaceholders($message,$userid);
// END RJC MODIFIED


In admin/import1.php:

After:
$subscribemessage = ereg_replace('\[LISTS\]', $listoflists, getUserConfig("subscribemessage",$userid));

Add:
// RJC ADDED - Includes User Placeholders in System Emails when a user is added through Import
$subscribemessage = RJC_ReplaceCustomPlaceholders($subscribemessage,$userid);
$subscribemessage = RJC_ReplaceBuiltinPlaceholders($subscribemessage,$userid);
// END RJC ADDED


In admin/import3.php:

After:
$subscribemessage = ereg_replace('\[LISTS\]', $listoflists, getUserConfig("subscribemessage",$userid));

Add:
// RJC ADDED - Includes User Placeholders in System Emails when a user is added through Import
$subscribemessage = RJC_ReplaceCustomPlaceholders($subscribemessage,$userid);
$subscribemessage = RJC_ReplaceBuiltinPlaceholders($subscribemessage,$userid);
// END RJC ADDED



In admin/reconcileusers.php:

Before:
logEvent($GLOBALS['I18N']->get('Resending confirmation request to')." ".$userdata["email"]);

Add:
// RJC ADDED - Includes User Placeholders in System Emails when Reconcile users performed
$subscribemessage = RJC_ReplaceCustomPlaceholders($subscribemessage,$userid);
$subscribemessage = RJC_ReplaceBuiltinPlaceholders($subscribemessage,$userid);
// END RJC ADDED


In admin/commonlib/pages/importcsv.php:

After:
$subscribemessage = ereg_replace('\[LISTS\]', $listoflists, getUserConfig("subscribemessage",$userid));

Add:
// RJC ADDED - Includes User Placeholders in System Emails when users are imported from csv
$subscribemessage = RJC_ReplaceCustomPlaceholders($subscribemessage,$userid);
$subscribemessage = RJC_ReplaceBuiltinPlaceholders($subscribemessage,$userid);
// END RJC ADDED



It seems to process Custom (userdefined) placeholders fine; since I don't know php or sql very well, I wasn't able to get any more of the Globals working (see Full Function below). Maybe someone with a bit more skill can do so...

As I mentioned, I don't know php, so someone really needs to go through it and check the code for insecurities/inefficiencies etc. For now my Custom Placeholders are showing up in (un)subscribe emails, along with system placeholders [DOMAIN] and [WEBSITE], so that's a start until someone else can get the rest of the System placeholders working (or at least those that are meant to according to documentation http://docs.phplist.com/Placeholders.

I guess the concept could also be extended to not just the message body, but the subject line of (un)subscribe emails too... Another day. :)


As mentioned above, I list the full Builtin Placeholders function below. I only have a few builtins working (limited by lack of php & sql knowledge).

--- FULL FUNCTION ---

function RJC_ReplaceBuiltinPlaceholders($systemmessage = '',$userid = 0) {
/* Function to replace Builtin Placeholders with the proper values from the database
PS: Made so that placeholders are replaced in System Messages (eg Subscribe/Unsubscribe emails)
(See Issue 3288):
NOTE: Does it cause a clash with specs as listed http://docs.phplist.com/Placeholders (eg Allowed In)???
Maybe some of these should be removed from this function to avoid any problems??? */

/* The commented lines don't work successfully; someone who's more adept at select tables
should be able to help us out here...
I assume it needs to select tables from database for various user info; don't know php and sql enough
to do it confidently. */

/* I guess the function needs some sort of check to make sure parameters are supplied???
(to avoid a crash if $systemmessage or $userid are not supplied)
Someone should check for insecurities/inefficiencies as I don't know php well */

$systemmessage = ereg_replace('\[DOMAIN\]', getConfig("domain"), $systemmessage);
$systemmessage = ereg_replace('\[WEBSITE\]', getConfig("website"), $systemmessage);
/* The following work, but don't put a UID on the end of the url. The documentation http://docs.phplist.com/Placeholders
seems to imply that a UID should be on the end... Job for someone :) */
$systemmessage = ereg_replace('\[SUBSCRIBEURL\]', getConfig("subscribeurl"), $systemmessage);
$systemmessage = ereg_replace('\[CONFIRMATIONURL\]', getConfig("confirmationurl"), $systemmessage);
$systemmessage = ereg_replace('\[PREFERENCESURL\]', getConfig("preferencesurl"), $systemmessage);
$systemmessage = ereg_replace('\[UNSUBSCRIBEURL\]', getConfig("unsubscribeurl"), $systemmessage);
$systemmessage = ereg_replace('\[FORWARDURL\]', getConfig("forwardurl"), $systemmessage);

/* These following are meant to have url with uid, in the form of "this link" (ie <a>this link</a> */
// $systemmessage = ereg_replace('\[SUBSCRIBE\]', /*something goes here*/, $systemmessage);
// $systemmessage = ereg_replace('\[PREFERENCES\]', /*something goes here*/, $systemmessage);
// $systemmessage = ereg_replace('\[UNSUBSCRIBE\]', /*something goes here*/, $systemmessage);
// $systemmessage = ereg_replace('\[FORWARD\]', /*something goes here*/, $systemmessage);

// $systemmessage = ereg_replace('\[EMAIL\]', /*something goes here*/, $systemmessage);
// $systemmessage = ereg_replace('\[FORWARDFORM\]', /*something goes here*/, $systemmessage);
// $systemmessage = ereg_replace('\[LISTOWNER\]', /*something goes here*/, $systemmessage);
/* Signature result is blank, needs fixing (I think this is trying to give an html result)*/
// $systemmessage = ereg_replace('\[SIGNATURE\]', preg_replace('/src=".*power-phplist.png"/','src="powerphplist.png"',$PoweredByImage), $systemmessage);
// $systemmessage = ereg_replace('\[USERID\]', /*something goes here*/, $systemmessage);
// $systemmessage = ereg_replace('\[USERTRACK\]', /*something goes here*/, $systemmessage);

/* I guess for completeness I should put the lot, even [LISTS] is already processed (eg in index.php).
In theory, if they've already been processed in index.php, then the placeholders won't exist when this function is run, so
no harm done. This needs to be verified */
// $systemmessage = ereg_replace('\[USERDATA\]', /*something goes here*/, $systemmessage);
// $systemmessage = ereg_replace('\[LISTS\]', /*something goes here*/, $systemmessage);

return $systemmessage;
}
rjc
PL Nut
 
Posts: 28
Joined: 10:57pm, Mon 11 Dec, 2006

Postby H2B2 » 4:38am, Tue 12 Dec, 2006

Hi rjc,

Finally someone brave enough to tackle this issue! Thanks for your contribution.

I whish I could help, but my PHP coding by far isn't what I would like it to be.
H2B2
Moderator
 
Posts: 7188
Joined: 1:51am, Wed 15 Mar, 2006

Postby rain999 » 8:52am, Wed 18 Apr, 2007

Hello,

Has anyone worked with RJC's fixes to help him troubleshoot them? Is there a new release of PHPlist on the horizon with the ability to use custom placeholders within system eMails and subject lines?

Thanks for your time,
-r999
rain999
phpLister
 
Posts: 11
Joined: 5:42am, Tue 17 Apr, 2007

Re: [mod] Customizing confirmation emails with custom attributes

Postby splowar » 5:20am, Mon 26 Jul, 2010

I hate to bring back an on old thread, but I have come up with a slightly more elegant way to accomplish this. The only files that need to be modified is admin/lib.php

This also includes hacks added on to make the confirmation emails HTML-ready, and also the CONDITIONAL attributes. Basically, I copied/modified the code from sendemaillib.php and put it in lib.php.

in admin/lib.php, after this:
Code: Select all
function sendMailPhpMailer ($to,$subject,$message) {
 global $strThisLink;
  # global function to capture sending emails, to avoid trouble with
  # older (and newer!) php versions
  $fromemail = getConfig("message_from_address");
  $fromname = getConfig("message_from_name");
  $message_replyto_address = getConfig("message_replyto_address");
  if ($message_replyto_address)
    $reply_to = $message_replyto_address;
  else
    $reply_to = $from_address;
  $destinationemail = '';


Add this text:
Code: Select all
  $htmlmessage = $message;
  $htmlmessage = nl2br($htmlmessage);

  $textmessage = $message;
  $textmessage = preg_replace('/(<script.*\/script>)|(<style.*\/style>)/i', '', $textmessage );
  $textmessage = preg_replace('/<a\s*.*?href\s*=\s*("|\')([^"\']*?)("|\').*?>(.*?)<\/a>/i', "$4:\n$2\n", $textmessage );
  $textmessage = strip_tags($textmessage );

$email=$to;
if($user_att_values = getUserAttributeValues($email)){
 
  $userdata = Sql_Fetch_Assoc_Query(sprintf('select * from %s where email = "%s"',
    $GLOBALS["tables"]["user"],$email));
  $hash = $userdata['id'];

  $url = getConfig("unsubscribeurl");$sep = ereg('\?',$url)?'&':'?';
  $html["unsubscribe"] = sprintf('<a href="%s%suid=%s">%s</a>',$url,$sep,$hash,$strThisLink);
  $text["unsubscribe"] = sprintf('%s%suid=%s',$url,$sep,$hash);
  $html["unsubscribeurl"] = sprintf('%s%suid=%s',$url,$sep,$hash);
  $text["unsubscribeurl"] = sprintf('%s%suid=%s',$url,$sep,$hash);

  #0013076: Blacklisting posibility for unknown users
  $url = getConfig("blacklisturl");$sep = ereg('\?',$url)?'&':'?';
  $html["blacklist"] = sprintf('<a href="%s%semail=%s">%s</a>',$url,$sep,$email,$strThisLink);
  $text["blacklist"] = sprintf('%s%semail=%s',$url,$sep,$email);
  $html["blacklisturl"] = sprintf('%s%semail=%s',$url,$sep,$email);
  $text["blacklisturl"] = sprintf('%s%semail=%s',$url,$sep,$email);

 
  $url = getConfig("subscribeurl");$sep = ereg('\?',$url)?'&':'?';
  $html["subscribe"] = sprintf('<a href="%s">%s</a>',$url,$strThisLink);
  $text["subscribe"] = sprintf('%s',$url);
  $html["subscribeurl"] = sprintf('%s',$url);
  $text["subscribeurl"] = sprintf('%s',$url);

    $text["signature"] = "";
  $url = getConfig("preferencesurl");$sep = ereg('\?',$url)?'&':'?';
  $html["preferences"] = sprintf('<a href="%s%suid=%s">%s</a>',$url,$sep,$hash,$strThisLink);
  $text["preferences"] = sprintf('%s%suid=%s',$url,$sep,$hash);
  $html["preferencesurl"] = sprintf('%s%suid=%s',$url,$sep,$hash);
  $text["preferencesurl"] = sprintf('%s%suid=%s',$url,$sep,$hash);
  $html["signature"] = "";

 
## Fetch external content
  if ($GLOBALS["has_pear_http_request"] && preg_match("/\[URL:([^\s]+)\]/i",$message,$regs)) {
    while (isset($regs[1]) && strlen($regs[1])) {
      $url = $regs[1];
      if (!preg_match('/^http/i',$url)) {
        $url = 'http://'.$url;
      }
      $remote_content = fetchUrl($url,$userdata);
      if ($remote_content) {
        $message = eregi_replace(preg_quote($regs[0]),$remote_content,$message);
      } else {
        logEvent("Error fetching URL: $regs[1] to send to $email");
        return 0;
      }
      preg_match("/\[URL:([^\s]+)\]/i",$message,$regs);
    }
  }

## Parse placeholders
  #0013076: Blacklisting posibility for unknown users
  foreach (array("subscribe","preferences","unsubscribe", 'blacklist') as $item) { #BUGFIX 0015303, 1/2
    if (eregi('\['.$item.'\]',$htmlmessage,$regs)) {
      $htmlmessage = eregi_replace('\['.$item.'\]',$html[$item],$htmlmessage);
//      unset($html[$item]); //ASK: Why was this done? It breaks placeholders in the footer
    }
    if (eregi('\['.$item.'\]',$textmessage,$regs)) {
      $textmessage = eregi_replace('\['.$item.'\]',$text[$item],$textmessage);
//      unset($text[$item]);
    }
  }
  #0013076: Blacklisting posibility for unknown users
  foreach (array("forward","forwardurl","subscribeurl","preferencesurl","unsubscribeurl",'blacklisturl') as $item) {
    if (eregi('\['.$item.'\]',$htmlmessage,$regs)) {
      $htmlmessage = eregi_replace('\['.$item.'\]',$html[$item],$htmlmessage);
    }
    if (eregi('\['.$item.'\]',$textmessage,$regs)) {
      $textmessage = eregi_replace('\['.$item.'\]',$text[$item],$textmessage);
    }
  }


  $textmessage = eregi_replace("\[SUBSCRIBE\]",$text["subscribe"],$textmessage );
  $htmlmessage = eregi_replace("\[SUBSCRIBE\]",$html["subscribe"],$htmlmessage );
  $textmessage  = eregi_replace("\[PREFERENCES\]",$text["preferences"],$textmessage );
  $htmlmessage = eregi_replace("\[PREFERENCES\]",$html["preferences"],$htmlmessage );
  $textmessage  = eregi_replace("\[BLACKLIST\]",$text["blacklist"],$textmessage );
  $htmlmessage  = eregi_replace("\[BLACKLIST\]",$html["blacklist"],$htmlmessage );
  $textmessage  = eregi_replace("\[UNSUBSCRIBE\]",$text["unsubscribe"],$textmessage);
  $htmlmessage  = eregi_replace("\[UNSUBSCRIBE\]",$html["unsubscribe"],$htmlmessage);

  $htmlmessage = eregi_replace("\[USERID\]",$hash,$htmlmessage);
  $textmessage = eregi_replace("\[USERID\]",$hash,$textmessage);
 


  if (is_array($GLOBALS["default_config"])) {
    foreach($GLOBALS["default_config"] as $key => $val) {
      if (is_array($val)) {
        $htmlmessage = eregi_replace("\[$key\]",getConfig($key),$htmlmessage);
        $textmessage = eregi_replace("\[$key\]",getConfig($key),$textmessage);
      }
    }
  }

  if (is_array($userdata)) {
    foreach ($userdata as $name => $value) {
      if (eregi("\[".$name."\]",$htmlmessage,$regs)) {
        $htmlmessage = eregi_replace("\[".$name."\]",$value,$htmlmessage);
      }
      if (eregi("\[".$name."\]",$textmessage,$regs)) {
        $textmessage = eregi_replace("\[".$name."\]",$value,$textmessage);
      }
    }
  }
   
  //-- START of Conditional Statements modification --

  /**
   * @since 2007/09/30
   * @version 2008/07/18
   * @author flug @ forums.phplist.com
   * @author pd @ forums.phplist.com
   * @link http://forums.phplist.com/viewtopic.php?t=11225
   * @todo several characters -like {} and |- should be able to be escaped like \} and \{ and \|
   * @todo maybe it should be possible as well to put several conditions in one conditional statement
   *       although this might be a little bit to much as well...
   *
   * Example 1:
   * {CONDITIONAL|[FIRST NAME]|Dear [FIRST NAME],|Greetings!}
   *
   * This checks whether attribute "first name" in the database is filled.
   * If yes: then print "Dear [FIRST NAME]," (ie. Dear Paul,)
   * If no: then print "Greetings!"
   *
   *
   * Example 2:
   * Sehr {CONDITIONAL|[***SPAM***=male]|geehrter Herr|geehrte Frau} [FIRST NAME],
   *
   * This checks whether attribute "***SPAM***" in the database matches the value behind the equals-sign (=)
   * If yes: then print "geehrter Herr", otherwise print "geehrte Frau"
   *
   *
   * Example 3:
   * Sehr {CONDITIONAL|[FIRST NAME=Paul]|We all love you [FIRST NAME]!|I don't like you ;)} [FIRST NAME],
   *
   * This checks whether attribute "first name" in the database matches the value behind the equals-sign (=)
   * If yes: then print "We all love you Paul!", otherwise print "I don't like you ;)"
   *
   */

  //upcase the keys here because the format within email messages is the [UPPER CASE]
  $user_att_values_upper=array_change_key_case($user_att_values, CASE_UPPER);
  $condition_regex = '/\{CONDITIONAL\|\[(.*?)\]\|(.*?)\|(.*?)\}/si';

  /**
   * We want to modify both the htmlmessage and the textmessage
   * We want to do that that by using the same code for both, but without using a function
   * The easiest way to do that is by putting both variables in an array by reference and loop through
   * that array.
   */
  $changemessages = Array(&$htmlmessage, &$textmessage);

  for ($i=0; $i<count($changemessages); $i++) {
      //do conditional substitution for HTML message:
      if (preg_match_all ($condition_regex,
             $changemessages[$i],$matches, PREG_SET_ORDER))
      {
        foreach ($matches as $regs) {
         
          $conditional=""; # if the attribute isn't found or there are no attributes we will still just erase the matching conditional statement
          if (is_array($user_att_values_upper)) {
           
            $check_conditional_value = ( strpos('=', $regs[1])===false ? false : true );

            list($field_name,$match_conditional_value) = explode('=', $regs[1], 2);
           
            if (  array_key_exists( $field_name, $user_att_values_upper )) {
               $att_value=$user_att_values_upper[ $field_name ];
   
              /**
               * When there is no conditional value given (so there is no equals-sign)
               *  we want to check whether the $att_value is not empty
               * 
               * Otherwise we want the $att_value to match our conditional value
               */
              if ( (!$check_conditional_value && $att_value<>"") || ($check_conditional_value && $att_value==$match_conditional_value) ) {
                //note: no need to replace [ATTRIBUTE] placeholders here, it will be done later
                $conditional=$regs[2];
              } else {
                $conditional=$regs[3];
              }
           }
          }
          //now substitute the conditional expression into the message (or erase it if no matching attributes found)
          $changemessages[$i] = str_replace($regs[0] , $conditional, $changemessages[$i]);
        }
      }
  }
 
  /**
   * A little cleanup
   */
  unset($changemessages, $check_conditional_value, $field_name, $match_conditional_value, $condition_regex,
        $matches, $regs, $conditional);
 
  //-- END of Conditional Statements modification --
 
   
 
  $destinationemail = '';
  if (is_array($user_att_values)) {
    foreach ($user_att_values as $att_name => $att_value) {
      if (eregi("\[".$att_name."\]",$htmlmessage,$regs)) {
        # the value may be a multiline textarea field
        $htmlatt_value = str_replace("\n","<br/>\n",$att_value);
        $htmlmessage = eregi_replace("\[".$att_name."\]",$htmlatt_value,$htmlmessage);
      }
      if (eregi("\[".$att_name."\]",$textmessage,$regs)) {
        $textmessage = eregi_replace("\[".$att_name."\]",$att_value,$textmessage);
      }
    }
  }


  if (eregi("\[LISTS\]",$htmlmessage)) {
    $lists = "";$listsarr = array();
    $req = Sql_Query(sprintf('select list.name from %s as list,%s as listuser where list.id = listuser.listid and listuser.userid = %d',$GLOBALS["tables"]["list"],$GLOBALS["tables"]["listuser"],$user_system_values["id"]));
    while ($row = Sql_Fetch_Row($req)) {
      array_push($listsarr,$row[0]);
    }
    $lists_html = join('<br/>',$listsarr);
    $lists_text = join("\n",$listsarr);
    $htmlmessage = ereg_replace("\[LISTS\]",$lists_html,$htmlmessage);
    $textmessage = ereg_replace("\[LISTS\]",$lists_text,$textmessage);
  }

}


  ## remove any existing placeholders
  $htmlmessage = eregi_replace("\[[A-Z\. ]+\]","",$htmlmessage);
  $textmessage = eregi_replace("\[[A-Z\. ]+\]","",$textmessage);




you can remove the block with conditional attributes if you don't want it.

Then... just below the text you added, there are two lines that need to be added and two lines that need to be deleted...
Code: Select all
 if (!ereg("dev",VERSION)) {
    $mail = new PHPlistMailer('systemmessage',$to);
    $destinationemail = $to;
    $mail->add_html($htmlmessage); // add this line
    $mail->add_text($textmessage); // change this line
  } else {
    # send mails to one place when running a test version
    $message = "To: $to\n".$message;
    if ($GLOBALS["developer_email"]) {
      # fake occasional failure
      if (mt_rand(0,50) == 1) {
        return 0;
      } else {
        $mail = new PHPlistMailer('systemmessage',$GLOBALS["developer_email"]);
          $mail->add_html($htmlmessage); // add this line
        $mail->add_text($textmessage); //change this line
        $destinationemail = $GLOBALS["developer_email"];
      }
    } else {
      print "Error: Running CVS version, but developer_email not set";
    }
  }
 
splowar
phpList newbie
 
Posts: 1
Joined: 5:13am, Mon 26 Jul, 2010

Re: [mod] Customizing confirmation emails with custom attributes

Postby AndrewFickling » 9:00am, Thu 16 Sep, 2010

This is excellent.... Applied and standard system emails now have correct placeholder info.

However does this work with the system messages/pages created using a custom subscribe page?

My custom subscribe page seems not to work in the same way as the main customisation pages.

Also can all pages have html content to format the system messages. If so what is the format for these... A full html page or just part?

Many thanks
AndrewFickling
phpLister
 
Posts: 5
Joined: 6:38pm, Mon 07 Sep, 2009

Re: [mod] Customizing confirmation emails with custom attributes

Postby NickLaenen » 7:15am, Thu 07 Oct, 2010

wow amazing add-on! Almost all confirmation mails are in html and with the attributes.

The only mail that doesn't work with the HTML is the mail when the user has changed it's information.
Does anyone know how to make this work?


*** Update: The problem with the changed information e-mail is the fact that somewhere in the code the it puts a '\' before every "-sign. Does someone know how to solve this issue? It seems to be a PHP thing called 'addslashes', but I can't find the problem in the LIB file
NickLaenen
phpList newbie
 
Posts: 1
Joined: 7:02am, Thu 07 Oct, 2010

Re: [mod] Customizing confirmation emails with custom attributes

Postby shiftinglight » 4:03pm, Sun 12 Dec, 2010

Yes, thanks, works a treat!
shiftinglight
phpLister
 
Posts: 5
Joined: 3:31pm, Fri 12 Nov, 2010

Re: [mod] Customizing confirmation emails with custom attributes

Postby andrew55 » 4:57pm, Thu 04 Aug, 2011

I can't seem to get this mod working. I have checked and rechecked my code. I'm not great a php. Can someone take a look at my code (admin/lib) and let me know if I'm doing something wrong. Thank you for any suggestions:

Code: Select all
<?php
require_once dirname(__FILE__)."/accesscheck.php";
# library used for plugging into the webbler, instead of "connect"
# depricated and should be removed

#error_reporting(63);

# set some defaults if they are not specified
if (!defined("REGISTER")) define("REGISTER",1);
if (!defined("USE_PDF")) define("USE_PDF",0);
if (!defined("VERBOSE")) define("VERBOSE",0);
if (!defined("ENABLE_RSS")) define("ENABLE_RSS",0);
if (!defined("ALLOW_ATTACHMENTS")) define("ALLOW_ATTACHMENTS",0);
if (!defined("EMAILTEXTCREDITS")) define("EMAILTEXTCREDITS",0);
if (!defined("PAGETEXTCREDITS")) define("PAGETEXTCREDITS",0);
if (!defined("USEFCK")) define("USEFCK",0);
if (!defined("ASKFORPASSWORD")) define("ASKFORPASSWORD",0);
if (!defined("UNSUBSCRIBE_REQUIRES_PASSWORD")) define("UNSUBSCRIBE_REQUIRES_PASSWORD",0);
if (!defined("UNSUBSCRIBE_JUMPOFF")) define("UNSUBSCRIBE_JUMPOFF",0);
if (!defined("ENCRYPTPASSWORD")) define("ENCRYPTPASSWORD",0);
if (!defined("PHPMAILER")) define("PHPMAILER",0);
if (!defined("MANUALLY_PROCESS_QUEUE")) define("MANUALLY_PROCESS_QUEUE",1);
if (!defined("CHECK_SESSIONIP")) define("CHECK_SESSIONIP",1);
if (!defined("FILESYSTEM_ATTACHMENTS")) define("FILESYSTEM_ATTACHMENTS",0);
if (!defined("MIMETYPES_FILE")) define("MIMETYPES_FILE","/etc/mime.types");
if (!defined("DEFAULT_MIMETYPE")) define("DEFAULT_MIMETYPE","application/octet-stream");
if (!defined("USE_REPETITION")) define("USE_REPETITION",0);
if (!defined("USE_EDITMESSAGE")) define("USE_EDITMESSAGE",0);
if (!defined("FCKIMAGES_DIR")) define("FCKIMAGES_DIR","uploadimages");
if (!defined("USE_MANUAL_TEXT_PART")) define("USE_MANUAL_TEXT_PART",0);
if (!defined("ALLOW_NON_LIST_SUBSCRIBE")) define("ALLOW_NON_LIST_SUBSCRIBE",0);
if (!defined("MAILQUEUE_BATCH_SIZE")) define("MAILQUEUE_BATCH_SIZE",0);
if (!defined("MAILQUEUE_BATCH_PERIOD")) define("MAILQUEUE_BATCH_PERIOD",3600);
if (!defined('MAILQUEUE_THROTTLE')) define('MAILQUEUE_THROTTLE',0);
if (!defined('MAILQUEUE_AUTOTHROTTLE')) define('MAILQUEUE_AUTOTHROTTLE',0);
if (!defined("NAME")) define("NAME",'phplist');
if (!defined("USE_OUTLOOK_OPTIMIZED_HTML")) define("USE_OUTLOOK_OPTIMIZED_HTML",0);
if (!defined("EXPORT_EXCEL")) define("EXPORT_EXCEL",0);
if (!defined("USE_PREPARE")) define("USE_PREPARE",0);
if (!defined("HTMLEMAIL_ENCODING")) define("HTMLEMAIL_ENCODING","quoted-printable");
if (!defined('TEXTEMAIL_ENCODING')) define('TEXTEMAIL_ENCODING','7bit');
if (!defined("USE_LIST_EXCLUDE")) define("USE_LIST_EXCLUDE",0);
if (!defined("WARN_SAVECHANGES")) define("WARN_SAVECHANGES",1);
if (!defined("STACKED_ATTRIBUTE_SELECTION")) define("STACKED_ATTRIBUTE_SELECTION",0);
if (!defined("REMOTE_URL_REFETCH_TIMEOUT")) define('REMOTE_URL_REFETCH_TIMEOUT',3600);
if (!defined('CLICKTRACK')) define('CLICKTRACK',0);
if (!defined('CLICKTRACK_SHOWDETAIL')) define('CLICKTRACK_SHOWDETAIL',0);
if (!defined('USETINYMCEMESG')) define('USETINYMCEMESG',0);
if (!defined('USETINYMCETEMPL')) define('USETINYMCETEMPL',0);
if (!defined('TINYMCEPATH')) define('TINYMCEPATH','');
if (!defined('STATS_INTERVAL')) define('STATS_INTERVAL','monthly');
if (!defined('USE_DOMAIN_THROTTLE')) define('USE_DOMAIN_THROTTLE',0);
if (!defined('DOMAIN_BATCH_SIZE')) define('DOMAIN_BATCH_SIZE',1);
if (!defined('DOMAIN_BATCH_PERIOD')) define('DOMAIN_BATCH_PERIOD',120);
if (!defined('DOMAIN_AUTO_THROTTLE')) define('DOMAIN_AUTO_THROTTLE',0);
if (!defined('LANGUAGE_SWITCH')) define('LANGUAGE_SWITCH',1);
if (!defined('USE_ADVANCED_BOUNCEHANDLING')) define('USE_ADVANCED_BOUNCEHANDLING',0);
if (!defined('DATE_START_YEAR')) define('DATE_START_YEAR',1900);
if (!defined('DATE_END_YEAR')) define('DATE_END_YEAR',0);
if (!defined('ALLOW_IMPORT')) define('ALLOW_IMPORT',1);
if (!defined('EMPTY_VALUE_PREFIX')) define('EMPTY_VALUE_PREFIX','--');
if (!defined('USE_ADMIN_DETAILS_FOR_MESSAGES')) define('USE_ADMIN_DETAILS_FOR_MESSAGES',1);
if (!defined('SEND_ONE_TESTMAIL')) define('SEND_ONE_TESTMAIL',0);
if (!defined('USE_SPAM_BLOCK')) define('USE_SPAM_BLOCK',1);
if (!defined('NOTIFY_SPAM')) define('NOTIFY_SPAM',1);
if (!defined('FORWARD_ALTERNATIVE_CONTENT')) define('FORWARD_ALTERNATIVE_CONTENT',0);
if (!defined('KEEPFORWARDERATTRIBUTES')) define('KEEPFORWARDERATTRIBUTES',0);
if (!defined('FORWARD_EMAIL_COUNT') ) define('FORWARD_EMAIL_COUNT',1);
if (FORWARD_EMAIL_COUNT < 1) {Error('FORWARD_EMAIL_COUNT must be > (int) 0');}
# allows FORWARD_EMAIL_COUNT forwards per user per period in mysql interval terms default one day 
if (!defined('FORWARD_EMAIL_PERIOD') ) define('FORWARD_EMAIL_PERIOD', '1 day');
if (!defined('SEND_QUEUE_PROCESSING_REPORT')) define('SEND_QUEUE_PROCESSING_REPORT',true);
if (!defined('FORWARD_PERSONAL_NOTE_SIZE')) define('FORWARD_PERSONAL_NOTE_SIZE',0);
if (!defined('FORWARD_FRIEND_COUNT_ATTRIBUTE')) define('FORWARD_FRIEND_COUNT_ATTRIBUTE','');
if (!defined('EMBEDUPLOADIMAGES')) define('EMBEDUPLOADIMAGES',0);
if (!defined('IMPORT_FILESIZE'))  define('IMPORT_FILESIZE',1);
if (!defined('CHECK_REFERRER')) define('CHECK_REFERRER',false);
if (!defined("EMAIL_ADDRESS_VALIDATION_LEVEL")) define("EMAIL_ADDRESS_VALIDATION_LEVEL",1);
if (!isset($GLOBALS["export_mimetype"])) $GLOBALS["export_mimetype"] = 'application/csv';
if (!isset($GLOBALS["admin_auth_module"])) $GLOBALS["admin_auth_module"] = 'phplist_auth.inc';
if (!isset($GLOBALS["require_login"])) $GLOBALS["require_login"] = 0;

if (!isset($allowed_referrers)) $allowed_referrers = array();

if (!defined("WORKAROUND_OUTLOOK_BUG") && defined("USE_CARRIAGE_RETURNS")) {
  define("WORKAROUND_OUTLOOK_BUG",USE_CARRIAGE_RETURNS);
}
if (!isset($GLOBALS["blacklist_gracetime"])) $GLOBALS["blacklist_gracetime"] = 5;
if (!isset($GLOBALS["message_envelope"])) $GLOBALS["message_envelope"] = '';

$domain = getConfig("domain");
$website = getConfig("website");

if (defined("IN_WEBBLER") && is_object($GLOBALS["config"]["plugins"]["phplist"])) {
  $GLOBALS["tables"] = $GLOBALS["config"]["plugins"]["phplist"]->tables;
  $GLOBALS["table_prefix"] = $GLOBALS["config"]["plugins"]["phplist"]->table_prefix;
}

$usephpmailer = 0;
if (PHPMAILER && is_file(dirname(__FILE__).'/phpmailer/class.phpmailer.php')) {
  include_once dirname(__FILE__) . '/class.phplistmailer.php';
  $usephpmailer = 1;
}

$GLOBALS['bounceruleactions'] = array(
  'deleteuser' => $GLOBALS['I18N']->get('delete user'),
  'unconfirmuser' => $GLOBALS['I18N']->get('unconfirm user'),
  'blacklistuser' => $GLOBALS['I18N']->get('blacklist user'),
  'deleteuserandbounce' => $GLOBALS['I18N']->get('delete user and bounce'),
  'unconfirmuseranddeletebounce' => $GLOBALS['I18N']->get('unconfirm user and delete bounce'),
  'blacklistuseranddeletebounce' => $GLOBALS['I18N']->get('blacklist user and delete bounce'),
  'deletebounce' => $GLOBALS['I18N']->get('delete bounce'),
);

# check whether Pear HTTP/Request is available
@include_once "HTTP/Request.php";
$GLOBALS['has_pear_http_request'] = class_exists('HTTP_Request');

ini_set('error_append_string','<font style=\"{font-variant: small-caps;font-size: 12px}\">phplist</font> version '.VERSION);
ini_set('error_prepend_string','<P><font color=red style=\"{font-size: 12px}\">Sorry a software error occurred:</font><br/>
  Please <a href="http://mantis.phplist.com">report a bug</a> when reporting the bug, please include URL and the entire content of this page.<br/>');

function listName($id) {
  global $tables;
  $req = Sql_Fetch_Row_Query(sprintf('select name from %s where id = %d',$tables["list"],$id));
  return $req[0] ? stripslashes($req[0]) : $GLOBALS['I18N']->get('Unnamed List');
}

function setMessageData($msgid,$name,$value) {
  Sql_Query(sprintf('replace into %s set id = %d,name = "%s", data = "%s"',
    $GLOBALS['tables']['messagedata'],$msgid,addslashes($name),$value));
#  print "setting $name for $msgid to $value";
#  exit;
}

function loadMessageData($msgid) {
  $messagedata = array();
  $msgdata_req = Sql_Query(sprintf('select * from %s where id = %d',
    $GLOBALS['tables']['messagedata'],$msgid));
  while ($row = Sql_Fetch_Array($msgdata_req)) {
    $messagedata[$row['name']] = $row['data'];
  }
  return $messagedata;
}

function HTMLselect ($name, $table, $column, $value) {
  $res = "<!--$value--><select name=$name>\n";
  $result = Sql_Query("SELECT id,$column FROM $table");
  while($row = Sql_Fetch_Array($result)) {
    $res .= "<option value=".$row["id"] ;
    if ($row["$column"] == $value)
      $res .= " selected";
    if ($row["id"] == $value)
      $res .= " selected";
    $res .= ">" . $row[$column] . "\n";
  }
  $res .= "</select>\n";
  return $res;
}

function sendMail ($to,$subject,$message,$header = "",$parameters = "",$skipblacklistcheck = 0) {
  if (TEST)
    return 1;

  # do a quick check on mail injection attempt, @@@ needs more work
  if (preg_match("/\n/",$to)) {
    logEvent("Error: invalid recipient, containing newlines, email blocked");
    return 0;
  }
  if (preg_match("/\n/",$subject)) {
    logEvent("Error: invalid subject, containing newlines, email blocked");
    return 0;
  }

  if (!$to)  {
    logEvent("Error: empty To: in message with subject $subject to send");
    return 0;
  } elseif (!$subject) {
    logEvent("Error: empty Subject: in message to send to $to");
    return 0;
  }
  if (!$skipblacklistcheck && isBlackListed($to)) {
    logEvent("Error, $to is blacklisted, not sending");
    Sql_Query(sprintf('update %s set blacklisted = 1 where email = "%s"',$GLOBALS["tables"]["user"],$to));
    addUserHistory($to,"Marked Blacklisted","Found user in blacklist while trying to send an email, marked black listed");
    return 0;
  }
  if ($GLOBALS['usephpmailer']) {
    return sendMailPhpMailer($to,$subject,$message);
  } else {
    return sendMailOriginal($to,$subject,$message,$header,$parameters);
  }
  return 0;
}


function sendMailOriginal ($to,$subject,$message,$header = "",$parameters = "") {
  # global function to capture sending emails, to avoid trouble with
  # older (and newer!) php versions
  $v = phpversion();
  $v = preg_replace("/\-.*$/","",$v);
  if ($GLOBALS["message_envelope"]) {
    $header = rtrim($header);
    if ($header)
      $header .= "\n";
    $header .= "Errors-To: ".$GLOBALS["message_envelope"];
    if (!$parameters || !ereg("-f".$GLOBALS["message_envelope"],$parameters)) {
      $parameters = '-f'.$GLOBALS["message_envelope"];
    }
  }

  // Use the system email encoding method
  if (TEXTEMAIL_ENCODING) {
    // only add if the required header is not already present
    if (!strpos(strtolower($header), 'content-transfer-encoding')) {
      $header = rtrim($header);
      if ($header)
        $header .= "\n";
      $header .= "Content-Transfer-Encoding: " . TEXTEMAIL_ENCODING;
    }
  }

  if (WORKAROUND_OUTLOOK_BUG) {
    $header = rtrim($header);
    if ($header)
      $header .= "\n";
     $header .= "X-Outlookbug-fixed: Yes";
    $message = preg_replace("/\r?\n/", "\r\n", $message);
  }

  # version 4.2.3 (and presumably up) does not allow the fifth parameter in safe mode
  # make sure not to send out loads of test emails to ppl when developing
  if (!ereg("dev",VERSION)) {
    if ($v > "4.0.5" && !ini_get("safe_mode")) {
      if (mail($to,$subject,$message,$header,$parameters))
        return 1;
      else
        return mail($to,$subject,$message,$header);
    }
    else
      return mail($to,$subject,$message,$header);
  } else {
    # send mails to one place when running a test version
    $message = "To: $to\n".$message;
    if ($GLOBALS["developer_email"]) {
      # fake occasional failure
      if (mt_rand(0,50) == 1) {
        return 0;
      } else {
        if(@mail($GLOBALS["developer_email"],$subject,$message,$header,$parameters)) {
          return 1;
        } else {
          # Changed by Bas: Always ok, since the mac/xampp return false while sending and no error in /var/log/mail.log
          # We are in developermode anyway, and errors are faked by code just above this.
          mail($GLOBALS["developer_email"],$subject,$message,$header);
          return 1;
        }
      }
    } else {
      print "Error: Running CVS version, but developer_email not set";
    }
  }
}

function sendMailPhpMailer ($to,$subject,$message) {
  # global function to capture sending emails, to avoid trouble with
  # older (and newer!) php versions
  $fromemail = getConfig("message_from_address");
  $fromname = getConfig("message_from_name");
  $message_replyto_address = getConfig("message_replyto_address");
  if ($message_replyto_address)
    $reply_to = $message_replyto_address;
  else
  $reply_to = $from_address;
  $destinationemail = '';
   $htmlmessage = $message;
   $htmlmessage = nl2br($htmlmessage);

   $textmessage = $message;
   $textmessage = preg_replace('/(<script.*\/script>)|(<style.*\/style>)/i', '', $textmessage );
   $textmessage = preg_replace('/<a\s*.*?href\s*=\s*("|\')([^"\']*?)("|\').*?>(.*?)<\/a>/i', "$4:\n$2\n", $textmessage );
   $textmessage = strip_tags($textmessage );

    $email=$to;
    if($user_att_values = getUserAttributeValues($email)){
     
      $userdata = Sql_Fetch_Assoc_Query(sprintf('select * from %s where email = "%s"',
        $GLOBALS["tables"]["user"],$email));
      $hash = $userdata['id'];

      $url = getConfig("unsubscribeurl");$sep = ereg('\?',$url)?'&':'?';
      $html["unsubscribe"] = sprintf('<a href="%s%suid=%s">%s</a>',$url,$sep,$hash,$strThisLink);
      $text["unsubscribe"] = sprintf('%s%suid=%s',$url,$sep,$hash);
      $html["unsubscribeurl"] = sprintf('%s%suid=%s',$url,$sep,$hash);
      $text["unsubscribeurl"] = sprintf('%s%suid=%s',$url,$sep,$hash);

      #0013076: Blacklisting posibility for unknown users
      $url = getConfig("blacklisturl");$sep = ereg('\?',$url)?'&':'?';
      $html["blacklist"] = sprintf('<a href="%s%semail=%s">%s</a>',$url,$sep,$email,$strThisLink);
      $text["blacklist"] = sprintf('%s%semail=%s',$url,$sep,$email);
      $html["blacklisturl"] = sprintf('%s%semail=%s',$url,$sep,$email);
      $text["blacklisturl"] = sprintf('%s%semail=%s',$url,$sep,$email);

     
      $url = getConfig("subscribeurl");$sep = ereg('\?',$url)?'&':'?';
      $html["subscribe"] = sprintf('<a href="%s">%s</a>',$url,$strThisLink);
      $text["subscribe"] = sprintf('%s',$url);
      $html["subscribeurl"] = sprintf('%s',$url);
      $text["subscribeurl"] = sprintf('%s',$url);

        $text["signature"] = "";
      $url = getConfig("preferencesurl");$sep = ereg('\?',$url)?'&':'?';
      $html["preferences"] = sprintf('<a href="%s%suid=%s">%s</a>',$url,$sep,$hash,$strThisLink);
      $text["preferences"] = sprintf('%s%suid=%s',$url,$sep,$hash);
      $html["preferencesurl"] = sprintf('%s%suid=%s',$url,$sep,$hash);
      $text["preferencesurl"] = sprintf('%s%suid=%s',$url,$sep,$hash);
      $html["signature"] = "";


    ## Fetch external content
      if ($GLOBALS["has_pear_http_request"] && preg_match("/\[URL:([^\s]+)\]/i",$message,$regs)) {
        while (isset($regs[1]) && strlen($regs[1])) {
          $url = $regs[1];
          if (!preg_match('/^http/i',$url)) {
            $url = 'http://'.$url;
          }
          $remote_content = fetchUrl($url,$userdata);
          if ($remote_content) {
            $message = eregi_replace(preg_quote($regs[0]),$remote_content,$message);
          } else {
            logEvent("Error fetching URL: $regs[1] to send to $email");
            return 0;
          }
          preg_match("/\[URL:([^\s]+)\]/i",$message,$regs);
        }
      }

    ## Parse placeholders
      #0013076: Blacklisting posibility for unknown users
      foreach (array("subscribe","preferences","unsubscribe", 'blacklist') as $item) { #BUGFIX 0015303, 1/2
        if (eregi('\['.$item.'\]',$htmlmessage,$regs)) {
          $htmlmessage = eregi_replace('\['.$item.'\]',$html[$item],$htmlmessage);
    //      unset($html[$item]); //ASK: Why was this done? It breaks placeholders in the footer
        }
        if (eregi('\['.$item.'\]',$textmessage,$regs)) {
          $textmessage = eregi_replace('\['.$item.'\]',$text[$item],$textmessage);
    //      unset($text[$item]);
        }
      }
      #0013076: Blacklisting posibility for unknown users
      foreach (array("forward","forwardurl","subscribeurl","preferencesurl","unsubscribeurl",'blacklisturl') as $item) {
        if (eregi('\['.$item.'\]',$htmlmessage,$regs)) {
          $htmlmessage = eregi_replace('\['.$item.'\]',$html[$item],$htmlmessage);
        }
        if (eregi('\['.$item.'\]',$textmessage,$regs)) {
          $textmessage = eregi_replace('\['.$item.'\]',$text[$item],$textmessage);
        }
      }


      $textmessage = eregi_replace("\[SUBSCRIBE\]",$text["subscribe"],$textmessage );
      $htmlmessage = eregi_replace("\[SUBSCRIBE\]",$html["subscribe"],$htmlmessage );
      $textmessage  = eregi_replace("\[PREFERENCES\]",$text["preferences"],$textmessage );
      $htmlmessage = eregi_replace("\[PREFERENCES\]",$html["preferences"],$htmlmessage );
      $textmessage  = eregi_replace("\[BLACKLIST\]",$text["blacklist"],$textmessage );
      $htmlmessage  = eregi_replace("\[BLACKLIST\]",$html["blacklist"],$htmlmessage );
      $textmessage  = eregi_replace("\[UNSUBSCRIBE\]",$text["unsubscribe"],$textmessage);
      $htmlmessage  = eregi_replace("\[UNSUBSCRIBE\]",$html["unsubscribe"],$htmlmessage);

      $htmlmessage = eregi_replace("\[USERID\]",$hash,$htmlmessage);
      $textmessage = eregi_replace("\[USERID\]",$hash,$textmessage);
     


      if (is_array($GLOBALS["default_config"])) {
        foreach($GLOBALS["default_config"] as $key => $val) {
          if (is_array($val)) {
            $htmlmessage = eregi_replace("\[$key\]",getConfig($key),$htmlmessage);
            $textmessage = eregi_replace("\[$key\]",getConfig($key),$textmessage);
          }
        }
      }

      if (is_array($userdata)) {
        foreach ($userdata as $name => $value) {
          if (eregi("\[".$name."\]",$htmlmessage,$regs)) {
            $htmlmessage = eregi_replace("\[".$name."\]",$value,$htmlmessage);
          }
          if (eregi("\[".$name."\]",$textmessage,$regs)) {
            $textmessage = eregi_replace("\[".$name."\]",$value,$textmessage);
          }
        }
      }       
     
      $destinationemail = '';
      if (is_array($user_att_values)) {
        foreach ($user_att_values as $att_name => $att_value) {
          if (eregi("\[".$att_name."\]",$htmlmessage,$regs)) {
            # the value may be a multiline textarea field
            $htmlatt_value = str_replace("\n","<br/>\n",$att_value);
            $htmlmessage = eregi_replace("\[".$att_name."\]",$htmlatt_value,$htmlmessage);
          }
          if (eregi("\[".$att_name."\]",$textmessage,$regs)) {
            $textmessage = eregi_replace("\[".$att_name."\]",$att_value,$textmessage);
          }
        }
      }


      if (eregi("\[LISTS\]",$htmlmessage)) {
        $lists = "";$listsarr = array();
        $req = Sql_Query(sprintf('select list.name from %s as list,%s as listuser where list.id = listuser.listid and listuser.userid = %d',$GLOBALS["tables"]["list"],$GLOBALS["tables"]["listuser"],$user_system_values["id"]));
        while ($row = Sql_Fetch_Row($req)) {
          array_push($listsarr,$row[0]);
        }
        $lists_html = join('<br/>',$listsarr);
        $lists_text = join("\n",$listsarr);
        $htmlmessage = ereg_replace("\[LISTS\]",$lists_html,$htmlmessage);
        $textmessage = ereg_replace("\[LISTS\]",$lists_text,$textmessage);
      }

    }


      ## remove any existing placeholders
      $htmlmessage = eregi_replace("\[[A-Z\. ]+\]","",$htmlmessage);
      $textmessage = eregi_replace("\[[A-Z\. ]+\]","",$textmessage);

      preg_match_all("@<(br|p|a)@i", $message, $m);
      if(count($m[0]) > 2) $htmled = true;
      else $htmled = false;
   
      $htmlmessage = $message;
     
      if(!$htmled) $htmlmessage = nl2br($htmlmessage);

      $textmessage = $message;
      $textmessage = preg_replace('/(<script.*\/script>)|(<style.*\/style>)/i', '', $textmessage );
      $textmessage = preg_replace('/<a\s*.*?href\s*=\s*("|\')([^"\']*?)("|\').*?>(.*?)<\/a>/i', "$4:\n$2\n", $textmessage );
      $textmessage = strip_tags($textmessage );

    $email=$to;
    if($user_att_values = getUserAttributeValues($email)){
      $userdata = Sql_Fetch_Assoc_Query(sprintf('select * from %s where email = "%s"',
        $GLOBALS["tables"]["user"],$email));
      $hash = $userdata['id'];

      $url = getConfig("unsubscribeurl");$sep = ereg('\?',$url)?'&':'?';
      $html["unsubscribe"] = sprintf('<a href="%s%suid=%s">%s</a>',$url,$sep,$hash,$strThisLink);
      $text["unsubscribe"] = sprintf('%s%suid=%s',$url,$sep,$hash);
      $html["unsubscribeurl"] = sprintf('%s%suid=%s',$url,$sep,$hash);
      $text["unsubscribeurl"] = sprintf('%s%suid=%s',$url,$sep,$hash);

      #0013076: Blacklisting posibility for unknown users
      $url = getConfig("blacklisturl");$sep = ereg('\?',$url)?'&':'?';
      $html["blacklist"] = sprintf('<a href="%s%semail=%s">%s</a>',$url,$sep,$email,$strThisLink);
      $text["blacklist"] = sprintf('%s%semail=%s',$url,$sep,$email);
      $html["blacklisturl"] = sprintf('%s%semail=%s',$url,$sep,$email);
      $text["blacklisturl"] = sprintf('%s%semail=%s',$url,$sep,$email);

     
      $url = getConfig("subscribeurl");$sep = ereg('\?',$url)?'&':'?';
      $html["subscribe"] = sprintf('<a href="%s">%s</a>',$url,$strThisLink);
      $text["subscribe"] = sprintf('%s',$url);
      $html["subscribeurl"] = sprintf('%s',$url);
      $text["subscribeurl"] = sprintf('%s',$url);

        $text["signature"] = "";
      $url = getConfig("preferencesurl");$sep = ereg('\?',$url)?'&':'?';
      $html["preferences"] = sprintf('<a href="%s%suid=%s">%s</a>',$url,$sep,$hash,$strThisLink);
      $text["preferences"] = sprintf('%s%suid=%s',$url,$sep,$hash);
      $html["preferencesurl"] = sprintf('%s%suid=%s',$url,$sep,$hash);
      $text["preferencesurl"] = sprintf('%s%suid=%s',$url,$sep,$hash);
      $html["signature"] = "";


    ## Fetch external content
      if ($GLOBALS["has_pear_http_request"] && preg_match("/\[URL:([^\s]+)\]/i",$message,$regs)) {
        while (isset($regs[1]) && strlen($regs[1])) {
          $url = $regs[1];
          if (!preg_match('/^http/i',$url)) {
            $url = 'http://'.$url;
          }
          $remote_content = fetchUrl($url,$userdata);
          if ($remote_content) {
            $message = eregi_replace(preg_quote($regs[0]),$remote_content,$message);
          } else {
            logEvent("Error fetching URL: $regs[1] to send to $email");
            return 0;
          }
          preg_match("/\[URL:([^\s]+)\]/i",$message,$regs);
        }
      }

    ## Parse placeholders
      #0013076: Blacklisting posibility for unknown users
      foreach (array("subscribe","preferences","unsubscribe", 'blacklist') as $item) { #BUGFIX 0015303, 1/2
        if (eregi('\['.$item.'\]',$htmlmessage,$regs)) {
          $htmlmessage = eregi_replace('\['.$item.'\]',$html[$item],$htmlmessage);
    //      unset($html[$item]); //ASK: Why was this done? It breaks placeholders in the footer
        }
        if (eregi('\['.$item.'\]',$textmessage,$regs)) {
          $textmessage = eregi_replace('\['.$item.'\]',$text[$item],$textmessage);
    //      unset($text[$item]);
        }
      }
      #0013076: Blacklisting posibility for unknown users
      foreach (array("forward","forwardurl","subscribeurl","preferencesurl","unsubscribeurl",'blacklisturl') as $item) {
        if (eregi('\['.$item.'\]',$htmlmessage,$regs)) {
          $htmlmessage = eregi_replace('\['.$item.'\]',$html[$item],$htmlmessage);
        }
        if (eregi('\['.$item.'\]',$textmessage,$regs)) {
          $textmessage = eregi_replace('\['.$item.'\]',$text[$item],$textmessage);
        }
      }


      $textmessage = eregi_replace("\[SUBSCRIBE\]",$text["subscribe"],$textmessage );
      $htmlmessage = eregi_replace("\[SUBSCRIBE\]",$html["subscribe"],$htmlmessage );
      $textmessage  = eregi_replace("\[PREFERENCES\]",$text["preferences"],$textmessage );
      $htmlmessage = eregi_replace("\[PREFERENCES\]",$html["preferences"],$htmlmessage );
      $textmessage  = eregi_replace("\[BLACKLIST\]",$text["blacklist"],$textmessage );
      $htmlmessage  = eregi_replace("\[BLACKLIST\]",$html["blacklist"],$htmlmessage );
      $textmessage  = eregi_replace("\[UNSUBSCRIBE\]",$text["unsubscribe"],$textmessage);
      $htmlmessage  = eregi_replace("\[UNSUBSCRIBE\]",$html["unsubscribe"],$htmlmessage);

      $htmlmessage = eregi_replace("\[USERID\]",$hash,$htmlmessage);
      $textmessage = eregi_replace("\[USERID\]",$hash,$textmessage);
     


      if (is_array($GLOBALS["default_config"])) {
        foreach($GLOBALS["default_config"] as $key => $val) {
          if (is_array($val)) {
            $htmlmessage = eregi_replace("\[$key\]",getConfig($key),$htmlmessage);
            $textmessage = eregi_replace("\[$key\]",getConfig($key),$textmessage);
          }
        }
      }

      if (is_array($userdata)) {
        foreach ($userdata as $name => $value) {
          if (eregi("\[".$name."\]",$htmlmessage,$regs)) {
            $htmlmessage = eregi_replace("\[".$name."\]",$value,$htmlmessage);
          }
          if (eregi("\[".$name."\]",$textmessage,$regs)) {
            $textmessage = eregi_replace("\[".$name."\]",$value,$textmessage);
          }
        }
      }
       
     
      $destinationemail = '';
      if (is_array($user_att_values)) {
        foreach ($user_att_values as $att_name => $att_value) {
          if (eregi("\[".$att_name."\]",$htmlmessage,$regs)) {
            # the value may be a multiline textarea field
            $htmlatt_value = str_replace("\n","<br/>\n",$att_value);
            $htmlmessage = eregi_replace("\[".$att_name."\]",$htmlatt_value,$htmlmessage);
          }
          if (eregi("\[".$att_name."\]",$textmessage,$regs)) {
            $textmessage = eregi_replace("\[".$att_name."\]",$att_value,$textmessage);
          }
          if (eregi("\[".$att_name."\]",$subject,$regs)) {
            $subject = eregi_replace("\[".$att_name."\]",$htmlatt_value,$subject);
          }
        }
      }


      if (eregi("\[LISTS\]",$htmlmessage)) {
        $lists = "";$listsarr = array();
        $req = Sql_Query(sprintf('select list.name from %s as list,%s as listuser where list.id = listuser.listid and listuser.userid = %d',$GLOBALS["tables"]["list"],$GLOBALS["tables"]["listuser"],$user_system_values["id"]));
        while ($row = Sql_Fetch_Row($req)) {
          array_push($listsarr,$row[0]);
        }
        $lists_html = join('<br/>',$listsarr);
        $lists_text = join("\n",$listsarr);
        $htmlmessage = ereg_replace("\[LISTS\]",$lists_html,$htmlmessage);
        $textmessage = ereg_replace("\[LISTS\]",$lists_text,$textmessage);
      }

    }


      ## remove any existing placeholders
      $htmlmessage = eregi_replace("\[[A-Z\. ]+\]","",$htmlmessage);
      $textmessage = eregi_replace("\[[A-Z\. ]+\]","",$textmessage);



  $htmlmessage = preg_replace("@([^\"'])(https?://[^ <]+)@i", '${1}<a href="${2}">${2}</a>', $htmlmessage );

  if (!ereg("dev",VERSION)) {
    $mail = new PHPlistMailer('systemmessage',$to);
    $destinationemail = $to;
    $mail->add_html($htmlmessage);
    $mail->add_text($textmessage);
  } else {
    # send mails to one place when running a test version
    $message = "To: $to\n".$message;
    if ($GLOBALS["developer_email"]) {
      # fake occasional failure
      if (mt_rand(0,50) == 1) {
        return 0;
      } else {
        $mail = new PHPlistMailer('systemmessage',$GLOBALS["developer_email"]);
        $mail->add_html($htmlmessage);
        $mail->add_text($textmessage);
        $destinationemail = $GLOBALS["developer_email"];
      }
    } else {
      print "Error: Running CVS version, but developer_email not set";
    }
  }
  # 0008549: message envelope not passed to php mailer,
  $mail->Sender = $GLOBALS["message_envelope"];
 
  $mail->build_message(
      array(
        "html_charset" => getConfig("html_charset"),
        "html_encoding" => HTMLEMAIL_ENCODING,
        "text_charset" => getConfig("text_charset"),
        "text_encoding" => TEXTEMAIL_ENCODING)
      );
  return $mail->send("", $destinationemail, $fromname, $fromemail, $subject);
}


function sendAdminCopy($subject,$message) {
  $sendcopy = getConfig("send_admin_copies");
  if ($sendcopy == "true") {
    $admin_mail = getConfig("admin_address");
    $mails = explode(",",getConfig("admin_addresses"));
    array_push($mails,$admin_mail);
    $sent = array();
    foreach ($mails as $admin_mail) {
      $admin_mail = trim($admin_mail);
      if (!$sent[$admin_mail] && $admin_mail) {
        sendMail($admin_mail,$subject,$message,system_messageheaders($admin_mail));
        $sent[$admin_mail] = 1;
       }
     }
  }
}

function safeImageName($name) {
  $name = "image".ereg_replace("\.","DOT",$name);
  $name = ereg_replace("-","DASH",$name);
  $name = ereg_replace("_","US",$name);
  $name = ereg_replace("/","SLASH",$name);
  $name = ereg_replace(':','COLON',$name);
  return $name;
}

function clean2 ($value) {
  $value = trim($value);
  $value = ereg_replace("\r","",$value);
  $value = ereg_replace("\n","",$value);
  $value = ereg_replace('"',"&quot;",$value);
  $value = ereg_replace("'","&rsquo;",$value);
  $value = ereg_replace("`","&lsquo;",$value);
  $value = stripslashes($value);
  return $value;
}

function cleanEmail ($value) {
  $value = trim($value);
  $value = preg_replace("/\r/","",$value);
  $value = preg_replace("/\n/","",$value);
  $value = preg_replace('/"/',"&quot;",$value);
  ## these are allowed in emails
//  $value = preg_replace("/'/","&rsquo;",$value);
  $value = preg_replace("/`/","&lsquo;",$value);
  $value = stripslashes($value);
  return $value;
}

if (TEST && REGISTER)
  $pixel = '<img src="http://phplist.tincan.co.uk/images/pixel.gif" width=1 height=1>';


function timeDiff($time1,$time2) {
  if (!$time1 || !$time2) {
    return $GLOBALS['I18N']->get('Unknown');
   }
  $t1 = strtotime($time1);
  $t2 = strtotime($time2);

  if ($t1 < $t2) {
    $diff = $t2 - $t1;
  } else {
    $diff = $t1 - $t2;
  }
  if ($diff == 0)
    return $GLOBALS['I18N']->get('very little time');
  $hours = (int)($diff / 3600);
  $mins = (int)(($diff - ($hours * 3600)) / 60);
  $secs = (int)($diff - $hours * 3600 - $mins * 60);

  $res = '';
  if ($hours)
    $res = $hours . " hours";
  if ($mins)
    $res .= " ".$mins . " mins";
  if ($secs)
    $res .= " ".$secs . " secs";
  return $res;
}

function previewTemplate($id,$adminid = 0,$text = "", $footer = "") {
  global $tables;
  if (defined("IN_WEBBLER")) {
    $more = '&pi='.$_GET["pi"];
  } else {
    $more = '';
  }
  $tmpl = Sql_Fetch_Row_Query(sprintf('select template from %s where id = %d',$tables["template"],$id));
  $template = stripslashes($tmpl[0]);
  $img_req = Sql_Query(sprintf('select id,filename from %s where template = %d order by filename desc',$tables["templateimage"],$id));
  while ($img = Sql_Fetch_Array($img_req)) {
    $template = preg_replace("#".preg_quote($img["filename"])."#","?page=image&id=".$img["id"].$more,$template);
  }
  if ($adminid) {
    $att_req = Sql_Query("select name,value from {$tables["adminattribute"]},{$tables["admin_attribute"]} where {$tables["adminattribute"]}.id = {$tables["admin_attribute"]}.adminattributeid and {$tables["admin_attribute"]}.adminid = $adminid");
    while ($att = Sql_Fetch_Array($att_req)) {
      $template = preg_replace("#\[LISTOWNER.".strtoupper(preg_quote($att["name"]))."\]#",$att["value"],$template);
    }
  }
  if ($footer)
    $template = eregi_replace("\[FOOTER\]",$footer,$template);
  $template = preg_replace("#\[CONTENT\]#",$text,$template);
  $template = eregi_replace("\[UNSUBSCRIBE\]",sprintf('<a href="%s">%s</a>',getConfig("unsubscribeurl"),$GLOBALS["strThisLink"]),$template);
  #0013076: Blacklisting posibility for unknown users
  $template = eregi_replace("\[BLACKLIST\]",sprintf('<a href="%s">%s</a>',getConfig("blacklisturl"),$GLOBALS["strThisLink"]),$template);
  $template = eregi_replace("\[PREFERENCES\]",sprintf('<a href="%s">%s</a>',getConfig("preferencesurl"),$GLOBALS["strThisLink"]),$template);
  if (!EMAILTEXTCREDITS) {
    $template = eregi_replace("\[SIGNATURE\]",$GLOBALS["PoweredByImage"],$template);
  } else {
    $template = eregi_replace("\[SIGNATURE\]",$GLOBALS["PoweredByText"],$template);
  }
  $template = ereg_replace("\[[A-Z\. ]+\]","",$template);
  $template = ereg_replace('<form','< form',$template);
  $template = ereg_replace('</form','< /form',$template);

  return $template;
}


function parseMessage($content,$template,$adminid = 0) {
  global $tables;
  $tmpl = Sql_Fetch_Row_Query("select template from {$tables["template"]} where id = $template");
  $template = $tmpl[0];
  $template = preg_replace("#\[CONTENT\]#",$content,$template);
  $att_req = Sql_Query("select name,value from {$tables["adminattribute"]},{$tables["admin_attribute"]} where {$tables["adminattribute"]}.id = {$tables["admin_attribute"]}.adminattributeid and {$tables["admin_attribute"]}.adminid = $adminid");
  while ($att = Sql_Fetch_Array($att_req)) {
    $template = preg_replace("#\[LISTOWNER.".strtoupper(preg_quote($att["name"]))."\]#",$att["value"],$template);
  }
  return $template;
}

function listOwner($listid = 0) {
  global $tables;
  $req = Sql_Fetch_Row_Query("select owner from {$tables["list"]} where id = $listid");
  return $req[0];
}

function system_messageHeaders($useremail = "") {
  $from_address = getConfig("message_from_address");
  $from_name = getConfig("message_from_name");
  if ($from_name)
    $additional_headers = "From: \"$from_name\" <$from_address>\n";
  else
    $additional_headers = "From: $from_address\n";
  $message_replyto_address = getConfig("message_replyto_address");
  if ($message_replyto_address)
    $additional_headers .= "Reply-To: $message_replyto_address\n";
  else
    $additional_headers .= "Reply-To: $from_address\n";
  $v = VERSION;
  $v = ereg_replace("-dev","",$v);
  $additional_headers .= "X-Mailer: phplist version $v (www.phplist.com)\n";
  $additional_headers .= "X-MessageID: systemmessage\n";
  if ($useremail)
    $additional_headers .= "X-User: ".$useremail."\n";
  return $additional_headers;
}

function logEvent($msg) {
  global $tables;
  if (isset($GLOBALS['page'])) {
    $p = $GLOBALS['page'];
  } elseif (isset($_GET['page'])) {
    $p = $_GET['page'];
  } elseif (isset($_GET['p'])) {
    $p = $_GET['p'];
  } else {
    $p = 'unknown page';
  }
  if (Sql_Table_Exists($tables["eventlog"]))
  Sql_Query(sprintf('insert into %s (entered,page,entry) values(now(),"%s","%s")',$tables["eventlog"],
    $p,addslashes($msg)));
}

### process locking stuff
function getPageLock() {
  global $tables;
  $thispage = $GLOBALS["page"];
  $running_req = Sql_query("select now() - modified,id from ".$tables["sendprocess"]." where page = \"$thispage\" and alive order by started desc");
  $running_res = Sql_Fetch_row($running_req);
  $waited = 0;
  while ($running_res[1]) { # a process is already running
    if ($running_res[0] > 600) {# some sql queries can take quite a while
      # process has been inactive for too long, kill it
      Sql_query("update {$tables["sendprocess"]} set alive = 0 where id = $running_res[1]");
    } else {
      output ($GLOBALS['I18N']->get('A process for this page is already running and it was still alive').' '.$running_res[0].' '.$GLOBALS['I18N']->get('seconds ago'));
      sleep(1); # to log the messages in the correct order
      if ($GLOBALS["commandline"]) {
        output("Running commandline, quitting. We'll find out what to do in the next run.");
        exit;
      }
      output ($GLOBALS['I18N']->get('Sleeping for 20 seconds, aborting will quit'));
      flush();
      $abort = ignore_user_abort(0);
      sleep(20);
    }
    $waited++;
    if ($waited > 10) {
      # we have waited 10 cycles, abort and quit script
      output($GLOBALS['I18N']->get('We have been waiting too long, I guess the other process is still going ok'));
      exit;
    }
    $running_req = Sql_query("select now() - modified,id from ".$tables["sendprocess"]." where page = \"$thispage\" and alive order by started desc");
    $running_res = Sql_Fetch_row($running_req);
  }
  $res = Sql_query('insert into '.$tables["sendprocess"].' (started,page,alive,ipaddress) values(now(),"'.$thispage.'",1,"'.getenv("REMOTE_ADDR").'")');
  $send_process_id = Sql_Insert_Id();
  $abort = ignore_user_abort(1);
  return $send_process_id;
}

function keepLock($processid) {
  global $tables;
  $thispage = $GLOBALS["page"];
  Sql_query("Update ".$tables["sendprocess"]." set alive = alive + 1 where id = $processid");
}

function checkLock($processid) {
  global $tables;
  $thispage = $GLOBALS["page"];
  $res = Sql_query("select alive from {$tables['sendprocess']} where id = $processid");
  $row = Sql_Fetch_Row($res);
  return $row[0];
}

function addAbsoluteResources($text,$url) {
  $parts = parse_url($url);
  $tags = array('src\s*=\s*','href\s*=\s*','action\s*=\s*',
    'background\s*=\s*','@import\s+','@import\s+url\(');
  foreach ($tags as $tag) {
#   preg_match_all('/'.preg_quote($tag).'"([^"|\#]*)"/Uim', $text, $foundtags);
# we're only handling nicely formatted src="something" and not src=something, ie quotes are required
# bit of a nightmare to not handle it with quotes.
    preg_match_all('/('.$tag.')"([^"|\#]*)"/Uim', $text, $foundtags);
    for ($i=0; $i< count($foundtags[0]); $i++) {
      $match = $foundtags[2][$i];
      $tagmatch = $foundtags[1][$i];
#      print "$match<br/>";
      if (preg_match("#^(http|javascript|https|ftp|mailto):#i",$match)) {
        # scheme exists, leave it alone
      } elseif (preg_match("#\[.*\]#U",$match)) {
        # placeholders used, leave alone as well
      } elseif (ereg("^/",$match)) {
        # starts with /
        $text = preg_replace('#'.preg_quote($foundtags[0][$i]).'#im',$tagmatch.'"'.$parts["scheme"].'://'.$parts["host"].$match.'"',$text,1);
      } else {
        $path = '';
        if (isset($parts['path'])) {
          $path = $parts["path"];
        }
        if (!preg_match('#/$#',$path)) {
          $pathparts = explode('/',$path);
          array_pop($pathparts);
          $path = join('/',$pathparts);
          $path .= '/';
        }
        $text = preg_replace('#'.preg_quote($foundtags[0][$i]).'#im',
          $tagmatch.'"'.$parts["scheme"].'://'.$parts["host"].$path.$match.'"',$text,1);
      }
    }
  }

 # $text = preg_replace('#PHPSESSID=[^\s]+
  return $text;
}

function getPageCache($url,$lastmodified = 0) {
  $req = Sql_Fetch_Row_Query(sprintf('select content from %s where url = "%s" and lastmodified >= %d',$GLOBALS["tables"]["urlcache"],$url,$lastmodified));
  return $req[0];
}

function getPageCacheLastModified($url) {
  $req = Sql_Fetch_Row_Query(sprintf('select lastmodified from %s where url = "%s"',$GLOBALS["tables"]["urlcache"],$url));
  return $req[0];
}

function setPageCache($url,$lastmodified = 0,$content) {
  if (isset($GLOBALS['developer_email'])) return;
  Sql_Query(sprintf('delete from %s where url = "%s"',$GLOBALS["tables"]["urlcache"],$url));
  Sql_Query(sprintf('insert into %s (url,lastmodified,added,content)
    values("%s",%d,now(),"%s")',$GLOBALS["tables"]["urlcache"],$url,$lastmodified,addslashes($content)));
}

function fetchUrl($url,$userdata = array()) {
  require_once "HTTP/Request.php";
 # logEvent("Fetching $url");
  if (sizeof($userdata)) {
    foreach ($userdata as $key => $val) {
      $url = eregi_replace("\[$key\]",urlencode($val),$url);
    }
  }

  if (!isset($GLOBALS['urlcache'])) {
    $GLOBALS['urlcache'] = array();
  }

  # keep in memory cache in case we send a page to many emails
  if (isset($GLOBALS['urlcache'][$url]) && is_array($GLOBALS['urlcache'][$url])
    && (time() - $GLOBALS['urlcache'][$url]['fetched'] < REMOTE_URL_REFETCH_TIMEOUT)) {
#     logEvent($url . " is cached in memory");
      return $GLOBALS['urlcache'][$url]['content'];
  }

  $dbcache_lastmodified = getPageCacheLastModified($url);
  $timeout = time() - $dbcache_lastmodified;
  if ($timeout < REMOTE_URL_REFETCH_TIMEOUT) {
#    logEvent($url.' was cached in database');
    return getPageCache($url);
  } else {
#    logEvent($url.' is not cached in database '.$timeout.' '. $dbcache_lastmodified." ".time());
  }

  # add a small timeout, although the biggest timeout will exist in doing the DNS lookup,
  # so it won't make too much of a difference
  $request_parameters = array(
    'timeout' => 10,
    'allowRedirects' => 1,
    'method' => 'HEAD',
  );
  $headreq =& new HTTP_Request($url,$request_parameters);
  $headreq->addHeader('User-Agent', 'phplist v'.VERSION.' (http://www.phplist.com)');
  if (!PEAR::isError($headreq->sendRequest(false))) {
    $code = $headreq->getResponseCode();
    if ($code != 200) {
      logEvent('Fetching '.$url.' failed, error code '.$code);
      return 0;
    }
    $header = $headreq->getResponseHeader();

    ## relying on the last modified header doesn't work for many pages
    ## use current time instead
    ## see http://mantis.phplist.com/view.php?id=7684
#    $lastmodified = strtotime($header["last-modified"]);
    $lastmodified = time();
    $cache = getPageCache($url,$lastmodified);
    if (!$cache) {
      $request_parameters['method'] = 'GET';
      $req =& new HTTP_Request($url,$request_parameters);
      $req->addHeader('User-Agent', 'phplist v'.VERSION.' (http://www.phplist.com)');
      logEvent('Fetching '.$url);
      if (!PEAR::isError($req->sendRequest(true))) {
        $content = $req->getResponseBody();
        $content = addAbsoluteResources($content,$url);
        logEvent('Fetching '.$url.' success');
        setPageCache($url,$lastmodified,$content);
      } else {
        logEvent('Fetching '.$url.' failed');
        return 0;
      }
    } else {
      logEvent($url.' was cached in database');
      $content = $cache;
    }
  } else {
    logEvent('Fetching '.$url.' failed');
    return 0;
  }
  $GLOBALS['urlcache'][$url] = array(
    'fetched' => time(),
    'content' => $content,
  );
  return $content;
}

function releaseLock($processid) {
  global $tables;
  if (!$processid) return;
  Sql_query("delete from {$tables["sendprocess"]} where id = $processid");
}

function cleanUrl($url,$disallowed_params = array('PHPSESSID')) {
  $parsed = @parse_url($url);
  $params = array();

  if (empty($parsed['query'])) {
    $parsed['query'] = '';
  }
  # hmm parse_str should take the delimiters as a parameter
  if (strpos($parsed['query'],'&amp;')) {
    $pairs = explode('&amp;',$parsed['query']);
    foreach ($pairs as $pair) {
      list($key,$val) = explode('=',$pair);
      $params[$key] = $val;
    }
  } else {
    parse_str($parsed['query'],$params);
  }
  $uri = !empty($parsed['scheme']) ? $parsed['scheme'].':'.((strtolower($parsed['scheme']) == 'mailto') ? '':'//'): '';
  $uri .= !empty($parsed['user']) ? $parsed['user'].(!empty($parsed['pass'])? ':'.$parsed['pass']:'').'@':'';
  $uri .= !empty($parsed['host']) ? $parsed['host'] : '';
  $uri .= !empty($parsed['port']) ? ':'.$parsed['port'] : '';
  $uri .= !empty($parsed['path']) ? $parsed['path'] : '';
#  $uri .= $parsed['query'] ? '?'.$parsed['query'] : '';
  $query = '';
  foreach ($params as $key => $val) {
    if (!in_array($key,$disallowed_params)) {
      //0008980: Link Conversion for Click Tracking. no = will be added if key is empty.
      $query .= $key . ( $val ? '=' . $val . '&' : '&' );
    }
  }
  $query = substr($query,0,-1);
  $uri .= $query ? '?'.$query : '';
#  if (!empty($params['p'])) {
#    $uri .= '?p='.$params['p'];
#  }
  $uri .= !empty($parsed['fragment']) ? '#'.$parsed['fragment'] : '';
  return $uri;
}

function adminName($id = 0) {
  if (!$id) {
    $id = $_SESSION["logindetails"]["id"];
  }
  if (is_object($GLOBALS["admin_auth"])) {
    return $GLOBALS["admin_auth"]->adminName($id);
  }
  $req = Sql_Fetch_Row_Query(sprintf('select loginname from %s where id = %d',$GLOBALS["tables"]["admin"],$id));
  return $req[0] ? $req[0] : "<font color=red>Nobody</font>";
}

//if (!function_exists("dbg")) {
//  function dbg($msg,$logfile = "") {
//    if (!$logfile) return;
//    $fp = @fopen($logfile,"a");
//    $line = "[".date("d M Y, H:i:s")."] ".getenv("REQUEST_URI").'('.$config["stats"]["number_of_queries"].") $msg \n";
//    @fwrite($fp,$line);
//    @fclose($fp);
//  }
//}

function addSubscriberStatistics($item = '',$amount,$list = 0) {
  switch (STATS_INTERVAL) {
    case 'monthly':
      # mark everything as the first day of the month
      $time = mktime(0,0,0,date('m'),1,date('Y'));
      break;
    case 'weekly':
      # mark everything for the first sunday of the week
      $time = mktime(0,0,0,date('m'),date('d') - date('w'),date('Y'));
      break;
    case 'daily':
      $time = mktime(0,0,0,date('m'),date('d'),date('Y'));
      break;
  }
  Sql_Query(sprintf('update %s set value = value + %d where unixdate = %d and item = "%s" and listid = %d',
    $GLOBALS['tables']['userstats'],$amount,$time,$item,$list));
  $done = Sql_Affected_Rows();
  if (!$done) {
    Sql_Query(sprintf('insert into %s set value = %d,unixdate = %d,item = "%s",listid = %d',
      $GLOBALS['tables']['userstats'],$amount,$time,$item,$list));
  }
}

function deleteBounce($id = 0) {
  if (!$id) return;
  $id = sprintf('%d',$id);
  Sql_query(sprintf('delete from %s where id = %d',$GLOBALS['tables']['bounce'],$id));
  Sql_query(sprintf('delete from %s where bounce = %d',$GLOBALS['tables']['user_message_bounce'],$id));
  Sql_query(sprintf('delete from %s where bounce = %d',$GLOBALS['tables']['bounceregex_bounce'],$id));
}

function reverse_htmlentities($mixed)
{
   $htmltable = get_html_translation_table(HTML_ENTITIES);
   foreach($htmltable as $key => $value)
   {
       $mixed = ereg_replace(addslashes($value),$key,$mixed);
   }
   return $mixed;
}

function loadBounceRules($all = 0) {
  if ($all) {
    $status = '';
  } else {
    $status = ' where status = "active"';
  }
  $result = array();
  $req = Sql_Query(sprintf('select * from %s %s order by listorder',$GLOBALS['tables']['bounceregex'],$status));
  while ($row = Sql_Fetch_Array($req)) {
    if ($row['regex'] && $row['action']) {
      $result[$row['regex']] = array(
        'action' => $row['action'],
        'id' => $row['id']
      );
    }
  }
  return $result;
}

function matchedBounceRule($text,$activeonly = 0) {
  if ($activeonly) {
    $status = ' where status = "active"';
  } else {
    $status = '';
  }
  $req = Sql_Query(sprintf('select * from %s %s order by listorder',$GLOBALS['tables']['bounceregex'],$status));
  while ($row = Sql_Fetch_Array($req)) {
    $pattern = str_replace(' ','\s+',$row['regex']);
 #   print "Trying to match ".$pattern;
    #print ' with '.$text;
 #   print '<br/>';
    if (@preg_match('/'.preg_quote($pattern).'/iUm',$text)) {
      return $row['id'];
    } elseif (@preg_match('/'.$pattern.'/iUm',$text)) {
      return $row['id'];
    }
  }
  return '';
}

function matchBounceRules($text,$rules = array()) {
  if (!sizeof($rules)) {
    $rules = loadBounceRules();
  }

  foreach ($rules as $pattern => $rule) {
    $pattern = str_replace(' ','\s+',$pattern);
    if (@preg_match('/'.preg_quote($pattern).'/iUm',$text)) {
      return $rule;
    } elseif (@preg_match('/'.$pattern.'/iUm',$text)) {
      return $rule;
    } else {
#      print "Trying to match $pattern failed<br/>";
    }
  }
  return '';
}

function validateRssFrequency($freq = '') {
  if (!$freq) return '';
  if (in_array($freq,array_keys($GLOBALS['rssfrequencies']))) {
    return $freq;
  }
  return '';
}

function strip_newlines( $str, $placeholder = '' ) {
  $str = str_replace(chr(13) . chr(10), $placeholder , $str);
  $str = str_replace(chr(10), $placeholder , $str);
  $str = str_replace(chr(13), $placeholder , $str);
  return $str;
}

class timer {
  var $start;

  function timer() {
    $now =  gettimeofday();
    $this->start = $now["sec"] * 1000000 + $now["usec"];
  }

  function elapsed($seconds = 0) {
    $now = gettimeofday();
    $end = $now["sec"] * 1000000 + $now["usec"];
    $elapsed = $end - $this->start;
    if ($seconds) {
      return $elapsed / 1000000;
    } else {
      return $elapsed;
    }
  }

}

?>
andrew55
phpLister
 
Posts: 12
Joined: 1:54am, Sun 31 Jul, 2011

Re: [mod] Customizing confirmation emails with custom attributes

Postby fitzybhoy » 9:45am, Mon 08 Aug, 2011

everything seems to work fine for me...
fitzybhoy
phpList newbie
 
Posts: 1
Joined: 9:42am, Mon 08 Aug, 2011

Re: [mod] Customizing confirmation emails with custom attrib

Postby Craxx » 1:55pm, Tue 20 Sep, 2011

Why is that no STANDART in phplist, i can´t understand????
Craxx
PL Nut
 
Posts: 20
Joined: 7:11pm, Fri 26 Nov, 2010

Next

Return to Contributions: Plug-ins, Add-ons, Mods

Who is online

Users browsing this forum: No registered users and 2 guests