PHPMailer does not provide ErrorInfo - error-handling

I have a problem with PHP Mailer, which is not providing the $mail->ErrorInfo when an error occured.
I tested with the original example from [http://phpmailer.worxware.com/?pg=tutorial#1] as below.
<?php
require("class.phpmailer.php");
$mail = new PHPMailer();
$mail->IsSMTP(); // telling the class to use SMTP
$mail->Host = "smtp.example.com"; // SMTP server
$mail->From = "from#example.com";
$mail->Subject = "First PHPMailer Message";
$mail->Body = "Hi! \n\n This is my first e-mail sent through PHPMailer.";
$mail->WordWrap = 50;
if(!$mail->Send()) {
echo 'Message was not sent.';
echo 'Mailer error: ' . $mail->ErrorInfo;
} else {
echo 'Message has been sent.';
}
?>
I've set the host to my server, modified "from" and "AddAddress" to correct addresses and I've received the test mail as expected. But whhen I change the recipient address to blxxxa#blablaxxxx.de, just to check how the errors will be handled I don't get the error.
$mail->AddAddress("blxxxa#blablaxxxx.de");
I still receive "Message has been sent". Any Idea? Maybe server settings?

Try putting your $mail->Send() into a try-catch block.
try{
// ... Your Setup ...
$mail->Send();
}
catch (phpmailerException $e) {
echo $e->errorMessage(); //PHPMailer error messages
}
catch (Exception $e) {
echo $e->getMessage(); // other error messages
}
if you look at the code of the phpmailer library ( phpmailer library on github search for the public function send() code block )
you'll see that phpmailer throws exceptions in case of failure.
You have some good examples here : http://www.merocode.com/sending-emails-using-phpmailer-via-smtp/
good luck.

ErrorInfo will not contain an error message unless an error happens. It sounds like your mail server is accepting the message without complaining (as would be expected if it's a relay or on localhost), so you need to check your mail server logs and your bounce mailbox since the problem is further upstream from you and thus not visible to PHPMailer.
In short, you're not doing anything wrong, you're just looking in the wrong place.

Provide profer hostname, username and password. for example,
<?php
require("class.phpmailer.php");
$mail = new PHPMailer();
$mail->IsSMTP(); // telling the class to use SMTP
$mail->Host = "mail.example.com"; // SMTP server
$mail->Port = 25; // set the SMTP port for the GMAIL server
$mail->Username = "username"; // SMTP account username example
$mail->Password = "password";
$mail->From = "from#example.com";
$mail->Subject = "First PHPMailer Message";
$mail->Body = "Hi! \n\n This is my first e-mail sent through PHPMailer.";
$mail->WordWrap = 50;
if(!$mail->Send()) {
echo 'Message was not sent.';
echo 'Mailer error: ' . $mail->ErrorInfo;
} else {
echo 'Message has been sent.';
}
?>

In my case PhpMailer causes a warning at $mail->send();
Warning: stream_socket_enable_crypto(): Peer certificate CN=mail.xxx.com' did not match expected CN=mail.yyy.com'
in class.smtp.php on line 368
So imho PhpMailer misses some exception handing here.
In such a case you have the following possibilities:
Create an issue in the ticket system https://github.com/PHPMailer/PHPMailer/issues and hope for an update
add a "#" to the function call #$mail->send(); - which hides the warning, but does not help you further
Work with the PHP buffer to read out the warning.
Update:
In PHPMailer 6.x the warning was removed - but $mail->ErrorInfo does not contain any useful information. All I get is "SMTP connect() failed". Not really an improvement...

Related

PHP mail function not working in cpanel using G Suit

I want to submit my form on email but PHP mail function not working in my hostgator cloud server, i am using G Suit on this server. Please help
You can use PHPMailer instead of server mailing as send emails from php not work in most host providers so PHPMailer solve your problem as you can send email over SMTP from php
<?php
require 'PHPMailerAutoload.php';
$mail = new PHPMailer;
//Enable SMTP debugging.
$mail->SMTPDebug = 3;
//Set PHPMailer to use SMTP.
$mail->isSMTP();
//Set SMTP host name
$mail->Host = "smtp.gmail.com";
//Set this to true if SMTP host requires authentication to send email
$mail->SMTPAuth = true;
//Provide username and password
$mail->Username = "name#gmail.com";
$mail->Password = "super_secret_password";
//If SMTP requires TLS encryption then set it
$mail->SMTPSecure = "tls";
//Set TCP port to connect to
$mail->Port = 587;
$mail->From = "name#gmail.com";
$mail->FromName = "Full Name";
$mail->addAddress("name#example.com", "Recepient Name");
$mail->isHTML(true);
$mail->Subject = "Subject Text";
$mail->Body = "<i>Mail body in HTML</i>";
$mail->AltBody = "This is the plain text version of the email content";
if(!$mail->send()) {
echo "Mailer Error: " . $mail->ErrorInfo;
} else {
echo "Message has been sent successfully";
}
?>
PHPMailer docs https://github.com/PHPMailer/PHPMailer/wiki/Tutorial

how to handle error 500 when requesting a distant server with guzzle?

i am requesting a webservice using :
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ConnectException;
try {
$client = new Client();
$response = $client->request('GET', $url); //it crashes at this line
$content = json_decode($response->getBody(), true);
}
catch (ConnectException $e) {
\Drupal::logger('amu_hal')->error('incorrect_url'.$url);
}
today the distant server return a error 500.
How can i modify my code not to crash my site when it happens?
I assume that by distant server you mean a server that takes a long time to connect. You can specify a timeout for the request.
Or perhaps the server returned error 500 and it fails during json_decode? You can check the status code returned by the request.
Or even perhaps the code is failing the line that you indicate but the exception ConnectException is not being caught? Try using Exception as a catch-all to debug this situation.
Instead of using Guzzle directly, I recommend that you use the Drupal wrapper (which uses Guzzle under the hood).
$client = Drupal::httpClient();
$request = $client->get($uri, ['connect_timeout' => 5]);
if ($request->getStatusCode() === 200) {
echo 'Connection Success';
} else {
echo sprintf('Error %d occurred', $request->getStatusCode());
}

refreshTokenWithAssertion Permission Denied

I am trying to use google-api-client in PHP for a project.
I got a "permission denied" response while at this statement:
$client->getAuth()->refreshTokenWithAssertion();
Google_IO_Exception, Message:Failed to connect to 74.125.193.84: Permission denied
File: /home/www/blah.com/restful/libs/Google/IO/Curl.php
Line:81
/home/www/blah.com/restful/libs/Google/IO/Abstract.php(125): Google_IO_Curl->executeRequest(Object(Google_Http_Request))
#1 /home/www/blah.com/restful/libs/Google/Auth/OAuth2.php(326): Google_IO_Abstract->makeRequest(Object(Google_Http_Request))
#2 /home/www/blah.com/restful/libs/Google/Auth/OAuth2.php(306): Google_Auth_OAuth2->refreshTokenRequest(Array)
#3 /home/www/blah.com/restful/v2/index.php(122): Google_Auth_OAuth2->refreshTokenWithAssertion()
I checked all my credentials and they look correct, what could be the problem?
Thanks,
John
code:
$client_id = '1234blahblahblah.apps.googleusercontent.com'; //Client ID
$service_account_name = '1234blahblah#developer.gserviceaccount.com'; //Email Address
$key_file_location = 'blahblah-1234.p12'; //key.p12
$client = new Google_Client();
$client->setApplicationName("test");
$service = new Google_Service_Calendar($client);
if (isset($_SESSION['service_token'])) {
$client->setAccessToken($_SESSION['service_token']);
}
$key = file_get_contents($key_file_location);
$cred = new Google_Auth_AssertionCredentials(
$service_account_name,
array('https://www.googleapis.com/auth/calendar'),
$key
);
print_r($cred);
$client->setAssertionCredentials($cred);
$client->setClientId($client_id);
if($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion(); //<<<<<failed here.
}
$_SESSION['service_token'] = $client->getAccessToken();
echo $_SESSION['service_token'];
}
Hi John I´ve the same problem and finally this works for me:
Before the lines:
if($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion(); //<<<<<failed here.
}
I put a try catch and that returns me that I had a writtin permissions problem:
try {
$client->getAuth()->refreshTokenWithAssertion($cred);
} catch (Exception $e) {
var_dump($e->getMessage());
}
I could do 2 things:
1) Go to Google/src/Config.php and change line 94: 'directory' => sys_get_temp_dir() . '/Google_Client'and change the directory to save cache temp files
2) or like me, made a echo sys_get_temp_dir(); before the try catch and give a chmod 777 permission to that dir
This solution works for me, I hope also for you. Anyway made an try/catch waiting for the exception message
See the service-account.php sample in the examples/ directory of the Google APIs Client Library for PHP on Github.com:
if($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($cred); // set credentials there
}

