Commit | Line | Data |
---|---|---|
7f254ad8 AE |
1 | <?php |
2 | /** | |
3 | * File containing the ezcMailMboxTransport class | |
4 | * | |
5 | * @package Mail | |
6 | * @version 1.7beta1 | |
7 | * @copyright Copyright (C) 2005-2009 eZ Systems AS. All rights reserved. | |
8 | * @license http://ez.no/licenses/new_bsd New BSD License | |
9 | */ | |
10 | ||
11 | /** | |
12 | * ezcMailMboxTransport implements mail retrieval from an mbox file. | |
13 | * | |
14 | * The mbox set is constructed from a file pointer and iterates over all the | |
15 | * messages in an mbox file. | |
16 | * | |
17 | * @package Mail | |
18 | * @version 1.7beta1 | |
19 | * @mainclass | |
20 | */ | |
21 | class ezcMailMboxTransport | |
22 | { | |
23 | /** | |
24 | * Holds the filepointer to the mbox | |
25 | * | |
26 | * @var resource(filepointer) | |
27 | */ | |
28 | public $fh; | |
29 | ||
30 | /** | |
31 | * Constructs the ezcMailMboxTransport object | |
32 | * | |
33 | * Opens the mbox $fileName. | |
34 | * | |
35 | * @throws ezcBaseFileNotFoundException | |
36 | * if the mbox file could not be found. | |
37 | * @throws ezcBaseFilePermissionException | |
38 | * if the mbox file could be opened for reading. | |
39 | * @param string $fileName | |
40 | */ | |
41 | public function __construct( $fileName ) | |
42 | { | |
43 | if ( !file_exists( $fileName ) ) | |
44 | { | |
45 | throw new ezcBaseFileNotFoundException( $fileName, 'mbox' ); | |
46 | } | |
47 | if ( !is_readable( $fileName ) ) | |
48 | { | |
49 | throw new ezcBaseFilePermissionException( $fileName, ezcBaseFileException::READ ); | |
50 | } | |
51 | $this->fh = fopen( $fileName, 'rt' ); | |
52 | } | |
53 | ||
54 | /** | |
55 | * Finds the position of the first message while skipping a possible header. | |
56 | * | |
57 | * Mbox files can contain a header which does not describe an email | |
58 | * message. This method skips over this optional header by checking for a | |
59 | * specific From MAILER-DAEMON header. | |
60 | * | |
61 | * @return int | |
62 | */ | |
63 | private function findFirstMessage() | |
64 | { | |
65 | $data = fgets( $this->fh ); | |
66 | fseek( $this->fh, 0 ); | |
67 | if ( substr( $data, 0, 18 ) === 'From MAILER-DAEMON' ) | |
68 | { | |
69 | return $this->findNextMessage(); | |
70 | } | |
71 | else | |
72 | { | |
73 | return 0; | |
74 | } | |
75 | } | |
76 | ||
77 | /** | |
78 | * Reads through the Mbox file and stops at the next message. | |
79 | * | |
80 | * Messages in Mbox files are separated with lines starting with "From " | |
81 | * and this function reads to the next "From " marker. It then returns the | |
82 | * current posistion in the file. If EOF is detected during reading the | |
83 | * function returns false instead. | |
84 | * | |
85 | * @return int | |
86 | */ | |
87 | private function findNextMessage() | |
88 | { | |
89 | do | |
90 | { | |
91 | $data = fgets( $this->fh ); | |
92 | } while ( !feof( $this->fh ) && substr( $data, 0, 5 ) !== "From " ); | |
93 | ||
94 | if ( feof( $this->fh ) ) | |
95 | { | |
96 | return false; | |
97 | } | |
98 | return ftell( $this->fh ); | |
99 | } | |
100 | ||
101 | /** | |
102 | * This function reads through the whole mbox and returns starting positions of the messages. | |
103 | * | |
104 | * @return array(int=>int) | |
105 | */ | |
106 | public function listMessages() | |
107 | { | |
108 | $messages = array(); | |
109 | fseek( $this->fh, 0 ); | |
110 | // Skip the first mail as this is the mbox header | |
111 | $position = $this->findFirstMessage(); | |
112 | if ( $position === false ) | |
113 | { | |
114 | return $messages; | |
115 | } | |
116 | // Continue reading through the rest of the mbox | |
117 | do | |
118 | { | |
119 | $position = $this->findNextMessage(); | |
120 | if ( $position !== false ) | |
121 | { | |
122 | $messages[] = $position; | |
123 | } | |
124 | } while ( $position !== false ); | |
125 | ||
126 | return $messages; | |
127 | } | |
128 | ||
129 | /** | |
130 | * Returns an ezcMailMboxSet containing all the messages in the mbox. | |
131 | * | |
132 | * @return ezcMailMboxSet | |
133 | */ | |
134 | public function fetchAll() | |
135 | { | |
136 | $messages = $this->listMessages(); | |
137 | return new ezcMailMboxSet( $this->fh, $messages ); | |
138 | } | |
139 | ||
140 | /** | |
141 | * Returns an ezcMailMboxSet containing only the $number -th message in the mbox. | |
142 | * | |
143 | * @throws ezcMailNoSuchMessageException | |
144 | * if the message $number is out of range. | |
145 | * @param int $number | |
146 | * @return ezcMailMboxSet | |
147 | */ | |
148 | public function fetchByMessageNr( $number ) | |
149 | { | |
150 | $messages = $this->listMessages(); | |
151 | if ( !isset( $messages[$number] ) ) | |
152 | { | |
153 | throw new ezcMailNoSuchMessageException( $number ); | |
154 | } | |
155 | return new ezcMailMboxSet( $this->fh, array( 0 => $messages[$number] ) ); | |
156 | } | |
157 | ||
158 | /** | |
159 | * Returns an ezcMailMboxSet with $count messages starting from $offset. | |
160 | * | |
161 | * Fetches $count messages starting from the $offset and returns them as a | |
162 | * ezcMailMboxSet. If $count is not specified or if it is 0, it fetches | |
163 | * all messages starting from the $offset. | |
164 | * | |
165 | * @throws ezcMailInvalidLimitException | |
166 | * if $count is negative. | |
167 | * @throws ezcMailOffsetOutOfRangeException | |
168 | * if $offset is outside of the existing range of messages. | |
169 | * @param int $offset | |
170 | * @param int $count | |
171 | * @return ezcMailMboxSet | |
172 | */ | |
173 | public function fetchFromOffset( $offset, $count = 0 ) | |
174 | { | |
175 | if ( $count < 0 ) | |
176 | { | |
177 | throw new ezcMailInvalidLimitException( $offset, $count ); | |
178 | } | |
179 | $messages = $this->listMessages(); | |
180 | if ( !isset( $messages[$offset] ) ) | |
181 | { | |
182 | throw new ezcMailOffsetOutOfRangeException( $offset, $count ); | |
183 | } | |
184 | if ( $count == 0 ) | |
185 | { | |
186 | $range = array_slice( $messages, $offset ); | |
187 | } | |
188 | else | |
189 | { | |
190 | $range = array_slice( $messages, $offset, $count ); | |
191 | } | |
192 | return new ezcMailMboxSet( $this->fh, $range ); | |
193 | } | |
194 | } | |
195 | ?> |