MailGun Check if an email already is subscribing - php

I have been trying to solve this in all ways I can figure out, but have surely missed something. I've tried to access the fields using for-loops, just calling it, arrays, objects etc. I just can't get it to work.
What I'm talking about is to check if a provided email in a form already is subscribing to my maillist at MailGun. I don't know how to check this and I've been searching the web for answer for about 1-2 hours now and I'm finally asking here aswell.
My code so far:
<?php
session_start();
ini_set('display_errors', 1);
require_once 'init.php';
if (!isset($_POST['email']) && isset($_POST['name'])) {
echo 'You have to provide an email!';
} else if (!isset($_POST['name']) && isset($_POST['email'])) {
echo 'You have to provide a name!';
} else if (isset($_POST['name'], $_POST['email'])) {
$name = $_POST['name'];
$email = $_POST['email'];
// This is temporary to test and only works if an email existing is provided.
// If an invalid email is provided, an error is cast
// See below for the error
if (!$mailgun->get('lists/' . MAILGUN_LIST . '/members' . $email)) {
echo "Email doesnt exist";
die();
$validate = $mailgunValidate->get('address/validate', [
'address' => $email
])->http_response_body;
if ($validate->is_valid) {
$hash = $mailgunOptIn->generateHash(MAILGUN_LIST, MAILGUN_SECRET, $email);
$mailgun->sendMessage(MAILGUN_DOMAIN, [
'from' => 'noreply#adamastmar.se',
'to' => $email,
'subject' => 'Please confirm your subscription to the mailing list',
'html' => "
Hello {$name},<br><br>
You signed up to our mailing list. Please confirm your subscription below.<br><br>
<a href='http://www.adamastmar.se/confirm.php?hash={$hash}'>Click here to confirm</a>"
]);
$mailgun->post('lists/' . MAILGUN_LIST . '/members', [
'name' => $name,
'address' => $email,
'subscribed' => 'no'
]);
$_SESSION['joined'] = "A message has been sent to the provided email. Please confirm the subscription by clicking the link in the mail.";
header('Location: ./');
}
} else {
$_SESSION['alreadysub'] = "You are already a subscriber to this list!";
header('Location: ./');
}
}
?>
The error I get if I use the code above:
Uncaught exception 'Mailgun\Connection\Exceptions\MissingEndpoint' with message 'The endpoint you've tried to access does not exist.
Check your URL.' in /home/jivusmc/domains/adamastmar.se/public_html/vendor/mailgun/mailgun-php/src/Mailgun/Connection/RestClient.php:258
Stack trace: #0 /home/jivusmc/domains/adamastmar.se/public_html/vendor/mailgun/mailgun-php/src/Mailgun/Connection/RestClient.php(110):
Mailgun\Connection\RestClient->responseHandler(Object(GuzzleHttp\Psr7\Response))
#1 /home/jivusmc/domains/adamastmar.se/public_html/vendor/mailgun/mailgun-php/src/Mailgun/Connection/RestClient.php(195):
Mailgun\Connection\RestClient->send('GET', 'lists/news#mail...') #2 /home/jivusmc/domains/adamastmar.se/public_html/vendor/mailgun/mailgun-php/src/Mailgun/Mailgun.php(215):
Mailgun\Connection\RestClient->get('lists/news#mail...', Array) #3 /home/jivusmc/domains/adamastmar.se/public_html/mailinglist.php(16):
Mailgun\Mailgun->get('lists/news#mail...') #4 {main} thrown in /home/jivusmc/domains/adamastmar.se/public_html/vendor/mailgun/mailgun-php/src/Mailgun/Connection/RestClient.php on line 258
Any help & tips/tricks is appreciated!

