1: <?php
2:
3: namespace Charcoal\Email;
4:
5: // Dependencies from `PHP`
6: use \DateTime;
7: use \DateTimeInterface;
8: use \Exception;
9: use \InvalidArgumentException;
10:
11: // From `charcoal-core`
12: use \Charcoal\Model\AbstractModel;
13:
14: /**
15: * Email log
16: */
17: class EmailLog extends AbstractModel
18: {
19:
20: use EmailAwareTrait;
21:
22: /**
23: * Type of log (e.g., "email").
24: *
25: * @var string $type
26: */
27: private $type;
28:
29: /**
30: * The action logged (e.g., "send").
31: *
32: * @var string $action
33: */
34: private $action;
35:
36: /**
37: * The mailer's raw response.
38: *
39: * @var mixed $rawResponse
40: */
41: private $rawResponse;
42:
43: /**
44: * The Message-ID (Unique message identifier)
45: *
46: * @var string $messageId
47: */
48: private $messageId;
49:
50: /**
51: * The campaign ID.
52: *
53: * @var string $campaign
54: */
55: private $campaign;
56:
57: /**
58: * The sender's email address.
59: *
60: * @var string $from
61: */
62: private $from;
63:
64: /**
65: * The recipient's email address.
66: *
67: * @var string $to
68: */
69: private $to;
70:
71: /**
72: * The email subject.
73: *
74: * @var string $subject
75: */
76: private $subject;
77:
78: /**
79: * Whether the email has been semt.
80: *
81: * Error code (0 = success)
82: *
83: * @var int $sendStatus
84: */
85: private $sendStatus;
86:
87: /**
88: * The error message from a failed send.
89: *
90: * @var string $sendError
91: */
92: private $sendError;
93:
94: /**
95: * When the email should be sent.
96: *
97: * @var DateTime $sendDate
98: */
99: private $sendDate;
100:
101: /**
102: * The current IP address at the time of the log.
103: *
104: * @var string $ip
105: */
106: private $ip;
107:
108: /**
109: * The current session ID at the time of the log.
110: *
111: * @var string $sessionId
112: */
113: private $sessionId;
114:
115: /**
116: * Get the primary key that uniquely identifies each queue item.
117: *
118: * @return string
119: */
120: public function key()
121: {
122: return 'id';
123: }
124:
125: /**
126: * Set the type of log.
127: *
128: * @param string $type The log type. (e.g., "email").
129: * @throws InvalidArgumentException If the log type is not a string.
130: * @return EmailLog Chainable
131: */
132: public function setType($type)
133: {
134: if (!is_string($type)) {
135: throw new InvalidArgumentException(
136: 'Log type must be a string.'
137: );
138: }
139:
140: $this->type = $type;
141:
142: return $this;
143: }
144:
145: /**
146: * Get the log type.
147: *
148: * @return string
149: */
150: public function type()
151: {
152: return $this->type;
153: }
154:
155: /**
156: * Set the logged action.
157: *
158: * @param string $action The log action (e.g., "send").
159: * @throws InvalidArgumentException If the action is not a string.
160: * @return EmailLog Chainable
161: */
162: public function setAction($action)
163: {
164: if (!is_string($action)) {
165: throw new InvalidArgumentException(
166: 'Action must be a string.'
167: );
168: }
169:
170: $this->action = $action;
171:
172: return $this;
173: }
174:
175: /**
176: * Get the logged action.
177: *
178: * @return string
179: */
180: public function action()
181: {
182: return $this->action;
183: }
184:
185: /**
186: * Set the raw response from the mailer.
187: *
188: * @param mixed $res The response object or array.
189: * @return EmailLog Chainable
190: */
191: public function setRawResponse($res)
192: {
193: $this->rawResponse = $res;
194: return $this;
195: }
196:
197: /**
198: * Get the raw response from the mailer.
199: *
200: * @return mixed
201: */
202: public function rawResponse()
203: {
204: return $this->rawResponse;
205: }
206:
207: /**
208: * Set the Message-ID.
209: *
210: * @param string $messageId The Message-ID.
211: * @throws InvalidArgumentException If the Message-ID is not a string.
212: * @return EmailLog Chainable
213: */
214: public function setMessageId($messageId)
215: {
216: if (!is_string($messageId)) {
217: throw new InvalidArgumentException(
218: 'Message-ID must be a string.'
219: );
220: }
221:
222: $this->messageId = $messageId;
223:
224: return $this;
225: }
226:
227: /**
228: * Get the Message-ID.
229: *
230: * @return string
231: */
232: public function messageId()
233: {
234: return $this->messageId;
235: }
236:
237:
238: /**
239: * Set the campaign ID.
240: *
241: * @param string $campaign The campaign identifier.
242: * @throws InvalidArgumentException If the campaign is invalid.
243: * @return EmailInterface Chainable
244: */
245: public function setCampaign($campaign)
246: {
247: if (!is_string($campaign)) {
248: throw new InvalidArgumentException(
249: 'Campaign must be a string'
250: );
251: }
252:
253: $this->campaign = $campaign;
254:
255: return $this;
256: }
257:
258: /**
259: * Get the campaign identifier.
260: *
261: * @return string
262: */
263: public function campaign()
264: {
265: return $this->campaign;
266: }
267:
268: /**
269: * Set the sender's email address.
270: *
271: * @param string|array $email An email address.
272: * @throws InvalidArgumentException If the email address is invalid.
273: * @return EmailLog Chainable
274: */
275: public function setFrom($email)
276: {
277: if (is_string($email)) {
278: $this->from = $email;
279: } elseif (is_array($email)) {
280: $this->from = $this->emailFromArray($email);
281: } else {
282: throw new InvalidArgumentException(
283: 'Sender email address must be a string.'
284: );
285: }
286:
287: return $this;
288: }
289:
290: /**
291: * Get the sender's email address.
292: *
293: * @return string
294: */
295: public function from()
296: {
297: return $this->from;
298: }
299:
300: /**
301: * Set the recipient's email address.
302: *
303: * @param string|array $email An email address.
304: * @throws InvalidArgumentException If the email address is invalid.
305: * @return EmailLog Chainable
306: */
307: public function setTo($email)
308: {
309: if (is_string($email)) {
310: $this->to = $email;
311: } elseif (is_array($email)) {
312: $this->to = $this->emailFromArray($email);
313: } else {
314: throw new InvalidArgumentException(
315: 'Recipient email address must be a string.'
316: );
317: }
318:
319: return $this;
320: }
321:
322: /**
323: * Get the recipient's email address.
324: *
325: * @return string
326: */
327: public function to()
328: {
329: return $this->to;
330: }
331:
332: /**
333: * Set the email subject.
334: *
335: * @param string $subject The email subject.
336: * @throws InvalidArgumentException If the subject is not a string.
337: * @return EmailLog Chainable
338: */
339: public function setSubject($subject)
340: {
341: if (!is_string($subject)) {
342: throw new InvalidArgumentException(
343: 'Subject needs to be a string'
344: );
345: }
346:
347: $this->subject = $subject;
348:
349: return $this;
350: }
351:
352: /**
353: * Get the email subject.
354: *
355: * @return string
356: */
357: public function subject()
358: {
359: return $this->subject;
360: }
361:
362: /**
363: * @param null|string|DateTime $ts The "send date" datetime value.
364: * @throws InvalidArgumentException If the ts is not a valid datetime value.
365: * @return EmailLog Chainable
366: */
367: public function setSendDate($ts)
368: {
369: if ($ts === null) {
370: $this->sendDate = null;
371: return $this;
372: }
373:
374: if (is_string($ts)) {
375: try {
376: $ts = new DateTime($ts);
377: } catch (Exception $e) {
378: throw new InvalidArgumentException($e->getMessage());
379: }
380: }
381:
382: if (!($ts instanceof DateTimeInterface)) {
383: throw new InvalidArgumentException(
384: 'Invalid "Send Date" value. Must be a date/time string or a DateTime object.'
385: );
386: }
387:
388: $this->sendDate = $ts;
389: return $this;
390: }
391:
392: /**
393: * @return null|DateTimeInterface
394: */
395: public function sendDate()
396: {
397: return $this->sendDate;
398: }
399:
400: /**
401: * @param mixed $ip The IP adress.
402: * @return EmailLog Chainable
403: */
404: public function setIp($ip)
405: {
406: $this->ip = $ip;
407: return $this;
408: }
409:
410: /**
411: * @return mixed
412: */
413: public function ip()
414: {
415: return $this->ip;
416: }
417:
418: /**
419: * @param string $sessionId The session identifier.
420: * @return EmailLog Chainable
421: */
422: public function setSessionId($sessionId)
423: {
424: $this->sessionId = $sessionId;
425: return $this;
426: }
427:
428: /**
429: * @return string
430: */
431: public function sessionId()
432: {
433: return $this->sessionId;
434: }
435:
436: /**
437: * @see StorableTrait::preSave()
438: * @return boolean
439: */
440: public function preSave()
441: {
442: parent::preSave();
443: $ip = (isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '');
444: $sessionId = session_id();
445:
446: $this->setIp($ip);
447: $this->setSessionId($sessionId);
448:
449: return true;
450: }
451: }
452: