0

Form mail desired outcome: Name, email address and message is sent to the website owner @yahoo.com.

The form asks . . . Name: Email: Message:

Current status: If a @yahoo email address is placed in the form's "Email" field, (a real email address @yahoo.com) does not get an email. If the "Email" field is filled out with an address using @gmail.com, or @godaddy.com it works! Below is the form's HTML, and the send.php code.

Thank you for your help!

<!-- CONTACT FORM -->           
                    <div id="contact_form" class="animated fadeInDown">
                        
                        <!-- Success Message -->
                        <div class="form-success">
                            <p><i class="fa fa-check"></i>Thank you, your message has been sent!</p>
                        </div>
                        
                        <!-- Begin form -->
                        <div class="contact-form"> 
                            <form action="contact-form/send.php" method="post" class="form">    
                                <div class="name">
                                    <input class="text" type="text" name="name" placeholder="Name"> 
                                </div>
                                <div class="email">  
                                    <input class="text" type="text" name="email" placeholder="Email"> 
                                </div>
                                <div class="message">    
                                    <textarea name="message" rows="8" cols="60" placeholder="Message & Phone Number"></textarea> 
                                                                    
                                </div>
                                
                                <div class="bt-contact">
                                    <a class="btn-color btn-color-1d" id="submit" href="javascript:;"><span>SEND EMAIL</span></a>
                                    
                                </div>
                                    
                                <div class="loading"></div>
                                
                            </form> 
                        </div>
                        <!-- End form -->
                    </div>
                    <!-- END CONTACT FORM -->
<?php
/*------------------------------------
       YOUR EMAIL GOES HERE
--------------------------------------*/
$to = '<a real email address@yahoo.com>';


//Retrieve form data. 
//GET - user submitted data using AJAX
//POST - in case user does not support javascript, we'll use POST instead
$name = ($_GET['name']) ? $_GET['name'] : $_POST['name'];
$email = ($_GET['email']) ?$_GET['email'] : $_POST['email'];
$comment = ($_GET['comment']) ?$_GET['comment'] : $_POST['message'];

//flag to indicate which method it uses. If POST set it to 1
if ($_POST) $post=1;

//Include email validator
    require 'email-validator.php';
    $validator = new EmailAddressValidator();
    
//Simple server side validation for POST data, of course, you should validate the email
if (!$name) $errors[count($errors)] = 'Please enter your name.';
if (!$email) $errors[count($errors)] = 'Please enter your email.'; 
if (!$comment) $errors[count($errors)] = 'Please enter your comment.'; 

$email = strip_tags($email);

if (!$validator->check_email_address($email)) {
    $errors[count($errors)] = 'Invalid email address.'; 
}

//if the errors array is empty, send the mail
if (!$errors) {

    //sender
    $from = $name . ' <' . $email . '>';
    
    //Structure of the message:
    $subject = 'Message from ' . $name; 
    $message = '
    <!DOCTYPE html>
    <head></head>
    <body>
    <table>
        <tr><td>Name:</td><td>' . $name . '</td></tr>
        <tr><td>Email:</td><td>' . $email . '</td></tr>
        <tr><td>Message:</td><td>' . nl2br($comment) . '</td></tr>
    </table>
    </body>
    </html>';

    //End of the message structure
    
    
    //send the mail
    $result = sendmail($to, $subject, $message, $from);
    
    //if POST was used, display the message straight away
    if ($_POST) {
        if ($result) echo 'Thank you! We have received your message.';
        else echo 'Sorry, unexpected error. Please try again later';
        
    //else if GET was used, return the boolean value so that 
    //ajax script can react accordingly
    //1 means success, 0 means failed
    } else {
        echo $result;   
    }

//if the errors array has values
} else {
    //display the errors message
    for ($i=0; $i<count($errors); $i++) echo $errors[$i] . '<br/>';
    echo '<a href="../contact.html">Back</a>';
    exit;
}


