1<?php 2 3/** 4 * Swift Mailer Throttling Plugin. 5 * Please read the LICENSE file 6 * @author Chris Corbyn <chris@w3style.co.uk> 7 * @package Swift_Plugin 8 * @license GNU Lesser General Public License 9 */ 10 11require_once dirname(__FILE__) . "/../ClassLoader.php"; 12Swift_ClassLoader::load("Swift_Plugin_BandwidthMonitor"); 13Swift_ClassLoader::load("Swift_Events_SendListener"); 14 15/** 16 * Throttler plugin for Swift Mailer. 17 * Restricts the speed at which Swift will operate. 18 * @package Swift_Plugin 19 * @author Chris Corbyn <chris@w3style.co.uk> 20 */ 21class Swift_Plugin_Throttler extends Swift_Plugin_BandwidthMonitor implements Swift_Events_SendListener 22{ 23 /** 24 * The rate in byte-per-minute 25 * @var int 26 */ 27 protected $bpm = null; 28 /** 29 * The rate as emails-per-minute 30 * @var int 31 */ 32 protected $epm = null; 33 /** 34 * The number of emails sent so far 35 * @var int 36 */ 37 protected $sent = 0; 38 /** 39 * The time at the start of overall execution 40 * @var int 41 */ 42 protected $time = null; 43 44 /** 45 * Part of the interface which is notified after a command is sent. 46 * @param Swift_Events_CommandEvent 47 */ 48 public function commandSent(Swift_Events_CommandEvent $e) 49 { 50 parent::commandSent($e); 51 if (null === $rate = $this->getBytesPerMinute()) return; 52 53 $duration = $this->getTimeLapse(); 54 $bytes_sent = $this->getBytesOut(); 55 $bytes_per_sec = $rate / 60; 56 $seconds_allowed_so_far = ceil($bytes_sent / $bytes_per_sec); 57 $overrun = $seconds_allowed_so_far - $duration; 58 if ($overrun > 0) 59 { 60 $this->wait($overrun); 61 } 62 } 63 /** 64 * Part of the interface which is notified when a message has been sent. 65 * @param Swift_Events_SendEvent 66 */ 67 public function sendPerformed(Swift_Events_SendEvent $e) 68 { 69 $this->setSent($this->getSent() + 1); 70 if (null === $rate = $this->getEmailsPerMinute()) return; 71 72 $duration = $this->getTimeLapse(); 73 $emails_sent = $this->getSent(); 74 $emails_per_sec = $rate / 60; 75 $seconds_allowed_so_far = ceil($emails_sent / $emails_per_sec); 76 $overrun = $seconds_allowed_so_far - $duration; 77 if ($overrun > 0) 78 { 79 $this->wait($overrun); 80 } 81 } 82 /** 83 * Wait for $seconds before continuing 84 * @param int The number of seconds to wait 85 */ 86 public function wait($secs) 87 { 88 sleep($secs); 89 } 90 /** 91 * Set the time if it's not already set 92 */ 93 protected function setTime() 94 { 95 if ($this->time === null) $this->time = time(); 96 } 97 /** 98 * Get the time taken thus far (full seconds). 99 * @return int 100 */ 101 public function getTimeLapse() 102 { 103 $this->setTime(); 104 return time() - $this->time; 105 } 106 /** 107 * Set the number of emails sent 108 * @param int Emails sent so far 109 */ 110 public function setSent($num) 111 { 112 $this->sent = (int)$num; 113 } 114 /** 115 * Get the number of emails sent 116 * @return int 117 */ 118 public function getSent() 119 { 120 return $this->sent; 121 } 122 /** 123 * Set the throttling rate as bytes per minute 124 * @param int The maximum number of outgoing bytes in 60 seconds. 125 */ 126 public function setBytesPerMinute($bpm) 127 { 128 if ($bpm === null) 129 { 130 $this->bpm = null; 131 return; 132 } 133 $this->setEmailsPerMinute(null); 134 $this->bpm = abs((int)$bpm); 135 } 136 /** 137 * Get the number of bytes allowed per minute. 138 * Reurns NULL if not used. 139 * @return int 140 */ 141 public function getBytesPerMinute() 142 { 143 return $this->bpm; 144 } 145 /** 146 * Set the rate as emails-per-minute. 147 * @param int The max number of emails to send in a minute. 148 */ 149 public function setEmailsPerMinute($epm) 150 { 151 if ($epm === null) 152 { 153 $this->epm = null; 154 return; 155 } 156 $this->setBytesPerMinute(null); 157 $this->epm = abs((int)$epm); 158 } 159 /** 160 * Get the rate as number of emails per minute. 161 * Returns null if not used. 162 * @return int 163 */ 164 public function getEmailsPerMinute() 165 { 166 return $this->epm; 167 } 168} 169