1: <?php
2:
3: /**
4: * Avisota newsletter and mailing system
5: *
6: * PHP Version 5.3
7: *
8: * @copyright bit3 UG 2013
9: * @author Tristan Lins <tristan.lins@bit3.de>
10: * @package avisota-core
11: * @license LGPL-3.0+
12: * @link http://avisota.org
13: */
14:
15: namespace Avisota\Queue;
16:
17: use Avisota\Event\PostEnqueueEvent;
18: use Avisota\Event\PreEnqueueEvent;
19: use Avisota\RecipientSource\RecipientSourceInterface;
20: use Avisota\Templating\MessageTemplateInterface;
21: use Symfony\Component\EventDispatcher\EventDispatcher;
22:
23: /**
24: * A collection of helper functions.
25: *
26: * @package avisota-core
27: */
28: class QueueHelper
29: {
30: /**
31: * @var MessageTemplateInterface
32: */
33: protected $messageTemplate = null;
34:
35: /**
36: * @var RecipientSourceInterface
37: */
38: protected $recipientSource = null;
39:
40: /**
41: * @var QueueInterface
42: */
43: protected $queue = null;
44:
45: /**
46: * @var int
47: */
48: protected $limit = null;
49:
50: /**
51: * @var int
52: */
53: protected $offset = null;
54:
55: /**
56: * @var array
57: */
58: protected $newsletterData = null;
59:
60: /**
61: * @var \DateTime
62: */
63: protected $deliveryDate = null;
64:
65: /**
66: * @var EventDispatcher
67: */
68: protected $eventDispatcher = null;
69:
70: /**
71: * @param \Avisota\Templating\MessageTemplateInterface $messageTemplate
72: */
73: public function setMessageTemplate($messageTemplate)
74: {
75: $this->messageTemplate = $messageTemplate;
76: return $this;
77: }
78:
79: /**
80: * @return \Avisota\Templating\MessageTemplateInterface
81: */
82: public function getMessageTemplate()
83: {
84: return $this->messageTemplate;
85: }
86:
87: /**
88: * @param \Avisota\RecipientSource\RecipientSourceInterface $recipientSource
89: */
90: public function setRecipientSource($recipientSource)
91: {
92: $this->recipientSource = $recipientSource;
93: return $this;
94: }
95:
96: /**
97: * @return \Avisota\RecipientSource\RecipientSourceInterface
98: */
99: public function getRecipientSource()
100: {
101: return $this->recipientSource;
102: }
103:
104: /**
105: * @param \Avisota\Queue\QueueInterface $queue
106: */
107: public function setQueue($queue)
108: {
109: $this->queue = $queue;
110: return $this;
111: }
112:
113: /**
114: * @return \Avisota\Queue\QueueInterface
115: */
116: public function getQueue()
117: {
118: return $this->queue;
119: }
120:
121: /**
122: * @param int $limit
123: */
124: public function setLimit($limit)
125: {
126: $this->limit = $limit;
127: return $this;
128: }
129:
130: /**
131: * @return int
132: */
133: public function getLimit()
134: {
135: return $this->limit;
136: }
137:
138: /**
139: * @param int $offset
140: */
141: public function setOffset($offset)
142: {
143: $this->offset = $offset;
144: return $this;
145: }
146:
147: /**
148: * @return int
149: */
150: public function getOffset()
151: {
152: return $this->offset;
153: }
154:
155: /**
156: * @param array $newsletterData
157: */
158: public function setNewsletterData($newsletterData)
159: {
160: $this->newsletterData = $newsletterData;
161: return $this;
162: }
163:
164: /**
165: * @return array
166: */
167: public function getNewsletterData()
168: {
169: return $this->newsletterData;
170: }
171:
172: /**
173: * @param \DateTime $deliveryDate
174: */
175: public function setDeliveryDate($deliveryDate)
176: {
177: $this->deliveryDate = $deliveryDate;
178: return $this;
179: }
180:
181: /**
182: * @return \DateTime
183: */
184: public function getDeliveryDate()
185: {
186: return $this->deliveryDate;
187: }
188:
189: /**
190: * @param EventDispatcher $eventDispatcher
191: */
192: public function setEventDispatcher(EventDispatcher $eventDispatcher = null)
193: {
194: $this->eventDispatcher = $eventDispatcher;
195: return $this;
196: }
197:
198: /**
199: * @return EventDispatcher
200: */
201: public function getEventDispatcher()
202: {
203: return $this->eventDispatcher;
204: }
205:
206: /**
207: * Enqueue the message for all recipients into the queue.
208: *
209: * @param mixed $_ All data that is not yet provided.
210: * Please note that $limit is prefered before $offset,
211: * if you want to only set $offset pass 0 for $limit first.
212: *
213: * @return int
214: *
215: * Complexity cannot easily reduced without a huge overhead :-(
216: * @SuppressWarnings(PHPMD.CyclomaticComplexity)
217: * @SuppressWarnings(PHPMD.NPathComplexity)
218: */
219: public function enqueue()
220: {
221: $messageTemplate = $this->messageTemplate;
222: $recipientSource = $this->recipientSource;
223: $queue = $this->queue;
224: $limit = $this->limit;
225: $offset = $this->offset;
226: $newsletterData = $this->newsletterData;
227: $deliveryDate = $this->deliveryDate;
228:
229: $args = func_get_args();
230: foreach ($args as $arg) {
231: if ($arg instanceof MessageTemplateInterface) {
232: $messageTemplate = $arg;
233: continue;
234: }
235: else if ($arg instanceof RecipientSourceInterface) {
236: $recipientSource = $arg;
237: continue;
238: }
239: else if ($arg instanceof QueueInterface) {
240: $queue = $arg;
241: continue;
242: }
243: else if (is_int($arg)) {
244: if ($limit === null) {
245: $limit = $arg;
246: continue;
247: }
248: if ($offset === null) {
249: $offset = $arg;
250: continue;
251: }
252: }
253: else if (is_array($arg)) {
254: $newsletterData = $arg;
255: continue;
256: }
257: else if ($arg instanceof \DateTime) {
258: $deliveryDate = $arg;
259: continue;
260: }
261:
262: if (is_object($arg)) {
263: $arg = get_class($arg);
264: }
265: else {
266: $arg = gettype($arg) . ' ' . var_export($arg, true);
267: }
268: throw new \RuntimeException('Unexpected parameter ' . $arg);
269: }
270:
271: if (!$messageTemplate) {
272: throw new \RuntimeException('Missing required message template');
273: }
274: if (!$recipientSource) {
275: throw new \RuntimeException('Missing required recipient source');
276: }
277: if (!$queue) {
278: throw new \RuntimeException('Missing required queue');
279: }
280:
281: $count = 0;
282: $recipients = $recipientSource->getRecipients($limit, $offset);
283:
284: foreach ($recipients as $recipient) {
285: $message = $messageTemplate->render($recipient, $newsletterData);
286:
287: if ($this->eventDispatcher) {
288: $event = new PreEnqueueEvent($message, $queue);
289: $this->eventDispatcher->dispatch($event::NAME, $event);
290:
291: if ($event->isSkip()) {
292: continue;
293: }
294: }
295:
296: if ($queue->enqueue($message, $deliveryDate)) {
297: $count ++;
298:
299: if ($this->eventDispatcher) {
300: $event = new PostEnqueueEvent($message, $queue);
301: $this->eventDispatcher->dispatch($event::NAME, $event);
302: }
303: }
304: }
305:
306: return $count;
307: }
308: }
309: