I am trying to have an SMS sent as a reminder to the users of my web application. I am not too familiar or good with cron jobs. I know that I have to set one up, I don't think that I did it effectively though.
I am not sure if my path is correct, how could I test that? Also, should I set it to every minute or should I set it to once a day. What is the difference?
Would this work if the path is correct?
<?php
//This was based upon http://glennstovall.com/blog/2013/01/07/writing-cron-jobs-and-command-line-scripts-in-codeigniter/ with modifications for Easy!Appointments by Craig Tucker, 7/18/2014.
class Reminders extends CI_Controller {
public function __construct() {
parent::__construct();
$this->load->library('email');
$this->load->library('session');
$this->load->model('settings_model');
$this->load->model('reminders_model');
// Set user's selected language.
if ($this->session->userdata('language')) {
$this->config->set_item('language', $this->session->userdata('language'));
$this->lang->load('translations', $this->session->userdata('language'));
} else {
$this->lang->load('translations', $this->config->item('language')); // default
}
}
public function index() {
if(!$this->input->is_cli_request()) {
echo "This script can only be accessed via the command line" . PHP_EOL;
return;
}
$d = 3; //Number of days out for the reminder
$timestamp = strtotime("+".$d." days");
$appointments = $this->reminders_model->get_days_appointments($timestamp);
$baseurl = $this->config->base_url();
$company_name = $this->settings_model->get_setting('company_name');
$appointment_link = $this->config->base_url().'index.php/appointments/index/';
if ($d == "1") {
$notice = "One more day until your appointment.";
} else {
$notice = $d." more days until your appointment.";
}
$msg = '';
if(!empty($appointments)) {
foreach($appointments as $appointment) {
$aptdatetime=date('D g:i a',strtotime($result["start_datetime"]));
$startdatetime=date('l, F j, Y, g:i a',strtotime($appointment->start_datetime));
$config['mailtype'] = 'text';
$this->email->initialize($config);
$this->email->set_newline("\r\n");
$this->email->to($appointment->customer_email);
if (!empty($appointment->customer_cellurl)){
$phone = $appointment->customer_phone_number;
$phone = preg_replace('/[^\dxX]/', '', $phone);
$this->email->bcc($phone.$appointment->customer_cellurl);
}
$this->email->from($appointment->provider_email, $company_name);
$this->email->subject($notice);
$msg .= $company_name."\r\n";
$msg .= "REMINDER: Your appointment with ".$appointment->provider_first_name." ".
$appointment->provider_last_name." is on ".$startdatetime."\r\n";
$msg .= "\r\n";
$msg .= "If you have had a good experience, let others know! Please review me at:\r\n";
$msg .= "www.healthgrades.com/review/XGVRC\r\n";
$msg .= "\r\n";
$msg .= "To edit, reschedule, or cancel your appointment please click the following link:\r\n";
$msg .= $appointment_link.$appointment->hash."\r\n";
$msg .= "\r\n";
$msg .="To attend your session on line, log in to www.craigtuckerlcsw.com and go to 'My Appointments'\r\n";
$this->email->message($msg);
$this->email->send();
$msg = "";
echo $this->email->print_debugger();
}
}
}
}
/* End of file reminders.php */
/* Location: ./application/controllers/cli/reminders.php */
Related
I have a PHP script which opens an email inbox, searches for the last email and then performs some other operations if this email has the UNSEEN header.
The script is run by a cron job, and it works fine. The problem is that sometimes it takes several attempts before actually finding the new email, even if the email has already arrived.
If someone sees i'm missing something, or knows how to ensure i get all emails on the first try, please let me know. This is the relevant email opening and searching code code:
//open mailbox
$inbox = imap_open('{<domain>/imap/ssl/novalidate-cert}INBOX', '<email-address>', '<password>');
$newEmails = false;
// grab a list of all the mail headers
$msgnos = imap_search($inbox, 'ALL');
$headers = imap_headers($inbox);
$last = imap_num_msg($inbox);
//check if the last email is marked as unread (U means unread)
$headerinfo = imap_headerinfo($inbox, $last);
if($headerinfo->Unseen == 'U') {
$newEmails = true;
file_put_contents("program_logs.txt","[".date('d-m-Y H:i') . "] program executed. New mails found. \r\n",FILE_APPEND);
}
echo $headerinfo->Unseen . "<br>";
//read email if the last email is unread
if($newEmails == true){
$header = imap_header($inbox, $last);
$body = imap_fetchbody($inbox, $last,1);
$structure = imap_fetchstructure($inbox, $last);
$boxname = $header->from[0]->mailbox;
$hostname = $header->from[0]->host;
$title = $header->subject;
$from = $boxname."#".$hostname;
echo "<h2>Body structure Encoding:</h2>";
var_dump($structure->encoding);
echo "<hr>";
if($structure->encoding == 3){
$body = base64_decode($body);
}
if($structure->encoding == 4){
$body=quoted_printable_decode($body);
}
echo "<h2>Is body html?</h2>";
if($body != strip_tags($body)){
echo "body is html.<br>";
$body = preg_replace( "/\n\s+/", "\n", rtrim(html_entity_decode(strip_tags($body))) );
echo "converted to plain text.";
}else{
echo "body is not html";
}
echo "<hr>";
echo "<h2>From:</h2>".$from;
echo "<hr>";
echo "<h2>Body:</h2>".$body;
echo "<hr>";
echo "<h2>title:</h2>".$title;
echo "<hr>";
file_put_contents("program_logs.txt","Email is from ".$from. " \r\n",FILE_APPEND);
}else{
echo 'No new notifications';
echo "<hr>";
echo "<h2>imap erros:</h2>";
var_dump(imap_errors());
imap_close($inbox);
echo '<hr>';
file_put_contents("program_logs.txt","[".date('d-m-Y H:i') . "] program executed, no new mails found. \r\n",FILE_APPEND);
}
Problem
I have a script to send newsletters to my contacts. The script works fine, if I have no attachement (proven with 2,000 emails).
Now, if I use attachments, the script works fine too. But only by sending about 30 emails.
Test-Setup
group of 100 emails to be performed (loop).
attachments: 2 files (total 4,6 MB) --> the script terminates (but without error message) after 50 seconds and 34 emails sent. (~ 156 MB).
Test-Variations
changing in php.ini memory_limit from 100M to 500M --> has no effect. Still error after 34 emails.
putting a sleep(5) after each loop --> has no effect. Still error after 34 emails.
no attachments: all 100 emails are sent (about 30 seconds).
no attachements on 2000 emails: all 2000 emails are sent (about 6 minutes).
no effect of changing max_execution_time in php.ini.
Assumtions
Due to the behaviour I expect to have a memory-problem and not a time-problem.
But a test of the memory (memory_get_usage()) in each loop showed that the memory of the first loop is 1.1 MBand of the 34th loop 1.2 MB.
Question
Please find below my code, but I guess it sould be ok.
Does anybody has an idea what is causing the issue? Many thanks!
myMailer.class
class myMailer extends PHPMailer {
public function __construct(?bool $exceptions = true) {
$config = parse_ini_file('../../ini/config.ini', true);
parent::__construct($exceptions);
try {
// Language of Errors
$this->setLanguage('en', dirname(__FILE__) . '/../external/PHPMailer/language/');
// Server settings
$this->SMTPDebug = 0; // Enable verbose debug output
$this->isSMTP(); // Set mailer to use SMTP
$this->SMTPAuth = true; // Enable SMTP authentication
$this->SMTPSecure = 'ssl'; // Enable TLS encryption, `ssl` also accepted
$this->Port = 465; // TCP port to connect to
$this->Host = $config['smtp_server']['host']; // SMTP server
$this->Username = $config['smtp_server']['username']; // SMTP username
$this->Password = $config['smtp_server']['password']; // SMTP password
$this->CharSet ='UTF-8'; // Set Character Set
$this->isHTML(true); // Set email format to HTML
$this->setFrom("office#superman.com", "superman OFFICE");
} catch (Exception $e) {
// echo 'Message could not be sent. Mailer Error: ', $mail->ErrorInfo;
trigger_error("myMailer(): " . $this->ErrorInfo,E_USER_ERROR);
}
}
public function setBody(string $salutation, string $receiver, string $message) : void {
// Linebreak to <BR>
$message = nl2br($message);
// Create Body
$body = file_get_contents('../../ini/email_template.html');
$body = str_replace("{Receiver}", $receiver, $body);
$body = str_replace("{Salutation}", $salutation, $body);
$body = str_replace("{Message}", $message, $body);
$this->Body = $body;
}
}
send_emails.php
<?php
$groupID = $_POST['id'];
$subject = $_POST['Subject'];
$message = $_POST['Message'];
$attachments = (key_exists('Files', $_POST)) ? $_POST['Files'] : array();
$group = new Group($groupID);
// Prepare and get HTML
$htmlGenerator = HtmlGenerator::getInstance();
$htmlGenerator->setTitle("sending emails");
$header = $htmlGenerator->getWebbaseHtmlHeader();
$footer = $htmlGenerator->getWebbaseHtmlFooter();
echo $header;
?>
<div class="container">
<h1>Emailing</h1>
<h3>Group: <?php echo $group->getTitle(); ?></h3>
<h4>Number of members: <?php echo $group->getNumberOfMembers(); ?></h4>
<?php
$strScreenOutput = "
<table class='table table-sm table-hover table-responsive-md'>
<thead class='thead-dark'>
<th scope='col'>Nr.</th>
<th scope='col'>Date</th>
<th scope='col'>Company</th>
<th scope='col'>Lastname</th>
<th scope='col'>Firstname</th>
<th scope='col'>Email</th>
<th scope='col'>Newsletter</th>
<th scope='col'>Result</th>
</thead>
<tbody>";
$protocol = $strScreenOutput;
echo $strScreenOutput;
$i = 0;
$members = Contact::getAllOfGroup($groupID);
foreach ($members as $contact) {
$i++;
$datRun = date('d.m.Y (H:i:s)');
if ($contact->getNewsletter() === false) {
$result = "no sub.";
} elseif ($contact->getEmail() === "" || $contact->getEmail() === null) {
$result = "no email";
} else {
$return = $contact->sendEmail($subject, $message, $attachments);
$result = ($return===true) ? "ok" : $return;
}
// create feedback for browser
$strScreenOutput = "<tr>";
$strScreenOutput .= "<th scope='row'>".str_pad($i, 4 ,'0', STR_PAD_LEFT)."</th>";
$strScreenOutput .= "<td>{$datRun}</td>";
$strScreenOutput .= "<td>{$contact->getCompany()}</td>";
$strScreenOutput .= "<td>{$contact->getLastName()}</td>";
$strScreenOutput .= "<td>{$contact->getFirstName()}</td>";
$strScreenOutput .= "<td>{$contact->getEmail()}</td>";
$strScreenOutput .= "<td>".(($contact->getNewsletter()) ? "yes" : "no")."</td>";
$strScreenOutput .= "<td>{$result}</td>";
$strScreenOutput .= "</tr>";
echo str_pad($strScreenOutput,4096)."\n"; // Add some additional blanks to enable flushing (as some browsers suppress flushing)
// create internal protocol
$protocol .= $strScreenOutput . "\n";
// Send to browser
flush();
ob_flush();
// add some execution time
set_time_limit(30);
}
$strScreenOutput = "</tbody>
</table>";
$protocol .= $strScreenOutput;
echo $strScreenOutput;
?>
<h3>Emails successfully transmitted.</h3>
</div>
<?php
// send protocols
$protocol = "<h3>Group: {$group->getTitle()}</h3>".$protocol;
$protocol = "<div style='margin-top: 30px'>$protocol</div>";
$internal = new Contact(1);
$internal->sendEmail("PROTOCOL: ".$subject, $message . $protocol, $attachments);
echo $footer;
Contact::sendEmail()
public function sendEmail(string $subject, string $message, array $attachments = array()) {
$mail = new myMailer();
if ( is_null($this->getEmail() || $this->getEmail() == "") ) {
return false;
} else {
try {
// Compose Email
$mail->addAddress($this->getEmail(), $this->getFirstName() . " " . $this->getLastName());
$mail->Subject = $subject;
$mail->setBody($this->getSalutationText(), $this->getAddress(), $message);
foreach ($attachments as $file) {
$uploadPath = $_SERVER['DOCUMENT_ROOT'] . "/../../files/email_attachments/";
$file_url = $uploadPath.$file;
if (! is_dir($uploadPath)) { die("Folder \"$uploadPath\" does not exist.");}
if (! file_exists($file_url)) { die("File \"$file_url\" does not exist."); }
$mail->addAttachment($file_url);
}
$return = $mail->send();
// clean up
$mail->clearAddresses();
$mail->clearAttachments();
} catch (Exception $error) {
$return = $error->getMessage();
}
return $return;
}
unset($mail);
}
It does sound like a memory problem - PHPMailer isn't very efficient on memory when sending large attachments - try echoing what you get from memory_get_usage() inside your loop to confirm memory consumption.
Generally though, you're sending quite inefficiently because you're creating a new PHPMailer instance, reprocessing the same attachments, and opening a new SMTP connection for every message, all of which only need doing once. For how to send more efficiently, look at the mailing list example provided with PHPMailer, and the wiki doc on sending to lists.
A more efficient reuse of instance and connection may reduce your overall memory requirements.
I'm trying to make a program that takes e-mails from the post.
Everything is nice, beautiful. Almost..
Unfortunately, the problem is when the mail is "unseen". The script changes its status to "seen".
And I don't want this.
I tried to do that: at the beginning I check that emails are unseen, and at the end I'd like them to restore the status "unseen".
However, I met only with "imap_setflag_full" and it doesn't have that option.
public function pop_mails(){
$message_count = imap_num_msg($this -> _inbox);
$date = date('Y-m-d');
mkdir("./$date", 0777);
for($i=1; $i<=$message_count; $i++){
$overview = imap_fetch_overview($this->_inbox, $i);
$seen = $overview[0] -> seen;
$name = imap_utf8($overview[0]->subject);
$named = strtr($name, ":", ".");
$headers = imap_fetchheader($this->_inbox, $i, FT_PREFETCHTEXT);
$body = imap_body($this->_inbox, $i);
file_put_contents($date.'/'.$named. '.eml', $headers . "\n" . $body);
if($seen =="0") {
imap_setflag_full($this->_inbox, $seen, "\\Seen");
}
}
}
Can you help me?
You just have to clear the \\Seen Flag at the end of your process :
$status = imap_clearflag_full($this->_inbox, "$email_number", " \\Seen");
I'm new to PHP and trying to create a form with all fields required, including one where a file must be selected. Here is what I would like to achieve:
user must complete 4 fields + upload a file
file can only be of a certain type + under a certain size
if user does not complete one of the requirements and clicks submit, the word "Required" appears next to the empty field
if selected file does not meet criteria, a different message appears
data is preserved in the fields that were filled in if the user left something blank and has to go back to fill it in.
when form submits, info goes into database + into an email
I am close but missing something. If I select a file that meets the requirements, the form submits even if the other fields are blank. As long as the form field is empty, the other fields behave correctly. What am I missing? I would appreciate any help. Thank you.
<?php require_once('../scripts/lcoa.php'); ?>
<?php
if (isset($_GET['jobid'])) {
$jobid = $_GET['jobid'];
}
if (isset($_GET['jobtitle'])) {
$jobtitle = $_GET['jobtitle'];
}
//This is the directory where resumes will be saved
$timestamp = time();
$folder = "../careers/resumes/";
$resume = ($_FILES['resume']['name']);
$target = $folder.basename($timestamp.$_FILES['resume']['name']);
$type = ($_FILES['resume']['type']);
$extension = strtolower(substr($resume, strpos($resume, '.') + 1));
$size = ($_FILES['resume']['size']);
$max_size = 3145728;
$name = ($_POST['name']);
$email = ($_POST['email']);
$phone = ($_POST['phone']);
$jobid = ($_POST['jobid']);
$jobtitle = ($_POST['jobtitle']);
$cover = ($_POST['coverletter']);
$error=array();
if(isset($name)){
if (empty ($name)){
$error['name']="<p class='error'>Required </p>";
}
}
if(isset($email)){
if (empty ($email)){
$error['email']="<p class='error'>Required </p>";
}
}
if(isset($phone)){
if (empty ($phone)){
$error['phone']="<p class='error'>Required </p>";
}
}
if(isset($cover)){
if (empty ($cover)){
$error['coverletter']="<p class='error'>Required </p>";
}
}
//Writes the resume to the server
if (isset ($resume)) {
if (empty ($resume)){
$error['resume']="<p class='error'>Resume Required </p>";
}
if (!empty ($resume)){
if(($extension=='doc'||$extension=='docx'||$extension=='txt'||$extension=='pdf')&&($type=='application/pdf'||'application/msword'||'application/vnd.openxmlformats-officedocument.wordprocessingml.document'||'text/plain')&&$size<=$max_size) {
if(move_uploaded_file($_FILES['resume']['tmp_name'], $target)) {
//Writes the information to the database
$insertSQL = "INSERT INTO applicants (id, name, email, phone, jobid, jobtitle, coverletter, resume) VALUES ('','".$_POST['name']."','".$_POST['email']."','".$_POST['phone']."','".$_POST['jobid']."','".$_POST['jobtitle']."','".$_POST['coverletter']."','".$resume."')";
mysql_select_db($database_lcoa, $lcoa);
$Result1 = mysql_query($insertSQL, $lcoa) or die(mysql_error());
//Sends Email
$sendto = "emailaddress";
$name = nl2br($_POST['name']);
$email = nl2br($_POST['email']);
$phone = nl2br($_POST['phone']);
$jobid = nl2br($_POST['jobid']);
$jobtitle = nl2br($_POST['jobtitle']);
$cover = nl2br($_POST['coverletter']);
$subject = "Submitted Job Application";
$headers .= "Content-Type: text/html;charset=utf-8 \r\n";
$headers = "From: " . strip_tags($email) . "\r\n";
$headers .= "Reply-To: ". strip_tags($email) . "\r\n";
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: text/html;charset=utf-8 \r\n";
$msg = "<html><body style='font-family:Arial,sans-serif;'>";
$msg .= "<h2 style='font-weight:bold;border-bottom:1px dotted #ccc;'>Job Application Submitted</h2>\r\n";
$msg .= "<p><strong>Applied for:</strong> ".$jobtitle."</p>\r\n";
$msg .= "<p><strong>Job ID:</strong> ".$jobid."</p>\r\n";
$msg .= "<p><strong>Applicant Name:</strong> ".$name."</p>\r\n";
$msg .= "<p><strong>Email:</strong> ".$email."</p>\r\n";
$msg .= "<p><strong>Phone:</strong> ".$phone."</p>\r\n";
$msg .= "<p><strong>Cover Letter:</strong> ".$cover."</p>\r\n";
$msg .= "<a href='http://domain.com/".$target."'>Download Resume</a>\r\n";
$msg .= "</body></html>";
if(#mail($sendto, $subject, $msg, $headers)) {
echo "";
} else {
echo "false";
}
//Tells you if its all ok
echo "<div id='confirm-app'><p>Thank you for submitting your application. Resumes submitted will be reviewed to determine qualifications that match our hiring needs.<br /><br /> If you are selected you will be contacted by a member of our recruiting team.</p><br /><br /><a href='../careers/job-postings.php'>Return to current opportunities</a></div>";
}
}
else {
//Gives and error if its not
echo "<p style='color: #6D6E71; font-family: Arial,Helvetica,sans-serif; font-size: 13px;'>We accept resumes in <strong>.doc</strong>, <strong>.docx</strong>, <strong>.pdf</strong>, or <strong>.txt</strong> formats, 3MB or less. Please <a href='javascript:history.back(-1);'>go back</a> to upload a file that meets these requirements.<br /><br />If you continue to experience errors, please report them.</p>";
die();
}
}
}
?>
You have to add one more condition near if (!empty ($resume)) that checks your $error array empty if not empty then print the errors else insert or email etc
if (!empty ($resume) && empty($error)){
//do your stuff
}else{
//display errors
}
you are only testing to see if if (!empty ($resume)){ and the requirements for the file before you execute the database insert and email sending. you will have to test for other elements being correct as well. Since you are building an array called $error you can test to see if empty($error) before performing the database insert and email.
Problem: Blank email from PHP web application.
Confirmed: App works in Linux, has various problems in Windows server environment. Blank emails are the last remaining problem.
PHP Version 5.2.6 on the server
I'm a librarian implementing a PHP based web application to help students complete their assignments.I have installed this application before on a Linux based free web host and had no problems.
Email is controlled by two files, email_functions.php and email.php. While email can be sent, all that is sent is a blank email.
My IT department is an ASP only shop, so I can get little to no help there. I also cannot install additional libraries like PHPmail or Swiftmailer.
You can see a functional copy at http://rpc.elm4you.org/ You can also download a copy from Sourceforge from the link there.
Thanks in advance for any insight into this!
email_functions.php
<?php
/**********************************************************
Function: build_multipart_headers
***********************************************************
Purpose:
Creates email headers for a message of type multipart/mime
This will include a plain text part and HTML.
**********************************************************/
function build_multipart_headers($boundary_rand)
{
global $EMAIL_FROM_DISPLAY_NAME, $EMAIL_FROM_ADDRESS, $CALC_PATH, $CALC_TITLE, $SERVER_NAME;
// Using \n instead of \r\n because qmail doubles up the \r and screws everything up!
$crlf = "\n";
$message_date = date("r");
// Construct headers for multipart/mixed MIME email. It will have a plain text and HTML part
$headers = "X-Calc-Name: $CALC_TITLE" . $crlf;
$headers .= "X-Calc-Url: http://{$SERVER_NAME}/{$CALC_PATH}" . $crlf;
$headers .= "MIME-Version: 1.0" . $crlf;
$headers .= "Content-type: multipart/alternative;" . $crlf;
$headers .= " boundary=__$boundary_rand" . $crlf;
$headers .= "From: $EMAIL_FROM_DISPLAY_NAME <$EMAIL_FROM_ADDRESS>" . $crlf;
$headers .= "Sender: $EMAIL_FROM_DISPLAY_NAME <$EMAIL_FROM_ADDRESS>" . $crlf;
$headers .= "Reply-to: $EMAIL_FROM_DISPLAY_NAME <$EMAIL_FROM_ADDRESS>" . $crlf;
$headers .= "Return-Path: $EMAIL_FROM_DISPLAY_NAME <$EMAIL_FROM_ADDRESS>" . $crlf;
$headers .= "Date: $message_date" . $crlf;
$headers .= "Message-Id: $boundary_rand#$SERVER_NAME" . $crlf;
return $headers;
}
/**********************************************************
Function: build_multipart_body
***********************************************************
Purpose:
Builds the email body content to go with the headers from
build_multipart_headers()
**********************************************************/
function build_multipart_body($plain_text_message, $html_message, $boundary_rand)
{
//$crlf = "\r\n";
$crlf = "\n";
$boundary = "__" . $boundary_rand;
// Begin constructing the MIME multipart message
$multipart_message = "This is a multipart message in MIME format." . $crlf . $crlf;
$multipart_message .= "--{$boundary}{$crlf}Content-type: text/plain; charset=\"us-ascii\"{$crlf}Content-Transfer-Encoding: 7bit{$crlf}{$crlf}";
$multipart_message .= $plain_text_message . $crlf . $crlf;
$multipart_message .= "--{$boundary}{$crlf}Content-type: text/html; charset=\"iso-8859-1\"{$crlf}Content-Transfer-Encoding: 7bit{$crlf}{$crlf}";
$multipart_message .= $html_message . $crlf . $crlf;
$multipart_message .= "--{$boundary}--$crlf$crlf";
return $multipart_message;
}
/**********************************************************
Function: build_step_email_body_text
***********************************************************
Purpose:
Returns a plain text version of the email body to be used
for individually sent step reminders
**********************************************************/
function build_step_email_body_text($stepnum, $arr_instructions, $dates, $query_string, $teacher_info ,$name, $class, $project_id)
{
global $CALC_PATH, $CALC_TITLE, $SERVER_NAME;
$step_email_body =<<<BODY
$CALC_TITLE
Step $stepnum: {$arr_instructions["step$stepnum"]["title"]}
Name: $name
Class: $class
BODY;
$step_email_body .= build_text_single_step($stepnum, $arr_instructions, $dates, $query_string, $teacher_info);
$step_email_body .= "\n\n";
$step_email_body .=<<<FOOTER
The $CALC_TITLE offers suggestions, but be sure to check with your teacher to find out the best working schedule for your assignment!
If you would like to stop receiving further reminders for this project, click the link below:
http://$SERVER_NAME/$CALC_PATH/deleteproject.php?proj=$project_id
FOOTER;
// Wrap text to 78 chars per line
// Convert any remaining HTML <br /> to \r\n
// Strip out any remaining HTML tags.
$step_email_body = strip_tags(linebreaks_html2text(wordwrap($step_email_body, 78, "\n")));
return $step_email_body;
}
/**********************************************************
Function: build_step_email_body_html
***********************************************************
Purpose:
Same as above, but with HTML
**********************************************************/
function build_step_email_body_html($stepnum, $arr_instructions, $dates, $query_string, $teacher_info, $name, $class, $project_id)
{
global $CALC_PATH, $CALC_TITLE, $SERVER_NAME;
$styles = build_html_styles();
$step_email_body =<<<BODY
<html>
<head>
<title> $CALC_TITLE </title>
$styles
</head>
<body>
<h1> $CALC_TITLE Schedule </h1>
<strong>Name:</strong> $name <br />
<strong>Class:</strong> $class <br />
BODY;
$step_email_body .= build_html_single_step($stepnum, $arr_instructions, $dates, $query_string, $teacher_info);
$step_email_body .=<<<FOOTER
<p>
The $CALC_TITLE offers suggestions, but be sure to check with your teacher to find out the best working schedule for your assignment!
</p>
<p>
If you would like to stop receiving further reminders for this project,
click this link.
</p>
</body>
</html>
FOOTER;
return $step_email_body;
}
/**********************************************************
Function: build_html_styles
***********************************************************
Purpose:
Just returns a string of <style /> for the HTML message body
**********************************************************/
function build_html_styles()
{
$styles =<<<STYLES
<style type="text/css">
body { font-family: Arial, sans-serif; font-size: 85%; }
h1 { font-size: 120%; }
table { border: none; }
tr { vertical-align: top; }
img { display: none; }
hr { border: 0; }
</style>
STYLES;
return $styles;
}
/**********************************************************
Function: linebreaks_html2text
***********************************************************
Purpose:
Convert <br /> html tags to \n line breaks
**********************************************************/
function linebreaks_html2text($in_string)
{
$out_string = "";
$arr_br = array("<br>", "<br />", "<br/>");
$out_string = str_replace($arr_br, "\n", $in_string);
return $out_string;
}
?>
email.php
<?php
require_once("include/config.php");
require_once("include/instructions.php");
require_once("dbase/dbfunctions.php");
require_once("include/email_functions.php");
ini_set("sendmail_from", "reference#cna-qatar.edu.qa");
ini_set("SMTP", "mail.qatar.net.qa");
// Verify that the email has not already been sent by checking for a cookie
// whose value is generated each time the form is loaded freshly.
if (!(isset($_COOKIE['rpc_transid']) && $_COOKIE['rpc_transid'] == $_POST['transid']))
{
// Setup some preliminary variables for email.
// The scanning of $_POST['email']already took place when this file was included...
$to = $_POST['email'];
$subject = $EMAIL_SUBJECT;
$boundary_rand = md5(rand());
$mail_type = "";
switch ($_POST['reminder-type'])
{
case "progressive":
$arr_dbase_dates = array();
$conn = rpc_connect();
if (!$conn)
{
$mail_success = FALSE;
$mail_status_message = "Could not register address!";
break;
}
// Sanitize all the data that will be inserted into table...
// We need to remove "CONTENT-TYPE:" from name/class to defang them.
// Additionall, we can't allow any line-breaks in those fields to avoid
// hacks to email headers.
$ins_name = mysql_real_escape_string($name);
$ins_name = eregi_replace("CONTENT-TYPE", "...Content_Type...", $ins_name);
$ins_name = str_replace("\n", "", $ins_name);
$ins_class = mysql_real_escape_string($class);
$ins_class = eregi_replace("CONTENT-TYPE", "...Content_Type...", $ins_class);
$ins_class = str_replace("\n", "", $ins_class);
$ins_email = mysql_real_escape_string($email);
$ins_teacher_info = $teacher_info ? "YES" : "NO";
switch ($format)
{
case "Slides": $ins_format = "SLIDES"; break;
case "Video": $ins_format = "VIDEO"; break;
case "Essay":
default: $ins_format = "ESSAY"; break;
}
// The transid from the previous form will be used as a project identifier
// Steps will be grouped by project identifier.
$ins_project_id = mysql_real_escape_string($_POST['transid'] . md5(rand()));
$arr_dbase_dates = dbase_dates($dates);
$arr_past_dates = array();
// Iterate over the dates array and build a SQL statement for each one.
$insert_success = TRUE;
//
$min_reminder_date = date("Ymd", mktime(0,0,0,date("m"),date("d")+$EMAIL_REMINDER_DAYS_AHEAD,date("Y")));
for ($date_index = 0; $date_index < sizeof($arr_dbase_dates); $date_index++)
{
// Make sure we're using the right keys...
$ins_date_index = $date_index + 1;
// The insert will only happen if the date of the event is in the future.
// For dates today and earlier, no insert.
// For dates today or after the reminder deadline, we'll send the email immediately after the inserts.
if ($arr_dbase_dates[$date_index] > (int)$min_reminder_date)
{
$qry =<<<QRY
INSERT INTO email_queue
(
NOTIFICATION_ID,
PROJECT_ID,
EMAIL,
NAME,
CLASS,
FORMAT,
TEACHER_INFO,
STEP,
MESSAGE_DATE
)
VALUES (
NULL,
'$ins_project_id',
'$ins_email',
'$ins_name',
'$ins_class',
'$ins_format',
'$ins_teacher_info',
$ins_date_index, /*step number*/
{$arr_dbase_dates[$date_index]} /* Date in the integer format yyyymmdd */
)
QRY;
// Attempt to do the insert...
$result = mysql_query($qry);
// If even one insert fails, bail out.
if (!$result)
{
$mail_success = FALSE;
$mail_status_message = "Could not register address!";
break;
}
}
// For dates today or earlier, store the steps=>dates in an array so the mails can
// be sent immediately.
else
{
$arr_past_dates[$ins_date_index] = $arr_dbase_dates[$date_index];
}
}
// Close the connection resources.
mysql_close($conn);
// SEND OUT THE EMAILS THAT HAVE TO GO IMMEDIATELY...
// This should only be step 1, but who knows...
//var_dump($arr_past_dates);
for ($stepnum=1; $stepnum<=sizeof($arr_past_dates); $stepnum++)
{
$email_teacher_info = ($teacher_info && $EMAIL_TEACHER_REMINDERS) ? TRUE : FALSE;
$boundary = md5(rand());
$plain_text_body = build_step_email_body_text($stepnum, $arr_instructions, $dates, $query_string, $email_teacher_info ,$name, $class, $ins_project_id);
$html_body = build_step_email_body_html($stepnum, $arr_instructions, $dates, $query_string, $email_teacher_info ,$name, $class, $ins_project_id);
$multipart_headers = build_multipart_headers($boundary);
$multipart_body = build_multipart_body($plain_text_body, $html_body, $boundary);
mail($to, $subject . ": Step " . $stepnum, $multipart_body, $multipart_headers, "-fresearch#rpc.elm4you.org");
}
// Set appropriate flags and messages
$mail_success = TRUE;
$mail_status_message = "Email address registered!";
$mail_type = "progressive";
set_mail_success_cookie();
break;
// Default to a single email message.
case "single":
default:
// We don't want to send images in the message, so strip them out of the existing structure.
// This big ugly regex strips the whole table cell containing the image out of the table.
// Must find a better solution...
//$email_table_html = eregi_replace("<td class=\"stepImageContainer\" width=\"161px\">[\s\r\n\t]*<img class=\"stepImage\" src=\"images/[_a-zA-Z0-9]*\.gif\" alt=\"Step [1-9]{1} logo\" />[\s\r\n\t]*</td>", "\n", $table_html);
// Show more descriptive text based on the value of $format
switch ($format)
{
case "Video": $format_display = "Video"; break;
case "Slides": $format_display = "Presentation with electronic slides"; break;
case "Essay":
default:
$format_display = "Essay"; break;
}
$days = (int)$days;
$html_message = "";
$styles = build_html_styles();
$html_message =<<<HTMLMESSAGE
<html>
<head>
<title> $CALC_TITLE </title>
$styles
</head>
<body>
<h1> $CALC_TITLE Schedule </h1>
<strong>Name:</strong> $name <br />
<strong>Class:</strong> $class <br />
<strong>Email:</strong> $email <br />
<strong>Assignment type:</strong> $format_display <br /><br />
<strong>Starting on:</strong> $date1 <br />
<strong>Assignment due:</strong> $date2 <br />
<strong>You have $days days to finish.</strong><br />
<hr />
$email_table_html
</body>
</html>
HTMLMESSAGE;
// Create the plain text version of the message...
$plain_text_message = strip_tags(linebreaks_html2text(build_text_all_steps($arr_instructions, $dates, $query_string, $teacher_info)));
// Add the title, since it doesn't get built in by build_text_all_steps...
$plain_text_message = $CALC_TITLE . " Schedule\n\n" . $plain_text_message;
$plain_text_message = wordwrap($plain_text_message, 78, "\n");
$multipart_headers = build_multipart_headers($boundary_rand);
$multipart_message = build_multipart_body($plain_text_message, $html_message, $boundary_rand);
$mail_success = FALSE;
if (mail($to, $subject, $multipart_message, $multipart_headers, "-reference#cna-qatar.edu.qa"))
{
$mail_success = TRUE;
$mail_status_message = "Email sent!";
$mail_type = "single";
set_mail_success_cookie();
}
else
{
$mail_success = FALSE;
$mail_status_message = "Could not send email!";
}
break;
}
}
function set_mail_success_cookie()
{
// Prevent the mail from being resent on page reload. Set a timestamp cookie.
// Expires in 24 hours.
setcookie("rpc_transid", $_POST['transid'], time() + 86400);
}
?>
Instead of sending it, build the email and display all of the vars used in the mail call to the screen and comment out the mail call. That will confirm that the vars are being properly constructed.
Then start using the mail function again, if you have access to mail logs that would help as well, as it may give you more information. Also, take a look at the headers on the email you receive as that also may show you that a header or 2 is messed up.
Also try setting $crlf = "\r\n";
brett, if you think it's the headers, i'd try the bare minimum and get it to work. once it works, start adding headers until you get the error. then let us know what the problem is.