From 8d9ee9a498ba3be9d98ac4113b4ca781220aa5f7 Mon Sep 17 00:00:00 2001 From: igor Date: Sat, 21 Jun 2025 18:33:36 +0200 Subject: [PATCH] added basic library, added instruscions into README --- .gitignore | 2 + README.md | 126 +++++++++++++++++++++++++++++++++- composer.json | 23 +++++++ examples/example1.php | 27 ++++++++ src/Emailer.php | 155 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 332 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 composer.json create mode 100644 examples/example1.php create mode 100644 src/Emailer.php diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4fbb073 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/vendor/ +/composer.lock diff --git a/README.md b/README.md index 3bf7bbc..f072e67 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,127 @@ # Emailer -Simple send plain text and HTML e-mails over SMTP server with save messages in IMAP server. \ No newline at end of file +Simple send plain text and HTML e-mails over SMTP server with save messages in IMAP server. + +## Installation + +### Via Composer + +Install the package using Composer: + +```bash +composer require tpsoft/emailer +``` + +### Via Git Repository + +Clone the repository directly from the Git server: + +```bash +git clone https://gitea.tpsoft.org/TPsoft.org/Emailer.git +cd Emailer +composer install +``` + +## Requirements + +- PHP 7.0 or higher +- PEAR Mail package (automatically installed via Composer) +- PEAR Net_SMTP package (automatically installed via Composer) +- PEAR Mail_Mime package (automatically installed via Composer) + +## Usage + +### Basic Example + +```php + array( + 'host' => 'smtp.gmail.com', + 'port' => 465, + 'username' => 'your-email@gmail.com', + 'password' => 'your-password', + 'encryption' => 'ssl' + ), + 'imap' => array( + 'host' => 'imap.gmail.com', + 'port' => 993, + 'encryption' => 'ssl', + 'folder' => 'Sent', + 'username' => 'your-email@gmail.com', + 'password' => 'your-password' + ) +); + +// Create Emailer instance +$emailer = new Emailer($config); + +// Send email with both plain text and HTML content +$emailer->send( + 'recipient@example.com', + 'Test Email at ' . date('Y-m-d H:i:s'), + 'This is the plain text version of the message', + 'This is the HTML version of the message' +); +``` + +### Configuration Options + +#### SMTP Configuration + +- `host` - SMTP server hostname +- `port` - SMTP server port (usually 587 for TLS, 465 for SSL) +- `username` - SMTP authentication username +- `password` - SMTP authentication password +- `encryption` - Encryption type ('tls' or 'ssl') + +#### IMAP Configuration (Optional) + +The IMAP configuration is used to save sent messages to your mail server's sent folder: + +- `host` - IMAP server hostname +- `port` - IMAP server port (usually 993 for SSL, 143 for non-encrypted) +- `encryption` - Encryption type ('ssl' or leave empty for non-encrypted) +- `folder` - Folder name where sent messages will be saved (e.g., 'Sent', 'INBOX.Sent') +- `username` - IMAP authentication username +- `password` - IMAP authentication password + +### Method Parameters + +The `send()` method accepts the following parameters: + +```php +$emailer->send($to, $subject, $plainText, $htmlContent); +``` + +- `$to` - Recipient email address +- `$subject` - Email subject line +- `$plainText` - Plain text version of the message +- `$htmlContent` - HTML version of the message (optional) + +## Features + +- Send emails via SMTP with authentication +- Support for both plain text and HTML content +- Automatic saving of sent messages to IMAP folder +- SSL/TLS encryption support +- Easy configuration through array + +## License + +This project is licensed under the GPL-3.0-or-later License. + +## Author + +- **Igor Mino** - [mino@tpsoft.org](mailto:mino@tpsoft.org) + +## Support + +For issues and questions, please visit the repository at: https://gitea.tpsoft.org/TPsoft.org/Emailer diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..682db48 --- /dev/null +++ b/composer.json @@ -0,0 +1,23 @@ +{ + "name": "tpsoft/emailer", + "description": "Simple send plain text and HTML e-mails over SMTP server with save messages in IMAP server.", + "type": "library", + "license": "GPL-3.0-or-later", + "autoload": { + "psr-4": { + "TPsoft\\Emailer\\": "src/" + } + }, + "authors": [ + { + "name": "igor", + "email": "mino@tpsoft.org" + } + ], + "minimum-stability": "stable", + "require": { + "pear/mail": "^2.0", + "pear/net_smtp": "^1.12", + "pear/mail_mime": "^1.10" + } +} diff --git a/examples/example1.php b/examples/example1.php new file mode 100644 index 0000000..faebe64 --- /dev/null +++ b/examples/example1.php @@ -0,0 +1,27 @@ + array( + 'host' => 'smtp.gmail.com', + 'port' => 465, + 'username' => 'username', + 'password' => 'password', + 'encryption' => 'ssl' + ), + 'imap' => array( + 'host' => 'imap.gmail.com', + 'port' => 993, + 'encryption' => 'ssl', + 'folder' => 'Sent', + 'username' => 'username', + 'password' => 'password' + ) +); + + +$emailer = new Emailer($config); +$emailer->send('joe@exemple.com', 'Test at ' . date('Y-m-d H:i:s'), 'Plain text message', 'HTML message'); diff --git a/src/Emailer.php b/src/Emailer.php new file mode 100644 index 0000000..5c021ff --- /dev/null +++ b/src/Emailer.php @@ -0,0 +1,155 @@ + + License: GNU GPL-3.0 or later + + Description: Simple send plain text and HTML e-mails over SMTP server with save messages in IMAP server. + Version: 1.0.0 + + Milestones: + 2025-06-20 22:30 Igor - Forked from Beteha to standalone public library +*/ + +namespace TPsoft\Emailer; + +require_once __DIR__ . '/../vendor/autoload.php'; + +use PEAR; +use Mail; +use Mail_mime; +use Exception; + +class Emailer +{ + private $config_smtp = array( + 'host' => null, + 'port' => null, + 'encryption' => null, + 'username' => null, + 'password' => null, + ); + + private $config_imap = array( + 'host' => null, + 'port' => null, + 'username' => null, + 'password' => null, + 'encryption' => null, + 'folder' => null + ); + + public function __construct(array $config = array()) + { + $this->config_smtp = array_merge($this->config_smtp, $config['smtp']); + $this->config_imap = array_merge($this->config_imap, $config['imap']); + } + + public function send(string $send_to, string $subject, string $message_text, string $message_html): bool + { + $secure = $this->config_smtp['encryption'] ?? 'smtp'; + // Odoslanie spravu + $suc = $this->smtpEmail( + $secure . '://' . $this->config_smtp['host'], + $this->config_smtp['port'], + $this->config_smtp['username'], + $this->config_smtp['password'], + $this->config_smtp['username'], + $send_to, + $subject, + $message_text, + $message_html, + null, + $message_mime + ); + if ($suc != true) { + return false; + } + // Ulozenie spravy do odoslanych + if ($this->config_imap['host']) { + $suc2 = $this->imapEmailSave( + $this->config_imap['host'], + $this->config_imap['port'], + $this->config_imap['encryption'], + $this->config_imap['folder'], + $this->config_imap['username'], + $this->config_imap['password'], + $message_mime + ); + if ($suc2 != true) { + return false; + } + } + return true; + } + + public function smtpEmail($smtp_host, $smtp_port = 465, $smtp_username, $smtp_password, $email_from, $email_to, $subject, $message_text = null, $message_html = null, $reply_to = null, &$message_mime = null) + { + if (is_null($reply_to)) $reply_to = $email_from; + + $crlf = "\n"; + $hdrs = array( + 'From' => $email_from, + 'To' => $email_to, + 'Subject' => '=?UTF-8?B?' . base64_encode($subject) . '?=', + 'Reply-To' => $reply_to, + 'Content-Type' => 'text/plain; charset=utf-8', + 'X-Mailer' => 'TPsoft/Emailer' + ); + $mime_params = array( + 'eol' => $crlf, + 'text_encoding' => '7bit', + 'text_charset' => 'UTF-8', + 'html_charset' => 'UTF-8', + 'head_charset' => 'UTF-8' + ); + $mime = new Mail_mime($mime_params); + + if (!is_null($message_text)) $mime->setTXTBody($message_text); + if (!is_null($message_html)) $mime->setHTMLBody($message_html); + //$mime->addAttachment($file, 'text/plain'); + + $body = $mime->get(); + $headers = $mime->headers($hdrs); + $message_mime = $mime->getMessage(); + + $smtp = Mail::factory('smtp', ['host' => $smtp_host, 'port' => $smtp_port, 'auth' => true, 'username' => $smtp_username, 'password' => $smtp_password]); + $mail = $smtp->send($email_to, $headers, $body); + + if (PEAR::isError($mail)) { + throw new Exception($mail->getMessage()); + } + return true; + } + + public function imapEmailSave($imap_host, $imap_port = 993, $imap_secure = 'ssl', $imap_folder = 'Sent', $imap_username, $imap_password, $message_mime) + { + // example $path = "{imap.gmail.com:993/imap/ssl}[Gmail]/Sent Mail"; + $path = sprintf('{%s:%s/%s}%s', $imap_host, $imap_port, $imap_secure, $imap_folder); + //Tell your server to open an IMAP connection using the same username and password as you used for SMTP + $imapStream = imap_open($path, $imap_username, $imap_password); + $result = imap_append($imapStream, $path, $message_mime); + imap_close($imapStream); + return $result; + } + + public function imapList($imap_host, $imap_port = 993, $imap_secure = 'ssl', $imap_username, $imap_password) + { + $mbox = imap_open('{' . $imap_host . ':' . $imap_port . '/' . $imap_secure . '}', $imap_username, $imap_password, OP_HALFOPEN); + if (!$mbox) { + throw new Exception('Can\'t connect: '.imap_last_error()); + } + $list = imap_list($mbox, '{' . $imap_host . ':' . $imap_port . '/' . $imap_secure . '}', "*"); + $ret = array(); + if (is_array($list)) { + foreach ($list as $val) { + $ret[] = imap_utf7_decode($val); + } + } else { + throw new Exception('imap_list failed: ' . imap_last_error()); + } + imap_close($mbox); + return $ret; + } + +}