BxMassMailerModule.php 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636
  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 MassMailer Mass Mailer
  7. * @ingroup UnaModules
  8. *
  9. * @{
  10. */
  11. class BxMassMailerModule extends BxBaseModGeneralModule
  12. {
  13. private $aSegments = array();
  14. function __construct(&$aModule)
  15. {
  16. parent::__construct($aModule);
  17. $CNF = &$this->_oConfig->CNF;
  18. $aRv = array('lvl:0' => _t('_bx_massmailer_segments_all'));
  19. $oAccountQuery = BxDolAclQuery::getInstance();
  20. $aTmp = array();
  21. $oAccountQuery->getLevels(array('type' => 'all_active_pair'), $aTmp);
  22. foreach ($aTmp as $sKey => $sTmp){
  23. if ($sKey != MEMBERSHIP_ID_NON_MEMBER && $sKey != MEMBERSHIP_ID_ACCOUNT)
  24. $aRv['lvl:' . $sKey] = _t($sTmp);
  25. };
  26. $aTmp = $this->_oDb->getSegments();
  27. foreach ($aTmp as $sKey => $sTmp){
  28. $aRv['cst:' . $sKey] = _t($sTmp);
  29. };
  30. $this->aSegments = $aRv;
  31. }
  32. /**
  33. * ACTION METHODS
  34. */
  35. public function actionTrack($sActionName, $sHash)
  36. {
  37. if (isset($sHash) && trim($sHash) != ""){
  38. switch ($sActionName) {
  39. case 'click':
  40. $sLink = $this->_oDb->updateDateClickForLink($sHash);
  41. if (strpos($sLink, '://') === false)
  42. $sLink = BX_DOL_URL_ROOT . $sLink;
  43. header('Location: ' . $sLink);
  44. break;
  45. case 'seen':
  46. header('Content-Type: image/png');
  47. $this->_oDb->updateDateSeenForLetter($sHash);
  48. break;
  49. }
  50. }
  51. }
  52. public function actionGetReportsData($sReportName, $sReportType, $sDateFrom, $sDateTo, $sSegment)
  53. {
  54. if(!BxDolAcl::getInstance()->isMemberLevelInSet(128))
  55. return '';
  56. header('Content-Type: application/json');
  57. $aColors = array('#3366CC', '#DC3912', '#FF9900', '#109618', '#990099');
  58. $iDateFrom = strtotime($sDateFrom);
  59. $iDateTo = strtotime($sDateTo);
  60. $sType = "bar";
  61. $bIsTimeX = false;
  62. $iMinValueY = 0;
  63. $iMaxValueY = 0;
  64. $aValues = array('labels' => array(), 'values' => array(array('legend' => '', 'data' => array())), 'links' => array(), 'strings' => array(0 => _t('_bx_massmailer_txt_item'), 1 => _t('_bx_massmailer_txt_value')));
  65. switch ($sReportName) {
  66. case "SUBSCRIBERS_INFO":
  67. $sType = "line";
  68. $bIsTimeX = true;
  69. $aValues['strings'][0] = _t('_bx_massmailer_txt_date');
  70. $aValues['strings'][1] = '';
  71. $sSql = $this->getSqlBySegment($sSegment);
  72. $aData = $this->_oDb->getAccountsByTermsStat($iDateFrom, $iDateTo, $sSql);
  73. $aData2 = $this->_oDb->getAccountsByTermsStatUnsubscribe($iDateFrom, $iDateTo, $sSql);
  74. $iValuePrev = $this->_oDb->getAccountsByTermsStatInitValue($iDateFrom, $sSql);
  75. $iValuePrev2 = $this->_oDb->getAccountsByTermsStatInitValueUnsubscribe($iDateFrom, $sSql);
  76. $aTmpDates = array();
  77. $aTmpDates2 = array();
  78. $aValues['values'][0]['legend'] = _t('_bx_massmailer_txt_subscribed');
  79. $aValues['values'][1] = array('legend' => _t('_bx_massmailer_txt_unsubscribed') , 'data' => array());
  80. foreach ($aData as $aValue) {
  81. $aTmpDates[$aValue['period']] = $aValue['count'];
  82. }
  83. foreach ($aData2 as $aValue) {
  84. $aTmpDates2[$aValue['period']] = $aValue['count'];
  85. }
  86. for ($i = $iDateFrom; $i < $iDateTo ; $i = $i + 86400 ){
  87. $sX = date('Y-m-d', $i);
  88. if (!array_key_exists($sX, $aTmpDates)){
  89. array_push($aValues['values'][0]['data'], array('x' => $sX, 'y' => $sReportType == 'content_total' ? $iValuePrev : 0));
  90. }
  91. else{
  92. array_push($aValues['values'][0]['data'], array('x' => $sX, 'y' => $sReportType == 'content_total' ? $iValuePrev : $aTmpDates[$sX]));
  93. $iValuePrev += $aTmpDates[$sX];
  94. }
  95. if (!array_key_exists($sX, $aTmpDates2)){
  96. array_push($aValues['values'][1]['data'], array('x' => $sX, 'y' => $sReportType == 'content_total' ? $iValuePrev2 : 0));
  97. }
  98. else{
  99. array_push($aValues['values'][1]['data'], array('x' => $sX, 'y' => $sReportType == 'content_total' ? $iValuePrev2 : $aTmpDates2[$sX]));
  100. $iValuePrev2 += $aTmpDates2[$sX];
  101. }
  102. if ($sReportType == 'content_total'){
  103. if ($iValuePrev > $iMaxValueY)
  104. $iMaxValueY = $iValuePrev;
  105. if ($iValuePrev2 > $iMaxValueY)
  106. $iMaxValueY = $iValuePrev2;
  107. }
  108. else{
  109. if (array_key_exists($sX, $aTmpDates) && $aTmpDates[$sX] > $iMaxValueY)
  110. $iMaxValueY = $aTmpDates[$sX];
  111. if (array_key_exists($sX, $aTmpDates2) && $aTmpDates2[$sX] > $iMaxValueY)
  112. $iMaxValueY = $aTmpDates2[$sX];
  113. }
  114. }
  115. break;
  116. case "CAMPAIGN_REPORT":
  117. $aDataStat = $this->_oDb->getStatByCampaignId($sReportType);
  118. $aValues['values'][0]['legend'] = _t('_bx_massmailer_txt_sent_total_title', $aDataStat['total']);
  119. array_push($aValues['values'][0]['data'], $aDataStat['total']);
  120. $aValues['values'][1] = array('legend' => _t('_bx_massmailer_txt_opened_total_title', $aDataStat['seen']) , 'data' => array($aDataStat['seen']));
  121. $aValues['values'][2] = array('legend' => _t('_bx_massmailer_txt_unopened_total_title', $aDataStat['total'] - $aDataStat['seen']), 'data' => array($aDataStat['total'] - $aDataStat['seen']));
  122. $aValues['values'][3] = array('legend' => _t('_bx_massmailer_txt_clicked_total_title', $aDataStat['clicked']), 'data' => array($aDataStat['clicked']));
  123. $aValues['values'][4] = array('legend' => _t('_bx_massmailer_txt_unsubscribed_total_title', $aDataStat['unsubscribed']), 'data' => array($aDataStat['unsubscribed']));
  124. $iMaxValueY = $aDataStat['total'];
  125. break;
  126. }
  127. $iMaxValueY = ceil($iMaxValueY * 1.1);
  128. $aDataForChartXAxes = array();
  129. if ($bIsTimeX){
  130. $sUnit = 'day';
  131. $iInterval = ($iDateTo - $iDateFrom) / 86400;
  132. if ($iInterval > 50)
  133. $sUnit = 'week';
  134. if ($iInterval > 100)
  135. $sUnit = 'month';
  136. $aDataForChartXAxes = array(
  137. 'type' => 'time',
  138. 'time' => array(
  139. 'tooltipFormat' => 'DD.MM.YYYY',
  140. 'unit' => $sUnit,
  141. ),
  142. 'display' => true,
  143. 'distribution' => 'linear',
  144. 'ticks' => array(
  145. 'display' => true,
  146. 'autoSkip' => true,
  147. )
  148. );
  149. }
  150. else{
  151. $aDataForChartXAxes = array(
  152. 'ticks' => array(
  153. 'autoSkip' => false
  154. ),
  155. 'display' => true
  156. );
  157. }
  158. $aDataForChartDatasets = array();
  159. for($i = 0; $i < count($aValues['values']); $i++){
  160. $aDataForChartDatasets[] = array(
  161. 'label' => $aValues['values'][$i]['legend'],
  162. 'fill' => false,
  163. 'backgroundColor' => $aColors[$i],
  164. 'borderColor' => $aColors[$i],
  165. 'borderWidth' => 1,
  166. 'data' => $aValues['values'][$i]['data']
  167. );
  168. }
  169. $aDataForChart = array(
  170. 'type' => $sType,
  171. 'data' => array(
  172. 'labels' => $aValues['labels'],
  173. 'datasets' => $aDataForChartDatasets
  174. ),
  175. 'options' => array(
  176. 'legend' => array(
  177. 'position' => 'bottom',
  178. 'display' => count($aValues['values']) == 1 ? false : true
  179. ),
  180. 'scales' => array(
  181. 'yAxes' => array(
  182. array(
  183. 'ticks' => array(
  184. 'max' => $iMaxValueY,
  185. 'min' => $iMinValueY,
  186. 'stepSize' => $this->getReportStep($iMinValueY, $iMaxValueY),
  187. 'autoSkip' => true
  188. )
  189. )
  190. ),
  191. 'xAxes' => array($aDataForChartXAxes)
  192. )
  193. ),
  194. 'links' => $aValues['links'],
  195. 'strings' => $aValues['strings'],
  196. );
  197. echo json_encode($aDataForChart);
  198. }
  199. /**
  200. * SERVICE METHODS
  201. */
  202. public function serviceGetSafeServices()
  203. {
  204. return array ();
  205. }
  206. /**
  207. * @page service Service Calls
  208. * @section bx_massmailer Mass mailer
  209. * @subsection bx_massmailer-page_blocks Page Blocks
  210. * @subsubsection bx_massmailer-campagn_subscribers campagn_subscribers
  211. *
  212. * @code bx_srv('bx_massmailer', 'campagn_subscribers', [...]); @endcode
  213. *
  214. * Get page block with the campagn's subscribers list
  215. *
  216. * @param $iContentId content ID.
  217. * @return HTML string with block content to display on the site. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
  218. *
  219. * @see BxMassMailerModule::serviceCampagnSubscribers
  220. */
  221. /**
  222. * @ref bx_massmailer-campagn_subscribers "entity_view"
  223. */
  224. public function serviceCampagnSubscribers ($iContentId = 0, $sDisplay = false)
  225. {
  226. if(!$iContentId)
  227. $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
  228. if(!$iContentId)
  229. return false;
  230. $aData = $this->_oDb->getLettersByCampaignId($iContentId);
  231. if (count($aData) > 0)
  232. return $this->_oTemplate->getSubscribers($aData);
  233. return $iContentId;
  234. }
  235. /**
  236. * @page service Service Calls
  237. * @section bx_massmailer Mass mailer
  238. * @subsection bx_massmailer-page_blocks Page Blocks
  239. * @subsubsection bx_massmailer-campagn_info campagn_info
  240. *
  241. * @code bx_srv('bx_massmailer', 'campagn_info', [...]); @endcode
  242. *
  243. * Get page block with the campagn info
  244. *
  245. * @param $iContentId content ID.
  246. * @return HTML string with block content to display on the site. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
  247. *
  248. * @see BxMassMailerModule::serviceCampagnInfo
  249. */
  250. /**
  251. * @ref bx_massmailer-campagn_info "campagn_info"
  252. */
  253. public function serviceCampagnInfo ($iContentId = 0, $sDisplay = false)
  254. {
  255. if(!$iContentId)
  256. $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
  257. if(!$iContentId)
  258. return false;
  259. return $this->_oTemplate->getInfo($iContentId);
  260. }
  261. /**
  262. * @page service Service Calls
  263. * @section bx_massmailer Mass mailer
  264. * @subsection bx_massmailer-page_blocks Page Blocks
  265. * @subsubsection bx_massmailer-campagn_links campagn_links
  266. *
  267. * @code bx_srv('bx_massmailer', 'campagn_links', [...]); @endcode
  268. *
  269. * Get page block with the campagn links list
  270. *
  271. * @param $iContentId content ID
  272. * @return HTML string with block content to display on the site. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
  273. *
  274. * @see BxMassMailerModule::serviceCampagnLinks
  275. */
  276. /**
  277. * @ref bx_massmailer-campagn_links "campagn_links"
  278. */
  279. public function serviceCampagnLinks ($iContentId = 0, $sDisplay = false)
  280. {
  281. if(!$iContentId)
  282. $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
  283. if(!$iContentId)
  284. return false;
  285. $aData = $this->_oDb->getClicksByCampaignId($iContentId);
  286. if (count($aData) > 0)
  287. return $this->_oTemplate->getClicks($aData);
  288. return $iContentId;
  289. }
  290. /**
  291. * @page service Service Calls
  292. * @section bx_massmailer Mass mailer
  293. * @subsection bx_massmailer-page_blocks Page Blocks
  294. * @subsubsection bx_massmailer-total_subscribers total_subscribers
  295. *
  296. * @code bx_srv('bx_massmailer', 'total_subscribers', [...]); @endcode
  297. *
  298. * Get page block with subscribers charts
  299. *
  300. * @param $aParams an array with search params.
  301. * @return HTML string with block content to display on the site. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
  302. *
  303. * @see BxMassMailerModule::serviceTotalSubscribers
  304. */
  305. /**
  306. * @ref bx_massmailer-total_subscribers "total_subscribers"
  307. */
  308. public function serviceTotalSubscribers ()
  309. {
  310. return $this->_oTemplate->getTotalSubscribers();
  311. }
  312. /**
  313. * @page service Service Calls
  314. * @section bx_massmailer Mass mailer
  315. * @subsection bx_massmailer-page_blocks Page Blocks
  316. * @subsubsection bx_massmailer-entity_breadcrumb entity_breadcrumb
  317. *
  318. * @code bx_srv('bx_massmailer', 'entity_breadcrumb', [...]); @endcode
  319. *
  320. * Get page block with page's breadcrumbs
  321. *
  322. * @param $iContentId content ID
  323. * @return HTML string with block content to display on the site. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
  324. *
  325. * @see BxMassMailerModule::serviceEntityBreadcrumb
  326. */
  327. /**
  328. * @ref bx_massmailer-entity_breadcrumb "entity_breadcrumb"
  329. */
  330. public function serviceEntityBreadcrumb ($iContentId = 0)
  331. {
  332. $CNF = &$this->_oConfig->CNF;
  333. $oPermalink = BxDolPermalinks::getInstance();
  334. if (!$iContentId)
  335. $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
  336. if (!$iContentId){
  337. $aContentInfo[$CNF['FIELD_TITLE']] = _t('_bx_massmailer_txt_breadcrumb_title_new_campaign');
  338. $aContentInfo['url'] = $oPermalink->permalink('page.php?i=' . $CNF['URI_ADD_CAMPAIGN']);
  339. }
  340. else{
  341. $aContentInfo = $this->_oDb->getCampaignInfoById($iContentId);
  342. if (!$aContentInfo)
  343. return false;
  344. $aContentInfo['url'] = $oPermalink->permalink('page.php?i=' . $CNF['URI_VIEW_CAMPAIGN'] . '&id=' . $aContentInfo[$CNF['FIELD_ID']]);
  345. }
  346. return $this->_oTemplate->entryBreadcrumb($aContentInfo);
  347. }
  348. /**
  349. * @page service Service Calls
  350. * @section bx_massmailer Mass mailer
  351. * @subsection bx_massmailer-page_blocks Page Blocks
  352. * @subsubsection bx_massmailer-attributes attributes
  353. *
  354. * @code bx_srv('bx_massmailer', 'attributes', [...]); @endcode
  355. *
  356. * Get page block with attributes list
  357. *
  358. * @return HTML string with block content to display on the site. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
  359. *
  360. * @see BxMassMailerModule::serviceAttributes
  361. */
  362. /**
  363. * @ref bx_massmailer-attributes "attributes"
  364. */
  365. public function serviceAttributes ()
  366. {
  367. $aAttributesParts = array();
  368. $aAttributesParts['account'] = array(_t('_bx_massmailer_txt_attribute_global'), array('email' => _t('_bx_massmailer_txt_attribute_email'), 'account_name' => _t('_bx_massmailer_txt_attribute_account_name'), 'account_id' => _t('_bx_massmailer_txt_attribute_account_id'), 'unsubscribe_url' => _t('_bx_massmailer_txt_attribute_unsubscribe_url')));
  369. $BxDolModuleQuery = BxDolModuleQuery::getInstance();
  370. $aModules = $BxDolModuleQuery->getModulesBy(array('type' => 'modules', 'active' => 1));
  371. foreach($aModules as $aModule){
  372. if(BxDolRequest::serviceExists($aModule['name'], 'act_as_profile') && BxDolService::call($aModule['name'], 'act_as_profile') == true){
  373. $oModule = BxDolModule::getInstance($aModule['name']);
  374. $aTmp2 = array();
  375. $aTmp = $oModule->serviceGetSearchableFieldsExtended('view');
  376. foreach($aTmp as $sKey => $aField){
  377. $aTmp2[$sKey] = _t($aField['caption']);
  378. }
  379. $aAttributesParts[$aModule['name']] = array($aModule['title'], $aTmp2);
  380. }
  381. }
  382. return $this->_oTemplate->getAttributes($aAttributesParts);
  383. }
  384. /**
  385. * @return CHECK_ACTION_RESULT_ALLOWED if access is granted or error message if access is forbidden. So make sure to make strict(===) checking.
  386. */
  387. public function checkAllowedAdd ($isPerformAction = false)
  388. {
  389. return $this->checkAllowed($isPerformAction);
  390. }
  391. /**
  392. * @return CHECK_ACTION_RESULT_ALLOWED if access is granted or error message if access is forbidden. So make sure to make strict(===) checking.
  393. */
  394. public function checkAllowedEdit ($aDataEntry, $isPerformAction = false)
  395. {
  396. return $this->checkAllowed($isPerformAction);
  397. }
  398. /**
  399. * @return CHECK_ACTION_RESULT_ALLOWED if access is granted or error message if access is forbidden. So make sure to make strict(===) checking.
  400. */
  401. public function checkAllowedDelete (&$aDataEntry, $isPerformAction = false)
  402. {
  403. return $this->checkAllowed($isPerformAction);
  404. }
  405. public function getSegments($sKey = "")
  406. {
  407. if ($sKey == ""){
  408. return $this->aSegments;
  409. }
  410. else{
  411. if (isset($this->aSegments[$sKey]))
  412. return $this->aSegments[$sKey];
  413. return false;
  414. }
  415. }
  416. public function sendTest($sEmail, $iCampaignId)
  417. {
  418. $aTmp = $this->getDataForCampaign($iCampaignId);
  419. $aTemplate = $aTmp[0];
  420. $aCustomHeaders = $aTmp[1];
  421. if (!$aTemplate)
  422. return false;
  423. return $this->sendLetter($sEmail, $iCampaignId, $aCustomHeaders, bx_get_logged_profile_id(), $aTemplate, false);
  424. }
  425. public function sendAll($iCampaignId)
  426. {
  427. $aEmails = array();
  428. $aTmp = $this->getDataForCampaign($iCampaignId);
  429. $aTemplate = $aTmp[0];
  430. $aCustomHeaders = $aTmp[1];
  431. $aCampaign = $aTmp[2];
  432. if (!$aTemplate)
  433. return false;
  434. $this->_oDb->deleteCampaignData($iCampaignId);
  435. $aAccounts = $this->getEmailsBySegment($aCampaign['segments'], $aCampaign['is_one_per_account']);
  436. foreach ($aAccounts as $aAccountInfo){
  437. array_push($aEmails, $aAccountInfo['email']);
  438. $this->sendLetter($aAccountInfo['email'], $iCampaignId, $aCustomHeaders, $aAccountInfo['profile_id'], $aTemplate, true);
  439. }
  440. $this->_oDb->sendCampaign($iCampaignId, implode(',', $aEmails));
  441. return true;
  442. }
  443. private function sendLetter($sEmail, $iCampaignId, $aCustomHeaders, $iProfileId, $aTemplate, $bAddToQueue)
  444. {
  445. $sLetterCode = $this->_oDb->addLetter($iCampaignId, $sEmail);
  446. $aMarkers = $this->addMarkers($iProfileId, $sLetterCode);
  447. bx_alert($this->_aModule['name'], 'user_fields', $iCampaignId, $iProfileId, array('email' => $sEmail, 'markers' => &$aMarkers));
  448. $regexp = "<a\s[^>]*href=(\"??)([^\" >]*?)\\1[^>]*>(.*)<\/a>";
  449. $aTemplate['Body'] = preg_replace_callback("/$regexp/siU",
  450. function ($aMatch) use ($iCampaignId, $sLetterCode, $aMarkers) {
  451. if ($aMatch[2] != '{unsubscribe_url}'){
  452. $sUrl = bx_replace_markers($aMatch[2], $aMarkers);
  453. $sLinkCode = $this->_oDb->addLink($sLetterCode, $sUrl, $aMatch[3], $iCampaignId);
  454. return str_replace($sUrl, BX_DOL_URL_ROOT . $this->_oConfig->getBaseUri() . 'track/click/' . $sLinkCode . "/", $aMatch[0]);
  455. }
  456. else{
  457. return $aMatch[0];
  458. }
  459. },
  460. $aTemplate['Body']);
  461. return sendMail($sEmail, $aTemplate['Subject'], $aTemplate['Body'], 0, $aMarkers, BX_EMAIL_MASS, 'html', false, $aCustomHeaders, $bAddToQueue);
  462. }
  463. public function getEmailCountInSegment($iCampaignId)
  464. {
  465. $aTmp = $this->getDataForCampaign($iCampaignId);
  466. $aCampaign = $aTmp[2];
  467. $aAccounts = $this->getEmailsBySegment($aCampaign['segments'], $aCampaign['is_one_per_account']);
  468. return count($aAccounts);
  469. }
  470. private function getEmailsBySegment($sSegment, $bIsOnePerAccount)
  471. {
  472. $sTerms = $this->getSqlBySegment($sSegment);
  473. if ($bIsOnePerAccount){
  474. $sTerms .= "AND `tp`.`id` = `ta`.`profile_id` ";
  475. }
  476. return $this->_oDb->getAccountsByTerms($sTerms);
  477. }
  478. private function checkAllowed($isPerformAction = false)
  479. {
  480. $aCheck = checkActionModule($this->_iProfileId, 'use massmailer', $this->getName(), $isPerformAction);
  481. if ($aCheck[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED)
  482. return _t('_sys_txt_access_denied');
  483. return CHECK_ACTION_RESULT_ALLOWED;
  484. }
  485. private function getSqlBySegment($sSegment)
  486. {
  487. $sRv = '';
  488. $sJoin = ' INNER ';
  489. if (strpos($sSegment, 'lvl:') !== false){
  490. $sLvl = str_replace('lvl:', '', $sSegment);
  491. switch ($sLvl) {
  492. case 0:
  493. $sRv = '';
  494. $sJoin = ' LEFT ';
  495. break;
  496. case MEMBERSHIP_ID_UNCONFIRMED:
  497. $sRv = " AND `ta`.`email_confirmed` = 0 AND `ta`.`phone_confirmed` = 0 ";
  498. break;
  499. case MEMBERSHIP_ID_SUSPENDED:
  500. $sRv = " AND `tp`.`status` = 'suspended' ";
  501. break;
  502. case MEMBERSHIP_ID_PENDING:
  503. $sRv = " AND `tp`.`status` = 'pending' ";
  504. break;
  505. case MEMBERSHIP_ID_STANDARD:
  506. $sRv = " AND `tp`.`id` NOT IN (SELECT `IDMember` FROM `sys_acl_levels_members`) ";
  507. break;
  508. default:
  509. $sRv = $this->_oDb->prepareAsString(" AND `tp`.`id` IN (SELECT `IDMember` FROM `sys_acl_levels_members` WHERE IDLevel = ?) ", $sLvl);
  510. break;
  511. }
  512. $sRv .= " AND `tp`.`type` IN (" . $this->_oDb->implode_escape($this->getProfileModules()) . ")";
  513. }
  514. return $sJoin . " JOIN `sys_profiles` AS `tp` ON `tp`.`account_id`=`ta`.`id` " . $sRv;
  515. }
  516. private function getProfileModules()
  517. {
  518. $aResult = array();
  519. $BxDolModuleQuery = BxDolModuleQuery::getInstance();
  520. $aModules = $BxDolModuleQuery->getModulesBy(array('type' => 'modules', 'active' => 1));
  521. foreach($aModules as $aModule){
  522. if(BxDolRequest::serviceExists($aModule['name'], 'act_as_profile') && BxDolService::call($aModule['name'], 'act_as_profile') == true){
  523. array_push($aResult, $aModule['name']);
  524. }
  525. }
  526. return $aResult;
  527. }
  528. private function getDataForCampaign($iCampaignId)
  529. {
  530. $aCampaign = $this->_oDb->getCampaignInfoById($iCampaignId);
  531. $oEmailTemplates = BxDolEmailTemplates::getInstance();
  532. $aTemplate = $oEmailTemplates->parseTemplate('bx_massmailer_email', array('content' => $aCampaign['body']));
  533. $aTemplate['Subject'] = $aCampaign['subject'];
  534. $aCustomHeaders = array();
  535. $sFrom = $aCampaign['from_name'] != '' ? $aCampaign['from_name'] : getParam('site_title');
  536. $aCustomHeaders['From'] = "=?UTF-8?B?" . base64_encode($sFrom) . "?= <" . getParam('site_email_notify') . ">" ;
  537. if ($aCampaign['reply_to'] != ''){
  538. $sFrom = $aCampaign['from_name'] != '' ? $aCampaign['from_name'] : getParam('site_title');
  539. $aCustomHeaders['Reply-To'] = "=?UTF-8?B?" . base64_encode($sFrom) . '?= <' . bx_process_output($aCampaign['reply_to']) . '>';
  540. $aCustomHeaders['X-Original-From'] = "=?UTF-8?B?" . base64_encode($sFrom) . '?= <' . bx_process_output($aCampaign['reply_to']) . '>';
  541. }
  542. return array($aTemplate, $aCustomHeaders, $aCampaign);
  543. }
  544. private function addMarkers($iProfileId, $sLetterCode)
  545. {
  546. $CNF = &$this->_oConfig->CNF;
  547. $aMarkers = array();
  548. $oProfile = BxDolProfile::getInstance($iProfileId);
  549. if ($oProfile){
  550. $oAccount = BxDolAccount::getInstance($oProfile->getAccountId());
  551. $aMarkers['email'] = $oAccount->getEmail();
  552. $aMarkers['account_name'] = $oAccount->getDisplayName();
  553. $aMarkers['account_id'] = $oProfile->getAccountId();
  554. $oModule = BxDolModule::getInstance($oProfile->getModule());
  555. if (BxDolRequest::serviceExists($oProfile->getModule(), 'get_info')){
  556. $aProfileInfo = $oModule->serviceGetInfo($oProfile->getContentId(), false);
  557. foreach ($aProfileInfo as $sKey => $sValue){
  558. if (!isset($aMarkers[$sKey]))
  559. $aMarkers[$sKey] = $sValue;
  560. }
  561. $aMarkers['seen_image_url'] = BX_DOL_URL_ROOT . $this->_oConfig->getBaseUri() . 'track/seen/' . $sLetterCode . "/";
  562. $aMarkers['unsubscribe_url'] = BX_DOL_URL_ROOT . $oAccount->getUnsubscribeLink(BX_EMAIL_MASS) . "&lhash=" . $sLetterCode;
  563. }
  564. }
  565. return $aMarkers;
  566. }
  567. private function getReportStep($iMin, $iMax)
  568. {
  569. $iCount = 10;
  570. return ceil(($iMax - $iMin) / $iCount);
  571. }
  572. }
  573. /** @} */