Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/applications/config/option/PhabricatorPHPMailerConfigOptions.php b/src/applications/config/option/PhabricatorPHPMailerConfigOptions.php
index d4918f934c..a9b5643206 100644
--- a/src/applications/config/option/PhabricatorPHPMailerConfigOptions.php
+++ b/src/applications/config/option/PhabricatorPHPMailerConfigOptions.php
@@ -1,50 +1,67 @@
<?php
final class PhabricatorPHPMailerConfigOptions
extends PhabricatorApplicationConfigOptions {
public function getName() {
return pht('PHPMailer');
}
public function getDescription() {
return pht('Configure PHPMailer.');
}
public function getOptions() {
return array(
$this->newOption('phpmailer.mailer', 'string', 'smtp')
->setLocked(true)
->setSummary(pht('Configure mailer used by PHPMailer.'))
->setDescription(
pht(
"If you're using PHPMailer to send email, provide the mailer and ".
"options here. PHPMailer is much more enormous than ".
"PHPMailerLite, and provides more mailers and greater enormity. ".
"You need it when you want to use SMTP instead of sendmail as the ".
"mailer.")),
$this->newOption('phpmailer.smtp-host', 'string', null)
->setLocked(true)
->setDescription(pht('Host for SMTP.')),
$this->newOption('phpmailer.smtp-port', 'int', 25)
->setLocked(true)
->setDescription(pht('Port for SMTP.')),
// TODO: Implement "enum"? Valid values are empty, 'tls', or 'ssl'.
$this->newOption('phpmailer.smtp-protocol', 'string', null)
->setLocked(true)
->setSummary(pht('Configure TLS or SSL for SMTP.'))
->setDescription(
pht(
"Using PHPMailer with SMTP, you can set this to one of 'tls' or ".
"'ssl' to use TLS or SSL, respectively. Leave it blank for ".
"vanilla SMTP. If you're sending via Gmail, set it to 'ssl'.")),
$this->newOption('phpmailer.smtp-user', 'string', null)
->setLocked(true)
->setDescription(pht('Username for SMTP.')),
$this->newOption('phpmailer.smtp-password', 'string', null)
->setMasked(true)
->setDescription(pht('Password for SMTP.')),
+ $this->newOption('phpmailer.smtp-encoding', 'string', '8bit')
+ ->setSummary(pht('Configure how mail is encoded.'))
+ ->setDescription(
+ pht(
+ "Mail is normally encoded in `8bit`, which works correctly with ".
+ "most MTAs. However, some MTAs do not work well with this ".
+ "encoding. If you're having trouble with mail being mangled or ".
+ "arriving with too many or too few newlines, you may try ".
+ "adjusting this setting.\n\n".
+ "Supported values are `8bit` (default), `quoted-printable`, ".
+ "`7bit`, `binary` and `base64`.\n\n".
+ "The settings in the table below may work well.\n\n".
+ "| MTA | Setting | Notes\n".
+ "|-----|---------|------\n".
+ "| SendGrid via SMTP | `quoted-printable` | Double newlines under ".
+ "`8bit`.\n".
+ "| All Other MTAs | `8bit` | Default setting.")),
);
}
}
diff --git a/src/applications/metamta/adapter/PhabricatorMailImplementationPHPMailerAdapter.php b/src/applications/metamta/adapter/PhabricatorMailImplementationPHPMailerAdapter.php
index 32f152f8ff..d9609b1a7b 100644
--- a/src/applications/metamta/adapter/PhabricatorMailImplementationPHPMailerAdapter.php
+++ b/src/applications/metamta/adapter/PhabricatorMailImplementationPHPMailerAdapter.php
@@ -1,123 +1,121 @@
<?php
final class PhabricatorMailImplementationPHPMailerAdapter
extends PhabricatorMailImplementationAdapter {
/**
* @phutil-external-symbol class PHPMailer
*/
public function __construct() {
$root = phutil_get_library_root('phabricator');
$root = dirname($root);
require_once $root.'/externals/phpmailer/class.phpmailer.php';
$this->mailer = new PHPMailer($use_exceptions = true);
$this->mailer->CharSet = 'utf-8';
- // NOTE: This works around what seems to be a bug in SendGrid, see
- // D10278. This affects other SMTP mailers too, but as long as they
- // don't have an opposite bug to SendGrid's bug that should be OK.
- $this->mailer->Encoding = 'quoted-printable';
+ $encoding = PhabricatorEnv::getEnvConfig('phpmailer.smtp-encoding', '8bit');
+ $this->mailer->Encoding = $encoding;
// By default, PHPMailer sends one mail per recipient. We handle
// multiplexing higher in the stack, so tell it to send mail exactly
// like we ask.
$this->mailer->SingleTo = false;
$mailer = PhabricatorEnv::getEnvConfig('phpmailer.mailer');
if ($mailer == 'smtp') {
$this->mailer->IsSMTP();
$this->mailer->Host = PhabricatorEnv::getEnvConfig('phpmailer.smtp-host');
$this->mailer->Port = PhabricatorEnv::getEnvConfig('phpmailer.smtp-port');
$user = PhabricatorEnv::getEnvConfig('phpmailer.smtp-user');
if ($user) {
$this->mailer->SMTPAuth = true;
$this->mailer->Username = $user;
$this->mailer->Password =
PhabricatorEnv::getEnvConfig('phpmailer.smtp-password');
}
$protocol = PhabricatorEnv::getEnvConfig('phpmailer.smtp-protocol');
if ($protocol) {
$protocol = phutil_utf8_strtolower($protocol);
$this->mailer->SMTPSecure = $protocol;
}
} else if ($mailer == 'sendmail') {
$this->mailer->IsSendmail();
} else {
// Do nothing, by default PHPMailer send message using PHP mail()
// function.
}
}
public function supportsMessageIDHeader() {
return true;
}
public function setFrom($email, $name = '') {
$this->mailer->SetFrom($email, $name, $crazy_side_effects = false);
return $this;
}
public function addReplyTo($email, $name = '') {
$this->mailer->AddReplyTo($email, $name);
return $this;
}
public function addTos(array $emails) {
foreach ($emails as $email) {
$this->mailer->AddAddress($email);
}
return $this;
}
public function addCCs(array $emails) {
foreach ($emails as $email) {
$this->mailer->AddCC($email);
}
return $this;
}
public function addAttachment($data, $filename, $mimetype) {
$this->mailer->AddStringAttachment(
$data,
$filename,
'base64',
$mimetype);
return $this;
}
public function addHeader($header_name, $header_value) {
if (strtolower($header_name) == 'message-id') {
$this->mailer->MessageID = $header_value;
} else {
$this->mailer->AddCustomHeader($header_name.': '.$header_value);
}
return $this;
}
public function setBody($body) {
$this->mailer->IsHTML(false);
$this->mailer->Body = $body;
return $this;
}
public function setHTMLBody($html_body) {
$this->mailer->IsHTML(true);
$this->mailer->Body = $html_body;
return $this;
}
public function setSubject($subject) {
$this->mailer->Subject = $subject;
return $this;
}
public function hasValidRecipients() {
return true;
}
public function send() {
return $this->mailer->Send();
}
}
diff --git a/src/applications/metamta/adapter/PhabricatorMailImplementationPHPMailerLiteAdapter.php b/src/applications/metamta/adapter/PhabricatorMailImplementationPHPMailerLiteAdapter.php
index 5b27b78561..e758832039 100644
--- a/src/applications/metamta/adapter/PhabricatorMailImplementationPHPMailerLiteAdapter.php
+++ b/src/applications/metamta/adapter/PhabricatorMailImplementationPHPMailerLiteAdapter.php
@@ -1,103 +1,105 @@
<?php
/**
* TODO: Should be final, but inherited by SES.
*/
class PhabricatorMailImplementationPHPMailerLiteAdapter
extends PhabricatorMailImplementationAdapter {
/**
* @phutil-external-symbol class PHPMailerLite
*/
public function __construct() {
$root = phutil_get_library_root('phabricator');
$root = dirname($root);
require_once $root.'/externals/phpmailer/class.phpmailer-lite.php';
$this->mailer = new PHPMailerLite($use_exceptions = true);
$this->mailer->CharSet = 'utf-8';
- $this->mailer->Encoding = 'quoted-printable';
+
+ $encoding = PhabricatorEnv::getEnvConfig('phpmailer.smtp-encoding', '8bit');
+ $this->mailer->Encoding = $encoding;
// By default, PHPMailerLite sends one mail per recipient. We handle
// multiplexing higher in the stack, so tell it to send mail exactly
// like we ask.
$this->mailer->SingleTo = false;
}
public function supportsMessageIDHeader() {
return true;
}
public function setFrom($email, $name = '') {
$this->mailer->SetFrom($email, $name, $crazy_side_effects = false);
return $this;
}
public function addReplyTo($email, $name = '') {
$this->mailer->AddReplyTo($email, $name);
return $this;
}
public function addTos(array $emails) {
foreach ($emails as $email) {
$this->mailer->AddAddress($email);
}
return $this;
}
public function addCCs(array $emails) {
foreach ($emails as $email) {
$this->mailer->AddCC($email);
}
return $this;
}
public function addAttachment($data, $filename, $mimetype) {
$this->mailer->AddStringAttachment(
$data,
$filename,
'base64',
$mimetype);
return $this;
}
public function addHeader($header_name, $header_value) {
if (strtolower($header_name) == 'message-id') {
$this->mailer->MessageID = $header_value;
} else {
$this->mailer->AddCustomHeader($header_name.': '.$header_value);
}
return $this;
}
public function setBody($body) {
$this->mailer->Body = $body;
$this->mailer->IsHTML(false);
return $this;
}
/**
* Note: phpmailer-lite does NOT support sending messages with mixed version
* (plaintext and html). So for now lets just use HTML if it's available.
* @param $html
*/
public function setHTMLBody($html_body) {
$this->mailer->Body = $html_body;
$this->mailer->IsHTML(true);
return $this;
}
public function setSubject($subject) {
$this->mailer->Subject = $subject;
return $this;
}
public function hasValidRecipients() {
return true;
}
public function send() {
return $this->mailer->Send();
}
}
diff --git a/src/docs/user/configuration/configuring_outbound_email.diviner b/src/docs/user/configuration/configuring_outbound_email.diviner
index fdc5abf153..77d09f7cf2 100644
--- a/src/docs/user/configuration/configuring_outbound_email.diviner
+++ b/src/docs/user/configuration/configuring_outbound_email.diviner
@@ -1,189 +1,200 @@
@title Configuring Outbound Email
@group config
Instructions for configuring Phabricator to send mail.
= Overview =
Phabricator can send outbound email via several different providers, called
"Adapters".
| Send Mail With | Setup | Cost | Inbound | Notes |
|---------|-------|------|---------|-------|
| Mailgun | Easy | Cheap | Yes | Recommended |
| Amazon SES | Easy | Cheap | No | Recommended |
-| SendGrid | Easy | Cheap | Yes | |
+| SendGrid | Medium | Cheap | Yes | Discouraged (See Note) |
| External SMTP | Medium | Varies | No | Gmail, etc. |
| Local SMTP | Hard | Free | No | (Default) sendmail, postfix, etc |
| Custom | Hard | Free | No | Write an adapter for some other service. |
| Drop in a Hole | Easy | Free | No | Drops mail in a deep, dark hole. |
Of these options, sending mail via local SMTP is the default, but usually
requires some configuration to get working. See below for details on how to
select and configure a delivery method.
Overall, Mailgun and SES are much easier to set up, and using one of them is
recommended. In particular, Mailgun will also let you set up inbound email
easily.
If you have some internal mail service you'd like to use you can also
write a custom adapter, but this requires digging into the code.
Phabricator sends mail in the background, so the daemons need to be running for
it to be able to deliver mail. You should receive setup warnings if they are
not. For more information on using daemons, see
@{article:Managing Daemons with phd}.
+**Note on SendGrid**: Users have experienced a number of odd issues with
+SendGrid, compared to fewer issues with other mailers. We discourage SendGrid
+unless you're already using it. If you send to SendGrid via SMTP, you may need
+to adjust `phpmailer.smtp-encoding`.
+
= Basics =
Regardless of how outbound email is delivered, you should configure these keys
in your configuration:
- **metamta.default-address** determines where mail is sent "From" by
default. If your domain is `example.org`, set this to something like
`noreply@example.org`.
- **metamta.domain** should be set to your domain, e.g. `example.org`.
- **metamta.can-send-as-user** should be left as ##false## in most cases,
but see the documentation for details.
= Configuring Mail Adapters =
To choose how mail will be sent, change the `metamta.mail-adapter` key in
your configuration. Possible values are listed in the UI:
- ##PhabricatorMailImplementationAmazonMailgunAdapter##: use Mailgun, see
"Adapter: Mailgun".
- ##PhabricatorMailImplementationAmazonSESAdapter##: use Amazon SES, see
"Adapter: Amazon SES".
- ##PhabricatorMailImplementationPHPMailerLiteAdapter##: default, uses
"sendmail", see "Adapter: Sendmail".
- ##PhabricatorMailImplementationPHPMailerAdapter##: uses SMTP, see
"Adapter: SMTP".
- ##PhabricatorMailImplementationSendGridAdapter##: use SendGrid, see
"Adapter: SendGrid".
- ##Some Custom Class You Write##: use a custom adapter you write, see
"Adapter: Custom".
- ##PhabricatorMailImplementationTestAdapter##: this will
**completely disable** outbound mail. You can use this if you don't want to
send outbound mail, or want to skip this step for now and configure it
later.
= Adapter: Sendmail =
This is the default, and selected by choosing
`PhabricatorMailImplementationPHPMailerLiteAdapter` as the value for
**metamta.mail-adapter**. This requires a `sendmail` binary to be installed on
the system. Most MTAs (e.g., sendmail, qmail, postfix) should do this, but your
machine may not have one installed by default. For install instructions, consult
the documentation for your favorite MTA.
Since you'll be sending the mail yourself, you are subject to things like SPF
rules, blackholes, and MTA configuration which are beyond the scope of this
document. If you can already send outbound email from the command line or know
how to configure it, this option is straightforward. If you have no idea how to
do any of this, strongly consider using Mailgun or Amazon SES instead.
+If you experience issues with mail getting mangled (for example, arriving with
+too many or too few newlines) you may try adjusting `phpmailer.smtp-encoding`.
+
= Adapter: SMTP =
You can use this adapter to send mail via an external SMTP server, like Gmail.
To do this, set these configuration keys:
- **metamta.mail-adapter**: set to
`PhabricatorMailImplementationPHPMailerAdapter`.
- **phpmailer.mailer**: set to `smtp`.
- **phpmailer.smtp-host**: set to hostname of your SMTP server.
- **phpmailer.smtp-port**: set to port of your SMTP server.
- **phpmailer.smtp-user**: set to your username used for authentication.
- **phpmailer.smtp-password**: set to your password used for authentication.
- **phpmailer.smtp-protocol**: set to `tls` or `ssl` if necessary. Use
`ssl` for Gmail.
+ - **phpmailer.smtp-encoding**: Normally safe to leave as the default, but
+ adjusting it may help resolve mail mangling issues (for example, mail
+ arriving with too many or too few newlines).
= Adapter: Mailgun =
Mailgun is an email delivery service. You can learn more at
<http://www.mailgun.com>. Mailgun isn't free, but is very easy to configure
and works well.
To use Mailgun, sign up for an account, then set these configuration keys:
- **metamta.mail-adapter**: set to
`PhabricatorMailImplementationMailgunAdapter`.
- **mailgun.api-key**: set to your Mailgun API key.
- **mailgun.domain**: set to your Mailgun domain.
= Adapter: Amazon SES =
Amazon SES is Amazon's cloud email service. It is not free, but is easier to
configure than sendmail and can simplify outbound email configuration. To use
Amazon SES, you need to sign up for an account with Amazon at
<http://aws.amazon.com/ses/>.
To configure Phabricator to use Amazon SES, set these configuration keys:
- **metamta.mail-adapter**: set to
"PhabricatorMailImplementationAmazonSESAdapter".
- **amazon-ses.access-key**: set to your Amazon SES access key.
- **amazon-ses.secret-key**: set to your Amazon SES secret key.
NOTE: Amazon SES **requires you to verify your "From" address**. Configure which
"From" address to use by setting "##metamta.default-address##" in your config,
then follow the Amazon SES verification process to verify it. You won't be able
to send email until you do this!
= Adapter: SendGrid =
SendGrid is an email delivery service like Amazon SES. You can learn more at
<http://sendgrid.com/>. It is easy to configure, but not free.
You can configure SendGrid in two ways: you can send via SMTP or via the REST
API. To use SMTP, just configure ##sendmail## and leave Phabricator's setup
with defaults. To use the REST API, follow the instructions in this section.
To configure Phabricator to use SendGrid, set these configuration keys:
- **metamta.mail-adapter**: set to
"PhabricatorMailImplementationSendGridAdapter".
- **sendgrid.api-user**: set to your SendGrid login name.
- **sendgrid.api-key**: set to your SendGrid password.
If you're logged into your SendGrid account, you may be able to find this
information easily by visiting <http://sendgrid.com/developer>.
= Adapter: Custom =
You can provide a custom adapter by writing a concrete subclass of
@{class:PhabricatorMailImplementationAdapter} and setting it as the
`metamta.mail-adapter`.
TODO: This should be better documented once extending Phabricator is better
documented.
= Adapter: Disable Outbound Mail =
You can use the @{class:PhabricatorMailImplementationTestAdapter} to completely
disable outbound mail, if you don't want to send mail or don't want to configure
it yet. Just set **metamta.mail-adapter** to
`PhabricatorMailImplementationTestAdapter`.
= Testing and Debugging Outbound Email =
You can use the `bin/mail` utility to test, debug, and examine outbound mail. In
particular:
phabricator/ $ ./bin/mail list-outbound # List outbound mail.
phabricator/ $ ./bin/mail show-outbound # Show details about messages.
phabricator/ $ ./bin/mail send-test # Send test messages.
Run `bin/mail help <command>` for more help on using these commands.
You can monitor daemons using the Daemon Console (##/daemon/##, or click
**Daemon Console** from the homepage).
= Next Steps =
Continue by:
- @{article:Configuring Inbound Email} so users can reply to email they
receive about revisions and tasks to interact with them; or
- learning about daemons with @{article:Managing Daemons with phd}; or
- returning to the @{article:Configuration Guide}.

File Metadata

Mime Type
text/x-diff
Expires
Mon, Jul 28, 1:48 AM (1 w, 19 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
186335
Default Alt Text
(19 KB)

Event Timeline