How do I make better httpd down checker?

I have apache down checker script (remote server), but I think it doesn't work if httpd has a timeout issue or something similar.
For example, site was offline, but the server was online status.
Should I put timeout stuff or something else? How??
<?php
function GetServerStatus($site, $port)
{
$status = array("OFFLINE", "ONLINE");
$fp = #fsockopen($site, $port, $errno, $errstr, 2);
if (!$fp) {
return $status[0];
} else
{ return $status[1];}
}
?>
<?php
$status = GetServerStatus('xxx.xxx.xxx.xxx',80);
if($status == 'OFFLINE') {
$message = "Server is down now!!";
}
?>
I don't see how this can possibly report incorrectly. You could consider sending a GET / request and timing it out.
You could also consider closing the socket in the success case.

Uncaught exception 'apiServiceException' with message 'Error calling GET ....'

I have a small card game for Google+ which needs the visitor's name, avatar, gender and city.
It works for myself, but in the error_log I see a lot of PHP-exceptions:
[28-Jan-2012 19:06:33] PHP Fatal error: Uncaught exception 'apiServiceException' with message 'Error calling GET https://www.googleapis.com/plus/v1/people/me?alt=json&key=AIzaSyAgQl0UeNM553PfLnPmP0jTtcJ8ZIQ3q0g: (404) Not Found' in /var/www/html/preferans.de/google/google-api-php-client/src/io/apiREST.php:86
Stack trace:
#0 /var/www/html/preferans.de/google/google-api-php-client/src/io/apiREST.php(56): apiREST::decodeHttpResponse(Object(apiHttpRequest))
#1 /var/www/html/preferans.de/google/google-api-php-client/src/service/apiServiceResource.php(151): apiREST::execute(Object(apiServiceRequest))
#2 /var/www/html/preferans.de/google/google-api-php-client/src/contrib/apiPlusService.php(207): apiServiceResource->__call('get', Array)
#3 /var/www/html/preferans.de/google/index.php(33): PeopleServiceResource->get('me')
#4 {main}
thrown in /var/www/html/preferans.de/google/google-api-php-client/src/io/apiREST.php on line 86
Here is my script:
<?php
require_once('google-api-php-client/src/apiClient.php');
require_once('google-api-php-client/src/contrib/apiPlusService.php');
session_start();
$client = new apiClient();
$client->setApplicationName('Video-Preferans');
$client->setClientId('XXX.apps.googleusercontent.com');
$client->setClientSecret('XXX');
$client->setRedirectUri('http://preferans.de/google');
$client->setDeveloperKey('XXX');
$client->setScopes(array('https://www.googleapis.com/auth/plus.me'));
$plus = new apiPlusService($client);
if (isset($_REQUEST['logout']))
unset($_SESSION['access_token']);
if (isset($_GET['code'])) {
$client->authenticate();
$_SESSION['access_token'] = $client->getAccessToken();
header('Location: http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']);
}
if (isset($_SESSION['access_token']))
$client->setAccessToken($_SESSION['access_token']);
if ($client->getAccessToken()) {
$me = $plus->people->get('me'); # XXX line 33 XXX
# the access token may have been updated lazily
$_SESSION['access_token'] = $client->getAccessToken();
} else {
printf('
<!doctype html>
<html>
<head>
<body>
<p>Play Preferans</p>
</body>
</html>
', $client->createAuthUrl());
exit();
}
$viewer_id = $me['id'];
list($first_name, $last_name) = explode(' ', $me['displayName']);
$city = $me['placesLived'][0]['value'];
$female = ($me['gender'] == 'male' ? 0 : 1);
$avatar = $me['image']['url'];
....skipped some html code....
Does anybody please know, why the apiServiceException is being thrown?
Or how and where at least catch it, so that I can debug it better?
I'm using the latest Google+ SDK 0.4.8.3 and also I'm requesting very basic user information and as I've written - it works for me and also for my wife's account.
You can wrap $me = $plus->people->get('me') within a try/catch block.
The plus/v1/people/me API returns a 404 Not Found when the user hasn't registered for Google+, and you can catch this case with the following:
try {
$me = $plus->people->get('me')
} catch (apiServiceException $e) {
// Handle exception. You can also catch Exception here.
// You can also get the error code from $e->getCode();
}
I have the same problem, only difference is I'm trying to use the Calendar API. I get the exact same error response as you did in the first place, tried the try/catch-block and it kind of worked. If I print the error response it says "403", but I also get the JSON-response I want. Do you know why?
my code:
if ($client->getAccessToken()) {
try{
$activities = $plus->activities->listActivities('me', 'public');
print 'Your Activities: <pre>' . print_r($activities, true) . '</pre>';
// The access token may have been updated.
$_SESSION['token'] = $client->getAccessToken();
} catch (apiServiceException $e) {
// Handle exception. You can also catch Exception here.
// You can also get the error code from $e->getCode();
echo $e->getCode();
print_r($activities);
}
}