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