How avoid form resubmission on page refresh? - wordpress

I'm doing a simple feedback form on WordPress. And like many people, I encountered the problem of resending the form when refresh the browser page. I know that this problem is solved through the use of the pattern "Post/Redirect/Get". Which says that you need after processing the data $_POST, request the same page using the $_GET method. But I can not use the result of the wp_mail function for redirection.
if(wp_mail($email, $email_subject, $email_message, $headers)) {
add_action('send_headers', 'simplemail_add_header');
}
function simplemail_add_header() {
header("Location: http://google.com");
}
It just does not work.
UPD
Here is my full code:
class SimpleMailer {
private $nonce = 'feedback_nonce';
public function __construct() {
add_action('phpmailer_init', array($this, 'simplemail_smtp_config'));
add_shortcode('simplemail', array($this, 'simplemail_sendmail'));
}
public function simplemail_smtp_config($phpmailer) {
$phpmailer->isSMTP();
$phpmailer->SetFrom("admin#mail.com");
$phpmailer->addAddress("sender#mail.com");
$phpmailer->Host = "ssl://smtp.mail.com";
$phpmailer->SMTPAuth = true;
$phpmailer->Port = 465;
$phpmailer->Username = "admin#mail.com";
$phpmailer->Password = "password";
$phpmailer->SMTPSecure = 'ssl';
}
public function simplemail_sendmail($shortcode_attributes) {
global $wp;
$result = "";
$error = false;
$data = array();
$required_fields = array("feedback_name", "feedback_email", "feedback_message");
$atts = shortcode_atts(array(
"email" => get_bloginfo('admin_email'),
"form_action" => home_url($wp->request),
"form_cls" => '',
"mail_subject" => "Feedback message from",
"pls_name" => 'Your Name',
"pls_email" => 'Your E-mail Address',
"pls_message" => 'Your Message',
"label_submit" => 'Submit',
"error_common" => 'There was some mistake. Try again, a little later.',
"error_empty" => 'Please fill in all the required fields.',
"error_noemail" => 'Please enter a valid e-mail address.',
"success" => 'Thanks for your e-mail! We\'ll get back to you as soon as we can.'
), $shortcode_attributes);
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
foreach ($_POST as $field => $value) {
if (get_magic_quotes_gpc()) {
$value = stripslashes($value);
}
$data[$field] = trim(strip_tags($value));
}
foreach ($required_fields as $required_field) {
$value = trim($data[$required_field]);
if(empty($value)) {
$error = true;
$result = $atts['error_empty'];
}
}
if(!empty($data["feedback_blank"])) {
$error = true;
$result = $atts['error_empty'];
}
if(!is_email($data['feedback_email'])) {
$error = true;
$result = $atts['error_noemail'];
}
if(!wp_verify_nonce($data[$this->nonce],'simplemail_nonce')) {
$error = true;
$result = $atts['error_common'];
}
if ($error == false) {
$email_subject = $atts['mail_subject']." [".get_bloginfo('name')."]";
$email_message = $data['feedback_message']."\n\n";
$headers = "From: ".$data['feedback_name']." <".$data['feedback_email'].">\n";
$headers .= "Content-Type: text/plain; charset=UTF-8\n";
$headers .= "Content-Transfer-Encoding: 8bit\n";
if(wp_mail(null, $email_subject, $email_message, $headers)) {
add_action('send_headers', array($this, 'simplemail_add_header', 10, $atts['form_action']));
// wp_redirect( 'http://google.com', 301 );
// exit;
}
$data = array();
$result = $atts['success'];
}
}
return $this->simplemail_draw_form($atts, $data, $result);
}
public function simplemail_draw_form($atts, $data, $result) {
$output = "<form action='".$atts['form_action']."' class='".$atts['form_cls']."' method='post'>".PHP_EOL.
"<input type='text' name='feedback_name' placeholder='".$atts['pls_name']."' value='".#$data['feedback_name']."'>".PHP_EOL.
"<input type='text' name='feedback_blank'>".PHP_EOL.
"<input type='email' name='feedback_email' placeholder='".$atts['pls_email']."' value='".#$data['feedback_email']."'>".PHP_EOL.
"<textarea name='feedback_message' cols='30' rows='10' placeholder='".$atts['pls_message']."'>".#$data['feedback_message']."</textarea>".PHP_EOL;
$output .= wp_nonce_field('simplemail_nonce', $this->nonce, false);
$output .= ($result != "") ? '<div class="feedback-info">'.$result.'</div>' : '<div class="feedback-info"></div>';
$output .= "<button type='submit'>".$atts['label_submit']."</button>".PHP_EOL."</form>";
return $output;
}
public function simplemail_add_header($location) {
header("Location: {$location}");
}
}
$simplemailer = new SimpleMailer();
And I get this error if I uncomment the redirect. And nothing at all, if you try to use simplemail_add_header
Warning: Cannot modify header information - headers already sent by (output started at /var/www/vhosts/12/151953/webspace/httpdocs/skgk.kz/wp-includes/nav-menu-template.php:256) in /var/www/vhosts/12/151953/webspace/httpdocs/skgk.kz/wp-includes/pluggable.php on line 1216

