EN | CS | Přihlásit | Registrovat

nSMTPMailer

Tato knihovna slouží pro odesílání emailů přes (i zabezpečené) SMTP servery. Jedním z hlavních cílů je i její použitelnost bez Nette, ovšem s Nette je její použití samozřejmě mnohem pohodlnější (hlavně díky Nette\Mail). Dalším cílem je co nejvěrnější implementace příslušných RFC.

Vrták už podobnou knihovnu napsal dřív (SmtpSendmail­Mailer), a i ta jeho ve většině běžných případů funguje. Nicméně vypadá, že je daleko víc zadrátovaná do Nette, navíc je licencovaná pod LGPL.

Verze 1.0
Download http://github.com/…TPMailer.zip
Demo pouze ke stažení, jinak bych také použitý server mohl dostat na SMTP blacklisty; ukázka použití bez Nette: http://github.com/…/example.php ; ukázka použití s Nette: http://github.com/…_example.zip
Forum thread http://forum.nette.org/…tp-mailovani
Autor Martin Pecka (peci1 uzenáč seznam)
Licence New BSD
Homepage http://addons.nette.org/cs/nsmtpmailer
Git web http://github.com/…/nSMTPMailer
Git git://github.com/pe­ci1/nSMTPMailer­.git

Adresářová struktura

  • nSMTPMailer
    • Commands
      • Implementace SMTP příkazů
    • SmtpClient.php
    • exceptions.php
    • Communicator.php
    • Response.php
    • license.txt
    • netterobots.txt
  • SmtpMailer.php

Použití v Nette

Instalace

Stáhněte a archiv rozbalte do LIBS_DIR (v defaultní Nette struktuře je to /libs; je to ta složka, kde máte i složku Nette). Tím je instalace hotova (pokud tedy používáte RobotLoader, jinak musíte includnout SmtpMailer.php).

Můžete smazat soubory exceptions.php a netterobots.txt, ale buďto pouze oba najednou a nebo je oba nechte být!

Příklad použití

SendModel.php – nějaký model, který obstarává odesílání emailů

<?php

class SendModel
{
private $result = '';

/**
* Pošle email
* @param array of string $recipients Příjemci emailu
* @param string $body Tělo emailu
*/

public function send(array $recipients, $body) {

//povolíme nastavování přes config.ini
$conf = Environment::getConfig('mail');

//email sestavíme pomocí Nette\Mail
$mail = new Mail();

//nastavení nSMTPMaileru (z config.ini)
$mailer = new SmtpMailer($conf['host'], $conf['port'],
$conf['transport'], $conf['username'], $conf['password'],
$conf['authId'], $conf['mechanism'], $conf['tryUnauthenticated']);

$mail->setMailer($mailer); //důležité!!!

$mail->setFrom($conf['from']);

$undelivered = array();
foreach ($recipients as $email) {
try {
//tady můžeme prohnat zadané adresy nějakým úžasným regexem
if (!preg_match('/^\s*$/', $email)) {
//můžeme použít i addCC a addBcc
$mail->addTo($email);
} else {
$undelivered[] = $email;
}
} catch (InvalidArgumentException $e) {
$undelivered[] = $email;
}
}

$mail->setSubject('Great mail');

$mail->setBody($body);

try {
$mail->send();
$undelivered = array_merge(
$undelivered,
$mailer->getUndeliveredRecipients());

if (count($undelivered) > 0)
$this->result = $undelivered;
else
$this->result = TRUE;
} catch (InvalidStateException $e) {
$this->result = FALSE;
}

}

public function getResult()
{
return $this->result;
}
}

?>

A ukázkový config.ini

[common]
mail.from = "username@gmail.com"
mail.username = "username"
mail.password = "password"
mail.host = "smtp.gmail.com"
mail.port = "587"
mail.transport = "tcp"

Parametry konstruktoru SmtpMailer