I found a solution to the issue I had. Instead of doing everything in an if-statement, I instead surrounded it in a try-catch. I try to check if the email can be fetched from the mailgun list and if it fails, it catches the error and instead adds the mail to the list. (I'm posting it here since it's nearly impossible to find a solution to this in a better way)
$name = $_POST['name'];
$email = $_POST['email'];
try {
$mailgun->get('lists/' . MAILGUN_LIST . '/members/' . $email);
$_SESSION['alreadysub'] = "You are already a subscriber to this list!";
header('Location: ./');
} catch (Exception $e) {
$validate = $mailgunValidate->get('address/validate', [
'address' => $email
])->http_response_body;
if ($validate->is_valid) {
$hash = $mailgunOptIn->generateHash(MAILGUN_LIST, MAILGUN_SECRET, $email);
$mailgun->sendMessage(MAILGUN_DOMAIN, [
'from' => 'noreply#adamastmar.se',
'to' => $email,
'subject' => 'Please confirm your subscription to the mailing list',
'html' => "
Hello {$name},<br><br>
You signed up to our mailing list. Please confirm your subscription below.<br><br>
<a href='http://www.adamastmar.se/confirm.php?hash={$hash}'>Click here to confirm</a>"
]);
$mailgun->post('lists/' . MAILGUN_LIST . '/members', [
'name' => $name,
'address' => $email,
'subscribed' => 'no'
]);
$_SESSION['joined'] = "A message has been sent to the provided email. Please confirm the subscription by clicking the link in the mail.";
header('Location: ./');
}
}

I know this problem and the answer are in PHP. But I just figured out a way in NodeJS and wish I've found a solution for it earlier. Maybe it helps someone.
FYI: I'm checking if an email exists in mailing list from Mailgun.
var DOMAIN = 'YOUR_DOMAIN_NAME';
var mailgun = require('mailgun-js')({ apiKey: "YOUR_API_KEY", domain: DOMAIN});
const array = await mailgun.getList().catch(console.error);
if(checkIfEmailExcistInMailinglist(array.items, dbUser.email)){
// if then do something
}
checkIfEmailExcistInMailinglist(array, email) {
for (var i = 0; i < array.length; i++) {
if (array[i].address === email) {
return true;
}
}
return false;
}

Related

PHP Form Sending Issues (using SendInBlue)

I have a basic PHP contact form which I use on a couple of sites, which sends email using the SendInBlue API.
My problem is that I have the form working perfectly on 1 site, now I am using the EXACT same code for a second site and just changing the email, name, etc - however when testing it I now get this error:
Fatal error: Call to undefined method Mailin::send_email() in
/URL/contactpage.php on line 71
FYI, line 71 is:
$mailin->send_email($data);
I have attached the complete code below - this works perfectly on 1 site, but I get this error on my second site.
Any ideas?
Thank you!
<?php
//Email Details for Form Notifications
$email_to = 'Test#test.com'; //the address to which the email will be sent
$email_to_name = 'Test';
//Form Fields
$fname = $_POST['firstname'];
$lname = $_POST['lastname'];
$email = $_POST['email'];
$fullmessage = $_POST['message'];
//Subject Lines
$subject_to = 'Test';
$subject_touser = 'Test';
//URL Redirects
$confirm = 'TestConfirm';
$errorurl = 'TestError';
//Validate
$emailval = filter_var( $email, FILTER_VALIDATE_EMAIL );
if ($emailval == false)
{
header("Location: $errorurl");
} else {
// The email to us
$message_to = 'Message here';
//
// The email to them
$message_touser = 'Message here';
//
require('Mailin.php');
//Notification Email
$mailin = new Mailin('https://api.sendinblue.com/v2.0','MY_KEY');
$data = array( "to" => array($email_to=>$email_to_name),
"cc" => array($email_to_cc=>$email_to_cc_name),
"from" => array($email,$fname),
"subject" => $subject_to,
"html" => $message_to
);
$mailin->send_email($data);
//Email to User
$mailin = new Mailin('https://api.sendinblue.com/v2.0','MY_KEY');
$data2 = array( "to" => array($email=>$fname),
"from" => array($email_to,$email_to_name),
"subject" => $subject_touser,
"html" => $message_touser
);
$mailin->send_email($data2);
header("Location: $confirm");
}
?>
I was using a deprecated Mailin.php. Updated the file and everything works now.

php json return creating syntax error on responce

