diff --git a/composer.json b/composer.json index be697aa..4aed196 100644 --- a/composer.json +++ b/composer.json @@ -7,7 +7,9 @@ "require": { "php": "^7.3|^8.0", "symfony/yaml": "^5.1", - "studiometa/webpack-config": "^4.0" + "studiometa/webpack-config": "^4.0", + "monolog/monolog": "^2.9|^3.0", + "psr/log": "^1.1" }, "require-dev": { "squizlabs/php_codesniffer": "^3.4", diff --git a/composer.lock b/composer.lock index 25b7749..c85fbba 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "3673c457682ecd22e94f372b339a4700", + "content-hash": "5195ff182bfe92dc2aa3caebd3b47781", "packages": [ { "name": "anahkiasen/html-object", @@ -52,6 +52,158 @@ }, "time": "2017-05-31T07:52:45+00:00" }, + { + "name": "monolog/monolog", + "version": "2.9.1", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "f259e2b15fb95494c83f52d3caad003bbf5ffaa1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/f259e2b15fb95494c83f52d3caad003bbf5ffaa1", + "reference": "f259e2b15fb95494c83f52d3caad003bbf5ffaa1", + "shasum": "" + }, + "require": { + "php": ">=7.2", + "psr/log": "^1.0.1 || ^2.0 || ^3.0" + }, + "provide": { + "psr/log-implementation": "1.0.0 || 2.0.0 || 3.0.0" + }, + "require-dev": { + "aws/aws-sdk-php": "^2.4.9 || ^3.0", + "doctrine/couchdb": "~1.0@dev", + "elasticsearch/elasticsearch": "^7 || ^8", + "ext-json": "*", + "graylog2/gelf-php": "^1.4.2 || ^2@dev", + "guzzlehttp/guzzle": "^7.4", + "guzzlehttp/psr7": "^2.2", + "mongodb/mongodb": "^1.8", + "php-amqplib/php-amqplib": "~2.4 || ^3", + "phpspec/prophecy": "^1.15", + "phpstan/phpstan": "^0.12.91", + "phpunit/phpunit": "^8.5.14", + "predis/predis": "^1.1 || ^2.0", + "rollbar/rollbar": "^1.3 || ^2 || ^3", + "ruflin/elastica": "^7", + "swiftmailer/swiftmailer": "^5.3|^6.0", + "symfony/mailer": "^5.4 || ^6", + "symfony/mime": "^5.4 || ^6" + }, + "suggest": { + "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", + "doctrine/couchdb": "Allow sending log messages to a CouchDB server", + "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client", + "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", + "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler", + "ext-mbstring": "Allow to work properly with unicode symbols", + "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)", + "ext-openssl": "Required to send log messages using SSL", + "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)", + "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", + "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)", + "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", + "rollbar/rollbar": "Allow sending log messages to Rollbar", + "ruflin/elastica": "Allow sending log messages to an Elastic Search server" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Monolog\\": "src/Monolog" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "https://seld.be" + } + ], + "description": "Sends your logs to files, sockets, inboxes, databases and various web services", + "homepage": "https://github.com/Seldaek/monolog", + "keywords": [ + "log", + "logging", + "psr-3" + ], + "support": { + "issues": "https://github.com/Seldaek/monolog/issues", + "source": "https://github.com/Seldaek/monolog/tree/2.9.1" + }, + "funding": [ + { + "url": "https://github.com/Seldaek", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/monolog/monolog", + "type": "tidelift" + } + ], + "time": "2023-02-06T13:44:46+00:00" + }, + { + "name": "psr/log", + "version": "1.1.4", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/1.1.4" + }, + "time": "2021-05-03T11:20:27+00:00" + }, { "name": "studiometa/webpack-config", "version": "4.0.6", @@ -2871,5 +3023,5 @@ "php": "^7.3|^8.0" }, "platform-dev": [], - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.6.0" } diff --git a/src/Managers/EmailManager.php b/src/Managers/EmailManager.php index b73d7bc..d75b0e4 100644 --- a/src/Managers/EmailManager.php +++ b/src/Managers/EmailManager.php @@ -7,17 +7,47 @@ namespace Studiometa\WPToolkit\Managers; +use WP_Error; +use Monolog\Logger; +use Monolog\Handler\StreamHandler; +use Psr\Log\LoggerInterface; use PHPMailer\PHPMailer\PHPMailer; use function Studiometa\WPToolkit\env; /** Class **/ class EmailManager implements ManagerInterface { + /** + * Logger instance. + * + * @var LoggerInterface|null; + */ + private $logger; + + /** + * Class constructor. + * + * @param LoggerInterface|null $logger A logger instance to log mail actions. + */ + public function __construct( ?LoggerInterface $logger = null ) { + if ( ! is_null( $logger ) ) { + $this->logger = $logger; + } elseif ( env( 'MAIL_LOG' ) ) { + $this->logger = new Logger( 'email' ); + $this->logger->pushHandler( new StreamHandler( env( 'MAIL_LOG' ) ) ); + } + } + /** * {@inheritdoc} */ public function run() { if ( 'smtp' === env( 'MAIL_MAILER' ) ) { - add_action( 'phpmailer_init', array( $this, 'configure_smtp' ), 10, 1 ); + add_action( 'phpmailer_init', array( $this, 'configure_smtp' ) ); + } + + if ( $this->logger ) { + add_action( 'wp_mail_succeeded', array( $this, 'log_success' ) ); + add_action( 'wp_mail_failed', array( $this, 'log_failure' ) ); } } @@ -38,4 +68,36 @@ public function configure_smtp( PHPMailer $mailer ): void { $mailer->IsSMTP(); // phpcs:enable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase } + + /** + * Log successfully sent mails. + * + * @param array{to: string[], subject: string, message: string, headers: string[], attachments: string[]} $mail_data An array containing the email recipient(s), subject, message, headers, and attachments. + * + * @return void + */ + public function log_success( array $mail_data ): void { + if ( $this->logger ) { + $this->logger->info( 'Mail sent', $mail_data ); + } + } + + /** + * Log failure happening when sending mails. + * + * @param WP_Error $error The error sent. + * + * @return void + */ + public function log_failure( WP_Error $error ): void { + if ( $this->logger ) { + /** + * Mail data. + * + * @var array + */ + $mail_data = $error->get_error_data(); + $this->logger->error( $error->get_error_message(), $mail_data ); + } + } }