I think you need to add a token in a hidden textbox and within the form to be submitted, the text in this text box will be the token and it need to change on every page load. Save this token in a session variable. Then add a condition at the top of the page to validate the token, if the token is different kill the loading process or display a message or whatever you feel is needed. You may also add token longevity to allow submitting of a page within certain amount of time.
The token creation, token validation and token longevity are normally a function somewhere that is called as needed and form different pages.
Edit:
If all you want is redirect the user to a different page then do:
if(mail succeed) {
header('location: thankyou.html');
}

Related

Sending an email from WordPress through REST API with an Axios call

I'm using this snippet to send an email from WordPress through the REST API.
My Vue-based front end is posting form data to WordPress using an Axios put() call:
sendEmail () {
const formData = new FormData()
formData.append('contact_name', this.contactName)
formData.append('contact_email', this.contactEmail)
formData.append('contact_message', this.contactMessage)
this.$axios.$put(`${this.baseUrl}/wp-json/contact/v1/send`, formData)
.then((res) => {
this.success = true
})
.catch((err) => {
this.$toast.error(err.response)
})
}
I suppose the code above is correct, and that the issue lies on the WordPress side:
Functions.php:
function sendContactMail(WP_REST_Request $request) {
$response = array(
'status' => 304,
'message' => 'There was an error sending the form.'
);
$parameters = $request->get_json_params();
if (count($_POST) > 0) {
$parameters = $_POST;
}
$siteName = wp_strip_all_tags(trim(get_option('blogname')));
$contactName = wp_strip_all_tags(trim($parameters['contact_name']));
$contactEmail = wp_strip_all_tags(trim($parameters['contact_email']));
$contactMessage = wp_strip_all_tags(trim($parameters['contact_message']));
if (!empty($contactName) && !empty($contactEmail) && !empty($contactMessage)) {
$subject = "(New message sent from site $siteName) $contactName <$contactEmail>";
$body = "<h3>$subject</h3><br/>";
$body .= "<p><b>Name:</b> $contactName</p>";
$body .= "<p><b>Email:</b> $contactEmail</p>";
$body .= "<p><b>Message:</b> $contactMessage</p>";
if (send_email($contactEmail, $contactName, $body)) {
$response['status'] = 200;
$response['message'] = 'Form sent successfully.';
}
}
return json_decode(json_encode($response));
exit();
}
add_action('rest_api_init', function () {
register_rest_route( 'contact/v1', '/send', array(
'methods' => 'POST',
'callback' => 'sendContactMail'
));
});
However, I have no idea how to troubleshoot the issue, because whichever problem is occuring here doesn't produce any input that I can see (I don't have access to server PHP log unfortunately).
Any idea about what's wrong in my code or how I could troubleshoot it?
Just in case below is the code of the send_email() function as well:
function send_email($form_email, $form_name, $form_message) {
$email_subject = 'Message from '. get_bloginfo('name') . ' - ' . $form_email;
$headers = "From: '" . $form_name . "' <" . $form_email . "> \r\n";
$headers .= "Reply-To: ". strip_tags($form_email) . "\r\n";
$headers .= "Content-Type:text/html;charset=utf-8";
$email_message = '<html><body>';
$email_message .= "<table>";
$email_message .= "<tr><td>NAME: </td><td>" . $form_name . "</td></tr>";
$email_message .= "<tr><td>MESSAGE: </td><td>" . $form_message . "</td></tr>";
$email_message .= "</table>";
$email_message .= "</body></html>";
$email_message = nl2br($email_message);
wp_mail('me#gmail.com', $email_subject, $email_message, $headers);
}
the problem was in your axios put request. your form was not submitted correctly to the server due to missing header:
this.$axios.$put(`${this.baseUrl}/wp-json/contact/v1/send`, formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
.then((res) => {
this.success = true
})
.catch((err) => {
this.$toast.error(err.response)
})
i debugged it via more parameters in your wordpress function request response. i saw that all the form parameters where missing, so i investigated on that end and viola: its working now.

Drupal 7: How to send HTML Email

Could someone tell me what i am missing to send an HTML email using Drupal's function? Here is my call:
try{
drupal_mail('my_module', 'forgot', $node->field_email_address['und'][0]['value'], language_default(), array('reset_key' => $key),'do-not-reply#myemailaddress.com');
}catch(Exception $e){
print_r($e->getMessage());die();
}
And here is the function:
function my_module_mail($key, &$message, $params) {
$body = '<p>Click the link below to reset your password.</p>
<p>Click this link to reset your password</p>
';
// $headers = array(
// 'MIME-Version' => '1.0',
// 'Content-Type' => 'text/html; charset=UTF-8; format=flowed',
// 'Content-Transfer-Encoding' => '8Bit',
// 'X-Mailer' => 'Drupal'
// );
// $message['headers'] = $headers;
$message['subject'] = 'Why wont this send html??';
$message['headers']['Content-Type'] = 'text/html; charset=UTF-8;';
$message['body'][] = $body;
$message['from'] = 'do-not-reply#myemailaddress.com';
}
I tired just the html header and the full set that is commented out. What am I missing? The email sends fine but it's plain text. Thanks and let me know!
You can use this function
function my_module_custom_drupal_mail($target = NULL, $from = null, $subject, $message, $attachment = NULL){
$my_module = 'my_module';
$my_mail_token = microtime();
$message = array(
'id' => $my_module . '_' . $my_mail_token,
'to' => $target,
'subject' => $subject,
'body' => array($message),
'module' => $my_module,
'key' => $my_mail_token,
'from' => "$from <email#email.com>",
'headers' => array(
'From' => "$from <email#email.com>",
'Sender' => "$from <email#email.com>",
'Return-Path' => "$from <email#email.com>",
'Content-Type' => 'text/html; charset=utf-8'
),
);
if ($attachment) {
$file_content = file_get_contents($attachment[0]);
$message['params']['attachments'][] = array(
'filecontent' => $file_content,
'filename' => $attachment[1],
'filemime' => $attachment[2],
);
}
$system = drupal_mail_system($my_module, $my_mail_token);
$message = $system->format($message);
if ($system->mail($message)) {
return TRUE;
}
else {
return FALSE;
}
}
AND call it like :
$body = '<p>Click the link below to reset your password.</p>
<p>Click this link to reset your password</p>
';
$subject ='Why wont this send html??';
$from = 'myemail#email.com';
$sent = my_module_custom_drupal_mail($node->field_email_address['und'][0]['value'], $from, $subject, $body);
Customize it like you want ! :)
A few things need to be done:
/**
* Class SomeCustomModuleMailSystem Implements MailSystemInterface.
*
* Used to enable HTML email to be sent.
*/
class SomeCustomModuleMailSystem extends DefaultMailSystem {
public function format(array $message) {
$message['body'] = implode("\n\n", $message['body']);
$message['body'] = drupal_wrap_mail($message['body']);
return $message;
}
}
This to be done one time, so probably in a hook_enable or hook_update:
$current = variable_get('mail_system', ['default-system' => 'DefaultMailSystem']);
$addition = ['some_custom_module' => 'SomeCustomModuleMailSystem'];
variable_set('mail_system', array_merge($current, $addition));
Invoke hook_mail as normal, e.g.
/**
* Implements hook_mail().
*/
function some_custom_module_mail($key, &$message, $params) {
switch ($key) {
case 'some_mail_key':
$message['headers']['Content-Type'] = 'text/html; charset=UTF-8;';
$message['subject'] = $params['subject'];
$message['body'][] = $params['body'];
break;
}
}
Finally call it with something like this:
// Set variables required for the email.
$module = 'some_custom_module';
$key = 'some_mail_key';
$to = $email = 'thetoaddress#something.com';
$language = language_default();
$params['subject'] = 'Email subject';
$params['body'] = '<html><body>The HTML!</body></html>';
$from = 'thefromaddress#something.com';
$send = TRUE;
// Send the mail and log the result.
$result = drupal_mail($module, $key, $to, $language, $params, $from, $send);
if ($result['result'] === TRUE) {
watchdog('some_custom_module', 'HTML email successfully sent.', [], WATCHDOG_INFO);
}
else {
watchdog('some_custom_module', 'HTML email failed to send', [], WATCHDOG_ERROR);
}