I have looked at many posts here and elswhere on this error without success of resolving my error. In console the form data is being sent via json as expected to my php processing page, the php process is not returning any errors so I'm confident the process is completing. I have checked the way the result is formatted and cannot see anything wrong there, although I'm no expert at ajax/json so I could be wrong, Here is my code
Jquery code
<script type="text/javascript">
$(document).ready(function() {
$("#admin_login_but").click(function() {
if($("#admin_name").val()=="" || $("#admin_password").val()=="" || $("#admin_email").val()=="") {
$(".adminloginError").html("Please enter Admin Name, Admin Email and Admin Password");
return false;
}else{
$(".adminloginError").html('<img src="image/ajax-loader.gif" width="16" height="16" alt=""/>');
var adminName=$("#admin_name").val();
var adminPassword=$("#admin_password").val();
var adminEmail=$("#admin_email").val();
$.post("includes/admin_login.inc.php",{admin_name:adminName,admin_password:adminPassword, admin_email:adminEmail},function(json) {
if(json.result === "success") {
$(".adminloginError").html( "Welcome "+adminName+"!");
setTimeout(function(){
window.location= "admin_secure.php";
},2000);
}else{
$(".adminloginError").html(json.message);
}
});
}
Here is my php processing code
<?php
include_once 'functions.php';
include_once 'db_connect.php';
header("Content-Type: application/json"); //this will tell the browser to send a json object back to client not text/html (as default)
//convert variable (array) into a JSON object
function result($var){
echo json_encode($var);
exit();
}
sec_session_start();
error_reporting(E_ALL); ini_set('display_errors', 1);
//check if surname is empty
if (isset($_POST["admin_login_but"])) {
//check if first_name is empty
if (empty($_POST["admin_name"])) {
$response = array('result'=>'fail', 'message' => 'Missing Admin Name');
result($response);
}else{
// if not empty sanitize first_name input
$admin_name = filter_input(INPUT_POST, 'admin_name', FILTER_SANITIZE_STRING);
}
//Check if email is empty and santize and validate email
if (empty($_POST['admin_email'])) {
$response = array('result'=>'fail', 'message' => 'Missing Admin Email');
result($response);
}else{
$admin_email = filter_var($_POST['admin_email'], FILTER_SANITIZE_EMAIL);
}
if (!filter_var($admin_email, FILTER_VALIDATE_EMAIL)) {
$response = array('result'=>'fail', 'message' => 'The Email is not in a Valid Email Format!');
result($response);
}
//check if register password input is empty
if (empty($_POST["admin_password"])) {
$response = array('result'=>'fail', 'message' => 'Missing Admin Password');
result($response);
} else {
//Sanitize the data passed in 'password'
$admin_password = filter_input(INPUT_POST, 'admin_password', FILTER_SANITIZE_STRING);
}
//validate the data passed in 'password'
if (!preg_match("/^.*(?=.{8,})(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$/", $admin_password)) {
$response = array('result'=>'fail', 'message' => 'Password is in the Wrong Format!');
result($response);
}
//query database
$results = mysqli_query($mysqli, "SELECT * FROM admin WHERE name = '$admin_name' AND email = '$admin_email' AND hash = '$admin_password'");
// Check if SQL query had erors
if(!$results){
$response = array('result'=>'fail', 'message' => 'sql error: ' . mysqli_error($mysqli));
result($response);
}
// If query was successfull and there are rows do this:
if (mysqli_num_rows($results)>0){
$_GET['name'] = $admin_name;
$response = array('result'=>'success', 'message' => 'User is Authenticated');
result($response);
} else {
$response = array('result'=>'fail', 'message' => 'User Authentication Failed');
result($response);
}
}
?>
I cannot figure out how to resolve this. Can anyone help please
I just figured it out, I hadn't put an else option at the end of my php for the initial post check
if(!isset($_POST)) {
//all the processing code
}else{
$response = array('result'=>'success', 'message' => 'Post is Empty');
result($response);
}

Why is this PHP script not sending the e-mail?

Note: E-Mail address removed for privacy purposes.
Whenever the form executes this script, it returns the success JSON array at the end, however, the e-mail is never received at the e-mail address specified.
<?php
if(empty($_POST['fullname']) || empty($_POST['phonenumber']) || empty($_POST['emailaddress']))
{
$response = array('status' => 0, 'txt' => 'Please verify all required fields are complete.');
echo json_encode($response);
die();
}
if(!(preg_match("/^[\.A-z0-9_\-\+]+[#][A-z0-9_\-]+([.][A-z0-9_\-]+)+[A-z]{1,4}$/", $_POST['emailaddress'])))
{
$response = array('status' => 0, 'txt' => 'Please Provide a Valid E-Mail Address.');
echo json_encode($response);
die();
}
$name = mysql_real_escape_string($_POST['fullname']);
$phonenumber = mysql_real_escape_string($_POST['phonenumber']);
$email = mysql_real_escape_string($_POST['emailaddress']);
$comments = mysql_real_escape_string($_POST['comments']);
$emailbody = 'Name: ' . $name . '
Phone Number: ' . $phonenumber . '
E-Mail Address: ' . $email . '
Comments: ' . $comments . ' ';
mail("example#example.com","New Consultation Request",$emailbody,"From: noreply#example.com");
$response = array('status' => 1, 'txt' => 'consultation-request-successful');
echo json_encode($response);
?>
You've never bothered connecting to the database, so mysql_real_escape_string() is going to be turning a boolean FALSE for failure - it REQUIRES an active connection to the DB to do its work.
That means your $name, $phonenumber, $email, $comments are all going to be boolean FALSE, and translated into an empty string when you build your mail text.
As well, using mysql escaping for a simple email is beyond utterly pointless. Email is not vulnerable to SQL injection attacks.

Mailchimp API - Subscribe to list

I'm working on adding a script to my site for a MailChimp subscribe form. I think I have everything setup right but when I hit the subscribe button I'm getting a blank page.
Here is the script I have currently
<?php
ini_set('display_errors', 'On');
error_reporting(E_ALL);
require_once 'Mailchimp.php';
$apikey = "XXXXXXXXXXXXXXX";
$Mailchimp = new Mailchimp($apikey);
if (!empty($_POST)) {
$id = "XXXXXXXXXX";
$email = array(
'email' => trim($_POST['email'])
);
$result = $Mailchimp->$lists->subscribe($id, $email, $double_optin=false, $replace_interests=false);
var_dump($result);
}
echo "TESTING";
So I'm not getting the $result variable or "TESTING echo'd right now, so I assume I must be doing something simple wrong. Anyone see anything obvious? I believe I'm using the correct default JSON format. (keys have been X'd out, but the one's I'm using are correct)
Any help is much appreciated.
Thanks!!
EDIT: I have updated the code to something I believe to be more correct, but it still isn't working. I could really use some help on this.
Here's how I've handled AJAX email submissions in the past for MailChimp's API (MCAPI):
define("MC_API_KEY", "Your mailchimp API key");
define("MC_API_LIST", "The list ID to subscribe user to");
define("EMAIL_TO", "email address in case subscription fails");
require "MailChimp.API.class.php";
function json($error = true, $message = "Unknown error") {
die(json_encode(array("error" => $error, "message" => $message)));
}
if(!empty($_POST)) {
$email = !empty($_POST['email']) && filter_var($_POST['email'], FILTER_VALIDATE_EMAIL) ? $_POST['email'] : false;
if($email !== false) {
$api = new MCAPI(MC_API_KEY);
$result = $api->listSubscribe(MC_API_LIST, $email);
if($api->errorCode || !$result) {
if(isset($api->errorCode) && $api->errorCode == 214) { // already subscribed
json(true, "You are already subscribed!");
} else {
$error = "Unable to save user email via MailChimp API!\n\tCode=".$api->errorCode."\n\tMsg=".$api->errorMessage."\n\n";
$headers = "From: your#email.com\r\nReply-to: <{$email}>\r\nX-Mailer: PHP/".phpversion();
mail(EMAIL_TO, "Newsletter Submission FAIL [MC API ERROR]", "{$error}Saved info:\nFrom: {$email}\n\nSent from {$_SERVER['REMOTE_ADDR']} on ".date("F jS, Y \# g:iA e"), $headers);
json(false, "Thank you - your email will be subscribed shortly!");
}
} else {
json(false, "Thanks - A confirmation link has been sent to your email!");
}
} else {
json(true, "Please enter your valid email address");
}
} else json();
SOLVED:
Here is the correct code - hopefully this will help others looking to use the new api -
<?php
ini_set('display_errors', 'On');
error_reporting(E_ALL);
require_once 'Mailchimp.php';
$apikey = "XXXXXXXXXXXXXXXXXXX";
$Mailchimp = new Mailchimp($apikey);
if (!empty($_POST)) {
$id = "XXXXXXXXXX";
$email = array(
'email' => trim($_POST['email'])
);
$result = $Mailchimp->lists->subscribe($id, $email, $merge_vars=null, $double_optin=false, $replace_interests=false);
}

PHP Server Side Validation

Using various tutorials namely here and here I've managed to put together the following PHP script which performs server side validation on the form being submitted. (I already have script which is dealing with the 'client side' validation.
<?php
//email signup ajax call
if($_GET['action'] == 'signup'){
//sanitize data
$email = mysql_real_escape_string($_POST['signup-email']);
//validate email address - check if input was empty
if(empty($email)){
$status = "error";
$message = "You did not enter an email address!";
}
else if(!preg_match('/^[^\W][a-zA-Z0-9_]+(\.[a-zA-Z0-9_]+)*\#[a-zA-Z0-9_]+(\.[a-zA-Z0-9_]+)*\.[a-zA-Z]{2,4}$/', $email)){ //validate email address - check if is a valid email address
$status = "error";
$message = "You have entered an invalid email address!";
}
else {
$insertSignup = mysql_query("INSERT INTO signups (signup_email_address) VALUES ('$email')");
if($insertSignup){ //if insert is successful
$status = "success";
$message = "You have been signed up!";
}
else { //if insert fails
$status = "error";
$message = "Ooops, Theres been a technical error!";
}
}
//return json response
$data = array(
'status' => $status,
'message' => $message
);
echo json_encode($data);
exit;
}
?>
What I'm now trying to do is to add another field, in this case 'name' which I'd like to also validate.
The problem I'm having is that I'm not sure how to add another field into the above code. Again, I've been trying to find an example which I could use to study from, but I haven't found any that I can use.
I just wondered whether someone could possibly look at this please, and perhaps point me in the right direction.
Many thanks and kind regards
PHP has a Filter extension to validate and sanitize input.
The function you are looking for is
filter_var_array — Gets multiple variables and optionally filters them
There is also filter_input_array but since there is no easy way to unit-test that properly, it is easier to use the above one instead and pass it the superglobals as needed.
Example:
$userInput = array(
'signup-email' => 'foo at example.com',
'name' => 'ArthurDent42'
);
$validatedInput = filter_var_array(
$userInput,
array(
'signup-email' => FILTER_VALIDATE_EMAIL,
'name' => array(
'filter' => FILTER_VALIDATE_REGEXP,
'options' => array(
'regexp' => "/^[a-z ]{5,10}$/i"
)
)
)
);
var_dump($validatedInput);
Output (demo):
array(2) {
["signup-email"]=> bool(false)
["name"]=> bool(false)
}
Once you have the input validated and sanitized put some guard clauses for each of the values in the array and return early when they are false:
if (!$validatedInput['signup-email']) {
return json_encode(array(
'status' => 'error',
'message' => 'The eMail was invalid'
));
}
if (!$validatedInput['name']) {
return json_encode(array(
'status' => 'error',
'message' => 'Name must be 5 to 10 letters from A to Z only'
));
}
// everything's validated at this point. Insert stuff to database now.
Note that you want to use either PDO or mysqli instead of ext/mysql.
In your HTML add a field:
<input type="text" name="name" value="" />
In your PHP:
$name = trim($_POST['name']);
To validate:
if ($name === '') {
$status = 'error';
$message = 'need a name!';
}
Now add name to your insert statement (it would be better to use PDO prepared statements):
$nameSql = mysql_real_escape_string($name);
$insertSignup = mysql_query("INSERT INTO signups (signup_email_address, name) VALUES ('$email', '$nameSql')");
$rule['email']= '/^[^\W][a-zA-Z0-9_]+(\.[a-zA-Z0-9_]+)*\#[a-zA-Z0-9_]+(\.[a-zA-Z0-9_]+)*\.[a-zA-Z]{2,4}$`/'
$rule['name']= 'bla bla';
$rule['address']= 'bla bla';
$data = sanitize($_POST,$rule);
function sanitize($input_array,$rule){
$message = array();
foreach($input_array as $key=> $value){
$input_array[$key]= mysql_real_escape_string($value);
if(isset($rule[$key])){
if(!preg_match($rule[$key],$input_array[$key]){
$message[$key] = 'error';
unset($input_array[$key]);//optional
}
}
}
return array('data'=>$input_array,'message'=>$message);
}

Categories