[ Avaa Bypassed ]




Upload:

Command:

hmhc3928@18.118.1.63: ~ $
<?php
require_once dirname(__FILE__).'/accesscheck.php';

include_once dirname(__FILE__). "/date.php";

$errormsg = '';
//$rss_content = '';          //Obsolete by rssmanager plugin
$done = 0;
$messageid = 0;
$forwardsubject = $forwardmessage = $forwardfooter = '';
$placeinqueue = '';
$sendtestresult = '';
$duplicate_atribute = 0; # not actually used it seems @@@ check
$embargo = new date('embargo');
$embargo->useTime = true;
$repeatuntil = new date("repeatuntil");
$repeatuntil->useTime = true;
$requeueuntil = new date("requeueuntil");
$requeueuntil->useTime = true;

if (ALLOW_ATTACHMENTS) {
  $enctype = 'enctype="multipart/form-data"';
} else {
  $enctype = '';
}

### variable initialisation and sanity checks
if (isset($_GET['id'])) {
  $id = sprintf('%d',$_GET['id']);
} else {
  $id = 0;
}
## page actions
$send = isset($_POST["send"]);
$prepare = isset($_POST['prepare']);
$save = !empty($_POST["save"]) || !empty($_POST['followupto']);
$savedraft = !empty($_POST["savedraft"]);
$sendtest = !empty($_POST["sendtest"]);
$baseurl = PageURL2($_GET["page"].'&amp;id='.$id);

if (!isset($_GET['tab'])) $_GET['tab'] = '';
if (!empty($_GET['tab'])) {
  $baseurl .= '&tab='.$_GET['tab'];
}

### if we're not working on an existing message, create one and redirect to edit it
if (!$id) {
  $defaulttemplate = getConfig('defaultmessagetemplate');
  $defaultfooter = getConfig('messagefooter');
  $query
  = " insert into %s"
  . "    (subject, status, entered, sendformat, embargo"
  . "    , repeatuntil, owner, template, tofield, replyto,footer)"
  . " values"
  . "    ('(no subject)', 'draft', current_timestamp, 'HTML'"
  . "    , current_timestamp, current_timestamp, ?, ?, '', '', ? )";
  $query = sprintf($query, $GLOBALS['tables']['message']);
  Sql_Query_Params($query, array($_SESSION['logindetails']['id'], $defaulttemplate,$defaultfooter));
  $id = Sql_Insert_Id($GLOBALS['tables']['message'], 'id');

  if (isset($_GET['list'])) {
    if ($_GET['list'] == 'all') {
      $req = Sql_Query('select id from '.$tables['list']);
      while ($row = Sql_Fetch_Row($req)) {
        $addlists[] = $row[0];
      }
    } else {
      $addlists = explode(',',$_GET['list']);
    }
    $addlists = cleanArray($addlists);
    foreach ($addlists as $listid) {
      $query = "replace into %s (messageid,listid,entered) values(?,?,current_timestamp)";
      $query = sprintf($query,$GLOBALS['tables']['listmessage']);
      Sql_Query_Params($query,array($id,$listid));
    }
  }

  # 0008720: Using -p send from the commandline doesn't seem to work 
  if(!$GLOBALS["commandline"]) {
    Redirect($_GET["page"].'&id='.$id);
    exit;
  }
}

# load all message data
$messagedata = loadMessageData($id);

## auto generate the text version if empty
## hmm, might want this as config
/*
if (empty($messagedata['textmessage'])) {
  include 'actions/generatetext.php';
}
*/
  
#var_dump($messagedata);
#exit;
#print '<h3>'.$messagedata['status'].'</h3>';

if (!empty($_GET['deletecriterion'])) {
  include dirname(__FILE__).'/actions/deletecriterion.php';
  Redirect($_GET["page"].'&id='.$id.'&tab='.$_GET["tab"]);
}
ob_end_flush();

#load database data###########################

if ($id) {
  // Load message attributes / values
  $result = Sql_query("SELECT * FROM {$tables['message']} where id = $id $ownership");
  if (!Sql_Num_Rows($result)) {
    print $GLOBALS['I18N']->get('Access Denied');
    $done = 1;
    return;
  }

  print formStart($enctype . ' name="sendmessageform" class="sendSend" id="sendmessageform" ');
  if (empty($send)) {
    $placeinqueue = '<div id="addtoqueue"><button class="submit" type="submit" name="send" id="addtoqueuebutton">'.$GLOBALS['I18N']->get('Send Campaign').'</button></div>';
  } else {
    ## hide the div in the final "message added to queue" page
  #  print '<div id="addtoqueue"></div>';
  }
  require dirname(__FILE__)."/structure.php";  // This gets the database structures into DBStruct

  include dirname(__FILE__).'/actions/storemessage.php';
}

$htmlformatted = strip_tags($messagedata["message"]) != $messagedata["message"];

# sanitise the header fields, what else do we need to check on?
if (preg_match("/\n|\r/",$messagedata["fromfield"])) {
  $messagedata["fromfield"] = "";
} 
if (preg_match("/\n|\r/",$messagedata["forwardsubject"])) {
  $messagedata["forwardsubject"] = "";
} 

## check that the message does not contain URLs that look like click tracking links
## it seems people are pasting the results of test messages back in the editor, which would duplicate
## tracking

$hasClickTrackLinks = preg_match('/lt\.php\?id=[\w%]{22}/',$messagedata["message"],$regs) || preg_match('/lt\.php\?id=[\w%]{16}/',$messagedata["message"],$regs) ||
(CLICKTRACK_LINKMAP && (preg_match('#'.CLICKTRACK_LINKMAP.'/[\w%]{22}#',$messagedata['message']) || preg_match('#'.CLICKTRACK_LINKMAP.'/[\w%]{16}#',$messagedata['message'])));

if ($hasClickTrackLinks) {
  print Error(s('You should not paste the results of a test message back into the editor<br/>This will break the click-track statistics, and overload the server.'), 'http://resources.phplist.com/documentation/errors/pasteclicktrack');
}
// If the variable isn't filled in, then the input fields don't default to the
// values selected.  Need to fill it in so a post will correctly display.

if (!isset($_SESSION["fckeditor_height"])) {
  $_SESSION["fckeditor_height"] = getConfig("fckeditor_height");
}

#actions and store in database#######################