//Simple mail function with HTML header
function sendmail($to, $subject, $message, $from) {
    $headers = "MIME-Version: 1.0" . "\r\n";
    $headers .= "Content-type:text/html;charset=iso-8859-1" . "\r\n";
    $headers .= 'From: ' . $from . "\r\n";
    
    $result = mail($to,$subject,$message,$headers);
    
    if ($result) return 1;
    else return 0;
}

?>
<?php

    class EmailAddressValidator {

        /**
         * Check email address validity
         * @param   strEmailAddress     Email address to be checked
         * @return  True if email is valid, false if not
         */
        public function check_email_address($strEmailAddress) {
            
            // If magic quotes is "on", email addresses with quote marks will
            // fail validation because of added escape characters. Uncommenting
            // the next three lines will allow for this issue.
            //if (get_magic_quotes_gpc()) { 
            //    $strEmailAddress = stripslashes($strEmailAddress); 
            //}

            // Control characters are not allowed
            if (preg_match('/[\x00-\x1F\x7F-\xFF]/', $strEmailAddress)) {
                return false;
            }

            // Check email length - min 3 (a@a), max 256
            if (!$this->check_text_length($strEmailAddress, 3, 256)) {
                return false;
            }

            // Split it into sections using last instance of "@"
            $intAtSymbol = strrpos($strEmailAddress, '@');
            if ($intAtSymbol === false) {
                // No "@" symbol in email.
                return false;
            }
            $arrEmailAddress[0] = substr($strEmailAddress, 0, $intAtSymbol);
            $arrEmailAddress[1] = substr($strEmailAddress, $intAtSymbol + 1);

            // Count the "@" symbols. Only one is allowed, except where 
            // contained in quote marks in the local part. Quickest way to
            // check this is to remove anything in quotes. We also remove
            // characters escaped with backslash, and the backslash
            // character.
            $arrTempAddress[0] = preg_replace('/\./'
                                             ,''
                                             ,$arrEmailAddress[0]);
            $arrTempAddress[0] = preg_replace('/"[^"]+"/'
                                             ,''
                                             ,$arrTempAddress[0]);
            $arrTempAddress[1] = $arrEmailAddress[1];
            $strTempAddress = $arrTempAddress[0] . $arrTempAddress[1];
            // Then check - should be no "@" symbols.
            if (strrpos($strTempAddress, '@') !== false) {
                // "@" symbol found
                return false;
            }

            // Check local portion
            if (!$this->check_local_portion($arrEmailAddress[0])) {
                return false;
            }

            // Check domain portion
            if (!$this->check_domain_portion($arrEmailAddress[1])) {
                return false;
            }

            // If we're still here, all checks above passed. Email is valid.
            return true;

        }

        /**
         * Checks email section before "@" symbol for validity
         * @param   strLocalPortion     Text to be checked
         * @return  True if local portion is valid, false if not
         */
        protected function check_local_portion($strLocalPortion) {
            // Local portion can only be from 1 to 64 characters, inclusive.
            // Please note that servers are encouraged to accept longer local
            // parts than 64 characters.
            if (!$this->check_text_length($strLocalPortion, 1, 64)) {
                return false;
            }
            // Local portion must be:
            // 1) a dot-atom (strings separated by periods)
            // 2) a quoted string
            // 3) an obsolete format string (combination of the above)
            $arrLocalPortion = explode('.', $strLocalPortion);
            for ($i = 0, $max = sizeof($arrLocalPortion); $i < $max; $i++) {
                 if (!preg_match('.^('
                                .    '([A-Za-z0-9!#$%&\'*+/=?^_`{|}~-]' 
                                .    '[A-Za-z0-9!#$%&\'*+/=?^_`{|}~-]{0,63})'
                                .'|'
                                .    '("[^\\\"]{0,62}")'
                                .')$.'
                                ,$arrLocalPortion[$i])) {
                    return false;
                }
            }
            return true;
        }

        /**
         * Checks email section after "@" symbol for validity
         * @param   strDomainPortion     Text to be checked
         * @return  True if domain portion is valid, false if not
         */
        protected function check_domain_portion($strDomainPortion) {
            // Total domain can only be from 1 to 255 characters, inclusive
            if (!$this->check_text_length($strDomainPortion, 1, 255)) {
                return false;
            }
            // Check if domain is IP, possibly enclosed in square brackets.
            if (preg_match('/^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])'
               .'(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}$/'
               ,$strDomainPortion) || 
                preg_match('/^\[(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])'
               .'(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}\]$/'
               ,$strDomainPortion)) {
                return true;
            } else {
                $arrDomainPortion = explode('.', $strDomainPortion);
                if (sizeof($arrDomainPortion) < 2) {
                    return false; // Not enough parts to domain
                }
                for ($i = 0, $max = sizeof($arrDomainPortion); $i < $max; $i++) {
                    // Each portion must be between 1 and 63 characters, inclusive
                    if (!$this->check_text_length($arrDomainPortion[$i], 1, 63)) {
                        return false;
                    }
                    if (!preg_match('/^(([A-Za-z0-9][A-Za-z0-9-]{0,61}[A-Za-z0-9])|'
                       .'([A-Za-z0-9]+))$/', $arrDomainPortion[$i])) {
                        return false;
                    }
                    if ($i == $max - 1) { // TLD cannot be only numbers
                        if (strlen(preg_replace('/[0-9]/', '', $arrDomainPortion[$i])) <= 0) {
                            return false;
                        }
                    }
                }
            }
            return true;
        }

        /**
         * Check given text length is between defined bounds
         * @param   strText     Text to be checked
         * @param   intMinimum  Minimum acceptable length
         * @param   intMaximum  Maximum acceptable length
         * @return  True if string is within bounds (inclusive), false if not
         */
        protected function check_text_length($strText, $intMinimum, $intMaximum) {
            // Minimum and maximum are both inclusive
            $intTextLength = strlen($strText);
            if (($intTextLength < $intMinimum) || ($intTextLength > $intMaximum)) {
                return false;
            } else {
                return true;
            }
        }

    }

