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