if ($send || $sendtest || $prepare || $save || $savedraft) {

  if ($savedraft || $save || $sendtest) {
    // We're just saving, not sending.
    if (!isset($messagedata['status']) || $messagedata["status"] == "") {
      // No status - move to draft state
      $messagedata['status'] = "draft";
    } 
  } elseif ($send) {
    // We're sending - change state to "send-it" status!
    if (is_array($messagedata["targetlist"]) && sizeof($messagedata["targetlist"]) 
      && !empty($messagedata['subject']) && !empty($messagedata['fromfield']) && 
      !empty($messagedata['message']) && empty($duplicate_attribute)) {
      $messagedata['status'] = "submitted";
      setMessageData($id,'status','submitted');
    } else {
      if (USE_PREPARE) {
        $messagedata['status'] = "prepared";
      } else {
        $messagedata['status'] = "draft";
      }
    }
  }

  ### allow plugins manipulate data or save it somewhere else
  $plugintabs = array();
  foreach ($GLOBALS['plugins'] as $pluginname => $plugin) {
  #  print "Saving ".$plugin->name;
    $resultMsg = $plugin->sendMessageTabSave($id,$messagedata);
  }

  if (!$htmlformatted  && strip_tags($messagedata["message"]) !=  $messagedata["message"])
    $errormsg = '<span  class="error">'.$GLOBALS['I18N']->get("Warning: You indicated the content was not HTML, but there were  some HTML  tags in it. This  may  cause  errors").'</span>';
    
  $query = sprintf('update %s  set '
     . '  subject = ?'
     . ', fromfield = ?'
     . ', tofield = ?'
     . ', replyto = ?'
     . ', embargo = ?'
     . ', repeatinterval = ?'
     . ', repeatuntil = ?'
     . ', message = ?'
     . ', textmessage = ?'
     . ', footer = ?'
     . ', status = ?'
     . ', htmlformatted = ?'
     . ', sendformat  =  ?'
     . ', template  =  ?'
     . ' where id = ?', $tables["message"]);
  $result = Sql_Query_Params($query, array(
       $messagedata['subject']
     , $messagedata['fromfield']
     , $messagedata['tofield']
     , $messagedata['replyto']
     , sprintf('%04d-%02d-%02d %02d:%02d',
        $messagedata['embargo']['year'],$messagedata['embargo']['month'],$messagedata['embargo']['day'],
        $messagedata['embargo']['hour'],$messagedata['embargo']['minute'])
     , $messagedata['repeatinterval']
     , sprintf('%04d-%02d-%02d %02d:%02d',
        $messagedata["repeatuntil"]['year'],$messagedata["repeatuntil"]['month'],$messagedata["repeatuntil"]['day'],
        $messagedata["repeatuntil"]['hour'],$messagedata["repeatuntil"]['minute'])
     , $messagedata["message"]
     , $messagedata["textmessage"]
     , $messagedata["footer"]
     , $messagedata['status']
     , $htmlformatted ? '1' : '0'
     , $messagedata["sendformat"]
     , $messagedata["template"]
     , $id));

    ## do this seperately, so that the above query doesn't fail when the DB hasn't been upgraded
    $query = sprintf('update %s ' 
     . 'set requeueinterval = ?'
     . ', requeueuntil = ?'
     . ' where id = ?', $tables["message"]);    
    $result = Sql_Query_Params($query, array(
      $messagedata['requeueinterval']
     , sprintf('%04d-%02d-%02d %02d:%02d',
        $messagedata['requeueuntil']['year'],$messagedata['requeueuntil']['month'],$messagedata['requeueuntil']['day'],
        $messagedata['requeueuntil']['hour'],$messagedata['requeueuntil']['minute'])
     ,$id));

#    print $query;
#    print "Message ID: $id";
    #    exit;
    if (!$GLOBALS["can_fetchUrl"] && preg_match("/\[URL:/i",$_POST["message"])) {
      print $GLOBALS["can_fetchUrl"].Warn(s('You are trying to send a remote URL, but PEAR::HTTP_Request or CURL is not available, so this will fail'));
    }

    if ($GLOBALS["commandline"]) {
      if (isset($_POST["targetlist"]) && is_array($_POST["targetlist"])) {
        Sql_query("delete from {$tables["listmessage"]} where messageid = $id");
        foreach($_POST["targetlist"] as $listid => $val) {
          $result = Sql_query("insert ignore into {$tables["listmessage"]} (messageid,listid,entered) values($id,$listid,now())");
        }
      }
    }
    
# we want to create a join on tables as follows, in order to find users who have their attributes to the values chosen
# (independent of their list membership).
# select
#  table1.userid from user_attribute as table1
#  left join user_attribute as table2 on table1.userid = table2.userid
#  left join user_attribute as table3 on table1.userid = table3.userid
#  ...
# where
#  table1.attributeid = 2 and table1.value in (1,2,3,4)
#  and table2.attributeid = 1 and table2.value in (3,15)
#  and table3.attributeid = 3 and table3.value in (4,5,6)
#  ...

  # criteria system, add one by one:

  if (ALLOW_ATTACHMENTS && isset($_FILES) && is_array($_FILES) && sizeof($_FILES) > 0) {
    for ($att_cnt = 1;$att_cnt <= NUMATTACHMENTS;$att_cnt++) {
      $fieldname = "attachment".$att_cnt;
      if (isset($_FILES[$fieldname])) {
        $tmpfile = $_FILES[$fieldname]['tmp_name'];
        $remotename = $_FILES[$fieldname]["name"];
        $type = $_FILES[$fieldname]["type"];
        $newtmpfile = $remotename.time();
        move_uploaded_file($tmpfile, $GLOBALS['tmpdir'].'/'. $newtmpfile);
        if (is_file($GLOBALS['tmpdir'].'/'.$newtmpfile) && filesize($GLOBALS['tmpdir'].'/'.$newtmpfile)) {
          $tmpfile = $GLOBALS['tmpdir'].'/'.$newtmpfile;
        }
        if (strlen($type) > 255) {
          print Warn($GLOBALS['I18N']->get("Mime Type is longer than 255 characters, this is trouble"));
        }
        $description = $_POST[$fieldname."_description"];
      } else {
        $tmpfile = '';
      }
      if ($tmpfile && filesize($tmpfile) && $tmpfile != "none") {
        list($name,$ext) = explode(".",basename($remotename));
        # create a temporary file to make sure to use a unique file name to store with
        $newfile = tempnam($GLOBALS["attachment_repository"],$name);
        $newfile .= ".".$ext;
        $newfile = basename($newfile);
        $file_size = filesize($tmpfile);
        $fd = fopen( $tmpfile, "r" );
        $contents = fread( $fd, filesize( $tmpfile ) );
        fclose( $fd );
        if ($file_size) {
          # this may seem odd, but it allows for a remote (ftp) repository
          # also, "copy" does not work across filesystems
          $fd = fopen($GLOBALS["attachment_repository"]."/".$newfile, "w" );
          fwrite( $fd, $contents );
          fclose( $fd );
          Sql_query(sprintf('insert into %s (filename,remotefile,mimetype,description,size) values("%s","%s","%s","%s",%d)',
          $tables["attachment"],
          basename($newfile),$remotename,$type,$description,$file_size)
          );
          $attachmentid = Sql_Insert_Id($tables['attachment'], 'id');
          Sql_query(sprintf('insert into %s (messageid,attachmentid) values(%d,%d)',
          $tables["message_attachment"],$id,$attachmentid));
          if (is_file($tmpfile)) {
            unlink($tmpfile);
          }

          # do a final check
          if (filesize($GLOBALS["attachment_repository"]."/".$newfile)) {
            print Info(s('Attachment %d succesfully added',$att_cnt));
          } else {
            print Info(s('Adding attachment %d failed',$att_cnt));
          }
        } else {
          print Warn($GLOBALS['I18N']->get("Uploaded file not properly received, empty file"));
        }
      } elseif (!empty($_POST["localattachment".$att_cnt])) {
        $type = findMime(basename($_POST["localattachment".$att_cnt]));
        Sql_query(sprintf('insert into %s (remotefile,mimetype,description,size) values("%s","%s","%s",%d)',
          $tables["attachment"],
          $_POST["localattachment".$att_cnt],$type,$description,filesize($_POST["localattachment".$att_cnt]))
        );
        $attachmentid = Sql_Insert_Id($tables['attachment'], 'id');
        Sql_query(sprintf('insert into %s (messageid,attachmentid) values(%d,%d)',
        $tables["message_attachment"],$id,$attachmentid));
        print Info(s("Adding attachment")." ".$att_cnt. " mime: $type");
      }
    }
  }
  
  ## when followupto is set, go there
  if (!empty($_POST['followupto']) && isValidRedirect($_POST['followupto'])) {
    Header('Location: '.$_POST['followupto']);
    exit;
  } 

  if (!empty($id) && !$send) {
    if ($savedraft) {
      $_SESSION['action_result'] = s("Campaign saved as draft");
      Header('Location: ./?page=messages&tab=draft');
      exit;
    }
  } else {
#    $id = $messageid; // New ID - need to set it for later use (test email).
    print "<h3>".$GLOBALS['I18N']->get("Campaign added")."</h3><br/>";
  }
 // var_dump($messagedata);

  // If we're sending the message, just return now to the calling script
  # we only need to check that everything is there, once we actually want to send
  if ($send && !empty($messagedata['subject']) && !empty($messagedata['fromfield']) && !empty($messagedata['message']) && empty($duplicate_atribute) && sizeof($messagedata["targetlist"])) {
    if ($messagedata['status'] == "submitted") {
      
      ##16615, check that "send until" is in after the embargo and warn if it isn't
      $finishSending = mktime($messagedata['finishsending']['hour'],$messagedata['finishsending']['minute'],0,
        $messagedata['finishsending']['month'],$messagedata['finishsending']['day'],$messagedata['finishsending']['year']);
      $embargoTime = mktime($messagedata['embargo']['hour'],$messagedata['embargo']['minute'],0,
        $messagedata['embargo']['month'],$messagedata['embargo']['day'],$messagedata['embargo']['year']);
        
      if ($finishSending < $embargoTime) { 
        print Warn(s('This campaign is scheduled to stop sending before the embargo time. No mails will be sent.'));
        print PageLinkButton('send&amp;id='.$messagedata['id'].'&amp;tab=Scheduling',s('Review Scheduling'));
      }
      
      print "<h3>".$GLOBALS['I18N']->get("Campaign queued")."</h3>";
      foreach ($GLOBALS['plugins'] as $pluginname => $plugin) {
        $plugin->messageQueued($id);
      }
      if (getConfig('pqchoice') == 'phplistdotcom') {
        print activateRemoteQueue();
      } elseif (MANUALLY_PROCESS_QUEUE) {
        print '<p>'.PageLinkButton("processqueue",$GLOBALS['I18N']->get("processqueue")).'</p>';
      } else {
        print '<p>'.PageLinkButton("messages&tab=active",$GLOBALS['I18N']->get("view progress")).'</p>';
      }
    }
    $done = 1;
    return;
  } elseif ($send || $sendtest) {
    $errormessage = "";
    if ($messagedata['subject'] != stripslashes($messagedata['subject'])) {
      $errormessage = $GLOBALS['I18N']->get('Sorry, you used invalid characters in the Subject field.');
    } elseif (!empty($_POST["fromfield"]) && $messagedata['fromfield'] != $_POST["fromfield"]) {
      $errormessage = $GLOBALS['I18N']->get('Sorry, you used invalid characters in the From field.');
    } elseif (empty($messagedata['fromfield'])) {
      $errormessage = $GLOBALS['I18N']->get('Please enter a from line.');
    } elseif (empty($messagedata['message'])) {
      $errormessage = $GLOBALS['I18N']->get('Please enter a message');
    } elseif (empty($messagedata['subject'])) {
      $errormessage = $GLOBALS['I18N']->get('Please enter a subject');
    } elseif (!empty($duplicate_attribute)) {
      $errormessage = $GLOBALS['I18N']->get('Error: you can use an attribute in one rule only');
    } elseif ($send && !is_array($_POST["targetlist"])) {
      $errormessage = $GLOBALS['I18N']->get('Please select the list(s) to send the campaign to');
    }

    ## this is now handled on the last Tab, so don't display
#    echo "$errormessage<br/>";
  }

  // OK, the message has been saved, now check to see if we need to send a test message
  if ($sendtest) {

    $sendtestresult = "<r/>";
    if (empty($_SESSION['lasttestsent'])) {
      $_SESSION['lasttestsent'] = 0;
    }
    
    $sendtestAllowed = true;
    ## check with plugins that sending a test is allowed
    reset($GLOBALS['plugins']);
    while ($sendtestAllowed && $plugin = current($GLOBALS['plugins']) ) {
      $sendtestAllowed = $plugin->sendTestAllowed($messagedata);
      if (!$sendtestAllowed) {
        if (VERBOSE) {
          cl_output('Sending test blocked by plugin '.$plugin->name);
        }
      }
      next($GLOBALS['plugins']);
    } 
    
    $delay = time() - $_SESSION['lasttestsent'];
    if ($delay < SENDTEST_THROTTLE) {
      foreach ($GLOBALS['plugins'] as $plname => $plugin) {
        $plugin->processError('Send test throttled on '.$delay);
      }
      $sendtestresult .= s('You can send a test mail once every %d seconds',SENDTEST_THROTTLE)."<br/>";
      $emailaddresses = array();
    } elseif (!$sendtestAllowed) {
      $sendtestresult .= s('Sending test mails is currently not available')."<br/>";
      $emailaddresses = array();
    } else {
      // Let's send test messages to everyone that was specified in the
      if ($messagedata["testtarget"] == "") {
        $sendtestresult .= $GLOBALS['I18N']->get("No target email addresses listed for testing.")."<br/>";
      }

      if (isset($cached[$id])) {
        unset($cached[$id]);
      }
      clearPageCache();
      include "sendemaillib.php";

      // OK, let's get to sending!
      $emailaddresses = explode(',', $messagedata["testtarget"]);
      if (sizeof($emailaddresses) > SENDTEST_MAX) {
        foreach ($GLOBALS['plugins'] as $plname => $plugin) {
          $plugin->processError('Send test capped from '.sizeof($emailaddresses).' to '.SENDTEST_MAX);
        }
        $limited = array_chunk($emailaddresses,SENDTEST_MAX);
        $emailaddresses = $limited[0];
        $sendtestresult .= s("There is a maximum of %d test emails allowed",SENDTEST_MAX)."<br/>";
      }
    }
  #  var_dump($emailaddresses);#exit;

    foreach ($emailaddresses as $address) {
      $address = trim($address);
      if (empty($address)) continue;
      $query
      = ' select id, email, uniqid, htmlemail, confirmed'
      . ' from %s'
      . ' where email = ?';
      $query = sprintf($query, $tables['user']);
      $result = Sql_Query_Params($query, array($address));
                                                                                                          //Leftover from the preplugin era
      if ($user = Sql_fetch_array($result)) {
        if ( FORWARD_ALTERNATIVE_CONTENT && $_GET['tab'] == 'Forward') {
          if (SEND_ONE_TESTMAIL) {
            $success = sendEmail($id, $address, $user["uniqid"], $user['htmlemail'], array(), array($address) );
          } else {
            $success = sendEmail($id, $address, $user["uniqid"], 1,  array(), array($address) ) && sendEmail($id, $address, $user["uniqid"], 0,  array(), array($address));
          }
        } else {
          if (SEND_ONE_TESTMAIL) {
            $success = sendEmail($id, $address, $user["uniqid"], $user['htmlemail']);
          } else {
            $success = sendEmail($id, $address, $user["uniqid"], 1) && sendEmail($id, $address, $user["uniqid"], 0);
          }
        }
        $sendtestresult .= $GLOBALS['I18N']->get("Sent test mail to").": $address ";
        if (!$success) {
          $sendtestresult .= $GLOBALS['I18N']->get('failed');
        } else {
          $sendtestresult .= $GLOBALS['I18N']->get('success');
          $_SESSION['lasttestsent'] = time();
        }
        $sendtestresult .= '<br/>';
      } else {
        $sendtestresult .= $GLOBALS['I18N']->get("Email address not found to send test message.").": $address";
        $sendtestresult .= sprintf('  <div class="inline"><a href="%s&action=addemail&email=%s%s" class="button ajaxable">%s</a></div>',$baseurl,urlencode($address),addCsrfGetToken(),$GLOBALS['I18N']->get("add"));
      }
    }
    $sendtestresult .= "<hr/>";
    $sendtestresult .= '<script type="text/javascript">this.location.hash="sendTest";</script>';
  }
} elseif (isset($_POST["deleteattachments"]) && is_array($_POST["deleteattachments"]) && $id) {
  if (ALLOW_ATTACHMENTS) {
    // Delete Attachment button hit...
    $deleteattachments = $_POST["deleteattachments"];
    foreach($deleteattachments as $attid) {
      $attDetails = Sql_fetch_assoc_query(sprintf('select filename from %s where id = %d',$tables["attachment"],$attid));
      $phys_file = $GLOBALS["attachment_repository"]."/".$attDetails["filename"];
      $fileParts = pathinfo($phys_file);
      $phys_file2 = $GLOBALS["attachment_repository"]."/".$fileParts['filename']; ## to remove the file created by tempnam
      
      @unlink($phys_file);
      @unlink($phys_file2);
      
      $result = Sql_Query(sprintf("delete from %s where id = %d and messageid = %d",
        $tables["message_attachment"],
        $attid,
        $id));
      print Info($GLOBALS['I18N']->get("Removed Attachment "));
    }
  }
}

