45 $action =& $params[
'action'];
47 $app =& Dataface_Application::getInstance();
48 $query =& $app->getQuery();
50 $query[
'-limit'] = 9999999;
61 import(
'Dataface/Ontology.php');
62 Dataface_Ontology::registerType(
'Person',
'Dataface/Ontology/Person.php',
'Dataface_Ontology_Person');
63 $ontology =& Dataface_Ontology::newOntology(
'Person', $query[
'-table']);
64 $action[
'email_column'] = $ontology->getFieldname(
'email');
68 if ( !@$action[
'email_column'] )
return PEAR::raiseError(
"No email column specified in actions.ini", DATAFACE_E_WARNING);
69 if ( !@$action[
'email_table'] )
return PEAR::raiseError(
"No email table specified in actions.ini", DATAFACE_E_WARNING);
72 $this->emailColumn = $col = $action[
'email_column'];
73 if ( strpos($col,
'`') !==
false )
return PEAR::raiseError(
"Invalid email column name: '$col'", DATAFACE_E_WARNING);
75 $this->emailTable = $table =
'xataface__email_newsletters';
76 if ( strpos($table,
'`') !==
false )
return PEAR::raiseError(
"Invalid email table name: '$table'", DATAFACE_E_WARNING);
78 $this->joinTable = $join_table =
'xataface__email_log';
80 $this->recipientsTable = $query[
'-table'];
84 if ( !Dataface_Table::tableExists($table,
false) || !Dataface_Table::tableExists($join_table,
false) ){
88 $emailTableObj =& Dataface_Table::loadTable($this->emailTable);
89 $contentField =& $emailTableObj->getField(
'content');
90 $contentField[
'widget'][
'atts'][
'rows'] = 20;
91 $contentField[
'widget'][
'atts'][
'cols'] = 60;
92 $contentField[
'widget'][
'label'] =
'Message body';
93 $contentField[
'widget'][
'description'] =
'Please enter your message content in plain text.';
94 $contentField[
'widget'][
'type'] =
'ckeditor';
95 $contentField[
'widget'][
'ckeditor'][
'toolbar'] =
'XBasic';
96 $contentField[
'widget'][
'ckeditor'][
'extraPlugins'] =
'SchemaBrowser';
98 Dataface_JavascriptTool::getInstance()->import(
'xataface/modules/ckeditor/plugins/SchemaBrowser.js');
102 $subjectField =& $emailTableObj->getField(
'subject');
103 $subjectField[
'widget'][
'atts'][
'size'] = 60;
105 $fromField =& $emailTableObj->getField(
'from');
106 $fromField[
'widget'][
'atts'][
'size'] = 60;
107 $fromField[
'widget'][
'description'] =
'e.g. Web Lite Solutions <info@weblite.ca>';
110 $ccField =& $emailTableObj->getField(
'cc');
111 $ccField[
'widget'][
'atts'][
'size'] = 60;
112 $ccField[
'widget'][
'label'] =
'Bcc';
113 $ccField[
'widget'][
'description'] =
'e.g. youremail@example.com. Attention: Copies of every email sent in this batch will be sent to this bcc address if added. This may result in quite a large number of emails being sent to this single address. Use this feature carefully.';
115 $ignoreBlacklistField =& $emailTableObj->getField(
'ignore_blacklist');
116 $ignoreBlacklistField[
'widget'][
'type'] =
'checkbox';
117 $ignoreBlacklistField[
'widget'][
'description'] =
'The black list is a list of email addresses that have opted out of receiving email. I.e. Users on the black list do not want to receive email. Check this box if you want to send to blacklisted addresses despite their wish to be left alone.';
120 $templateField =& $emailTableObj->getField(
'template_id');
121 $templateField[
'widget'][
'filters'][
'table_name'] = $query[
'-table'];
123 $form = df_create_new_record_form($table);
126 $form->addElement(
'hidden',
'-action');
127 $form->addElement(
'hidden',
'-table');
128 $form->setDefaults(array(
'-action'=>$query[
'-action'],
'-table'=>$query[
'-table']));
129 $form->insertElementBefore($form->createElement(
'checkbox',
'send_now',
'',
'Send now (leave this box unchecked if you wish these emails to be queued for later sending by the daily cron job. Recommended to leave this box unchecked for large found sets (>100 records).)'),
'submit_new_newsletters_record');
130 $form->addElement(
'hidden',
'-query_string');
131 $form->setDefaults(array(
'-query_string'=>base64_encode(serialize($query))));
132 $form->setSubmitLabel(
"Add to Mail Queue");
133 if ( @$app->_conf[
'from_email'] ){
134 $form->setDefaults(array(
'from'=>$app->_conf[
'from_email']));
139 if ( $form->validate() ){
140 $res = $form->process(array(&$form,
'save'),
true);
141 if ( PEAR::isError($res) )
return $res;
144 $vals = $form->exportValues();
145 $q2 = unserialize(base64_decode($vals[
'-query_string']));
146 $qb =
new Dataface_QueryBuilder($query[
'-table'], $q2);
147 $recTable = Dataface_Table::loadTable($query[
'-table']);
149 $tkeys = $recTable->keys();
151 foreach ($tkeys as $key=>$val){
155 $sql =
"insert ignore into `$join_table` (recipient_email,messageid,date_created,primary_key) select distinct (`".$col.
"`) `".$col.
"`, '".$form->_record->val(
'id').
"' as messageid, now() as date_created, `".$keyCol.
"` as primary_key ".$qb->_from().
" ".$qb->_secure($qb->_where());
163 $q2[
'-action'] =
'email_progress';
164 $q2[
'-job-id'] = $jobId;
165 unset($q2[
'-limit']);
166 header(
'Location: '.$app->url($q2).
'&--msg='.urlencode(
"The message has been queued for delivery"));
172 $addresses = array();
177 $context[
'email_form'] = ob_get_contents();
178 $profileTable =& Dataface_Table::loadTable($query[
'-table']);
180 $context[
'fields'] = array_keys($profileTable->fields(
false,
true,
true));
181 $modurl = DATAFACE_SITE_URL.
'/modules/Email';
182 if ( realpath(__FILE__) == realpath(DATAFACE_PATH.
'/modules/Email/email.php') ){
183 $modurl = DATAFACE_URL.
'/modules/Email';
186 $context[
'EMAIL_ROOT'] = $modurl;
189 df_register_skin(
'email', dirname(__FILE__).
'/../templates');
190 df_display($context,
'email_form.html');
196 $app = Dataface_Application::getInstance();
197 $method =
'Email__isBlackListed';
198 $del = $app->getDelegate();
199 if ( isset($del) and method_exists($del, $method) ){
200 $res = $del->$method($email);
201 if ( isset($res) and is_bool($res) ){
205 if ( !Dataface_Table::tableExists(
'dataface__email_blacklist') ) $this->
createEmailTables(null,null);
206 $res = mysql_query(
"select email from dataface__email_blacklist where email='".addslashes($email).
"' limit 1", df_db());
207 if ( !$res ) trigger_error(mysql_error(df_db()), E_USER_ERROR);
208 list($num) = mysql_fetch_row($res);
209 @mysql_free_result($res);
214 if ( !Dataface_Table::tableExists(
'dataface__email_blacklist') ) $this->
createEmailTables(null,null);
215 if ( !is_array($emails) ) $emails = array($emails);
216 $res = mysql_query(
"select email from dataface__email_blacklist where email in ('".implode(
"','", array_map(
'addslashes',$emails)).
"')", df_db());
218 if (!$res ) trigger_error(mysql_error(df_db()), E_USER_ERROR);
219 while ($row = mysql_fetch_row($res) ) $out[] = $row[0];
220 @mysql_free_result($res);
233 $app =& Dataface_Application::getInstance();
236 if ( isset($tablename) ){
237 $sql[] =
"create table if not exists `{$tablename}` (
238 `id` int(11) not null auto_increment,
239 `template_id` int(11) default null,
240 `subject` varchar(128) not null,
241 `cc` varchar(128) default null,
242 `from` varchar(128) default null,
244 `ignore_blacklist` tinyint(1) default 0,
245 posted_by varchar(255) default null,
246 primary key (`id`)) DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";
248 if ( isset($join_table) ){
249 $sql[] =
"create table if not exists `{$join_table}` (
250 `messageid` int(11) not null,
251 `recipient_email` varchar(128) not null,
252 `sent` tinyint(1) default 0,
253 `date_created` datetime default null,
254 `date_sent` datetime default null,
255 `success` tinyint(1) default null,
256 `comment` varchar(255) default null,
257 primary key (`messageid`,`recipient_email`))";
261 $sql[] =
"create table if not exists `dataface__email_blacklist` (
262 `email` varchar(255) not null primary key
265 foreach ($sql as $q ){
266 $res = mysql_query($q, $app->db());
267 if ( !$res ) trigger_error(mysql_error($app->db()), E_USER_ERROR);
273 df_q(
"alter table `{$join_table}` add `comment` varchar(255) after `success`");
274 }
catch (Exception $ex){}
282 private $_tempRecipientRecord;
289 return $this->_tempRecipientRecord->display($matches[1]);
294 $res = df_q(
"select file from xataface__email_attachments where email_id='".addslashes($emailId).
"'");
298 $field =& Dataface_Table::loadTable(
'xataface__email_attachments')->getField(
'file');
299 $savepath = $field[
'savepath'];
300 if ( !$savepath || !is_dir($savepath) ){
303 $ajaxUploadMod = Dataface_ModuleTool::getInstance()->loadModule(
'modules_ajax_upload');
304 if ( !$ajaxUploadMod || PEAR::isError($ajaxUploadMod) ){
305 error_log(
"Could not send attachments because the ajax_upload module is not loaded.");
309 while ($row = mysql_fetch_row($res) ){
311 $fileName = basename($row[0]);
312 $filePath = $savepath . DIRECTORY_SEPARATOR. $fileName;
313 if ( !file_exists($filePath) ){
314 error_log(
"Failed to attach file $filePath because it could not be found.");
317 $contents = file_get_contents($filePath);
318 $mimetype = $ajaxUploadMod->getMimeType($filePath);
319 $attachment = MIME::message($contents, $mimetype, $fileName,
'ISO-8859-1',
'base64',
'attachment');
320 $out[] = $attachment;
322 @mysql_free_result($res);
336 require_once dirname(__FILE__).
'/../lib/XPM/MIME.php';
341 $app =& Dataface_Application::getInstance();
342 $conf =& $app->_conf;
346 $decorateEmailContextFunc =
'decorateEmailContext';
347 $recipientsTableObj = Dataface_Table::loadTable($this->recipientsTable);
348 $recipientsTableDelegate =& $recipientsTableObj->getDelegate();
349 $appDelegate =& $app->getDelegate();
350 $tableDecorateEmailContextFuncExists = (isset($recipientsTableDelegate) and method_exists($recipientsTableDelegate, $decorateEmailContextFunc) );
352 $onSuccessFunc =
'Email__onSuccess';
353 $onSuccessAppFuncExists = (isset($appDelegate) and method_exists($appDelegate, $onSuccessFunc));
354 $onSuccessTableFuncExists = (isset($recipientsTableDelegate) and method_exists($recipientsTableDelegate, $onSuccessFunc) );
356 $onFailFunc =
'Email__onFail';
357 $onFailAppFuncExists = (isset($appDelegate) and method_exists($appDelegate, $onFailFunc));
358 $onFailTableFuncExists = (isset($recipientsTableDelegate) and method_exists($recipientsTableDelegate, $onFailFunc) );
361 $appDecorateEmailContextFuncExists = (isset($appDelegate) and method_exists($appDelegate, $decorateEmailContextFunc));
362 $optOutMessageFunc =
'getEmailOptOutMessage';
363 $appOptOutMessageFuncExists = (isset($appDelegate) and method_exists($appDelegate, $optOutMessageFunc));
364 $tableOptOutMessageFuncExists = (isset($recipientsTableDelegate) and method_exists($recipientsTableDelegate, $optOutMessageFunc));
366 $defaultEmailOptOutHtml= null;
367 $defaultEmailOptOutText = null;
368 if ( @$conf[
'modules_Email'] ){
369 $emailConf =& $conf[
'modules_Email'];
370 if ( @$emailConf[
'opt_out_html'] ){
371 $defaultEmailOptOutHtml = $emailConf[
'opt_out_html'];
373 if ( @$emailConf[
'opt_out_text'] ){
374 $defaultEmailOptOutText = $emailConf[
'opt_out_text'];
380 if ( @$conf[
'_mail'][
'func'] ) $mail_func = $conf[
'_mail'][
'func'];
381 else $mail_func =
'mail';
383 $emailTableObj =& Dataface_Table::loadTable($this->emailTable);
385 $recTable = Dataface_Table::loadTable($this->recipientsTable);
387 $tkeys = $recTable->keys();
389 foreach ($tkeys as $key=>$val){
394 $emailTableObj->addRelationship(
'recipients',
395 array(
'__sql__' =>
'select * from `'.$this->recipientsTable.
'` r inner join `'.$this->joinTable.
'` j on (`r`.`'.$this->emailColumn.
'` = j.recipient_email and `r`.`'.$keyCol.
'`= j.primary_key) inner join `'.$this->emailTable.
'` e on e.id = j.messageid where e.id=\''.addslashes($emailId).
'\'')
399 $email = df_get_record($this->emailTable, array(
'id'=>$emailId));
400 if ( !$email)
return PEAR::raiseError(
"Failed to send email because no message with id {$emailId} could be found.", DATAFACE_E_ERROR);
402 $jres = df_q(
"select job_id from xataface__email_jobs where email_id='".addslashes($emailId).
"'");
403 if ( mysql_num_rows($jres) == 0 ){
404 throw new Exception(
"Could not find job associated with email.");
406 list($jobId) = mysql_fetch_row($jres);
407 @mysql_free_result($jres);
410 if ( $email->val(
'template_id') ){
411 $template = df_get_record(
'xataface__email_templates', array(
'template_id'=>
'='.$email->val(
'template_id')));
415 $totalRecipients = $email->numRelatedRecords(
'recipients');
416 $res = df_q(
"update xataface__email_jobs set total_emails='".addslashes($totalRecipients).
"' where email_id='".addslashes($emailId).
"'");
419 $recipients = $email->getRelatedRecordObjects(
'recipients', 0,500,
'sent=0');
420 foreach ($recipients as $recipient ){
424 $jres = df_q(
"select cancelled from xataface__email_jobs where job_id='".addslashes($jobId).
"'");
425 if ( mysql_num_rows($jres) == 0 ){
426 throw new Exception(
"Could not find job record. Must have been cancelled.");
428 list($cancelled) = mysql_fetch_row($jres);
429 @mysql_free_result($res);
436 $recipientObj = $recipient->toRecord($this->recipientsTable);
440 if ( $appDecorateEmailContextFuncExists ){
441 $appDelegate->$decorateEmailContextFunc($email, $template, $recipientObj);
444 if ( $tableDecorateEmailContextFuncExists ){
445 $recipientsTableDelegate->$decorateEmailContextFunc($email, $template, $recipientObj);
455 $this->_tempRecipientRecord = $recipientObj;
456 $content = preg_replace_callback(
'/\{\$([^\}]+)\}/', array($this,
'_replaceFieldCallback'), $recipient->strval(
'content'));
459 df_q(
"update xataface__email_log set uniqid='".addslashes($uniqid).
"' where log_id='".addslashes($recipient->val(
'log_id')).
"'");
462 $opt_out_url = df_absolute_url(DATAFACE_SITE_HREF.
'?-action=email_opt_out&email='.urlencode($uniqid));
464 $opt_out_html = <<<END
466 <p>If you don
't want to receive email updates from us, you can opt out of our mailing list by clicking <a href="$opt_out_url">here</a> .</p>
469 if ( $defaultEmailOptOutHtml ){
470 $opt_out_html = str_replace('$url
', $opt_out_url, $defaultEmailOptOutHtml);
473 if ( $defaultEmailOptOutText ){
474 $opt_out_text = str_replace('$url
', $opt_out_url, $defaultEmailOptOutText);
479 $opt_out_text = <<<END
481 ------------------------------------------------------------------
482 If you don't want to receive email updates from us, you can opt out of our mailing list by going to $opt_out_url .
486 if ( $defaultEmailOptOutText ){
487 $opt_out_text = str_replace(
'$url', $opt_out_url, $defaultEmailOptOutText);
491 $opt_out_params = array();
492 if ( $appOptOutMessageFuncExists ){
493 $opt_out_paramsa = $appDelegate->$optOutMessageFunc($recipientObj, $opt_out_url);
494 if ( is_array($opt_out_paramsa) ){
495 $opt_out_params = $opt_out_paramsa;
498 if ( $tableOptOutMessageFuncExists ){
499 $opt_out_paramst = $recipientsTableDelegate->$optOutMessageFunc($recipientObj, $opt_out_url);
500 if ( is_array($opt_out_paramst) ){
501 $opt_out_params = array_merge($opt_out_params, $opt_out_paramst);
505 if ( @$opt_out_params[
'html'] ){
506 $opt_out_html = $opt_out_params[
'html'];
509 if ( @$opt_out_params[
'text'] ){
510 $opt_out_text = $opt_out_params[
'text'];
513 $html_content = $content . $opt_out_html;
515 $content .= $opt_out_text;
519 if ( trim($email->strval(
'cc')) ){
520 $headers[] =
"Bcc: ".$email->strval(
'cc');
523 if ( trim($email->strval(
'from')) ){
524 $headers[] =
"From: ".$email->strval(
'from');
525 $headers[] =
"Reply-to: ".$email->strval(
'from');
528 if ( @$app->_conf[
'mail_host'] ){
529 $headers[] =
'Message-ID: <' . md5(uniqid(time())) .
'@'.$app->_conf[
'mail_host'].
'>';
533 $joinRecord = $recipient->toRecord($this->joinTable);
535 if ( !trim($recipient->val(
'recipient_email')) ){
536 $joinRecord->setValue(
'success',0);
537 $joinRecord->setValue(
'sent',1);
538 $joinRecord->setValue(
'comment',
'Blank address');
541 if( $onFailAppFuncExists ){
542 $appDelegate->$onFailFunc($recipientObj, $email);
545 if ( $onFailTableFuncExists ){
546 $recipientsTableDelegate->$decorateEmailContextFunc($recipientObj, $email);
559 $id = MIME::unique();
562 $text = MIME::message(htmlspecialchars_decode(strip_tags(preg_replace(array(
'/<br[^>]*>/i',
'/<div[^>]*>/i',
'/<p[^>]*>/i',
'/<table[^>]*>/i'), array(
"\r\n",
"\r\n",
"\r\n",
"\r\n"),$content))),
'text/plain', null, $app->_conf[
'oe']);
564 $html = MIME::message($html_content,
'text/html', null, $app->_conf[
'oe']);
578 $le = defined(
'PHP_EOL') ? PHP_EOL :
"\n";
581 if ( !$email->val(
'ignore_blacklist') and $this->
isBlackListed($recipient->val(
'recipient_email')) ){
582 error_log(
"\nEmail address '".$recipient->val(
'recipient_email').
"' is black listed so we do not send email to this address...");
583 $joinRecord->setValue(
'success',0);
584 $joinRecord->setValue(
'sent',1);
585 $joinRecord->setValue(
'comment',
'Black listed');
586 df_q(
"update xataface__email_jobs set sent_emails=sent_emails+1, blacklisted_emails=blacklisted_emails+1 where email_id='".addslashes($emailId).
"'");
588 if( $onFailAppFuncExists ){
589 $appDelegate->$onFailFunc($recipientObj, $email);
592 if ( $onFailTableFuncExists ){
593 $recipientsTableDelegate->$onFailFunc($recipientObj, $email);
598 else if ( $mail_func($recipient->strval(
'recipient_email'), $email->strval(
'subject'),
$mess[
'content'], implode($le, $headers).$le.$mess[
'header']) ){
599 $joinRecord->setValue(
'success',1);
600 $joinRecord->setValue(
'sent',1);
601 df_q(
"update xataface__email_jobs set sent_emails=sent_emails+1, successful_emails=successful_emails+1 where email_id='".addslashes($emailId).
"'");
606 if( $onSuccessAppFuncExists ){
607 $appDelegate->$onSuccessFunc($recipientObj, $email);
610 if ( $onSuccessTableFuncExists ){
611 $recipientsTableDelegate->$onSuccessFunc($recipientObj, $email);
614 $joinRecord->setValue(
'success',0);
615 $joinRecord->setValue(
'sent',1);
616 $this->messages[] =
"Failed to send email to ".$email->val(
'recipient_email');
617 error_log(
"Failed to send email to ".$email->val(
'recipient_email'));
618 df_q(
"update xataface__email_jobs set sent_emails=sent_emails+1, failed_emails=failed_emails+1 where email_id='".addslashes($emailId).
"'");
622 if( $onSuccessAppFuncExists ){
623 $appDelegate->$onSuccessFunc($recipientObj, $email);
626 if ( $onSuccessTableFuncExists ){
627 $recipientsTableDelegate->$onSuccessFunc($recipientObj, $email);
631 $joinRecord->setValue(
'date_sent',date(
'Y-m-d H:i:s'));
644 $res = df_q(
"select count(*) from `$joinTable` where messageid='".addslashes($emailId).
"'");
645 list($count) = mysql_fetch_row($res);
649 "insert into xataface__email_jobs (
660 '".addslashes($emailId).
"',
666 '".addslashes($count).
"',
669 return mysql_insert_id(df_db());