1<?php
2
3/*
4 * This file is part of SwiftMailer.
5 * (c) 2004-2009 Chris Corbyn
6 *
7 * For the full copyright and license information, please view the LICENSE
8 * file that was distributed with this source code.
9 */
10
11/**
12 * Reduces network flooding when sending large amounts of mail.
13 *
14 * @author Chris Corbyn
15 */
16class Swift_Plugins_BandwidthMonitorPlugin implements Swift_Events_SendListener, Swift_Events_CommandListener, Swift_Events_ResponseListener, Swift_InputByteStream
17{
18    /**
19     * The outgoing traffic counter.
20     *
21     * @var int
22     */
23    private $out = 0;
24
25    /**
26     * The incoming traffic counter.
27     *
28     * @var int
29     */
30    private $in = 0;
31
32    /** Bound byte streams */
33    private $mirrors = array();
34
35    /**
36     * Not used.
37     */
38    public function beforeSendPerformed(Swift_Events_SendEvent $evt)
39    {
40    }
41
42    /**
43     * Invoked immediately after the Message is sent.
44     *
45     * @param Swift_Events_SendEvent $evt
46     */
47    public function sendPerformed(Swift_Events_SendEvent $evt)
48    {
49        $message = $evt->getMessage();
50        $message->toByteStream($this);
51    }
52
53    /**
54     * Invoked immediately following a command being sent.
55     *
56     * @param Swift_Events_CommandEvent $evt
57     */
58    public function commandSent(Swift_Events_CommandEvent $evt)
59    {
60        $command = $evt->getCommand();
61        $this->out += strlen($command);
62    }
63
64    /**
65     * Invoked immediately following a response coming back.
66     *
67     * @param Swift_Events_ResponseEvent $evt
68     */
69    public function responseReceived(Swift_Events_ResponseEvent $evt)
70    {
71        $response = $evt->getResponse();
72        $this->in += strlen($response);
73    }
74
75    /**
76     * Called when a message is sent so that the outgoing counter can be increased.
77     *
78     * @param string $bytes
79     */
80    public function write($bytes)
81    {
82        $this->out += strlen($bytes);
83        foreach ($this->mirrors as $stream) {
84            $stream->write($bytes);
85        }
86    }
87
88    /**
89     * Not used.
90     */
91    public function commit()
92    {
93    }
94
95    /**
96     * Attach $is to this stream.
97     *
98     * The stream acts as an observer, receiving all data that is written.
99     * All {@link write()} and {@link flushBuffers()} operations will be mirrored.
100     *
101     * @param Swift_InputByteStream $is
102     */
103    public function bind(Swift_InputByteStream $is)
104    {
105        $this->mirrors[] = $is;
106    }
107
108    /**
109     * Remove an already bound stream.
110     *
111     * If $is is not bound, no errors will be raised.
112     * If the stream currently has any buffered data it will be written to $is
113     * before unbinding occurs.
114     *
115     * @param Swift_InputByteStream $is
116     */
117    public function unbind(Swift_InputByteStream $is)
118    {
119        foreach ($this->mirrors as $k => $stream) {
120            if ($is === $stream) {
121                unset($this->mirrors[$k]);
122            }
123        }
124    }
125
126    /**
127     * Not used.
128     */
129    public function flushBuffers()
130    {
131        foreach ($this->mirrors as $stream) {
132            $stream->flushBuffers();
133        }
134    }
135
136    /**
137     * Get the total number of bytes sent to the server.
138     *
139     * @return int
140     */
141    public function getBytesOut()
142    {
143        return $this->out;
144    }
145
146    /**
147     * Get the total number of bytes received from the server.
148     *
149     * @return int
150     */
151    public function getBytesIn()
152    {
153        return $this->in;
154    }
155
156    /**
157     * Reset the internal counters to zero.
158     */
159    public function reset()
160    {
161        $this->out = 0;
162        $this->in = 0;
163    }
164}
165