1 <?php
2 /* --------------------------------------------------------------
3 EmailService.inc.php 2015-07-21 gm
4 Gambio GmbH
5 http://www.gambio.de
6 Copyright (c) 2015 Gambio GmbH
7 Released under the GNU General Public License (Version 2)
8 [http://www.gnu.org/licenses/gpl-2.0.html]
9 --------------------------------------------------------------
10 */
11
12 MainFactory::load_class('EmailServiceInterface');
13
14 /**
15 * Class EmailService
16 *
17 * Represents the public API for the Email service of the system. External users must use this
18 * class for all the email operations except.
19 *
20 * Important: Since the attachments will be flat-stored in the "uploads/attachmetns" directory
21 * the "send" and "queue" method will have to perform multiple writes to the database in order to get
22 * robust attachment handling that will not crash the rest of the service.
23 *
24 * @category System
25 * @package Email
26 */
27 class EmailService implements EmailServiceInterface
28 {
29 /**
30 * E-Mail repository.
31 * @var EmailRepositoryInterface
32 */
33 protected $repository;
34
35 /**
36 * Mailer adapter.
37 * @var MailerAdapterInterface
38 */
39 protected $mailerAdapter;
40
41 /**
42 * E-Mail factory.
43 * @var EmailFactoryInterface
44 */
45 protected $factory;
46
47 /**
48 * E-Mail attachments handler.
49 * @var AttachmentsHandlerInterface
50 */
51 protected $attachmentsHandler;
52
53
54 /**
55 * Class Constructor
56 *
57 * @param EmailRepositoryInterface $repository E-Mail repository.
58 * @param EmailFactoryInterface $factory E-Mail factory.
59 * @param MailerAdapterInterface $mailerAdapter Mailer adapter.
60 * @param AttachmentsHandlerInterface $attachmentsHandler E-Mail attachments handler.
61 */
62 public function __construct(EmailRepositoryInterface $repository,
63 EmailFactoryInterface $factory,
64 MailerAdapterInterface $mailerAdapter,
65 AttachmentsHandlerInterface $attachmentsHandler)
66 {
67 $this->repository = $repository;
68 $this->factory = $factory;
69 $this->mailerAdapter = $mailerAdapter;
70 $this->attachmentsHandler = $attachmentsHandler;
71 }
72
73
74 /**
75 * Creates a new email
76 *
77 * Use this method to can a valid email object that can be sent without any
78 * additional modification. Optionally you can add more information to the
79 * email object such as attachments, BCC & CC contacts etc.
80 *
81 * @param EmailContactInterface $sender Contains the sender information.
82 * @param EmailContactInterface $recipient Contains the recipient information.
83 * @param EmailSubjectInterface $subject Email record subject.
84 * @param EmailContentInterface $content (optional) Html content of the email.
85 *
86 * @return EmailInterface Valid email.
87 */
88 public function create(EmailContactInterface $sender,
89 EmailContactInterface $recipient,
90 EmailSubjectInterface $subject,
91 EmailContentInterface $content = null)
92 {
93 $contacts = MainFactory::create('ContactCollection', $sender, $recipient);
94
95 return $this->factory->createEmail(null, $subject, $content, null, true, $contacts, null);
96 }
97
98
99 /**
100 * Sends and saves an email.
101 *
102 * @param EmailInterface $email Contains email information.
103 */
104 public function send(EmailInterface $email)
105 {
106 // Handle email attachments.
107 $this->repository->write($email); // Email instance gets a database ID.
108 $this->attachmentsHandler->backupEmailAttachments($email); // Requires the database ID for storing the attachments.
109 $this->repository->write($email); // Save the email with the new (backup) attachment paths.
110
111 // Send email and store it in the database.
112 $this->mailerAdapter->send($email);
113 $email->setPending(false);
114 $email->setSentDate(new DateTime());
115 $this->repository->write($email);
116 }
117
118
119 /**
120 * Saves an email as pending (will not be sent).
121 *
122 * @param EmailInterface $email Contains email information.
123 */
124 public function queue(EmailInterface $email)
125 {
126 $email->setPending(true);
127 $this->repository->write($email); // Email instance gets a database ID.
128 $this->attachmentsHandler->backupEmailAttachments($email); // Requires the database ID for storing the attachments.
129 $this->repository->write($email); // Save the email with the new (backup) attachment paths.
130 }
131
132
133 /**
134 * Writes an email instance to the DB.
135 *
136 * This method will store an email entity just the way it is without modifying other properties
137 * like the "send" or "queue" methods do. If you use this method or the "writeCollection" make
138 * sure that all the email properties are the desired ones.
139 *
140 * @param EmailInterface $email Email to write.
141 */
142 public function write(EmailInterface $email)
143 {
144 $this->repository->write($email);
145 }
146
147
148 /**
149 * Returns an email by id.
150 *
151 * @param IdType $id The database ID that matches the email record.
152 *
153 * @return EmailInterface Contains the email information.
154 */
155 public function getById(IdType $id)
156 {
157 return $this->repository->getById($id);
158 }
159
160
161 /**
162 * Finds an email by ID.
163 *
164 * @param IdType $id The record ID that matches the email.
165 *
166 * @return EmailInterface|null Email or null if not found.
167 */
168 public function findById(IdType $id)
169 {
170 return $this->repository->findById($id);
171 }
172
173
174 /**
175 * Removes an email from the database.
176 *
177 * @param EmailInterface $email Contains the email information.
178 */
179 public function delete(EmailInterface $email)
180 {
181 $this->attachmentsHandler->deleteEmailAttachments($email);
182 $this->repository->delete($email);
183 }
184
185
186 /**
187 * Filters email records with provided keyword string.
188 *
189 * @param string $p_keyword String to be used for filtering the email records.
190 * @param array $limit (optional) Array that contains LIMIT and OFFSET value
191 * e.g. array( 'limit' => 10, 'offset' => 5 )
192 * @param array $order (optional) Contains arrays with column, direction pairs
193 * e.g. array( 'column' => 'direction' )
194 *
195 * @return EmailCollection Email collection containing the email records.
196 */
197 public function filter($p_keyword, array $limit = array(), array $order = array())
198 {
199 return $this->repository->filter($p_keyword, $limit, $order);
200 }
201
202
203 /**
204 * Validate a string email address.
205 *
206 * @param string $p_emailAddress Email address to be validated.
207 *
208 * @throws InvalidArgumentException If argument is not a string.
209 *
210 * @return bool Returns the validation result (true for success, false for failure).
211 */
212 public function validateEmailAddress($p_emailAddress)
213 {
214 if(!is_string($p_emailAddress))
215 {
216 throw new InvalidArgumentException('Invalid $p_emailAddress argument value (string expected): '
217 . print_r($p_emailAddress, true));
218 }
219
220 return (bool)filter_var($p_emailAddress, FILTER_VALIDATE_EMAIL);
221 }
222
223
224 /**
225 * Sends pending email records.
226 */
227 public function sendPending()
228 {
229 $pending = $this->getPending();
230 $this->sendCollection($pending);
231 }
232
233
234 /**
235 * Return pending email records as an email collection.
236 *
237 * @return EmailCollectionInterface The pending emails.
238 */
239 public function getPending()
240 {
241 return $this->repository->getPending();
242 }
243
244
245 /**
246 * Returns sent email records as an email collection.
247 *
248 * @return EmailCollectionInterface Sent email records.
249 */
250 public function getSent()
251 {
252 return $this->repository->getSent();
253 }
254
255
256 /**
257 * Returns all email records from the database.
258 *
259 * @return EmailCollection Email records.
260 */
261 public function getAll()
262 {
263 return $this->repository->getAll();
264 }
265
266
267 /**
268 * Sends a collection of emails.
269 *
270 * @param EmailCollectionInterface $collection Email collection to send.
271 */
272 public function sendCollection(EmailCollectionInterface $collection)
273 {
274 foreach($collection->getArray() as $email)
275 {
276 $this->send($email);
277 }
278 }
279
280
281 /**
282 * Queues a collection of emails.
283 *
284 * @param EmailCollectionInterface $collection Email collection to queue.
285 */
286 public function queueCollection(EmailCollectionInterface $collection)
287 {
288 foreach($collection->getArray() as $email)
289 {
290 $this->queue($email);
291 }
292 }
293
294
295 /**
296 * Writes a collection of emails into database.
297 *
298 * @param EmailCollectionInterface $collection Email collection to write.
299 */
300 public function writeCollection(EmailCollectionInterface $collection)
301 {
302 foreach($collection->getArray() as $email)
303 {
304 $this->write($email);
305 }
306 }
307
308
309 /**
310 * Deletes a collection of emails.
311 *
312 * @param EmailCollectionInterface $collection Email collection to delete.
313 */
314 public function deleteCollection(EmailCollectionInterface $collection)
315 {
316 foreach($collection->getArray() as $email)
317 {
318 $this->delete($email);
319 }
320 }
321
322
323 /**
324 * Returns the current count of the email records in the database.
325 *
326 * @param string $p_filterKeyword (optional) If provided the records will be filtered.
327 *
328 * @return int The row number of the email table.
329 */
330 public function getRecordCount($p_filterKeyword = '')
331 {
332 return $this->repository->getRecordCount($p_filterKeyword);
333 }
334 }