Nessuna descrizione

MailerLog.php 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. <?php
  2. namespace MailPoet\Mailer;
  3. if (!defined('ABSPATH')) exit;
  4. use MailPoet\Settings\SettingsController;
  5. class MailerLog {
  6. const SETTING_NAME = 'mta_log';
  7. const STATUS_PAUSED = 'paused';
  8. const RETRY_ATTEMPTS_LIMIT = 3;
  9. const RETRY_INTERVAL = 120; // seconds
  10. public static function getMailerLog($mailerLog = false) {
  11. if ($mailerLog) return $mailerLog;
  12. $settings = SettingsController::getInstance();
  13. $mailerLog = $settings->get(self::SETTING_NAME);
  14. if (!$mailerLog) {
  15. $mailerLog = self::createMailerLog();
  16. }
  17. return $mailerLog;
  18. }
  19. public static function createMailerLog() {
  20. $mailerLog = [
  21. 'sent' => null,
  22. 'started' => time(),
  23. 'status' => null,
  24. 'retry_attempt' => null,
  25. 'retry_at' => null,
  26. 'error' => null,
  27. ];
  28. $settings = SettingsController::getInstance();
  29. $settings->set(self::SETTING_NAME, $mailerLog);
  30. return $mailerLog;
  31. }
  32. public static function resetMailerLog() {
  33. return self::createMailerLog();
  34. }
  35. public static function updateMailerLog($mailerLog) {
  36. $settings = SettingsController::getInstance();
  37. $settings->set(self::SETTING_NAME, $mailerLog);
  38. return $mailerLog;
  39. }
  40. public static function enforceExecutionRequirements($mailerLog = false) {
  41. $mailerLog = self::getMailerLog($mailerLog);
  42. if ($mailerLog['retry_attempt'] === self::RETRY_ATTEMPTS_LIMIT) {
  43. $mailerLog = self::pauseSending($mailerLog);
  44. }
  45. if (self::isSendingPaused($mailerLog)) {
  46. throw new \Exception(__('Sending has been paused.', 'mailpoet'));
  47. }
  48. if (!is_null($mailerLog['retry_at'])) {
  49. if (time() <= $mailerLog['retry_at']) {
  50. throw new \Exception(__('Sending is waiting to be retried.', 'mailpoet'));
  51. } else {
  52. $mailerLog['retry_at'] = null;
  53. self::updateMailerLog($mailerLog);
  54. }
  55. }
  56. // ensure that sending frequency has not been reached
  57. if (self::isSendingLimitReached($mailerLog)) {
  58. throw new \Exception(__('Sending frequency limit has been reached.', 'mailpoet'));
  59. }
  60. }
  61. public static function pauseSending($mailerLog) {
  62. $mailerLog['status'] = self::STATUS_PAUSED;
  63. $mailerLog['retry_attempt'] = null;
  64. $mailerLog['retry_at'] = null;
  65. return self::updateMailerLog($mailerLog);
  66. }
  67. public static function resumeSending() {
  68. return self::resetMailerLog();
  69. }
  70. /**
  71. * Process error, doesn't increase retry_attempt so it will not block sending
  72. *
  73. * @param string $operation
  74. * @param string $errorMessage
  75. * @param int $retryInterval
  76. *
  77. * @throws \Exception
  78. */
  79. public static function processNonBlockingError($operation, $errorMessage, $retryInterval = self::RETRY_INTERVAL) {
  80. $mailerLog = self::getMailerLog();
  81. $mailerLog['retry_at'] = time() + $retryInterval;
  82. $mailerLog = self::setError($mailerLog, $operation, $errorMessage);
  83. self::updateMailerLog($mailerLog);
  84. self::enforceExecutionRequirements();
  85. }
  86. /**
  87. * Process error, increase retry_attempt and block sending if it goes above RETRY_INTERVAL
  88. *
  89. * @param string $operation
  90. * @param string $errorMessage
  91. * @param string $errorCode
  92. * @param bool $pauseSending
  93. *
  94. * @throws \Exception
  95. */
  96. public static function processError($operation, $errorMessage, $errorCode = null, $pauseSending = false, $throttledBatchSize = null) {
  97. $mailerLog = self::getMailerLog();
  98. if (!isset($throttledBatchSize) || $throttledBatchSize === 1) {
  99. $mailerLog['retry_attempt']++;
  100. }
  101. $mailerLog['retry_at'] = time() + self::RETRY_INTERVAL;
  102. $mailerLog = self::setError($mailerLog, $operation, $errorMessage, $errorCode);
  103. self::updateMailerLog($mailerLog);
  104. if ($pauseSending) {
  105. self::pauseSending($mailerLog);
  106. }
  107. self::enforceExecutionRequirements();
  108. }
  109. public static function setError($mailerLog, $operation, $errorMessage, $errorCode = null) {
  110. $mailerLog['error'] = [
  111. 'operation' => $operation,
  112. 'error_message' => $errorMessage,
  113. ];
  114. if ($errorCode) {
  115. $mailerLog['error']['error_code'] = $errorCode;
  116. }
  117. return $mailerLog;
  118. }
  119. public static function getError($mailerLog = false) {
  120. $mailerLog = self::getMailerLog($mailerLog);
  121. return isset($mailerLog['error']) ? $mailerLog['error'] : null;
  122. }
  123. public static function incrementSentCount() {
  124. $mailerLog = self::getMailerLog();
  125. // do not increment count if sending limit is reached
  126. if (self::isSendingLimitReached($mailerLog)) return;
  127. // clear previous retry count, errors, etc.
  128. if ($mailerLog['error']) {
  129. $mailerLog = self::clearSendingErrorLog($mailerLog);
  130. }
  131. (int)$mailerLog['sent']++;
  132. return self::updateMailerLog($mailerLog);
  133. }
  134. public static function clearSendingErrorLog($mailerLog) {
  135. $mailerLog['retry_attempt'] = null;
  136. $mailerLog['retry_at'] = null;
  137. $mailerLog['error'] = null;
  138. return self::updateMailerLog($mailerLog);
  139. }
  140. public static function isSendingLimitReached($mailerLog = false) {
  141. $settings = SettingsController::getInstance();
  142. $mailerConfig = $settings->get(Mailer::MAILER_CONFIG_SETTING_NAME);
  143. // do not enforce sending limit for MailPoet's sending method
  144. if ($mailerConfig['method'] === Mailer::METHOD_MAILPOET) return false;
  145. $mailerLog = self::getMailerLog($mailerLog);
  146. $elapsedTime = time() - (int)$mailerLog['started'];
  147. if (empty($mailer['frequency'])) {
  148. $defaultSettings = $settings->getAllDefaults();
  149. $mailer['frequency'] = $defaultSettings['mta']['frequency'];
  150. }
  151. $frequencyInterval = (int)$mailerConfig['frequency']['interval'] * Mailer::SENDING_LIMIT_INTERVAL_MULTIPLIER;
  152. $frequencyLimit = (int)$mailerConfig['frequency']['emails'];
  153. if ($mailerLog['sent'] >= $frequencyLimit) {
  154. if ($elapsedTime <= $frequencyInterval) return true;
  155. // reset mailer log as enough time has passed since the limit was reached
  156. self::resetMailerLog();
  157. }
  158. return false;
  159. }
  160. public static function isSendingPaused($mailerLog = false) {
  161. $mailerLog = self::getMailerLog($mailerLog);
  162. return $mailerLog['status'] === self::STATUS_PAUSED;
  163. }
  164. }