##############################
# Stacked attributes, processing and calculation
##############################

## moved to plugin

##############################
# Stacked attributes, end
##############################

echo $errormsg;
if (!$done) {

  #$baseurl = sprintf('./?page=%s&amp;id=%d',$_GET["page"],$id);
  if ($id) {
    $tabs = new WebblerTabs();
    $tabbaseurl = preg_replace('/&tab=[^&]+/','',$baseurl);
    $tabs->addTab($GLOBALS['I18N']->get("Content"),$tabbaseurl.'&amp;tab=Content');
    $counttabs=1;
    if (USE_MANUAL_TEXT_PART) {
      $tabs->addTab($GLOBALS['I18N']->get("Text"),$tabbaseurl.'&amp;tab=Text');
    $counttabs++;
    }
    if (FORWARD_ALTERNATIVE_CONTENT) {
      $tabs->addTab($GLOBALS['I18N']->get("Forward"),$tabbaseurl.'&amp;tab=Forward');
    $counttabs++;
    }
    $tabs->addTab($GLOBALS['I18N']->get("Format"),$tabbaseurl.'&amp;tab=Format');
    $counttabs++;
    if (ALLOW_ATTACHMENTS) {
      $tabs->addTab($GLOBALS['I18N']->get("Attach"),$tabbaseurl.'&amp;tab=Attach');
    $counttabs++;
    }
    $tabs->addTab($GLOBALS['I18N']->get("Scheduling"),$tabbaseurl.'&amp;tab=Scheduling');
    $counttabs++;
#    if (USE_RSS) {
  #      $tabs->addTab("RSS",$baseurl.'&amp;tab=RSS');
#    }
#    $tabs->addTab($GLOBALS['I18N']->get("Criteria"),$tabbaseurl.'&amp;tab=Criteria');
    $tabs->addTab($GLOBALS['I18N']->get("Lists"),$tabbaseurl.'&amp;tab=Lists');
    $counttabs++;
#    $tabs->addTab("Review and Send",$baseurl.'&amp;tab=Review');

    if ($_GET["tab"]) {
      $tabs->setCurrent($GLOBALS['I18N']->get($_GET["tab"]));
    } else {
      $tabs->setCurrent($GLOBALS['I18N']->get("Content"));
    }
//    if (defined("WARN_SAVECHANGES")) {
      $tabs->addLinkCode(' class="savechanges" ');
//    }
  #$baseurl = sprintf('./?page=%s&amp;id=%d',$_GET["page"],$id);

    ### allow plugins to add tabs
    $plugintabs = array();
    foreach ($GLOBALS['plugins'] as $pluginname => $plugin) {
   #   print $plugin->name;
      $plugintab = $plugin->sendMessageTab($id,$messagedata);
      if ($plugintab) {
        $plugintabname = substr(strip_tags($plugin->sendMessageTabTitle()),0,10);
        $plugintabs[$plugintabname] = $plugintab;
        $tabs->addTab($GLOBALS['I18N']->get($plugintabname),"$tabbaseurl&amp;tab=".urlencode($plugintabname));
        $counttabs++;
      }
    }

    ## this one always last
    $tabs->addTab($GLOBALS['I18N']->get("Finish"),$tabbaseurl.'&amp;tab=Finish');
    $counttabs++;

  # print $tabs->display();
  }

  ?>

  <script language="Javascript" type="text/javascript">
  // some debugging stuff to see what happens
  function checkForm() {
  //  return true;
    for (var i=0;i < document.sendmessageform.elements.length;i++) {
      alert(document.sendmessageform.elements[i].name+" "+document.sendmessageform.elements[i].value);
    }
    return true;
  }

  // detection of unsaved changes,
  var browser = navigator.appName.substring ( 0, 9 );
  var changed = 1; function haschanged() {changed = 1; }
  function savechanges() { }
  var event_number = 0;if (browser=="Microsoft") {  document.onkeydown=haschanged;  document.onchange=haschanged;} else if (browser=="Netscape") {  document.captureEvents(Event.KEYDOWN);  document.captureEvents(Event.CHANGE); document.onkeydown=haschanged;document.onchange=haschanged;}
  function submitform() { document.sendmessageform.submit() }
  </script>
  <?php
  #print '<form method="post" enctype="multipart/form-data" name="sendmessageform" onSubmit="return checkForm()">';
  print '<input type="hidden" name="workaround_fck_bug" value="1" />';
  print '<input type="hidden" name="followupto" value="" />';

  if ($_GET["page"] == "preparemessage")
    print Help("preparemessage",$GLOBALS['I18N']->get("What is prepare a message"));

  if (!defined("IN_WEBBLER")) {
    if (empty($messagedata['fromfield'])) {
      $defaultFrom = getConfig("campaignfrom_default");
      if (!empty($defaultFrom)) {
        $messagedata['fromfield'] = $defaultFrom;
      } elseif (USE_ADMIN_DETAILS_FOR_MESSAGES && is_object($GLOBALS["admin_auth"]) && $GLOBALS['require_login']) {
        $adminemail = $GLOBALS["admin_auth"]->adminEmail($_SESSION["logindetails"]["id"]);
        if (!empty($adminemail)) {
          $messagedata['fromfield'] = $GLOBALS["admin_auth"]->adminName($_SESSION["logindetails"]["id"]).' '.$adminemail;
        } else {
          $messagedata['fromfield'] = getConfig("message_from_name") . ' '.getConfig("message_from_address");
        }
      } else {
        $messagedata['fromfield'] = getConfig("message_from_name") . ' '.getConfig("message_from_address");
      }
    }
  }

  $formatting_content = '<div id="formatcontent">';

  #0013076: different content when forwarding 'to a friend'
  //  value="'.htmlentities($subject,ENT_QUOTES,'UTF-8').'" size="40"></td></tr> --> previous code in line 1032
  //  value="'.htmlentities($from,ENT_QUOTES,'UTF-8').'" size="40"></td></tr> --> previous code in line 1038

  $tmp = '<div id="maincontent">';
  $maincontent = $tmp;
  $forwardcontent = $tmp;

// custom code - start
  $utf8_subject = $messagedata['subject'];
  $utf8_from = $messagedata['fromfield'];
/*
  if (0 && strcasecmp($GLOBALS['strCharSet'], 'utf-8') <> 0) {
     $utf8_subject = iconv($GLOBALS['strCharSet'],'UTF-8',$utf8_subject);
     $utf8_from = iconv($GLOBALS['strCharSet'],'UTF-8',$utf8_from);
  }
*/

  $maincontent .= '
  <div class="field"><label for="subject">'.$GLOBALS['I18N']->get("Subject").Help("subject").'</label>'.
  '<input type="text" name="subject"  id="subjectinput"
    value="'.htmlentities($utf8_subject,ENT_QUOTES,'UTF-8').'" size="60" /></div>
  <div class="field"><label for="fromfield">'.$GLOBALS['I18N']->get("From Line").Help("from").'</label>'.'
    <input type="text" name="fromfield"
   value="'.htmlentities($utf8_from,ENT_QUOTES,'UTF-8').'" size="60" /></div>';
   
   if ($GLOBALS['can_fetchUrl']) {
      $maincontent .= sprintf('
      
      <div id="contentchoice" class="field">
      <label for="sendmethod">'.$GLOBALS['I18N']->get("Content").Help("sendmethod").'</label>'.'
      <input type="radio" name="sendmethod" value="remoteurl" %s />'.$GLOBALS['I18N']->get("Send a Webpage").'
      <input type="radio" name="sendmethod" value="inputhere" %s />'.$GLOBALS['I18N']->get("Compose Message").'
      </div>',
        $messagedata['sendmethod'] == 'remoteurl' ? 'checked="checked"':'',
        $messagedata['sendmethod'] == 'inputhere' ? 'checked="checked"':''
      );

      if (empty($messagedata['sendurl'])) {
        $messagedata['sendurl'] = 'e.g. http://www.phplist.com/testcampaign.html';
      }
      
      $maincontent .= '
      <div id="remoteurl" class="field"><label for="sendurl">'.$GLOBALS['I18N']->get("Send a Webpage - URL").Help("sendurl").'</label>'.'
        <input type="text" name="sendurl" id="remoteurlinput"
       value="'.$messagedata['sendurl'].'" size="60" /> <span id="remoteurlstatus"></span></div>';
      if (isset($messagedata['sendmethod']) && $messagedata['sendmethod'] != 'remoteurl') {
        $GLOBALS['pagefooter']['hideremoteurl'] = '<script type="text/javascript">$("#remoteurl").hide();</script>';
      }
   }

// custom code - end
  #0013076: different content when forwarding 'to a friend'
  $forwardcontent .= 
  '<div class="field"><label for="forwardsubject">'.$GLOBALS['I18N']->get("Subject").Help("forwardsubject").'</label>'.'
    <input type="text" name="forwardsubject" value="'.htmlentities($messagedata['forwardsubject'],ENT_QUOTES,'UTF-8').'" size="40" /></div>';

  $currentTime = Sql_Fetch_Row_Query('select now()');

  $scheduling_content = '<div id="schedulecontent">';
  if (defined('SYSTEM_TIMEZONE')) {
    $scheduling_content .= '
    <div class="field">'.s('phpList operates in the time zone "%s"',SYSTEM_TIMEZONE).'</div>';
  } else {
    $scheduling_content .= '
    <div class="field">'.s('Dates and times are relative to the Server Time').'<br/>'.s('Current Server Time is').' <span id="servertime">'.$currentTime[0].'</span>'.'</div>';
  }
  
  $scheduling_content .= '  <div class="field"><label for="embargo">'.$GLOBALS['I18N']->get("Embargoed Until").Help('embargo').'</label>'.'
    '.$embargo->showInput('embargo',"",$messagedata['embargo']).'</div>
  <div class="field"><label for="finishsending">'.$GLOBALS['I18N']->get("Stop sending after").Help('finishsending').'</label>'.'
    '.$embargo->showInput('finishsending',"",$messagedata['finishsending']).'</div>
    <script type="text/javascript">
    getServerTime();
    </script>';

  if (USE_REPETITION) {
    $repeatinterval = $messagedata["repeatinterval"];

    $scheduling_content .= '
    <div class="field"><label for="repeatinterval">'.$GLOBALS['I18N']->get('Repeat campaign every').Help('repetition').'</label>'.'
        <select name="repeatinterval">
      <option value="0"';
      if ($repeatinterval == 0) { $scheduling_content .= ' selected="selected"'; }
      $scheduling_content .= '>-- '.$GLOBALS['I18N']->get('no repetition').'</option>
      <option value="60"';
      if ($repeatinterval == 60) { $scheduling_content .= ' selected="selected"'; }
      $scheduling_content .= '>'.$GLOBALS['I18N']->get('hour').'</option>
      <option value="1440"';
      if ($repeatinterval == 1440) { $scheduling_content .= ' selected="selected"'; }
      $scheduling_content .= '>'.$GLOBALS['I18N']->get('day').'</option>
      <option value="10080"';
      if ($repeatinterval == 10080) { $scheduling_content .= ' selected="selected"'; }
      $scheduling_content .= '>'.$GLOBALS['I18N']->get('week').'</option>
      <option value="20160"';
      if ($repeatinterval == 20160) { $scheduling_content .= ' selected="selected"'; }
      $scheduling_content .= '>'.$GLOBALS['I18N']->get('fortnight').'</option>
      <option value="40320"';
      ## @@@TODO adding "month" is a bit trickier, as we use minutes for value, and months have varying numbers of seconds
      if ($repeatinterval == 40320) { $scheduling_content .= ' selected="selected"'; }
      $scheduling_content .= '>'.$GLOBALS['I18N']->get('four weeks').'</option>
      </select>
        <label for="repeatuntil">'.$GLOBALS['I18N']->get("Repeat Until").'</label>
        '.$repeatuntil->showInput("repeatuntil","",$messagedata["repeatuntil"]);
      $scheduling_content .= '</div>';
  }

  $requeueinterval = $messagedata["requeueinterval"];
  $scheduling_content .= '
  <div class="field"><label for="requeueinterval"> '.$GLOBALS['I18N']->get("Requeue every").Help("requeueing").'</label>'.'
    <select name="requeueinterval">
    <option value="0"';
    if ($requeueinterval == 0) { $scheduling_content .= ' selected="selected"'; }
    $scheduling_content .= '>-- '.$GLOBALS['I18N']->get("do not requeue").'</option>
    <option value="60"';
    if ($requeueinterval == 60) { $scheduling_content .= ' selected="selected"'; }
    $scheduling_content .= '>'.$GLOBALS['I18N']->get("hour").'</option>
    <option value="1440"';
    if ($requeueinterval == 1440) { $scheduling_content .= ' selected="selected"'; }
    $scheduling_content .= '>'.$GLOBALS['I18N']->get("day").'</option>
    <option value="10080"';
    if ($requeueinterval == 10080) { $scheduling_content .= ' selected="selected"'; }
    $scheduling_content .= '>'.$GLOBALS['I18N']->get("week").'</option>
    </select>

      <label for="requeueuntil">'.$GLOBALS['I18N']->get("Requeue Until").'</label>
      '.$requeueuntil->showInput("requeueuntil","",$messagedata["requeueuntil"]);
    $scheduling_content .= '</div>';

  $scheduling_content .= '</div>';
    
  $formatting_content .= '<input type="hidden" name="htmlformatted" value="auto" />';

  $formatting_content .= '
    <div class="field">
    <label for="sendformat"> '.$GLOBALS['I18N']->get("Send as").Help("sendformat").'</label>'.'
  '.$GLOBALS['I18N']->get("html").' <input type="radio" name="sendformat" value="HTML" ';
    $formatting_content .= $messagedata["sendformat"]=="HTML"?'checked="checked"':'';
    $formatting_content .= '/>
  '.$GLOBALS['I18N']->get("text").' <input type="radio" name="sendformat" value="text" ';
    $formatting_content .= $messagedata["sendformat"]=="text"?'checked="checked"':'';
    $formatting_content .= '/>
  ';

//  0009687: Confusing use of the word "Both", indicating one email with both text and html and not two emails
//  $formatting_content .= $GLOBALS['I18N']->get("text and html").' <input type="radio" name="sendformat" value="text and HTML" ';
//  $formatting_content .= $_POST["sendformat"]=="text and HTML" || !isset($_POST["sendformat"]) ?"checked":"";
//  $formatting_content .= '/>';

  foreach ($GLOBALS['plugins'] as $pluginname => $plugin) {
    $plugins_sendformats = $plugin->sendFormats();
    if (is_array($plugins_sendformats) && sizeof($plugins_sendformats)) {
      foreach ($plugins_sendformats as $val => $desc) {
        $val = preg_replace("/\W/",'',strtolower(trim($val)));
        if ($val[0] != '_') { ## allow a plugin to add a format that is not actually displayed
          $formatting_content .= sprintf('%s <input type="radio" name="sendformat" value="%s" %s />',
            $desc,$val, $messagedata["sendformat"]==$val?'checked="checked"':'');
        }
      }
    }
  }
  $formatting_content .= '</div>';

  $req = Sql_Query("select id,title from {$tables["template"]} order by listorder");
  if (Sql_Num_Rows($req)) {
    $formatting_content .= '<div class="field"><label for="template">'.$GLOBALS['I18N']->get("Use Template").Help("usetemplate").'</label>'.'
      <select name="template"><option value="0">-- '.$GLOBALS['I18N']->get("select one").'</option>';
    $req = Sql_Query("select id,title from {$tables["template"]} order by listorder");
    while ($row = Sql_Fetch_Array($req)) {
      if ($row["title"]) {
        $formatting_content .= sprintf('<option value="%d" %s>%s</option>',$row["id"], $row["id"]==$messagedata["template"]?'selected="selected"':'',$row["title"]);
      }
    }
    $formatting_content .= '</select></div>';
  }
  $formatting_content .= '</div>';

  #0013076: different content when forwarding 'to a friend'
  $maincontent .= '<div id="messagecontent" class="field"><label for="message">'.s("Compose Message").Help("message").'</label> ';
  $forwardcontent .= '<div id="messagecontent" class="field"><label for="forwardmessage">'.s("Compose Message").Help("forwardmessage").'</label> ';

  if (!empty($GLOBALS['editorplugin'])) {
    $maincontent .= '<div>'.$GLOBALS['plugins'][$GLOBALS['editorplugin']]->editor('message',$messagedata["message"]) .'</div>';
  } else {
    $maincontent    .= '
      <div><textarea name="message" cols="65" rows="20">'.htmlspecialchars($messagedata["message"]).'</textarea></div>';
  }

  #0013076: different content when forwarding 'to a friend'
  $forwardcontent .= '<div><textarea name="forwardmessage" cols="65" rows="20">'.htmlspecialchars($messagedata['forwardmessage']).'</textarea></div>';

  #0013076: different content when forwarding 'to a friend'
  $tmp = '
 
  </div></div> <!-- end of message content -->
  ';
  
  if (isset($messagedata['sendmethod']) && $messagedata['sendmethod'] != 'inputhere') {
    $GLOBALS['pagefooter']['hidemessagecontent'] = '<script type="text/javascript">$("#messagecontent").hide()</script>';
  }
  $maincontent .= $tmp;
  $forwardcontent .= $tmp;

  if (USE_MANUAL_TEXT_PART) {
  $textcontent = '<div class="field">
    <label for="textmessage">'.$GLOBALS['I18N']->get("Plain text version of message").Help("plaintextversion").'</label>'.'
    <div id="generatetextversion">'.PageLinkAjax('send&tab=Text&id='.$id.'&action=generatetext',$GLOBALS['I18N']->get('generate from HTML')).'</a> '.Help('generatetext').'</div>
    <textarea id="textmessage" name="textmessage" cols="65" rows="20">'.$messagedata["textmessage"].'</textarea>
  </div>';
  }
#var_dump($messagedata);
  #0013076: different content when forwarding 'to a friend'
  $maincontent .= '<div class="field"><label for="footer">'.$GLOBALS['I18N']->get("Footer").Help("footer").'.</label>'.'
   <textarea name="footer" cols="65" rows="5">'.htmlspecialchars($messagedata['footer']).'</textarea></div>';
  $forwardcontent .= '<div class="field"><label for="forwardfooter">'.$GLOBALS['I18N']->get("forwardfooter").Help("forwardfooter").'</label>'.'
    <textarea name="forwardfooter" cols="65" rows="5">'.htmlspecialchars($messagedata['forwardfooter']).'</textarea></div>';

  if (ALLOW_ATTACHMENTS) {
    // If we have a message id saved, we want to query the attachments that are associated with this
    // message and display that (and allow deletion of!)

    $att_content = '<div class="field"><label for="attach">'.$GLOBALS['I18N']->get("Add attachments to your campaign").Help("attachments").'</label>';
    $att_content .= '<div class="info">
      '.$GLOBALS['I18N']->get("The upload has the following limits set by the server").':<br/>
      '.$GLOBALS['I18N']->get("Maximum size of total data being sent to the server").': '.ini_get("post_max_size").'<br/>
      '.$GLOBALS['I18N']->get("Maximum size of each individual file").': '.ini_get("upload_max_filesize").'</div>';

    if ($id) {
      $result = Sql_Query(sprintf("Select Att.id, Att.filename, Att.remotefile, Att.mimetype, Att.description, Att.size, MsgAtt.id linkid".
                        " from %s Att, %s MsgAtt where Att.id = MsgAtt.attachmentid and MsgAtt.messageid = %d",
        $tables["attachment"],
        $tables["message_attachment"],
        $id));


      $ls = new WebblerListing($GLOBALS['I18N']->get('Current Attachments'));
      $totalSize = 0;
      while ($row = Sql_fetch_array($result)) {
        $ls->addElement($row["id"]);
        $ls->addColumn($row["id"],$GLOBALS['I18N']->get('filename'),$row["remotefile"]);
        $ls->addColumn($row["id"],$GLOBALS['I18N']->get('desc'),$row["description"]);
        $ls->addColumn($row["id"],$GLOBALS['I18N']->get('size'),formatBytes($row["size"]));
        $totalSize += $row["size"];
        $phys_file = $GLOBALS["attachment_repository"]."/".$row["filename"];
        if (is_file($phys_file) && filesize($phys_file)) {
          $ls->addColumn($row["id"],$GLOBALS['I18N']->get('file'),$GLOBALS["img_tick"]);
        } else {
          $ls->addColumn($row["id"],$GLOBALS['I18N']->get('file'),$GLOBALS["img_cross"]);
        }
        $ls->addColumn($row["id"],$GLOBALS['I18N']->get('del'),sprintf('<input type="checkbox" name="deleteattachments[]" value="%s"/>',$row["linkid"]));
      }
      $ls->addButton(s('Delete checked'),"javascript:document.sendmessageform.submit()");
      $att_content .= '<div>'.$ls->display().'</div>';
    }
    if (defined('MAX_MAILSIZE') && 3 * $totalSize > MAX_MAILSIZE) {  ## the 3 is roughly the size increase to encode the string
      $att_content .= Warn(s('The total size of attachments is very large. Sending this campaign may fail due to resource limits.'));
    }
    
    for ($att_cnt = 1;$att_cnt <= NUMATTACHMENTS;$att_cnt++) {
      $att_content .= sprintf  ('<div>%s</div><div><input type="file" name="attachment%d"/>&nbsp;&nbsp;<input class="submit" type="submit" name="save" value="%s"/></div>',$GLOBALS['I18N']->get('New Attachment'),$att_cnt,$GLOBALS['I18N']->get('Add (and save)'));
      if (FILESYSTEM_ATTACHMENTS) {
        $att_content .= sprintf('<div><b>%s</b> %s:</div><div><input type="text" name="localattachment%d" size="50"/></div>',$GLOBALS['I18N']->get('or'),$GLOBALS['I18N']->get('Path to file on server'),$att_cnt,$att_cnt);
      }
      $att_content .= sprintf ('<div>%s:</div>
        <div><textarea name="attachment%d_description" cols="65" rows="3" wrap="virtual"></textarea></div>',$GLOBALS['I18N']->get('Description of attachment'),$att_cnt);
    }
    $att_content .= '</div>';
    # $shader = new WebblerShader("Attachments");
    # $shader->addContent($att_content);
    # $shader->initialstate = 'closed';
    # print $shader->display();
  }

  // Load the email address for the admin user so we can use that as the default value in the testtarget field
  # @@@ this only works with phplist authentication, needs to be abstracted
  if (!isset($messagedata["testtarget"])) {
    $res = Sql_Query(sprintf("Select email from %s where id = %d", $tables["admin"], $_SESSION["logindetails"]["id"]));
    $admin_details = Sql_Fetch_Array($res);

    $messagedata["testtarget"] = $admin_details["email"];
  }
  // if there isn't one, load the developer one, just being lazy here :-)
  if (empty($messagedata["testtarget"]) && isset($GLOBALS["developer_email"])) {
    $messagedata["testtarget"] = $GLOBALS["developer_email"];
  }

  // Display the HTML for the "Send Test" button, and the input field for the email addresses
  $sendtest_content = sprintf('<div class="sendTest" id="sendTest">
    %s
    <input class="submit" type="submit" name="sendtest" value="%s"/> '.Help('sendtest').' %s: 
    <input type="text" name="testtarget" size="40" value="'.$messagedata["testtarget"].'"/><br />%s
    </div>',$sendtestresult,
    $GLOBALS['I18N']->get('Send Test'),$GLOBALS['I18N']->get(' to email address(es)'),
    $GLOBALS['I18N']->get('(comma separate addresses - all must be existing subscribers)'));

  # notification of progress of message sending
  # defaulting to admin_details['email'] gives the wrong impression that this is the
  # value in the database, so it is better to leave that empty instead
  $notify_start = isset($messagedata['notify_start'])?$messagedata['notify_start']:'';#$admin_details['email'];
  $notify_end = isset($messagedata['notify_end'])?$messagedata['notify_end']:'';#$admin_details['email'];

  $send_content = sprintf('
    <div class="sendNotify">
    <label for="notify_start">%s<br/>%s</label><div><input type="text" name="notify_start" id="notify_start" value="%s" size="35"/></div>
    <label for="notify_end">%s<br/>%s</label><div><input type="text" name="notify_end" id="notify_end" value="%s" size="35"/></div>
    </div>',
    $GLOBALS['I18N']->get('email to alert when sending of this message starts'),
    $GLOBALS['I18N']->get('separate multiple with a comma'),$notify_start,
    $GLOBALS['I18N']->get('email to alert when sending of this message has finished'),
    $GLOBALS['I18N']->get('separate multiple with a comma'),$notify_end);

  $send_content .= sprintf('
    <div class="campaignTracking">
    <label for"cb[google_track]">%s</label><input type="hidden" name="cb[google_track]" value="1" /><input type="checkbox" name="google_track" id="google_track" value="1" %s />
    </div>',
     Help("googletrack").' '.s('add Google Analytics tracking code'),
     !empty($messagedata['google_track']) ? 'checked="checked"':'');

  ## @@TODO, maybe add a check on "sent" for this campaign and suppress this once it's over a threshold
  $send_content .= sprintf('
    <div class="resetStatistics">
    <label for"cb[resetstats]">%s</label><input type="hidden" name="cb[resetstats]" value="1" /><input type="checkbox" name="resetstats" id="resetstats" value="1" %s />
    </div>',
     Help("resetstats").' '.s('Reset click statistics'),
     !empty($messagedata['resetstats']) ? 'checked="checked"':'');

  $send_content .= sprintf('
    <div class="isTestCampaign">
    <label for"cb[istestcampaign]">%s</label><input type="hidden" name="cb[istestcampaign]" value="1" /><input type="checkbox" name="istestcampaign" id="istestcampaign" value="1" %s />
    </div>',
     Help("istestcampaign").' '.s('This is a test campaign'),
     !empty($messagedata['istestcampaign']) ? 'checked="checked"':'');
   
  $show_lists = 0;

  $send_content .= '<div class="sizeEstimate">';
  if (!empty($messagedata['htmlsize'])) {
    $send_content .= $GLOBALS['I18N']->get('Estimated size of HTML email').': '.formatBytes($messagedata['htmlsize']).'<br/>';
  }
  if (!empty($messagedata['textsize'])) {
    $send_content .= $GLOBALS['I18N']->get('Estimated size of text email').': '.formatBytes($messagedata['textsize']).'<br/>';
  }
/*
  var_dump($messagedata['targetlist']);
*/

  if (!empty($messagedata['textsize']) || !empty($messagedata['htmlsize'])) {
    if (is_array($messagedata['targetlist']) && sizeof($messagedata['targetlist'])) {
      $lists = $messagedata['targetlist'];
      if (isset($messagedata['excludelist'])) {
        $excludelists = $messagedata['excludelist'];
      } else {
        $excludelists = array();
      }

      if (!empty($lists['all']) || !empty($lists['allactive'])) {
        $allactive = isset($lists['allactive']);
        $all = isset($lists['all']);
        $req = Sql_Query(sprintf('select id,active from %s %s',$GLOBALS['tables']['list'],$subselect));
        $lists = array();
        while ($row = Sql_Fetch_Row($req)) {
          if (($allactive && $row[1]) || $all) {
            $lists[$row[0]] = $row[0];
          }
        }
      }
      unset($lists['all']);
      unset($lists['allactive']);
      if (isset($messagedata['excludelist']) && is_array($messagedata['excludelist']) && sizeof($messagedata['excludelist'])) {
        $exclude = sprintf(' and listuser.listid not in (%s)',join(',',$messagedata['excludelist']));
      } else {
        $exclude = '';
      }

      $htmlcnt = Sql_Fetch_Row_Query(sprintf('select count(distinct userid) from %s listuser,%s u where u.htmlemail and u.id = listuser.userid and listuser.listid in (%s) %s',
        $GLOBALS['tables']['listuser'],$GLOBALS['tables']['user'],join(',',array_keys($lists)),$exclude),1);
      $textcnt = Sql_Fetch_Row_Query(sprintf('select count(distinct userid) from %s listuser,%s user where !user.htmlemail and user.id = listuser.userid and listuser.listid in (%s) %s',
        $GLOBALS['tables']['listuser'],$GLOBALS['tables']['user'],join(',',array_keys($lists)),$exclude),1);
      if ($htmlcnt[0] || $textcnt[0]) {
        if (!isset($messagedata['textsize'])) $messagedata['textsize'] = 0;
        if (!isset($messagedata['htmlsize'])) $messagedata['htmlsize'] = 0;

        $send_content .= $GLOBALS['I18N']->get('Estimated size of mailout').': '.formatBytes($htmlcnt[0] * $messagedata['htmlsize'] + $textcnt[0] * $messagedata['textsize']).'<br/>';
        ## remember this to see how well the estimate was
        Sql_Query(sprintf('replace into %s set name = "estimatedsize",id=%d,data = "%s"',$GLOBALS['tables']['messagedata'],$id,$htmlcnt[0] * $messagedata['htmlsize'] + $textcnt[0] * $messagedata['textsize']));
        $send_content .= sprintf($GLOBALS['I18N']->get('About %d users to receive HTML and %s users to receive text version of email'),$htmlcnt[0],$textcnt[0]).'<br/>';
        Sql_Query(sprintf('replace into %s set name = "estimatedhtmlusers",id=%d,data = "%s"',$GLOBALS['tables']['messagedata'],$id,$htmlcnt[0]));
        Sql_Query(sprintf('replace into %s set name = "estimatedtextusers",id=%d,data = "%s"',$GLOBALS['tables']['messagedata'],$id,$textcnt[0]));
      }
    }
  }
  $send_content .= '</div>';

  ## the button to actually send the campagin
  $send_content .= $placeinqueue;

print '<div class="sendtabs_container">';


  $tabs->setListClass('sendcampaign');
  $tabs->setId('sendtabs');
#  $tabs->addPrevNext();
  $tabs->addTabNo();
  print $tabs->display();
  #print '<div id="tabcontent"></div>';

  $panelcontent = '';
  switch ($_GET["tab"]) {
    case "Attach": $panelcontent = $att_content; break;
 //   case "Criteria": print $criteria_content; break; // moved to plugin
    case "Text": $panelcontent =  $textcontent; break;
    case "Format": $panelcontent =  $formatting_content;break;
    case "Scheduling": $panelcontent =  $scheduling_content;break;
//    case "RSS": print $rss_content;break;            //Obsolete by rssmanager plugin
    case "Lists": $show_lists = 1;break;
    case "Review": $panelcontent =  $review_content; break;
    case "Finish": $panelcontent =  $send_content; break;
    case "Forward": $panelcontent =  $forwardcontent; break;
    default:
      $isplugin = 0;
      foreach ($plugintabs as $tabname => $tabcontent) {
        if ($_GET['tab'] == $tabname) {
          $panelcontent =  $tabcontent;
          $isplugin = 1;
        }
      }
      if (!$isplugin) {
        $panelcontent =  $maincontent;
      }
      break;
  }
}

$GLOBALS['pagefooter']['sendtabs'] = "<script type='text/javascript'>\n".
"$(document).ready(function() {
    var counttab = ".$counttabs.";
    var currenttab = $('.current').attr('id');
    if(matchMedia('only screen and (max-width: 480px)').matches){ tabs=2; starttab=currenttab-2;  }
    else if(matchMedia('only screen and (max-width: 767px)').matches){ tabs=3; starttab=currenttab-3;}
    else if(matchMedia('only screen and (max-width: 967px)').matches){ tabs=4; starttab=currenttab-4;}
    else{ tabs=6; starttab=currenttab-6; if ( counttab < 7 ){ $('.nexttab').addClass('disabled'); } }
    if ( starttab < 1 ){ starttab=0; $('.prevtab').addClass('disabled'); }
    if ( currenttab>=counttab ){ $('.nexttab').addClass('disabled'); }

    $('#sendtabs').jCarouselLite({
        btnNext: '.nexttab',
        btnPrev: '.prevtab',
        circular: false,
        visible: tabs,
        auto: null,
        speed:100,
        scroll:1,
        start: starttab
    });
});
$(window).resize(function(){
    var counttab = ".$counttabs.";
    var currenttab = $('.current').attr('id');
    if(matchMedia('only screen and (max-width: 480px)').matches){ tabs=2; $('.nexttab').removeClass('disabled'); starttab=currenttab-2;}
    else if(matchMedia('only screen and (max-width: 767px)').matches){ tabs=3; $('.nexttab').removeClass('disabled'); starttab=currenttab-3;}
    else if(matchMedia('only screen and (max-width: 967px)').matches){ tabs=4; $('.nexttab').removeClass('disabled'); starttab=currenttab-4;}
    else{ tabs=6; starttab=currenttab-6; if ( counttab < 7){ $('.nexttab').addClass('disabled'); } }
    if ( starttab < 1 ){ starttab=0; $('.prevtab').addClass('disabled'); }
    if ( currenttab>=counttab ){ $('.nexttab').addClass('disabled'); }
    $('#sendtabs').jCarouselLite({
        btnNext: '.nexttab',
        btnPrev: '.prevtab',
        circular: false,
        visible: tabs,
        auto: null,
        speed:100,
        scroll:1,
        start: starttab
    });
});

</script>";

print '<img src="ui/'.$GLOBALS['ui'].'/images/prevtab.png" id="prev" class="prevtab" />';
print '<img src="ui/'.$GLOBALS['ui'].'/images/nexttab.png" id="next" class="nexttab" />';
print '</div>';

## if all is there, we can enable the send button
$allReady = true;
$GLOBALS['pagefooter']['addtoqueue'] = '<script type="text/javascript">
$("#addtoqueue").html("");
</script>';

$testValue = trim($messagedata['subject']);
if (empty($testValue) || $testValue == '(no subject)') {
  $allReady = false;
  $GLOBALS['pagefooter']['addtoqueue'] .= '<script type="text/javascript">
  $("#addtoqueue").append(\'<div class="missing">'.$GLOBALS['I18N']->get('subject missing').'</div>\');
  </script>';
}
$testValue = trim($messagedata['message']);
$testValue2 = trim($messagedata['sendurl']);

if (empty($testValue) && (empty($testValue2) || $testValue2 == 'e.g. http://www.phplist.com/testcampaign.html')) {
  $allReady = false;
  $GLOBALS['pagefooter']['addtoqueue'] .= '<script type="text/javascript">
  $("#addtoqueue").append(\'<div class="missing">'.$GLOBALS['I18N']->get('message content missing').'</div>\');
  </script>';
} 
$testValue = trim($messagedata['fromfield']);
if (empty($testValue)) {
  $allReady = false;
  $GLOBALS['pagefooter']['addtoqueue'] .= '<script type="text/javascript">
  $("#addtoqueue").append(\'<div class="missing">'.$GLOBALS['I18N']->get('From missing').'</div>\');
  </script>';
} 

##16615, check that "send until" is in after the embargo and warn if it isn't
$finishSending = mktime($messagedata['finishsending']['hour'],$messagedata['finishsending']['minute'],0,
  $messagedata['finishsending']['month'],$messagedata['finishsending']['day'],$messagedata['finishsending']['year']);
$embargoTime = mktime($messagedata['embargo']['hour'],$messagedata['embargo']['minute'],0,
  $messagedata['embargo']['month'],$messagedata['embargo']['day'],$messagedata['embargo']['year']);
$currentTime = time();

if ($finishSending < $embargoTime) { 
  $allReady = false;
  $GLOBALS['pagefooter']['addtoqueue'] .= '<script type="text/javascript">
  $("#addtoqueue").append(\'<div class="missing">'.s('This campaign is scheduled to stop sending before the embargo time. No mails will be sent.').'<br/>'.PageLinkButton('send&amp;id='.$messagedata['id'].'&amp;tab=Scheduling',s('Review Scheduling')).'</div>\');
  </script>';  
} elseif ($finishSending < $currentTime) {
  $allReady = false;
  $GLOBALS['pagefooter']['addtoqueue'] .= '<script type="text/javascript">
  $("#addtoqueue").append(\'<div class="missing">'.s('This campaign is scheduled to stop sending in the past. No mails will be sent.').'<br/>'.PageLinkButton('send&amp;id='.$messagedata['id'].'&amp;tab=Scheduling',s('Review Scheduling')).'</div>\');
  </script>';  
}  

if (empty($messagedata['targetlist'])) {
  $allReady = false;
  $GLOBALS['pagefooter']['addtoqueue'] .= '<script type="text/javascript">
  $("#addtoqueue").append(\'<div class="missing">'.$GLOBALS['I18N']->get('destination lists missing').'</div>\');
  </script>';
}
if ($hasClickTrackLinks && BLOCK_PASTED_CLICKTRACKLINKS) {
  $allReady = false;
  $GLOBALS['pagefooter']['addtoqueue'] .= '<script type="text/javascript">
  $("#addtoqueue").append(\'<div class="missing">'.s('Content contains click track links.').resourceLink('http://resources.phplist.com/documentation/errors/pasteclicktrack').'</div>\');
  </script>';
}
 
foreach ($GLOBALS['plugins'] as $pluginname => $plugin) {
  $pluginerror = '';
  $pluginerror = $plugin->allowMessageToBeQueued($messagedata);
  if ($pluginerror) {
    $allReady = false;
    $pluginerror = preg_replace("/\n/","",$pluginerror);
    $GLOBALS['pagefooter']['addtoqueue'] .= '<script type="text/javascript">
    $("#addtoqueue").append(\'<div class="missing">'.$pluginerror.'</div>\');
    </script>';
  }
}

if ($allReady) {
  $GLOBALS['pagefooter']['addtoqueue'] .= '<script type="text/javascript">
  $("#addtoqueue").html(\'<input class="action-button" type="submit" name="send" id="addtoqueuebutton" value="'.htmlspecialchars($GLOBALS['I18N']->get('Send Campaign')).'">\');
  </script>';
} else {
  $GLOBALS['pagefooter']['addtoqueue'] .= '<script type="text/javascript">
  $("#addtoqueue").append(\'<div class="error">'.$GLOBALS['I18N']->get('Some required information is missing. The send button will be enabled when this is resolved.').'</div>\');
//  $("#addtoqueue").append(\'<button class="submit" type="submit" name="save" id="addtoqueuebutton" disabled="disabled">'.$GLOBALS['I18N']->get('Send Campaign').'</button>\');
  </script>';
}

$saveDraftButton = '<div class="sendSubmit">
    <input class="submit" type="submit" name="savedraft" value="'.s('Save as draft').'"/>
    <input type="hidden" name="id" value="'.$id.'"/>
    <input type="hidden" name="status" value="draft"/> <input class="submit" type="submit" name="save" value="'.s('Save and continue editing').'"/>
    <input type="hidden" name="id" value="'.$id.'"/>
    <input type="hidden" name="status" value="draft"/></div>
';

  $testpanel = new UIPanel($GLOBALS['I18N']->get('Send Test'),$sendtest_content);
  $testpanel->setID('testpanel');

 # print $testpanel->display();

Filemanager

Name Type Size Permission Actions
FCKeditor Folder 0755
PEAR Folder 0755
PHPMailer Folder 0755
PHPMailer6 Folder 0755
actions Folder 0755
auth Folder 0755
commonlib Folder 0755
css Folder 0755
data Folder 0755
help Folder 0755
images Folder 0755
inc Folder 0755
info Folder 0755
js Folder 0755
lan Folder 0755
locale Folder 0755
oldmailer Folder 0755
onyxrss Folder 0755
plugins Folder 0755
styles Folder 0755
tests Folder 0755
ui Folder 0755
uploadimages Folder 0755
.gitignore File 20 B 0644
.htaccess File 171 B 0644
.minceconf File 994 B 0644
AnalyticsQuery.php File 985 B 0644
CsvReader.php File 1.27 KB 0644
EmailSender.php File 477 B 0644
about.php File 4.22 KB 0644
accesscheck.php File 1.51 KB 0644
addprefix.php File 966 B 0644
adduser.php File 46 B 0644
admin.php File 10.68 KB 0644
adminattributes.php File 6.39 KB 0644
admins.php File 4.54 KB 0644
adodb.inc File 6.49 KB 0644
analytics.php File 2.84 KB 0644
attributes.php File 102 B 0644
blacklistemail.php File 1.04 KB 0644
bounce.php File 10.09 KB 0644
bouncemgt.php File 1.39 KB 0644
bouncerule.php File 3 KB 0644
bouncerules.php File 5.86 KB 0644
bounces.php File 6.01 KB 0644
catlists.php File 2.64 KB 0644
checkbouncerules.php File 1.34 KB 0644
checki18n.php File 2.69 KB 0644
checkprerequisites.php File 1.05 KB 0644
class.html.mime.mail-outlookfix.inc File 19.93 KB 0644
class.html.mime.mail.inc File 19.35 KB 0644
class.image.inc File 5.77 KB 0644
class.phplistmailer.php File 24.23 KB 0644
class.phplistmailerbase.php File 1.5 KB 0644
community.php File 1.78 KB 0644
communityfeed.php File 2.36 KB 0644
configure.php File 5.25 KB 0644
connect.php File 74.36 KB 0644
convertstats.php File 5.51 KB 0644
converttoutf8.php File 3.77 KB 0644
cron.php File 3.37 KB 0644
date.php File 6.08 KB 0644
dbcheck.php File 111 B 0644
defaultFrontendTexts.php File 9.57 KB 0644
defaultconfig.inc File 23.52 KB 0644
defaultconfig.php File 24.92 KB 0644
defaultplugin.php File 23.31 KB 0644
defaults.php File 2.83 KB 0644
defaultsystemtemplate.php File 1.83 KB 0644
defaulttest.php File 1.12 KB 0644
dlusers.php File 232 B 0644
domainbounces.php File 507 B 0644
domainstats.php File 2.83 KB 0644
editattributes.php File 6.7 KB 0644
editlist.php File 6.79 KB 0644
error_log File 274 B 0644
eventlog.php File 4.49 KB 0644
export.php File 4.84 KB 0644
exportuserdata.php File 6.36 KB 0644
fckphplist.php File 43.21 KB 0644
footer.inc File 1.19 KB 0644
footer.old.inc File 1.82 KB 0644
gchart.php File 869 B 0644
generatebouncerules.php File 5.24 KB 0644
getrss.php File 3.94 KB 0644
header.inc File 1.75 KB 0644
home.php File 16.36 KB 0644
hostedprocessqueuesetup.php File 1.64 KB 0644
htaccess File 311 B 0644
image.php File 795 B 0644
import.php File 2.54 KB 0644
import1.php File 9.41 KB 0644
import2.php File 243 B 0644
import3.php File 20.26 KB 0644
import4.php File 15.63 KB 0644
importadmin.php File 14.5 KB 0644
importlib.php File 2.86 KB 0644
importsimple.php File 5.84 KB 0644
index.php File 22.53 KB 0644
index.php.old File 22.53 KB 0644
info.php File 1.01 KB 0644
init.php File 21.7 KB 0644
initialise.php File 10.02 KB 0644
initlanguages.php File 794 B 0644
languages.php File 22.43 KB 0644
lib.php File 59.85 KB 0644
list.php File 11.79 KB 0644
listbounces.php File 4.64 KB 0644
login.php File 6.05 KB 0755
logout.php File 224 B 0644
massremove.php File 1.81 KB 0644
massunconfirm.php File 1.52 KB 0644
mclicks.php File 9.55 KB 0644
members.php File 16.58 KB 0644
mergeduplicates.php File 4.28 KB 0644
message.php File 7.27 KB 0644
messages.php File 18.94 KB 0644
mimePart.php File 10.7 KB 0644
minify.txt File 201 B 0644
msgbounces.php File 3.79 KB 0644
msgstatus.php File 1.18 KB 0644
mviews.php File 7.88 KB 0644
mysql.inc File 11.19 KB 0644
mysqli.inc File 11.58 KB 0644
pageaction.php File 1.08 KB 0644
pagetop.php File 1.17 KB 0644
phpListAdminAuthentication.php File 7.2 KB 0644
pluginlib.php File 6.39 KB 0644
plugins.php File 10.32 KB 0644
preparesend.php File 627 B 0644
processbounces.php File 29.71 KB 0644
processqueue.php File 3.73 KB 0644
purgerss.php File 1.38 KB 0644
readtestmail.php File 11.26 KB 0644
reconcileusers.php File 25.16 KB 0644
redirecttoupdater.php File 170 B 0644
reindex.php File 1.69 KB 0644
rsslib.php File 2.8 KB 0644
runcommand.php File 583 B 0644
send.php File 5.58 KB 0644
send_core.php File 56.08 KB 0644
sendemaillib.php File 64.2 KB 0644
sendprepared.php File 4.33 KB 0644
sessionlib.php File 2.92 KB 0644
setpermissions.php File 1.57 KB 0644
setup.php File 3.21 KB 0644
sidebar.php File 2.67 KB 0644
spage.php File 3.29 KB 0644
spageedit.php File 17.07 KB 0644
statsmgt.php File 1.22 KB 0644
statsoverview.php File 7.62 KB 0644
stresstest.php File 5.1 KB 0644
structure.php File 26.79 KB 0644
subscribelib2.php File 66.02 KB 0644
subscriberstats.php File 591 B 0644
suppressionlist.php File 1.71 KB 0644
system.php File 784 B 0644
systemstats.php File 7.71 KB 0644
template.php File 12.72 KB 0644
templates.php File 3.02 KB 0644
tests.php File 1.57 KB 0644
uclicks.php File 6.52 KB 0644
update.php File 187 B 0644
updateLib.php File 2.77 KB 0644
updatetlds.php File 399 B 0644
updatetranslation.php File 1.94 KB 0644
upgrade.php File 29.03 KB 0644
user.php File 2.35 KB 0644
usercheck.php File 2.27 KB 0644
userclicks.php File 8 KB 0644
userhistory.php File 127 B 0644
usermgt.php File 1.83 KB 0644
users.php File 393 B 0644
vCard.php File 1.9 KB 0644
viewmessage.php File 610 B 0644
viewrss.php File 4.07 KB 0644
viewtemplate.php File 1.82 KB 0644
vote.php File 38 B 0644