BxDolEmailTemplates.php 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. <?php defined('BX_DOL') or die('hack attempt');
  2. /**
  3. * Copyright (c) UNA, Inc - https://una.io
  4. * MIT License - https://opensource.org/licenses/MIT
  5. *
  6. * @defgroup UnaCore UNA Core
  7. * @{
  8. */
  9. bx_import('BxDolPermalinks');
  10. /**
  11. * Email templates are used to send preformated messages.
  12. *
  13. * Email templates are multilingual.
  14. *
  15. * User is sent email in language which is defined in their account, if account language is not set - then default site language is used.
  16. *
  17. * Email templates use template system, so it is possible to customize header/footer via Studio -> Polyglot -> Emails header/footer
  18. *
  19. * 1-click unsubscribe link is added automatically to every email (except a few system emails, which is not supposed to unsubscribe from, like forgot password email).
  20. * Please note: make sure that {unsubscribe} marker is not removed, or unsubscribe link will not be added.
  21. *
  22. *
  23. * @section example Example of usage
  24. *
  25. * Send an email using email templates:
  26. *
  27. * @code
  28. *
  29. * // define custom template variables
  30. * $aPlus = array();
  31. * $aPlus['email'] = 'ktoto@example.com';
  32. * $aPlus['conf_code'] = '123456';
  33. * $aPlus['conf_link'] = BX_DOL_URL_ROOT . 'page.php?i=confirm-email&code=123456';
  34. * $aPlus['conf_form_link'] = BX_DOL_URL_ROOT . 'page.php?i=confirm-email';
  35. *
  36. * $aTemplate = BxDolEmailTemplates::getInstance()->parseTemplate('t_Confirmation', $aPlus); // get class instance and parse template
  37. *
  38. * if ($aTemplate && sendMail('ktoto@example.com', $aTemplate['Subject'], $aTemplate['Body'])) // send email if template exists
  39. * echo 'email was successfully sent';
  40. * else
  41. * echo 'email send failed';
  42. *
  43. * @endcode
  44. *
  45. */
  46. class BxDolEmailTemplates extends BxDolFactory implements iBxDolSingleton
  47. {
  48. protected $_oEmailTemplatesQuery;
  49. protected $iDefaultLangId;
  50. protected $iFallbackLangId;
  51. protected $aDefaultKeys;
  52. protected function __construct()
  53. {
  54. if (isset($GLOBALS['bxDolClasses'][get_class($this)]))
  55. trigger_error ('Multiple instances are not allowed for the class: ' . get_class($this), E_USER_ERROR);
  56. parent::__construct();
  57. $oLang = BxDolLanguages::getInstance();
  58. $this->iDefaultLangId = $oLang->getCurrentLangId();
  59. $this->iFallbackLangId = $oLang->getLangId('en');
  60. $sAboutUs = _t('_sys_et_txt_about_us');
  61. $this->aDefaultKeys = array(
  62. 'site_url' => BX_DOL_URL_ROOT,
  63. 'site_name' => getParam('site_title'),
  64. 'about_us' => '<a href="' . BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=about') . '" title="' . bx_html_attribute($sAboutUs) . '">' . $sAboutUs . '</a>',
  65. );
  66. $this->_oEmailTemplatesQuery = BxDolEmailTemplatesQuery::getInstance();
  67. }
  68. /**
  69. * Prevent cloning the instance
  70. */
  71. public function __clone()
  72. {
  73. if (isset($GLOBALS['bxDolClasses'][get_class($this)]))
  74. trigger_error('Clone is not allowed for the class: ' . get_class($this), E_USER_ERROR);
  75. }
  76. /**
  77. * Get singleton instance of the class
  78. */
  79. static function getInstance()
  80. {
  81. if(!isset($GLOBALS['bxDolClasses'][__CLASS__]))
  82. $GLOBALS['bxDolClasses'][__CLASS__] = new BxDolEmailTemplates();
  83. return $GLOBALS['bxDolClasses'][__CLASS__];
  84. }
  85. /**
  86. * Function will return array of needed template ;
  87. *
  88. * @param string $sTemplateName - name of necessary template.
  89. * @param integer $iAccountId - account ID of registered member.
  90. * @return array with template 'Subject' and 'Body'.
  91. */
  92. function getTemplate($sTemplateName, $iAccountId = 0 )
  93. {
  94. $iUseLang = $this->iDefaultLangId;
  95. if ($iAccountId) {
  96. $oAccount = BxDolAccount::getInstance($iAccountId);
  97. if ($oAccount) {
  98. $iUseLang = $oAccount->getLanguageId();
  99. if(empty($iUseLang))
  100. $iUseLang = $this->iDefaultLangId;
  101. }
  102. }
  103. return $this->_oEmailTemplatesQuery->getTemplate ($sTemplateName, $iUseLang, $this->iDefaultLangId, $this->iFallbackLangId);
  104. }
  105. /**
  106. * Function will return array of needed template with neccessary markers replaced ;
  107. *
  108. * @param string $sTemplateName - name of necessary template.
  109. * @param string $aTemplatekeys - key ane value pairs to replace in subject and body.
  110. * @param integer $iAccountId - account ID of registered member.
  111. * @param integer $iProfileId - profile ID of registered member.
  112. * @return array with template 'Subject' and 'Body'.
  113. */
  114. function parseTemplate($sTemplateName, $aTemplateKeys, $iAccountId = 0, $iProfileId = 0)
  115. {
  116. $aTemplate = $this->getTemplate($sTemplateName, $iAccountId);
  117. /**
  118. * @hooks
  119. * @hookdef hook-system-parse_email_template 'system', 'parse_email_template' - hook on template with neccessary markers replaced
  120. * - $unit_name - equals `system`
  121. * - $action - equals `parse_email_template`
  122. * - $object_id - not used
  123. * - $sender_id - not used
  124. * - $extra_params - array of additional params with the following array keys:
  125. * - `template_name` - [string] by ref, name of necessary template, can be overridden in hook processing
  126. * - `template_keys` - [array] by ref, key ane value pairs to replace in subject and body, can be overridden in hook processing
  127. * - `account_id` - [int] by ref, account ID of registered member, can be overridden in hook processing
  128. * - `profile_id` - [int] by ref, profile ID of registered member, can be overridden in hook processing
  129. * - `template` - [array] by ref, template, can be overridden in hook processing
  130. * @hook @ref hook-system-parse_email_template
  131. */
  132. bx_alert('system', 'parse_email_template', 0, 0, array(
  133. 'template_name' => &$sTemplateName,
  134. 'template_keys' => &$aTemplateKeys,
  135. 'account_id' => &$iAccountId,
  136. 'profile_id' => &$iProfileId,
  137. 'template' => &$aTemplate,
  138. 'template_name_ref' => &$sTemplateName,
  139. 'template_keys_ref' => &$aTemplateKeys,
  140. 'account_id_ref' => &$iAccountId,
  141. 'profile_id_ref' => &$iProfileId,
  142. 'template_ref' => &$aTemplate
  143. ));
  144. if (!$aTemplate)
  145. return false;
  146. return array(
  147. 'Subject' => $this->parseContent($aTemplate['Subject'], $aTemplateKeys, $iAccountId, $iProfileId),
  148. 'Body' => $this->parseContent($aTemplate['Body'], $aTemplateKeys, $iAccountId, $iProfileId)
  149. );
  150. }
  151. function parseContent($sContent, $aKeys, $iAccountId = 0, $iProfileId = 0)
  152. {
  153. $aResultKeys = $this->aDefaultKeys;
  154. $oProfile = null;
  155. if ($iProfileId) {
  156. $oProfile = BxDolProfile::getInstance($iProfileId);
  157. if ($oProfile && ($aProfileInfo = $oProfile->getInfo())) {
  158. $aResultKeys = array_merge($aResultKeys, array(
  159. 'profile_name' => $oProfile->getDisplayName(),
  160. 'profile_url' => $oProfile->getUrl(),
  161. 'profile_thumb' => $oProfile->getThumb(),
  162. 'profile_icon' => $oProfile->getIcon(),
  163. 'profile_id' => $aProfileInfo['id'],
  164. 'profile_status' => $aProfileInfo['status'],
  165. 'profile_type' => $aProfileInfo['type'],
  166. 'profile_content_id' => $aProfileInfo['content_id'],
  167. ));
  168. }
  169. }
  170. if ($iAccountId || $oProfile) {
  171. $oAccount = BxDolAccount::getInstance($iAccountId ? $iAccountId : $oProfile->getAccountId());
  172. if ($oAccount && ($aAccountInfo = $oAccount->getInfo())) {
  173. $aResultKeys = array_merge($aResultKeys, array(
  174. 'account_id' => $aAccountInfo['id'],
  175. 'account_name' => $oAccount->getDisplayName(),
  176. 'account_email' => $aAccountInfo['email'],
  177. ));
  178. }
  179. }
  180. if (is_array($aKeys))
  181. $aResultKeys = array_merge($aResultKeys, $aKeys);
  182. $aKeyWrapper = array('{', '}');
  183. $sContent = BxDolTemplate::getInstance()->parseHtmlByContent($sContent, array(
  184. 'email_header' => getParam('site_email_html_template_header'),
  185. 'email_footer' => getParam('site_email_html_template_footer'),
  186. ), $aKeyWrapper);
  187. return BxDolTemplate::getInstance()->parseHtmlByContent($sContent, $aResultKeys, $aKeyWrapper);
  188. }
  189. }
  190. /** @} */