1

I am a reasonably new developer and finally hit my first unsolvable problem!

I have used a reusable form and successfully tested it on two of my own Gmail accounts (example@gmail.com), however as soon as I use the client's professional G suite email (info@example.co.uk) it doesn't work, the email never arrives. I have checked & rechecked obvious things such as the spelling, cached files, spam & junk folders & re-uploaded the code several times. I have been through all of the Gsuite email settings and even added the IP to both the email whitelist & inbound gateway. Nothing works.

I am wondering if there is something in the MX records I have to do? I didn't try this as it worked with my other emails and there was nothing in the info about this.

I also considered contacting Gsuite to see if some kind of block exists in professional email?

Here is the code i am using:

    <?php
    ini_set('display_errors', 1);
    ini_set('display_startup_errors', 1);
    error_reporting(E_ALL);
    /*
    Tested working with PHP5.4 and above (including PHP 7 )
    */
    require_once './vendor/autoload.php';

    use FormGuide\Handlx\FormHandler;


    $pp = new FormHandler(); 

    $validator = $pp->getValidator();
    $validator->fields(['name','email'])->areRequired()->maxLength(50);
    $validator->field('email')->isEmail();
    $validator->field('comments')->maxLength(6000);




    $pp->sendEmailTo('info@example.co.uk'); // ← Your email here

    echo $pp->process($_POST);

Update, I checked the Logs and I am getting this error Message:

PHP Fatal error: Uncaught Error: Class 'FormGuide\PHPFormValidator\FormValidator' not found in /home4/macatac5/public_html/anderscapeslandscaping.co.uk/src/FormHandler.php:41

This is the code it relates to:


<?php
namespace FormGuide\Handlx;
use FormGuide\PHPFormValidator\FormValidator;
use PHPMailer;
use FormGuide\Handlx\Microtemplate;
use Gregwar\Captcha\CaptchaBuilder;

/**
 * FormHandler 
 *  A wrapper class that handles common form handling tasks
 *      - handles Form validations using PHPFormValidator class
 *      - sends email using PHPMailer 
 *      - can handle captcha validation
 *      - can handle file uploads and attaching the upload to email
 *      
 *  ==== Sample usage ====
 *   $fh = FormHandler::create()->validate(function($validator)
 *          {
 *              $validator->fields(['name','email'])
 *                        ->areRequired()->maxLength(50);
 *              $validator->field('email')->isEmail();
 *              
 *           })->useMailTemplate(__DIR__.'/templ/email.php')
 *           ->sendEmailTo('you@website.com');
 *           
 *   $fh->process($_POST);
 */
class FormHandler
{
    private $emails;
    public $validator;
    private $mailer;
    private $mail_template;
    private $captcha;
    private $attachments;
    private $recaptcha;

    public function __construct()
    {
        $this->emails = array();
        $this->validator = FormValidator::create();
        $this->mailer = new PHPMailer;
        $this->mail_template='';

        $this->mailer->Subject = "Contact Form Submission ";

        $host = isset($_SERVER['SERVER_NAME'])?$_SERVER['SERVER_NAME']:'localhost';
        $from_email ='forms@'.$host;
        $this->mailer->setFrom($from_email,'Contact Form',false);  

        $this->captcha = false;   

        $this->attachments = [];

        $this->recaptcha =null;


    }

    /**
     * sendEmailTo: add a recipient email address
     * @param  string/array $email_s one or more emails. If more than one emails, pass the emails as array
     * @return The form handler object itself so that the methods can be chained
     */
    public function sendEmailTo($email_s)
    {
        if(is_array($email_s))
        {
            $this->emails =array_merge($this->emails, $email_s);
        }
        else
        {
            $this->emails[] = $email_s; 
        }
        
        return $this;
    }

    public function useMailTemplate($templ_path)
    {
        $this->mail_template = $templ_path;
        return $this;
    }

    /**
     * [attachFiles find the file uplods and attach to the email]
     * @param  array $fields The array of field names
      */
    public function attachFiles($fields)
    {
        $this->attachments = array_merge($this->attachments, $fields);
        return $this;
    }

    public function getRecipients()
    {
        return $this->emails;
    }

    /**
     * [validate add Validations. This function takes a call back function which receives the PHPFormValidator object]
     * @param  function $validator_fn The funtion gets a validator parameter using which, you can add validations 
     */
    public function validate($validator_fn)
    {
        $validator_fn($this->validator);
        return $this;
    }

    public function requireReCaptcha($config_fn=null)
    {
        $this->recaptcha = new ReCaptchaValidator();
        $this->recaptcha->enable(true);
        if($config_fn)
        {
            $config_fn($this->recaptcha);   
        }
        return $this;
    }
    public function getReCaptcha()
    {
        return $this->recaptcha;
    }

    public function requireCaptcha($enable=true)
    {
        $this->captcha = $enable;
        return $this;
    }

    public function getValidator()
    {
        return $this->validator;
    }