Parametr Význam Defaultní hodnota
$server URL adresa SMTP serveru (bez schématu (http://)) (viz Příklady konfigurace) povinný
$port Port, na který se připojit (viz Příklady konfigurace) 25
$transport Transportní vrstva (viz Příklady konfigurace) ‚tcp‘
$username Uživatelské jméno (viz Implementované autentizační mechanismy) NULL
$password Heslo (viz Implementované autentizační mechanismy) NULL
$authId Role pro PLAIN autentizaci (viz Implementované autentizační mechanismy) NULL
$mechanism Preferovaný autentizační mechanismus (viz Příklady konfigurace) LOGIN
$tryUnauthenticated Zkusit odeslat email i přes nepovedenou autentizaci? TRUE

Použití bez Nette

Instalace

Pokud nechcete tuto knihovnu používat v Nette, ale v nějaké jiné aplikaci, rozbalte archiv a někam do své aplikace překopírujte podsložku nSMTPMailer (tj. nekopírujte SmtpMailer.php !). Pak includněte SmtpClient.php.

Můžete smazat netterobots.txt

Pokud používáte nějakou formu autoloadingu, je třeba ho ve složce nSMTPMailer zakázat a includovat pouze SmtpClient.php!

Knihovna si definuje výjimky InvalidStateEx­ception a IOException. Pokud je vaše aplikace také definuje, musíte zajistit jejich kompatibilitu s výjimkami v exceptions.php!

Příklad použití

send.php

<?php

header('Content-Type: text/html; charset=utf-8');
require_once('nSMTPMailer/SMTPClient.php');

$client = new SMTPClient();

$client->setConnectionInfo('smtp.gmail.com', 587, 'tcp', 300);
$client->setLoginInfo('username', 'password');

$client->setFrom('username@gmail.com');

$recipients = array('user1@seznam.cz', 'user2@seznam.cz');
$client->setRecipients($recipients);

$client->setBody('Very dirty message without headers in it!');

try {
$client->send();
$undelivered = $client->getUndeliveredRecipients();
if (empty($undelivered))
echo 'Email byl úspěšně odeslán';
else
echo 'Email se neodeslal na tyto adresy: ' . implode (',', $undelivered);
} catch (InvalidStateException $e) {
echo 'Email se vůbec nepovedlo odeslat';
}

/* ?> omitted intentionally */

Parametry pro setConnectionInfo a setLoginInfo odpovídají parametrům konstruktoru SmtpMailer (viz Parametry konstruktoru SmtpMailer)

Jako argument pro setBody je nutné předat už hotový email včetně hlaviček a všeho ostatního! Právě tuhle práci pro Nettisty udělá Nette\Mail (a možná si ji i neNettisté mohou vyextrahovat a pak používat SmtpMailer).

Poznámky k implementaci

Návratová hodnota SmtpClient::send()

Metoda send() nemá žádnou návratovou hodnotu. Pokud vyhodí výjimku InvalidStateEx­ception, pak se nepovedlo připojení k serveru, selhala autentizace nebo nebyli specifikováni žádní (validní) příjemci. Pokud výjimku nevyhodí, pak byl email na alespoň jednu adresu odeslán. Pokud se ho na nějakou adresu nepovedlo odeslat, pak se tato adresa ocitne v poli SmtpClient::ge­tUndeliveredRe­cipients() (a to ať už z důvodu špatné adresy nebo z důvodu, že tuto adresu odmítl server). Takže byste vždy po odeslání měli obsah tohoto pole kontrolovat.

Implementované autentizační mechanismy

Zde je popis implementovaných autentizačních mechanismů a význam proměnných předávaných do SmtpClient::set­LoginInfo.

Mechanismus Popis Význam $username Význam $password Význam $authId
LOGIN Nejpoužívanější mechanismus (Google, Seznam). Bez SSL nebezpečný. Uživatelské jméno Heslo
PLAIN Nezabezpečený mechanismus, snad už se veřejně nepoužívá Uživatelské jméno Heslo Jméno role pro přihlášení
CRAM-MD5 Autentizační mechanismus bezpečný i bez SSL, ale málo používaný Uživatelské jméno Heslo

Příklady konfigurace

Konfigurace několika nejznámějších free SMTP serverů

Server Port Transportní vrstva Aut. mechanismus
smtp.gmail.com 587 tcp LOGIN
smtp.gmail.com 465 ssl LOGIN
smtp.gmail.com 25 tcp LOGIN
smtp.seznam.cz 25 tcp LOGIN

Ukázky použití

Odkazy jsou uvedeny výše. Po rozbalení příkladu pro Nette je třeba ještě vytvořit složku /libs a nahrát do ní Nette i nSMTPMailer

Debugging

Můžete nastavit statickou proměnnou SmtpClient::$de­bugMode na TRUE. Pak bude klient vypisovat komunikaci se serverem a výjimky, které nastaly uvnitř klienta. Pokud tento obsah nechcete vypsat, musíte použít output buffering (ob_start)

Poznámky k implementovaným RFC

Čísla implementovaných RFC už si nepamatuju :) Ovšem hlavní SMTP RFC vyžaduje, aby klient opakovaně zkoušel odeslat email, který se mu odeslat nepovedlo. To na běžně nastaveném PHP serveru není možné. Také doporučené timeouty nebylo možné dodržet vzhledem k omezení doby běhu skriptu.

Poznámky k licenci

Pokud New BSD licenci neznáte, tak v krátkosti – s knihovnou smíte dělat vše, co vás napadne, pokud zachováte copyrightové a právní doložky na začátku skriptů. Mimo jiné smíte knihovnu používat pro komerční účely, integrovat do non-open-source aplikací a tyto aplikace pak prodávat. Licence je plně kompatibilní s GPL (a snad i LGPL).


Komentáře Comments feed

oaki | 23. 4. 2010, 15:11 | bug

Ahoj, toto mi vyhadzuje pri odosielani. PHP Deprecated: Function eregi() is deprecated in /Nette-extras/nSMTPMa­iler/nSMTPMai­ler/Commands/Ba­seCommand.php on line 180

Matúš Matula | 26. 4. 2010, 1:40 | comment

v php 5.3 je eregi deprecated, pouzi namiesto toho preg_match s identifikatorom ‚i‘ . viac napr. tu http://takien.com/…hp-5-3-0.php

Login to submit a comment