?>
etsiap
  • 1
  • 1
  • 1
    Can you edit your question and add your code? I am assuming your question is why an email is not sent to the yahoo email. – zedfoxus Oct 27 '20 at 03:20
  • 1
    Thanks for checking this out! The question has been edited and the code added. – etsiap Oct 27 '20 at 07:22
  • include your `validator.php` file as well. could be the cause of the issue – RisingSun Oct 27 '20 at 17:57
  • Your emails most likely arrive in spam, because you're sending from a domain that doesn't match the domain in the from header. Instead of sending on behalf of the user, relay the email through Yahoo's SMTP server – Emanuel Vintilă Oct 27 '20 at 18:03
  • OK, I'll try that out, thanks! – etsiap Oct 27 '20 at 18:30

1 Answers1

0

If you're sending mail "From" an arbitrary address this will almost surely get blocked as this is called "spoofing" and is easily detected as illegitimate.

You need to send from an address you own and control.

Yahoo is very strict about SPF records and particular about DKIM, so ensure both of those are set up and validate correctly.

Whenever you set up an email form tool, be absolutely certain that someone can't hijack this to send arbitrary content to arbitrary addresses. If this is possible someone will inevitably discover this and use it to send out unsolicited mail.

tadman
  • 208,517
  • 23
  • 234
  • 262
  • Thanks @tadman for looking at this. I use legit yahoo email addresses when filling out the form on the website, they will not arrive at the To: yahoo address specified in the send.php script. All the other email tests from other domains work. – etsiap Oct 28 '20 at 08:42
  • You can't send email `From: ...@yahoo.com` through your own servers. This is spoofing and will be blocked. You **must send from a domain you control and can configure correctly**. – tadman Oct 28 '20 at 20:14