Facebook sdk error : Cross-site request forgery validation failed. The "state" param from the URL and session do not match

Anyone why i got this error? I am trying to log-in via Facebook.
It give me this error:
Cross-site request forgery validation failed. The "state" param from
the URL and session do not match.
This is my code!
$helper = $fb->getRedirectLoginHelper();
$this->facebook['callback_url'] = Yii::$app->urlManager->createAbsoluteUrl('users/user/set-info') . '&social_code=21g36fsdfe135e5';
$this->facebook['login_url'] = $helper->getLoginUrl('https://example.com/index.php?r=users/user/set-info&social_code=21g36fsdfe135e5', $this->facebook['permissions']);
try {
// Get the Facebook\GraphNodes\GraphUser object for the current user.
// If you provided a 'default_access_token', the '{access-token}' is optional.
$accessToken = $helper->getAccessToken();
} catch(Facebook\Exceptions\FacebookResponseException $e) {
// When Graph returns an error
echo 'Graph returned an error: ' . $e->getMessage();
exit;
} catch(Facebook\Exceptions\FacebookSDKException $e) {
// When validation fails or other local issues
echo 'Facebook SDK returned an error: ' . $e->getMessage();
exit;
}
if (isset($accessToken)) {
$this->setUserData([
'facebook' => [
'access_token' => (string) $accessToken
]
]);
// OAuth 2.0 client handler
$oAuth2Client = $fb->getOAuth2Client();
// Exchanges a short-lived access token for a long-lived one
$longLivedAccessToken = $oAuth2Client->getLongLivedAccessToken($_SESSION['facebook_access_token']);
$_SESSION['facebook_access_token'] = (string) $longLivedAccessToken;
// setting default access token to be used in script
$fb->setDefaultAccessToken($_SESSION['facebook_access_token']);
$response = $fb->get('/me?fields=email,id,name,first_name,last_name,link,gender,locale,timezone,updated_time,verified,location,friends', $accessToken);
$tmp = $response->getGraphObject();
echo 'Logged in as ' . $tmp->getName();
$this->user_information = [
'social_id' => $tmp['id'],
'social_name' => 'facebook',
'email' => $tmp['email'],
'public_profile' => $tmp['link'],
'first_name' => $tmp['first_name'],
'last_name' => $tmp['last_name'],
'gender' => $tmp['gender'],
'home_address' => $tmp['location']['name'],
'user_friends' => $tmp['friends'],
];
$friends_response = $fb->get('/me/taggable_friends?fields=id,name,picture,email&limit=5000', $accessToken);
$temp = $friends_response->getGraphEdge();
$friends = array();
for ($i = 0; $i < count($temp); ++$i) {
$friends[] = $temp[$i];
}
$_SESSION['friends'] = $friends;
$this->social_loggedIn = true;
}
else {
$this->social_loggedIn = false;
}
Please Go to the file
src/Facebook/PersistentData/PersistentDataFactory.php
In Your Facebook SDK
find this Code
if ('session' === $handler) {
new FacebookSessionPersistentDataHandler();
}
And Replace with
if ('session' === $handler) {
return new FacebookSessionPersistentDataHandler();
}

Wordpress validation for title

Need to add blank and already exist validation for 'supports' => array( 'title') on my custom post type. But i dont want to use any plugin for this.
Thanks in advance.
add_action( 'admin_notices', 'custom_error_notice' );
function custom_error_notice(){
global $current_screen, $post;
if ( $current_screen->parent_base == 'edit' ){
if((!$post->post_name) && $_GET['post']) {
wp_redirect(admin_url('post-new.php?empty=1'));
}
if($_GET['empty']) echo '<div class="error"><p>Warning - Please fill up all fields correctly!</p></div>';
}
}
But this not working properly.
This may help you:-
add_action('save_post', 'album_save_post', 10, 2);
function album_save_post( $album_id, $album ) {
if( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE || $album->post_type != 'music_album') return;
// echo '<pre>';
// print_r($album);
// echo '</pre>';
// die();
$errors = array();
// Validation filters
$title = $album->post_title;
if ( ! $title ) {
$errors['title'] = "The title is required";
}
// if we have errors lets setup some messages
if (! empty($errors)) {
// we must remove this action or it will loop for ever
remove_action('save_post', 'album_save_post');
// save the errors as option
update_option('album_errors', $errors);
// Change post from published to draft
$album->post_status = 'draft';
// update the post
wp_update_post( $album );
// we must add back this action
add_action('save_post', 'album_save_post');
// admin_notice is create by a $_GET['message'] with a number that wordpress uses to
// display the admin message so we will add a filter for replacing default admin message with a redirect
add_filter( 'redirect_post_location', 'album_post_redirect_filter' );
}
}
function album_post_redirect_filter( $location ) {
// remove $_GET['message']
$location = remove_query_arg( 'message', $location );
// add our new query sting
$location = add_query_arg( 'album', 'error', $location );
// return the location query string
return $location;
}
// Add new admin message
add_action( 'admin_notices', 'album_post_error_admin_message' );
function album_post_error_admin_message() {
if ( isset( $_GET['album'] ) && $_GET['album'] == 'error' ) {
// lets get the errors from the option album_errors
$errors = get_option('album_errors');
// now delete the option album errors
delete_option('album_errors');
$display = '<div id="notice" class="error"><ul>';
// Because we are storing as an array we should loop through them
foreach ( $errors as $error ) {
$display .= '<li>' . $error . '</li>';
}
$display .= '</ul></div>';
// finally echo out our display
echo $display;
// add some jQuery
?>
<script>
jQuery(function($) {
$("#title").css({"border": "1px solid red"})
});
</script>
<?php
}
}
i got the solution.
/** ADD Validation for title */
function force_post_title_init()
{
wp_enqueue_script('jquery');
}
function force_post_title()
{
echo "<script type='text/javascript'>\n";
echo "
jQuery('#publish').click(function(){
var testervar = jQuery('[id^=\"titlediv\"]')
.find('#title');
if (testervar.val().length < 1)
{
jQuery('[id^=\"titlediv\"]').css('border', '1px solid red');
alert('Post title is required');
return false;
}
});
";
echo "</script>\n";
}
add_action('admin_init', 'force_post_title_init');
add_action('edit_form_advanced', 'force_post_title');
// Add this row below to get the same functionality for page creations.
add_action('edit_page_form', 'force_post_title');
May be this also help for all of you.

Can't send email from Nginx php - fpm based dedi?

I have a site and it has contact page. in that page there is Email & Comment tab. Whenever someone Put his email & comment & click on submit mail should come to my email. but it is not working.
I am using this php file for mail function.
I have nginx & php - fpm installed in my dedicated server.
<?php
/*
This first bit sets the email address that you want the form to be submitted to.
You will need to change this value to a valid email address that you can access.
*/
$webmaster_email = "myemail#yahoo.com";
/*
This bit sets the URLs of the supporting pages.
If you change the names of any of the pages, you will need to change the values here.
*/
$feedback_page = "contact.html";
$error_page = "error_message.html";
$thankyou_page = "thank_you.html";
/*
This next bit loads the form field data into variables.
If you add a form field, you will need to add it here.
*/
$email_address = $_REQUEST['email_address'] ;
$comments = $_REQUEST['comments'] ;
/*
The following function checks for email injection.
Specifically, it checks for carriage returns - typically used by spammers to inject a CC list.
*/
function isInjected($str) {
$injections = array('(\n+)',
'(\r+)',
'(\t+)',
'(%0A+)',
'(%0D+)',
'(%08+)',
'(%09+)'
);
$inject = join('|', $injections);
$inject = "/$inject/i";
if(preg_match($inject,$str)) {
return true;
}
else {
return false;
}
}
// If the user tries to access this script directly, redirect them to the feedback form,
if (!isset($_REQUEST['email_address'])) {
header( "Location: $feedback_page" );
}
// If the form fields are empty, redirect to the error page.
elseif (empty($email_address) || empty($comments)) {
header( "Location: $error_page" );
}
// If email injection is detected, redirect to the error page.
elseif ( isInjected($email_address) ) {
header( "Location: $error_page" );
}
// If we passed all previous tests, send the email then redirect to the thank you page.
else {
mail( "$webmaster_email", "Feedback Form Results",
$comments, "From: $email_address" );
header( "Location: $thankyou_page" );
}
?>
But mail is not coming to my email. it was working when i have apache. I am new to nginx. so how can i make it work for nginx.
Any help would be appreciated.
There you go a very sweet alternative to using mail() function.
See last function for configuration.
<?php
class Xmail{
# LOG VAR
public $log = Array();
# NEW LINE
private $line = "\r\n";
# ATTACHED FILES
public $files = Array();
# CONFIG GENERAL
private $tpl = "";
private $mode = "mail";
function setTPL($value) { if($value != "") $this->tpl = $value; }
function setMODE($value) { if($value != "") $this->mode = $value; }
# CONFIG SMTP
private $smtp_host = "localhost";
private $smtp_port = "25";
private $smtp_username = "";
private $smtp_password = "";
function setSmtpHost($value) { if($value != "") $this->smtp_host = $value; }
function setSmtpPort($value) { if($value != "") $this->smtp_port = $value; }
function setSmtpUser($value) { if($value != "") $this->smtp_username = $value; }
function setSmtpPass($value) { if($value != "") $this->smtp_password = $value; }
# CONFIG SOCKET
private $from = "sokmail#localhost"; // sender email address
private $host = "localhost"; // your domain name here
private $port = "25"; // it is always 25 but i think it's best to have this for tests when developper pc has port 25 blocked and server has alternate port [i use 26 cause 25 is locked for anti SPAM by ISP]
private $time = "30"; // timeout [time short :D]
private $test = false; // test mode, does not send the email but you can see the log up to the point of sending email, good to check email addresses if valid or server if black-listed
function setFrom($value) { if($value != "") $this->from = $value; }
function setHost($value) { if($value != "") $this->host = $value; }
function setPort($value) { if($value != "") $this->port = $value; }
function setTime($value) { if($value != "") $this->time = $value; }
function setTest($value) { if($value != "") $this->test = $value; }
# MAIN FUNCTION
function mail($to, $subject, $msg, $headers, $attachments = NULL) {
# MESSAGE HTML
$msg = str_replace("\'","'",$msg);
$msg = str_replace('\"','"',$msg);
# Use template if case
if(is_file($this->tpl)){
$html = implode("", file($this->tpl));
$html = str_replace("{MESSAGE}", $msg, $html);
}else
$html = $msg;
$boundary1 = '-----='.md5(uniqid(rand()));
$boundary2 = '-----='.md5(uniqid(rand()));
$message .= "\r\nThis is a multi-part message in MIME format.\r\n\r\n";
$message .= "--".$boundary1."\r\n";
$message .= "Content-Type: multipart/alternative;\r\n boundary=\"$boundary2\"\r\n\r\n";
# MESSAGE TEXT
$message .= "--".$boundary2."\r\n";
$message .= "Content-Type: text/plain;\r\n charset=\"UTF-8\"\r\n";
$message .= "Content-Transfer-Encoding: 7bit\r\n";
$message .= strip_tags($msg) . "\r\n";
$message .= "\r\n\r\n";
# MESSAGE HTML
$message .= "--".$boundary2."\r\n";
$message .= "Content-Type: text/html;\r\n charset=\"UTF-8\"\r\n";
$message .= "Content-Transfer-Encoding: quoted-printable\r\n\r\n";
$message .= "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\r\n";
$message .= "<html>\r\n";
$message .= "<body>\r\n";
$message .= str_replace("
", "<br/>", $html) . "<br/>\r\n";
$message .= "</body>\r\n";
$message .= "</html>\r\n\r\n";
$message .= "--".$boundary2."--\r\n\r\n";
if(is_array($attachments)) {
foreach($attachments AS $file_url) {
if(is_file($file_url)) {
$file_name = pathinfo($file_url, PATHINFO_BASENAME);
$file_type = $this->find_mime(pathinfo($file_url, PATHINFO_EXTENSION));
# ATTACHMENT
$message .= "--".$boundary1."\r\n";
$message .= "Content-Type: ".$file_type.";\r\n name=\"$file_name\"\r\n";
$message .= "Content-Transfer-Encoding: base64\r\n";
$message .= "Content-Disposition: attachment;\r\n filename=\"$file_name\"\r\n\r\n";
$fp = fopen($file_url, 'r');
do {
$data = fread($fp, 8192);
if (strlen($data) == 0) break;
$content .= $data;
}
while (true);
$content_encode = chunk_split(base64_encode($content));
$message .= $content_encode."\r\n\r\n";
$content = '';
unset($content);
}
}
}
$message .= "--".$boundary1."--\r\n\r\n";
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: multipart/mixed;\r\n boundary=\"$boundary1\"\r\n";
if($this->mode == "smtp" || $this->mode == "mx")
return $this->sokmail($to, $subject, $message, $headers);
else {
if(mail($to, $subject, $message, $headers)) return true;
return false;
}
}
# send mail directly to destination MX server
function sokmail($to, $subject, $message, $headers) {
// get server based on mode
if($this->mode == "mx") {
list($user, $domain) = split("#",$to);
getmxrr($domain, $mxhosts);
$server = $mxhosts['0'];
}else{
$server = $this->smtp_host;
}
# open socket
$socket = #fsockopen($server, $this->port, $errno, $errstr, $this->time);
if(empty($socket)) { return false; }
if($this->parse_response($socket, 220, "SOCKET") != 220) { fclose($socket); return false; }
# say HELO to our little friend
fputs($socket, "EHLO " . $this->host . $this->line);
if($this->parse_response($socket, 250, "HELO") != 250) { fclose($socket); return false; }
# if SMTP
if($this->mode == "smtp" && !empty($this->smtp_username) && !empty($this->smtp_password) ) {
# start login
fputs($socket, "AUTH LOGIN" . $this->line);
if($this->parse_response($socket, 334, "AUTH LOGIN") != 334) { fclose($socket); return false; }
fputs($socket, base64_encode($this->smtp_username) . $this->line);
if($this->parse_response($socket, 334, "USERNAME") != 334) { fclose($socket); return false; }
fputs($socket, base64_encode($this->smtp_password) . $this->line);
if($this->parse_response($socket, 235, "PASSWORD") != 235) { fclose($socket); return false; }
}
# email from
fputs($socket, "MAIL FROM: <" . $this->from . ">" . $this->line);
if($this->parse_response($socket, 250, "MAIL FROM") != 250) { fclose($socket); return false; }
# email to
fputs($socket, "RCPT TO: <" . $to . ">" . $this->line);
if($this->parse_response($socket, 250, "RCPT TO") != 250) { fclose($socket); return false; }
# check for test mode
if($this->test != true) {
# send data start command
fputs($socket, "DATA" . $this->line);
if($this->parse_response($socket, 354, "DATA") != 354) { fclose($socket); return false; }
# make the deposit :)
fputs($socket, "Subject: " . $subject . $this->line);
fputs($socket, "To: " . $to . $this->line);
fputs($socket, $headers . $this->line);
fputs($socket, $message . $this->line);
fputs($socket, "." . $this->line); # this line sends a dot to mark the end of message
if($this->parse_response($socket, 250, ".") != 250) { fclose($socket); return false; }
}
# say goodbye
fputs($socket,"QUIT" . $this->line);
$this->parse_response($socket, 221, "QUIT");
fclose($socket);
return true;
}
# parse server responces for above function
function parse_response($socket, $expected, $cmd) {
$response = '';
$this->log[$cmd] = "";
while (substr($response, 3, 1) != ' ') {
if(!($response = fgets($socket, 256))) $this->log["ERROR RESPONSE"] = "Couldn't get mail server response codes.";
else $this->log[$cmd] .= $response;
# for security we break the loop after 10 cause this should not happen ever
$i++;
if($i == 10) return false;
}
# shows an error if expected code not received
if(substr($response, 0, 3) != $expected) $this->log["ERROR CODES"] = "Ran into problems sending Mail. Received: " . substr($response, 0, 3) . ".. but expected: " . $expected;
# access denied..quit
if(substr($response, 0, 3) == 451) $this->log["ERROR QUIT"] = "Server declined access. Quitting.";
return substr($response, 0, 3);
}
function find_mime($ext) {
# create mimetypes array
$mimetypes = $this->mime_array();
# return mime type for extension
if (isset($mimetypes[$ext])) {
return $mimetypes[$ext];
# if the extension wasn't found return octet-stream
} else {
return 'application/octet-stream';
}
}
function mime_array() {
return array(
"ez" => "application/andrew-inset",
"hqx" => "application/mac-binhex40",
"cpt" => "application/mac-compactpro",
"doc" => "application/msword",
"bin" => "application/octet-stream",
"dms" => "application/octet-stream",
"lha" => "application/octet-stream",
"lzh" => "application/octet-stream",
"exe" => "application/octet-stream",
"class" => "application/octet-stream",
"so" => "application/octet-stream",
"dll" => "application/octet-stream",
"oda" => "application/oda",
"pdf" => "application/pdf",
"ai" => "application/postscript",
"eps" => "application/postscript",
"ps" => "application/postscript",
"smi" => "application/smil",
"smil" => "application/smil",
"wbxml" => "application/vnd.wap.wbxml",
"wmlc" => "application/vnd.wap.wmlc",
"wmlsc" => "application/vnd.wap.wmlscriptc",
"bcpio" => "application/x-bcpio",
"vcd" => "application/x-cdlink",
"pgn" => "application/x-chess-pgn",
"cpio" => "application/x-cpio",
"csh" => "application/x-csh",
"dcr" => "application/x-director",
"dir" => "application/x-director",
"dxr" => "application/x-director",
"dvi" => "application/x-dvi",
"spl" => "application/x-futuresplash",
"gtar" => "application/x-gtar",
"hdf" => "application/x-hdf",
"js" => "application/x-javascript",
"skp" => "application/x-koan",
"skd" => "application/x-koan",
"skt" => "application/x-koan",
"skm" => "application/x-koan",
"latex" => "application/x-latex",
"nc" => "application/x-netcdf",
"cdf" => "application/x-netcdf",
"sh" => "application/x-sh",
"shar" => "application/x-shar",
"swf" => "application/x-shockwave-flash",
"sit" => "application/x-stuffit",
"sv4cpio" => "application/x-sv4cpio",
"sv4crc" => "application/x-sv4crc",
"tar" => "application/x-tar",
"tcl" => "application/x-tcl",
"tex" => "application/x-tex",
"texinfo" => "application/x-texinfo",
"texi" => "application/x-texinfo",
"t" => "application/x-troff",
"tr" => "application/x-troff",
"roff" => "application/x-troff",
"man" => "application/x-troff-man",
"me" => "application/x-troff-me",
"ms" => "application/x-troff-ms",
"ustar" => "application/x-ustar",
"src" => "application/x-wais-source",
"xhtml" => "application/xhtml+xml",
"xht" => "application/xhtml+xml",
"zip" => "application/zip",
"au" => "audio/basic",
"snd" => "audio/basic",
"mid" => "audio/midi",
"midi" => "audio/midi",
"kar" => "audio/midi",
"mpga" => "audio/mpeg",
"mp2" => "audio/mpeg",
"mp3" => "audio/mpeg",
"aif" => "audio/x-aiff",
"aiff" => "audio/x-aiff",
"aifc" => "audio/x-aiff",
"m3u" => "audio/x-mpegurl",
"ram" => "audio/x-pn-realaudio",
"rm" => "audio/x-pn-realaudio",
"rpm" => "audio/x-pn-realaudio-plugin",
"ra" => "audio/x-realaudio",
"wav" => "audio/x-wav",
"pdb" => "chemical/x-pdb",
"xyz" => "chemical/x-xyz",
"bmp" => "image/bmp",
"gif" => "image/gif",
"ief" => "image/ief",
"jpeg" => "image/jpeg",
"jpg" => "image/jpeg",
"jpe" => "image/jpeg",
"png" => "image/png",
"tiff" => "image/tiff",
"tif" => "image/tif",
"djvu" => "image/vnd.djvu",
"djv" => "image/vnd.djvu",
"wbmp" => "image/vnd.wap.wbmp",
"ras" => "image/x-cmu-raster",
"pnm" => "image/x-portable-anymap",
"pbm" => "image/x-portable-bitmap",
"pgm" => "image/x-portable-graymap",
"ppm" => "image/x-portable-pixmap",
"rgb" => "image/x-rgb",
"xbm" => "image/x-xbitmap",
"xpm" => "image/x-xpixmap",
"xwd" => "image/x-windowdump",
"igs" => "model/iges",
"iges" => "model/iges",
"msh" => "model/mesh",
"mesh" => "model/mesh",
"silo" => "model/mesh",
"wrl" => "model/vrml",
"vrml" => "model/vrml",
"css" => "text/css",
"html" => "text/html",
"htm" => "text/html",
"asc" => "text/plain",
"txt" => "text/plain",
"rtx" => "text/richtext",
"rtf" => "text/rtf",
"sgml" => "text/sgml",
"sgm" => "text/sgml",
"tsv" => "text/tab-seperated-values",
"wml" => "text/vnd.wap.wml",
"wmls" => "text/vnd.wap.wmlscript",
"etx" => "text/x-setext",
"xml" => "text/xml",
"xsl" => "text/xml",
"mpeg" => "video/mpeg",
"mpg" => "video/mpeg",
"mpe" => "video/mpeg",
"qt" => "video/quicktime",
"mov" => "video/quicktime",
"mxu" => "video/vnd.mpegurl",
"avi" => "video/x-msvideo",
"movie" => "video/x-sgi-movie",
"ice" => "x-conference-xcooltalk"
);
}
}
# PHP does not have getmxr function on windows so I built one
function win_getmxrr($hostname, &$mxhosts, &$mxweight=false) {
if (strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') return;
if (!is_array ($mxhosts) ) $mxhosts = array();
if (empty($hostname)) return;
$exec='nslookup -type=MX '.escapeshellarg($hostname);
#exec($exec, $output);
if (empty($output)) return;
$i=-1;
foreach ($output as $line) {
$i++;
if (preg_match("/^$hostname\tMX preference = ([0-9]+), mail exchanger = (.+)$/i", $line, $parts)) {
$mxweight[$i] = trim($parts[1]);
$mxhosts[$i] = trim($parts[2]);
}
if (preg_match('/responsible mail addr = (.+)$/i', $line, $parts)) {
$mxweight[$i] = $i;
$mxhosts[$i] = trim($parts[1]);
}
}
return ($i!=-1);
}
if (!function_exists('getmxrr')) {
function getmxrr($hostname, &$mxhosts, &$mxweight=false) {
return win_getmxrr($hostname, $mxhosts, $mxweight);
}
}
function xmail($to, $subject, $message, $headers="", $attachments=""){
$xmail = new Xmail();
$xmail->setMODE("mx"); // default is mail; options: mail,smtp,mx
// MX setup if in 'mx' mode
$xmail->setFrom("someone#somedomain.com");
$xmail->setHost($_SERVER['HTTP_HOST']);
// SMTP SETUP if in 'smtp' mode
$xmail->setSmtpHost("localhost");
$xmail->setSmtpPort(25);
$xmail->setSmtpUser("someuser");
$xmail->setSmtpPass("somepassword");
// from this point on you have to provide the same info as if you would use mail()
if($headers == "")
$headers = "From: <someone#somedomain.com>\r\n";
// !!! DO NOT ADD MIME VERSION OR CONTENT TYPE HEADERS !!!
// send the email
$xmail->mail($to, $subject, $message, $headers, $attachments);
}
?>

Resources