    public function configMailer($mailconfig_fn)
    {
        $mailconfig_fn($this->mailer);
        return $this;
    }

    public function getMailer()
    {
        return $this->mailer;
    }

    public static function create()
    {
        return new FormHandler();
    }

    public function process($post_data)
    {
        if($this->captcha === true)
        {
            $res = $this->validate_captcha($post_data);
            if($res !== true)
            {
                return $res;
            }
        }
        if($this->recaptcha !== null &&
           $this->recaptcha->isEnabled())
        {
            if($this->recaptcha->validate() !== true)
            {
                return json_encode([
                'result'=>'recaptcha_validation_failed',
                'errors'=>['captcha'=>'ReCaptcha Validation Failed.']
                ]);
            }
        }

        $this->validator->test($post_data);

        //if(false == $this->validator->test($post_data))
        if($this->validator->hasErrors())
        {
            return json_encode([
                'result'=>'validation_failed',
                'errors'=>$this->validator->getErrors(/*associative*/ true)
                ]);
        }

        if(!empty($this->emails))
        {
            foreach($this->emails as $email)
            {
                $this->mailer->addAddress($email);
            }
            $this->compose_mail($post_data);

            if(!empty($this->attachments))
            {
                $this->attach_files();
            }

            if(!$this->mailer->send())
            {
                return json_encode([
                    'result'=>'error_sending_email',
                    'errors'=> ['mail'=> $this->mailer->ErrorInfo]
                    ]);         
            }
        }
        
        return json_encode(['result'=>'success']);
    }

    private function validate_captcha($post)
    {
        @session_start();
        if(empty($post['captcha']))
        {
            return json_encode([
                        'result'=>'captcha_error',
                        'errors'=>['captcha'=>'Captcha code not entered']
                        ]);
        }
        else
        {
            $usercaptcha = trim($post['captcha']);

            if($_SESSION['user_phrase'] !== $usercaptcha)
            {
                return json_encode([
                        'result'=>'captcha_error',
                        'errors'=>['captcha'=>'Captcha code does not match']
                        ]);     
            }
        }
        return true;
    }


    private function attach_files()
    {
        
        foreach($this->attachments as $file_field)
        {
            if (!array_key_exists($file_field, $_FILES))
            {
                continue;
            }
            $filename = $_FILES[$file_field]['name'];

            $uploadfile = tempnam(sys_get_temp_dir(), sha1($filename));

            if (!move_uploaded_file($_FILES[$file_field]['tmp_name'], 
                $uploadfile))
            {
                continue;
            }

            $this->mailer->addAttachment($uploadfile, $filename);
        }
    }

    private function compose_mail($post)
    {
        $content = "Form submission: \n\n";
        foreach($post as $name=>$value)
        {
            $content .= ucwords($name).":\n";
            $content .= "$value\n\n";
        }
        $this->mailer->Body  = $content;
    }
}

Jamie Mac
  • 21
  • 4
  • What is that FormHandler class you are using there, and how _exactly_ is it sending those mails? Via SMTP with proper authentication? If so, did you specify the `From` field for the sender anywhere, and does that match with the SMTP credentials you used? – CBroe Jul 21 '20 at 11:16
  • https://stackoverflow.com/questions/24644436/php-mail-function-doesnt-complete-sending-of-e-mail has a lot of reasons why you can have problems with email delivery, check if any of those might apply to your situation. – CBroe Jul 21 '20 at 11:16

2 Answers2

1

Just a school boy MX error in the end. Hadn't double checked the details were matching and had an old record in there causing confusion. Thanks for the help anyways!

Jamie Mac
  • 21
  • 4
0

If you say that sending emails to a normal Gmail free account account works but you use a G Suite account it won't most likely is some G Suite settings or the DNS Domain settings the G Suite Domain.

If is as you said the MX record then refer to this:

  • Have you tried to send email from gmail to G suite (or from any other client, it doesn't matter), does it work?

  • To check if you MX record point at Goolge you can use this toolbox, you only have to put your domain and select MX: https://toolbox.googleapps.com/apps/dig/#MX/

If there are none (the records are shown in Bold), then you need to add the MX record for the Google Server, which are the following:

  • ASPMX.L.GOOGLE.COM : priorità 1
  • ALT1.ASPMX.L.GOOGLE.COM : priorità 5
  • ALT2.ASPMX.L.GOOGLE.COM : priorità 5
  • ALT3.ASPMX.L.GOOGLE.COM : priorità 10
  • ALT4.ASPMX.L.GOOGLE.COM : priorità 10

Set up MX records for G Suite Gmail: https://support.google.com/a/answer/140034?hl=en

If this is not the issue then it may be something else, if I understood right your code is sending to an email, and not actually using the account to send via SMPT right?

Are there any other errors? Are you the Super Admin of this G Suite Account?

Have tried to enable Less secure Apps? Control access to less secure apps: https://support.google.com/a/answer/6260879?hl=en

Federico Baù
  • 6,013
  • 5
  • 30
  • 38