555af4831be04ab292d682b72412938a640adad3
[namibia] / module / Utility / src / Utility / Comms / Notification.php
1 <?php
2 namespace Utility\Comms;
3
4
5 /**
6  * Easy notification functionality for anything that needs it.
7  * @author andre.fourie
8  */
9 class Notification
10 {
11
12         /**
13          * Data for repeater functionality.
14          * @var array
15          */
16         static protected $_data = null;
17         /**
18          * Send template as newsletter to all subscribers on sendFromTemplate.
19          * @var boolean
20          */
21         static protected $_sendAsNewsletter = false;
22         /**
23          * Skip unsubscribe check on sendFromTemplate.
24          * @var boolean
25          */
26         static protected $_skipSubscriptionCheck = false;
27         /**
28          * Gearman client.
29          * @var \GearmanClient
30          */
31         static protected $_gearClient = false;
32
33
34         /**
35          * Set repeater data for next notification sent.
36          * @param array $data
37          */
38         static public function setRepeaterData(array $data)
39         {
40                 self::$_data = $data;
41         }
42
43         /**
44          * Set next sendFromTemplate to send to all users subscribed to newsletters.
45          */
46         static public function setSendAsNewsletter()
47         {
48                 self::$_sendAsNewsletter = true;
49         }
50
51         /**
52          * Skip unsubscribe check on next sendFromTemplate.
53          */
54         static public function skipSubscriptionCheck()
55         {
56                 self::$_skipSubscriptionCheck = false;
57         }
58
59         /**
60          * Send email and/or sms notification.
61          * @param integer $fromCompanyId
62          * @param integer $fromProfileId
63          * @param integer $toCompanyId
64          * @param integer $toProfileId
65          * @param string  $email
66          * @param string  $mobile
67          * @param string  $subject
68          * @param string  $template
69          * @param array   $params
70          * @param array   $attachments
71          * @param boolean $disableSms
72          * @return void
73          */
74         static public function sendFromTemplate(
75                 $fromCompanyId, $fromProfileId, $toCompanyId, $toProfileId,
76                 $email, $mobile, $subject, $templateName, array $params,
77                 array $attachments = array(), array $complexAttachments = array(),
78                 $disableSms = false, $offline = false
79         )
80         {
81                 #-> Unsubscribe check.
82                 $em = \Utility\Registry::getEntityManager();
83                 if (!self::$_sendAsNewsletter && !self::$_skipSubscriptionCheck)
84                 {
85                         $oProfile = $em->getRepository('\User\Entity\Profile');
86                         $profile  = $email
87                                 ? $oProfile->findOneBy(array('email' => $email))
88                                 : $oProfile->findOneBy(array('mobile' => $mobile));
89                         if (!is_null($profile) && !$profile->subscribeReminders)
90                         {
91                                 return;
92                         }
93                 }
94                 self::$_skipSubscriptionCheck = false;
95
96                 #-> Retrieve template.
97                 $oTemplate = $em->getRepository('\Utility\Entity\Template');
98                 $oRepeater = $em->getRepository('\Utility\Entity\RepeaterTemplate');
99                 $template  = $oTemplate->findOneBy(array('name' => $templateName));
100
101                 if (is_null($template))
102                 {
103                         error_log('Template not found: ' . $templateName);
104                         return;
105                 }
106
107                 $template = $template->toArray();
108
109                 #-> Compile the template for use.
110                 $subject = ($subject)
111                         ? $subject
112                         : $template['subject'];
113                 $tagList = explode(',', $template['tags']);
114                 $search  = array('{APP_HOST}');
115
116 //        \Utility\Debug::errorLog('sendFromTemplate IS_BROCHURE', IS_BROCHURE ? 'true' : 'false');
117
118                 $replace = !IS_BROCHURE ? array(\Utility\Registry::getConfigParam('Host')) : array(\Utility\Registry::getConfigParam('CashCarsHost'));
119
120                 #-> Catering for data-grid?
121                 if (!is_null($template['repeaterTemplate']))
122                 {
123                         $repeater = $template['repeaterTemplate'];
124                         if (!is_array(self::$_data))
125                         {
126                                 \Utility\Debug::errorLog(__CLASS__, 'Data required but not provided for template: ' . $templateName);
127                                 return;
128                         }
129                         $repeatContent = '';
130                         $groupField    = ($repeater['groupField'])
131                                 ? $repeater['groupField']
132                                 : false;
133                         $group         = '';
134                         $i             = 1;
135                         $dateFormat    = \Utility\Definitions\Locale::getDateFormat();
136                         foreach (self::$_data as $row)
137                         {
138                                 $repSearch = array();
139                                 foreach ($row as $field => $value)
140                                 {
141                                         if (is_array($value))
142                                         {
143                                                 foreach ($value as $subField => $subValue)
144                                                 {
145                                                         $repSearch["$field.$subField"]  = "[$field.$subField]";
146                                                         $repReplace["$field.$subField"] = $subValue;
147                                                 }
148                                         }
149                                         else
150                                         {
151                                                 $repSearch[$field]  = "[$field]";
152                                                 $repReplace[$field] = !is_object($value)
153                                                         ? $value
154                                                         : $value->format($dateFormat);
155                                         }
156                                 }
157                                 if ($groupField && $repReplace[$groupField] != $group)
158                                 {
159                                         $group = $repReplace[$groupField];
160                                         $repeatContent .= str_replace($repSearch, $repReplace, $repeater['groupRepeater']) . "\n";
161                                 }
162                                 $repeatContent .= ($i % 2)
163                                         ? str_replace($repSearch, $repReplace, $repeater['rowRepeaterOdd']) . "\n"
164                                         : str_replace($repSearch, $repReplace, $repeater['rowRepeaterEven']) . "\n";
165                                 $i++;
166                         }
167                         $tagList[]          = 'repeater';
168                         $params['repeater'] = $repeatContent;
169                 }
170
171                 #-> Build up the template(s)
172                 foreach ($tagList as $key)
173                 {
174                         $key = trim($key);
175                         if (empty($key))
176                         {
177                                 continue;
178                         }
179                         if (!isset($params[$key]))
180                         {
181                                 \Utility\Debug::errorLog(__CLASS__, "All template tags not supplied for sending ($templateName): " . $key);
182                                 \Utility\Debug::errorLog('tags', $tagList);
183                                 \Utility\Debug::errorLog('params', $params);
184                                 return;
185                         }
186                         $search[]  = "[$key]";
187                         $replace[] = $params[$key];
188                 }
189                 $emailTemplate = !empty($template['emailTemplate'])
190                         ? str_replace($search, $replace, $template['emailTemplate'])
191                         : false;
192                 $smsTemplate   = !empty($template['smsTemplate'])
193                         ? str_replace($search, $replace, $template['smsTemplate'])
194                         : false;
195
196
197                 if (!self::$_sendAsNewsletter)
198                 {
199                         if (!$offline)
200                         {
201                                 self::send($fromCompanyId, $fromProfileId, $toCompanyId, $toProfileId,
202                                            $email, $mobile, $subject, $emailTemplate, $smsTemplate,
203                                            $attachments, $complexAttachments, $disableSms);
204                         }
205                         else
206                         {
207
208                                 self::sendOffline($fromCompanyId, $fromProfileId, $toCompanyId, $toProfileId,
209                                                   $email, $mobile, $subject, $emailTemplate, $smsTemplate,
210                                                   $attachments, $complexAttachments, $disableSms);
211                         }
212                 }
213                 else
214                 {
215                         $profiles = $em->createQuery(
216                                 'SELECT profile.id AS profileId, IDENTITY(profile.company) AS companyId, profile.email as email '
217                                 . 'FROM \User\Entity\Profile profile '
218                                 . 'LEFT JOIN profile.company company '
219                                 . 'WHERE profile.jobState = :status '
220                                 . 'AND profile.subscribeNewsletter = 1'
221                         )
222                                 ->setParameter('status', 'Active')
223                                 ->getArrayResult();
224                         $ii       = 0;
225                         $oo       = 0;
226                         if (!$offline)
227                         {
228                                 foreach ($profiles as $profile)
229                                 {
230                                         self::send($fromCompanyId, $fromProfileId, $profile['companyId'], $profile['profileId'],
231                                                    $profile['email'], false, $subject, $emailTemplate, $smsTemplate,
232                                                    $attachments, $complexAttachments, $disableSms);
233                                         $em->clear();
234                                         $ii++;
235                                         $oo++;
236                                         if (100 == $ii)
237                                         {
238                                                 $ii = 0;
239                                                 error_log('newsletter mails: ' . $oo);
240                                                 $em->getConnection()->close();
241                                         }
242                                 }
243                         }
244                         else
245                         {
246                                 foreach ($profiles as $profile)
247                                 {
248                                         self::sendOffline($fromCompanyId, $fromProfileId, $profile['companyId'], $profile['profileId'],
249                                                           $profile['email'], false, $subject, $emailTemplate, $smsTemplate,
250                                                           $attachments, $complexAttachments, $disableSms);
251                                         $em->clear();
252                                         $ii++;
253                                         $oo++;
254                                         if (100 == $ii)
255                                         {
256                                                 $ii = 0;
257                                                 error_log('newsletter mails: ' . $oo);
258                                                 $em->getConnection()->close();
259                                         }
260                                 }
261                         }
262                 }
263                 self::$_data             = null;
264                 self::$_sendAsNewsletter = false;
265         }
266
267         /**
268          * Send newsletter to all who are subscribed, or just to admin for a test.
269          * @param integer $newsletterId
270          * @param boolean $test
271          * @return void
272          */
273         static public function sendNewsletter($newsletterId, $test = false, $testProfileId = null)
274         {
275                 #-> Retrieve data handler.
276                 $em = \Utility\Registry::getEntityManager();
277
278                 #-> Collect some data.
279                 $template           = $em->getRepository('\Utility\Entity\Template')
280                         ->findOneBy(array('name' => 'newsletter-basic'))
281                         ->toArray();
282                 $newsletter         = $em->getRepository('\Newsletter\Entity\Newsletter')
283                         ->find($newsletterId)
284                         ->toArray();
285                 $complexAttachments = array();
286                 $search             = array('[headerImageSource]', '[footerImageSource]', '[body]');
287                 $host               = \Utility\Registry::getConfigParam('Host');
288                 $replace            = array(
289                         $host . '/images/EmailHeader.png',
290                         $host . '/images/EmailFooter.png',
291                         $newsletter['content']
292                 );
293
294                 $emailTemplate = str_replace($search, $replace, $template['emailTemplate']);
295                 $attachments   = array();
296                 $attachment    = $newsletter['attachment'];
297                 if (!is_null($attachment))
298                 {
299                         $attachments[$attachment['filename']] = file_get_contents(
300                                 \Utility\Registry::getConfigParam('DocumentPath') . $attachment['filename']
301                         );
302                 }
303
304                 $search = array('[first_name]', '[family_name]', '[mobile]');
305
306                 #-> Send.
307                 $sentTo = 0;
308                 if ($test)
309                 {
310                         if (!is_null($testProfileId))
311                         {
312                                 $testProfile = $em->getRepository('\User\Entity\Profile')
313                                         ->find($testProfileId);
314                                 $replace     = array(
315                                         $testProfile->firstName,
316                                         $testProfile->familyName,
317                                         $testProfile->mobile
318                                 );
319                                 self::send(0, 0, $testProfile->company->id, $testProfileId, $testProfile->email, false,
320                                            str_replace($search, $replace, $newsletter['subject']),
321                                            str_replace($search, $replace, $emailTemplate), '',
322                                            $attachments, $complexAttachments, true);
323                         }
324                         else
325                         {
326                                 $auth    = \Utility\Registry::getAuthData();
327                                 $replace = array(
328                                         'John', 'Doe', '0820820820'
329                                 );
330                                 self::send(0, 0, $auth['company']['id'], $auth['id'], $auth['email'], false,
331                                            str_replace($search, $replace, $newsletter['subject']),
332                                            str_replace($search, $replace, $emailTemplate), '',
333                                            $attachments, $complexAttachments, true);
334                         }
335                         $sentTo++;
336                         return $sentTo;
337                 }
338                 else
339                 {
340                         $profiles = $em->createQuery(
341                                 'SELECT profile.id AS profileId, IDENTITY(profile.company) AS companyId, '
342                                 . 'profile.firstName as firstName, profile.familyName as familyName, profile.email as email '
343                                 . 'FROM \User\Entity\Profile profile '
344                                 . 'LEFT JOIN profile.company company '
345                                 . 'WHERE profile.jobState = :status '
346                                 . 'AND profile.subscribeNewsletter = 1'
347                         )
348                                 ->setParameter('status', 'Active')
349                                 ->getArrayResult();
350                         $sentTo   = 0;
351                         foreach ($profiles as $profile)
352                         {
353                                 $replace = array(
354                                         $profile['firstName'], $profile['familyName'], $profile['mobile']
355                                 );
356                                 self::sendOffline(0, 0, $profile['companyId'], $profile['profileId'],
357                                                   $profile['email'], false,
358                                                   str_replace($search, $replace, $newsletter['subject']),
359                                                   str_replace($search, $replace, $emailTemplate), '',
360                                                   $attachments, $complexAttachments, true);
361                                 $em->clear();
362                                 $sentTo++;
363                         }
364                 }
365                 self::$_data = null;
366                 return $sentTo;
367         }
368
369         public function sendBasicEmail($email, $subject, $body)
370         {
371                 $templatesDir = __DIR__ . '/../../../../../data/templates/';
372                 $template     = file_get_contents($templatesDir . 'general.html');
373                 $body         = str_replace('[body]', $body, $template);
374                 self::send(null, null, null, null, $email, null, $subject, $body, '');
375         }
376
377
378         /**
379          * Send email and/or sms notification.
380          * @param integer $fromCompanyId
381          * @param integer $fromProfileId
382          * @param integer $toCompanyId
383          * @param integer $toProfileId
384          * @param string  $email
385          * @param string  $mobile
386          * @param string  $subject
387          * @param string  $emailTemplate
388          * @param string  $smsTemplate
389          * @param array   $attachments
390          * @param array   $complexAttachments
391          * @param boolean $disableSms
392          * @return void
393          */
394         static private function sendOffline(
395                 $fromCompanyId, $fromProfileId,
396                 $toCompanyId, $toProfileId, $email, $mobile,
397                 $subject, $emailTemplate, $smsTemplate,
398                 array $attachments = array(),
399                 array $complexAttachments = array(),
400                 $disableSms = false
401         )
402         {
403                 if (IS_BROCHURE)
404                 {
405                         self::send(
406                                 $fromCompanyId, $fromProfileId,
407                                 $toCompanyId, $toProfileId, $email, $mobile,
408                                 $subject, $emailTemplate, $smsTemplate,
409                                 $attachments, $complexAttachments, $disableSms
410                         );
411                 }
412                 else
413                 {
414                         $id = 'n' . microtime(true);
415                         while (\Utility\FileStore::existsJson($id))
416                         {
417                                 time_nanosleep(0, 1000);
418                                 $id = 'n' . microtime(true);
419                         };
420                         foreach ($attachments as $key => $data)
421                         {
422                                 $attachments[$key] = utf8_encode($data);
423                         }
424                         foreach ($complexAttachments as $key => $data)
425                         {
426                                 $complexAttachments[$key] = utf8_encode($data);
427                         }
428                         \Utility\FileStore::storeJson(
429                                 $id,
430                                 array(
431                                         'fromCompanyId'      => $fromCompanyId,
432                                         'fromProfileId'      => $fromProfileId,
433                                         'toCompanyId'        => $toCompanyId,
434                                         'toProfileId'        => $toProfileId,
435                                         'email'              => $email,
436                                         'mobile'             => $mobile,
437                                         'subject'            => $subject,
438                                         'emailTemplate'      => $emailTemplate,
439                                         'smsTemplate'        => $smsTemplate,
440                                         'attachments'        => $attachments,
441                                         'complexAttachments' => $complexAttachments,
442                                         'disableSms'         => $disableSms
443                                 )
444                         );
445                         if (false === self::$_gearClient)
446                         {
447                                 self::$_gearClient = new \GearmanClient();
448                                 self::$_gearClient->addServer();
449                         }
450                         self::$_gearClient->doBackground(
451                                 'Notify',
452                                 $id
453                         );
454                 }
455         }
456
457
458
459         /**
460          * Send email and/or sms notification.
461          * @param integer $fromCompanyId
462          * @param integer $fromProfileId
463          * @param integer $toCompanyId
464          * @param integer $toProfileId
465          * @param string  $email
466          * @param string  $mobile
467          * @param string  $subject
468          * @param string  $emailTemplate
469          * @param string  $smsTemplate
470          * @param array   $attachments
471          * @param array   $complexAttachments
472          * @param boolean $disableSms
473          * @return void
474          */
475         static private function send(
476                 $fromCompanyId, $fromProfileId,
477                 $toCompanyId, $toProfileId, $email, $mobile,
478                 $subject, $emailTemplate, $smsTemplate,
479                 array $attachments = array(),
480                 array $complexAttachments = array(),
481                 $disableSms = false
482         )
483         {
484                 #-> Send the email off, into the big wide world, with a message of hope, or something.
485                 try
486                 {
487                         if ($emailTemplate && $email)
488                         {
489 //                \Utility\Debug::errorLog('Email Sending IS_BROCHURE', IS_BROCHURE ? 'true' : 'false');
490
491                 $emailTemplate = str_replace(
492                     '{APP_HOST}',
493                     !IS_BROCHURE ? \Utility\Registry::getConfigParam('Host') : \Utility\Registry::getConfigParam('CashCarsHost'),
494                     $emailTemplate
495                 );
496 //                              $emailTemplate = str_replace('{APP_HOST}', \Utility\Registry::getConfigParam('Host'), $emailTemplate);
497                                 $mailer        = new Email();
498                                 $mailer->send(array(
499                                                       'From'              => IS_BROCHURE
500                                                               ? 'noreply@wepay4cars.co.za'
501                                                               : \Utility\Registry::getConfigParam('sourceEmailAddress'),
502                                                       'To'                => $email,
503                                                       'Subject'           => $subject,
504                                                       'Html'              => $emailTemplate,
505                                                       'Attachment'        => $attachments,
506                                                       'ComplexAttachment' => $complexAttachments
507                                               ));
508                         }
509                 }
510                 catch (\Exception $e)
511                 {
512                         \Utility\Debug::errorLog('Email Sending', "$e");
513                         \Utility\Debug::errorLog('Email Sending', '-----------------------------------------------------------------------------------');
514                         \Utility\Debug::errorLog('Email Sending', $emailTemplate);
515                         \Utility\Debug::errorLog('Email Sending', '-----------------------------------------------------------------------------------');
516                 }
517
518                 #-> Send the sms hurtling through cyberspace at insane speeds.
519                 $apiMsgId = '';
520                 try
521                 {
522                         if (!$disableSms && $smsTemplate && $mobile)
523                         {
524                                 if (IS_STAGE_ENV || 'production' == \Utility\Registry::getConfigParam('Instance'))
525                                 {
526                                         if (IS_STAGE_ENV)
527                                         {
528                                                 $mobile = '+27722208069';
529                                         }
530                                         $sms      = new Sms();
531                                         $apiMsgId = $sms->send(array(
532                                                                        'To'      => $mobile,
533                                                                        'From'    => \Utility\Registry::getConfigParam('smsSourceAddress'),
534                                                                        'Subject' => IS_BROCHURE
535                                                                                ? 'CashCars: '
536                                                                                : 'Bid4Cars: ',
537                                                                        'Body'    => $smsTemplate
538                                                                ));
539                                         $apiMsgId = (false == $apiMsgId)
540                                                 ? ''
541                                                 : $apiMsgId;
542                                 }
543                         }
544                 }
545                 catch (\Exception $e)
546                 {
547                         \Utility\Debug::errorLog(__CLASS__, "$e");
548                 }
549
550                 #-> Log notification entry.
551                 $em      = \Utility\Registry::getEntityManager();
552                 $log     = new \Utility\Entity\NotificationLog();
553                 $logData = array(
554                         'emailTo'      => $email,
555                         'emailSubject' => $subject,
556                         'emailBody'    => $emailTemplate,
557                         'smsTo'        => $mobile,
558                         'smsBody'      => $smsTemplate,
559                         'apiMsgId'     => $apiMsgId
560                 );
561                 $fromCompanyId
562                 && $logData['fromCompany'] = $em->getReference('Company\Entity\Company', $fromCompanyId);
563                 $fromProfileId
564                 && $logData['fromProfile'] = $em->getReference('User\Entity\Profile', $fromProfileId);
565                 $toCompanyId
566                 && $logData['toCompany'] = $em->getReference('Company\Entity\Company', $toCompanyId);
567                 $toProfileId
568                 && $logData['toProfile'] = $em->getReference('User\Entity\Profile', $toProfileId);
569                 $log->fromArray($logData);
570                 $em->persist($log);
571                 $em->flush();
572                 $em->clear('\Utility\Entity\NotificationLog');
573                 return;
574         }
575
576 }
577