Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create a diagnostic utility #612

Open
Synchro opened this issue Jan 28, 2016 · 22 comments
Open

Create a diagnostic utility #612

Synchro opened this issue Jan 28, 2016 · 22 comments

Comments

@Synchro
Copy link
Member

Synchro commented Jan 28, 2016

So many questions on SO and issues raised in here are addressed by the troubleshooting guide, but many seem unable to heed its advice. I propose creating a utility function that tries to diagnose a PHPMailer config issue by running through all the tests suggested in the guide in an automated fashion, producing diagnostic output that will direct the user to an appropriate fix.

@ooxi
Copy link

ooxi commented Jan 28, 2016

Should the utility run automatically or by the user? More often than not the error message already includes steps to fix the failure (e.g. issue #525) but not read by the user. Thus I fear that an utility that should be run by the user is no more useful than linking to a troubleshooting guide :(

@Synchro
Copy link
Member Author

Synchro commented Jan 28, 2016

No, not automatically as it's too intrusive, but many have no idea how to even get to a command line on their server, let alone install/run telnet or do DNS lookups, check SSL certs. It may still lead to duplicate questions on SO for those incapable of reading an error message, but it would make them much simpler to deal with.

I think the most effective way would be to implement it as a method that you would call just before or after send() - perhaps adjust the examples to call it if a send fails, perhaps:

if ($mail->send()) {
    echo 'yay!';
} else {
    echo $mail->diagnose();
}

We could also make the error message pointing at the guide a bit harder to ignore!

There was a problem sending your message.
 ____  _____    _    ____    _____ _   _ ___ ____  _
|  _ \| ____|  / \  |  _ \  |_   _| | | |_ _/ ___|| |
| |_) |  _|   / _ \ | | | |   | | | |_| || |\___ \| |
|  _ <| |___ / ___ \| |_| |   | | |  _  || | ___) |_|
|_| \_\_____/_/   \_\____/    |_| |_| |_|___|____/(_)
Before asking a question on SO or opening an issue on github, read this page:
https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting

@ooxi
Copy link

ooxi commented Jan 28, 2016

That's a great idea 👍

@elminson
Copy link

elminson commented Mar 8, 2016

Who is working on this ?

@elminson
Copy link

elminson commented Mar 8, 2016

I create the implementation of this but i don't now how to create a pull request. Who can help me?
e.g. __ __ _ _ _
| / | ___ ___ ___ __ _ __ _ ___ | |__ ___ | | _ _ ___ _ __ ___ _ __ | |_ _ _
| |/| | / _ \ / __| / __| / | / _ | / _ \ | ' \ / _ \ / | | | | | / _ \ | '_ _ \ | ' \ | __| | | | |
| | | | | __/ *
\ __ \ | (| | | (| | | / | |) | | () | | (| | | || | | __/ | | | | | | | |) | | | | || |
|
| |_| _
| |
_/ |/ __,| __, | | |./ _/ **,_| __, | _| || || |_| | ./ __| __, |
|
_/ |*/ || |___/

elminson added a commit to elminson/PHPMailer that referenced this issue Mar 8, 2016
@Synchro
Copy link
Member Author

Synchro commented Mar 8, 2016

@elminson Pulling in static copies of figlet isn't helpful - they should be loaded via composer, if at all, and isn't really the point of the diagnose function.

An implementation of the diagnose function as I suggested has some implications for class size - PHPMailer is already too big - and I'm not sure how to reconcile that with the need for being in-context with minimal code changes to use it. Take a look at #640 anyway.

@ivantcholakov
Copy link
Contributor

An idea I can imagine for the moment:

1- A new file class.phpmailerdiagnostics.php is to be created, it is to contain the implementations of the methods for diagnostics. The main class PHPMailer is to create an instance of PHPMailerDiagnostics and to use it for exposing public API for diagnostics.

2- The main class PHPMailer could have a method called diagnose:

public function diagnose($what) {

    static $diagnostics = null;

    if (!is_object($diagnostics)) {
        // Create the diagnoser instance, inject the corresponding dependency.
        $diagnostics = new PHPMailerDiagnostics($this);
    }

    // If it is necessary, the naming convention what -> method might be changed.
    $method = $what;

    // Take the parameters, skip the first one ($what).
    $parameters = func_get_args();
    array_shift($parameters);

    return call_user_func_array(array($diagnostics, $method), $parameters);
}

Edit: I've slightly corrected this code.

This method (which means the implementations in the auxiliary class too) is to return boolean (success/failure), the textual details are to be stored within the currently implemented info for debugging.

3- A good example to be implemented for illustration is this one https://github.com/PHPMailer/PHPMailer/blob/v5.2.14/examples/smtp_check.phps If the main class gives me this check respecting the set PHPMailers options, and in the way described above, then I could easily build within the administrator's area a page that tests the connection and giving feedback information. If PHPMailer is not set to use SMTP, the diagnostic method will return false, the debugging text will be sort of "SMTP is not set as mailer's protocol.".

4- This way also could be useful for the existing integration libraries for PHPMailer, for upgrading they would only need to expose/translate the new method PHPMailer::diagnose().

@net4u
Copy link

net4u commented Dec 28, 2017

Hi,
Troubleshooting guide it may nice, but it don't cover some scenarios: e.g. I have troubles with:
Mailer Error: Message body empty
since body is not empty at all (I used to echoed it just one row above). And I did not find any word about this exception.

@Synchro
Copy link
Member Author

Synchro commented Dec 28, 2017

Generally you will get that error when Body is empty, which really doesn't need further explanation, but it's also possible to get that exception if you do something silly like this:

$mail->addAttachment('filename.jpg');
unlink('filename.jpg');
$mail->send();

@net4u
Copy link

net4u commented Dec 28, 2017

Hi,
No I don't attach nothing.
Shortly is:

 $email_message = "";
 $email_message .= "Nume: $first_name |\n";
 $email_message .= "Prenume: $last_name |\n";
 $email_message .= "Email: $email_from |\n";
 $email_message .= "Telefon: $telephone |\n";
 $email_message .= "Mesaj: $comments |\n";
 echo("<p>Continutul mesajului: $email_message</p>");
 //
 $mail->isHTML(false);
 $mail->body = $email_message; 
 //send the message, check for errors
 if (!$mail->send()) {
     echo 'Mailer Error: ' . $mail->ErrorInfo;
 } else {
     echo 'Message sent!';
 }

@Synchro
Copy link
Member Author

Synchro commented Dec 28, 2017

Pay attention to the detail: PHP is case sensitive: $mail->body and $mail->Body are not the same thing.

@net4u
Copy link

net4u commented Dec 28, 2017

Thnx.
I am not PHP based so I have no Idea that is case sensitive. Now is working fine.
Have a nice day.

@0xrisec
Copy link

0xrisec commented Jun 23, 2019

i have a doubt.
$mail->Username = "[email protected]"; // GMAIL username
$mail->Password = "********"; // GMAIL password

it will steal my gmail username and password.
why we give gmail password.
what should i do.

@elminson
Copy link

elminson commented Jun 23, 2019 via email

@Synchro
Copy link
Member Author

Synchro commented Jun 23, 2019

@babuhacker, do not post the same question multiple times; twice is annoying; six times is abuse. Also search before you post.

Gmail is not “stealing” your ID and password; it’s how they know who you are. It’s true that managing secrets is tricky; the most common way is to inject the secrets through environment variables, which removes the need to have secrets embedded in your source code.

As @elminson said, PHPMailer supports XOAUTH2 authentication, which gmail can use. Look at the code example that shows how to do it, and read the wiki article about how to set it up.

@rootbabu
Copy link

I'm sorry I was thinking that different people reached this message.

@samdoj
Copy link

samdoj commented Jul 25, 2020

What are your thoughts on adding a diagnostics logger, which the diagnostics tool can analyze for problems, as well as looking for likely or common coding errors? Perhaps it could be in a composer module called PHPmailer/diagnostic_tool. The readme or the Phpmailer/Exception class could point users to that module.

The phpmailer/Exception message could be appended with "please run 'composer install PHPmailer/diagnostic_tool' for more information. If the module is installed, all errors and warnings will be logged to a file specified in diagnostic_tool.ini file. Using the diagnostic tool would be as simple as running the script after installing it and running yours. This gets around class size bloat, and if coded right could provide valuable information. I'd be happy to get the ball rolling if you like any/all of these ideas.

@Synchro
Copy link
Member Author

Synchro commented Jul 27, 2020

I think that's a bit too roundabout – many people have a hard time even finding their log files, and in shared hosting may not be able to see them at all; installing additional packages has similar issues. I'm still very much in favour of either adding a diagnose method like I suggested before:

if ($mail->send()) {
    echo 'yay!';
} else {
    echo $mail->diagnose();
}

Or in order to avoid bloating the main class further, a subclass that replaces the send method, producing a report instead of sending:

$mail = new PHPMailerDiagnostics(true);
//...
$mail->send();

We could also provide a diagnostic logger example that is injected via the Debugoutput mechanism we've already got.

@samdoj
Copy link

samdoj commented Jul 27, 2020

Okay, I'll get started on a PHPMailerDiagnostics class. I think it's probably best to leave everything else intact and make it so if you don't need it (ie when deploying your solution,) you can just delete those classes, much as you can for the language classes.

@lkppo
Copy link

lkppo commented Oct 11, 2021

Hello,

In my opinion it is possible to mitigate the problem. For example by offering for example a different default port number depending on the authentication method (plain, tls, ssl). The user can always force the port for special cases.

There may be something else of this type that will allow you not to have to add this diagnostic function.

Regards,

@Synchro
Copy link
Member Author

Synchro commented Oct 11, 2021

That makes no sense. The aim of a diagnostic function is to tell you what's wrong, and suggest ways that you might fix it. In many cases it will indeed be possible to mitigate the problem, but that's no help if you have no idea what to do. For example, if changing to a different port number is the solution to a problem, it would suggest that as something to try.

This ticket is not about fixing specific issues, but how to give people some better ideas of how to fix problems, guidance of what avenues are likely to be relevant. Specifically, many of these problems cannot be fixed in code, no matter what we do; if your ISP blocks outbound SMTP, there is no code you can write that will make that work.

@lkppo
Copy link

lkppo commented Oct 11, 2021

I understand your point and don't talk against to tool. My idea is about catching/removing minor issues before you need this tool.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants