BxMassMailerDb.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  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 BxMassMailerDb extends BxBaseModGeneralDb
  12. {
  13. function __construct(&$oConfig)
  14. {
  15. parent::__construct($oConfig);
  16. }
  17. public function copyCampaign($iCampaignId)
  18. {
  19. $CNF = &$this->_oConfig->CNF;
  20. $aBindings = array(
  21. 'campaign_id' => $iCampaignId,
  22. 'date_created' => time(),
  23. 'copy_title' => _t('_bx_massmailer_txt_copy_title')
  24. );
  25. $this->query("INSERT INTO `" . $CNF['TABLE_CAMPAIGNS'] . "` (`" . $CNF['FIELD_AUTHOR'] . "`, `" . $CNF['FIELD_TITLE'] . "`, `" . $CNF['FIELD_BODY'] . "`, `" . $CNF['FIELD_SEGMENTS'] . "`, `" . $CNF['FIELD_ADDED'] . "`, `" . $CNF['FIELD_SUBJECT'] . "`, `" . $CNF['FIELD_FROM_NAME'] . "`, `" . $CNF['FIELD_REPLY_TO'] . "`, `" . $CNF['FIELD_PER_ACCOUNT'] . "`) SELECT `" . $CNF['FIELD_AUTHOR'] . "`, CONCAT(`" . $CNF['FIELD_TITLE'] . "`, :copy_title), `" . $CNF['FIELD_BODY'] . "`, `" . $CNF['FIELD_SEGMENTS'] . "`, :date_created, `" . $CNF['FIELD_SUBJECT'] . "`, `" . $CNF['FIELD_FROM_NAME'] . "`, `" . $CNF['FIELD_REPLY_TO'] . "`, `" . $CNF['FIELD_PER_ACCOUNT'] . "` FROM `" . $CNF['TABLE_CAMPAIGNS'] . "` WHERE `" . $CNF['FIELD_ID'] . "` = :campaign_id", $aBindings);
  26. return $this->lastId();
  27. }
  28. public function sendCampaign($iCampaignId)
  29. {
  30. $CNF = &$this->_oConfig->CNF;
  31. $aBindings = array(
  32. 'campaign_id' => $iCampaignId,
  33. 'date_sent' => time()
  34. );
  35. $this->query("UPDATE `" . $CNF['TABLE_CAMPAIGNS'] . "` SET `" . $CNF['FIELD_DATE_SENT'] . "` = :date_sent WHERE `" . $CNF['FIELD_ID'] . "` = :campaign_id", $aBindings);
  36. }
  37. public function addEmailToSentListForCampaign($iCampaignId, $sEmailList)
  38. {
  39. $CNF = &$this->_oConfig->CNF;
  40. $aBindings = array(
  41. 'campaign_id' => $iCampaignId,
  42. 'email_list' => $sEmailList
  43. );
  44. $this->query("UPDATE `" . $CNF['TABLE_CAMPAIGNS'] . "` SET `" . $CNF['FIELD_EMAIL_LIST'] . "` = CONCAT(IFNULL(`" . $CNF['FIELD_EMAIL_LIST'] . "`, ''), ',', :email_list) WHERE `" . $CNF['FIELD_ID'] . "` = :campaign_id", $aBindings);
  45. }
  46. public function getCampaignInfoById ($iCampaignId)
  47. {
  48. $CNF = &$this->_oConfig->CNF;
  49. $sQuery = $this->prepare ("SELECT * FROM `" . $CNF['TABLE_CAMPAIGNS'] . "` WHERE `" . $CNF['FIELD_ID'] . "` = ?", $iCampaignId);
  50. return $this->getRow($sQuery);
  51. }
  52. public function getSegmentInfoById ($iSegmentId)
  53. {
  54. $CNF = &$this->_oConfig->CNF;
  55. $sQuery = $this->prepare ("SELECT * FROM `" . $CNF['TABLE_SEGMENTS'] . "` WHERE `" . $CNF['FIELD_ID'] . "` = ?", $iSegmentId);
  56. return $this->getRow($sQuery);
  57. }
  58. public function getSegments()
  59. {
  60. $CNF = &$this->_oConfig->CNF;
  61. $sQuery = $this->prepare ("SELECT `" . $CNF['FIELD_ID'] . "`, `" . $CNF['FIELD_TITLE'] . "` FROM `" . $CNF['TABLE_SEGMENTS'] . "`");
  62. return $this->getPairs($sQuery, $CNF['FIELD_ID'], $CNF['FIELD_TITLE']);
  63. }
  64. /**
  65. * Emails in a custom segment's list, separated by commas, semicolons or white space.
  66. */
  67. public function getSegmentEmails($iSegmentId)
  68. {
  69. $CNF = &$this->_oConfig->CNF;
  70. $sEmails = $this->getOne("SELECT `" . $CNF['FIELD_EMAIL_LIST'] . "` FROM `" . $CNF['TABLE_SEGMENTS'] . "` WHERE `" . $CNF['FIELD_ID'] . "` = :id", array('id' => $iSegmentId));
  71. $aEmails = $sEmails ? preg_split('/[\s,;]+/u', $sEmails, -1, PREG_SPLIT_NO_EMPTY) : false;
  72. if (!$aEmails)
  73. return array();
  74. return array_values(array_unique(preg_grep('/@/', $aEmails)));
  75. }
  76. /**
  77. * Account terms: only the accounts with one of these emails, none for an empty list.
  78. */
  79. public function getTermsByEmails($aEmails)
  80. {
  81. if (empty($aEmails))
  82. return " AND 0 ";
  83. return " AND `ta`.`email` IN (" . $this->implode_escape($aEmails) . ") ";
  84. }
  85. /**
  86. * Account terms: only the profiles of these types.
  87. */
  88. public function getTermsByProfileTypes($aTypes)
  89. {
  90. return " AND `tp`.`type` IN (" . $this->implode_escape($aTypes) . ")";
  91. }
  92. public function getAccountsByTerms($sTerms = "")
  93. {
  94. $sSql = "SELECT `ta`.`email`, `tp`.`id` AS `profile_id`, `ta`.`id` as `account_id` FROM `sys_accounts` AS `ta` " . $sTerms . " WHERE `ta`.`receive_news` <> 0 AND `ta`.`email_confirmed` = 1";
  95. return $this->getAll($sSql);
  96. }
  97. public function getAccountsByTermsStat($iDateFrom, $iDateTo, $sTerms = "")
  98. {
  99. $aBindings = array(
  100. 'datefrom' => $iDateFrom,
  101. 'dateto' => $iDateTo
  102. );
  103. $sSql = "SELECT DATE(FROM_UNIXTIME(`ta`.`added`)) AS `period`, YEAR(FROM_UNIXTIME(`ta`.`added`)) AS `year`, COUNT(*) AS `count` FROM `sys_accounts` AS `ta` " . $sTerms . " WHERE `ta`.`receive_news` <> 0 AND `ta`.`email_confirmed` = 1 AND `ta`.`added` >= :datefrom AND `ta`.`added` <= :dateto GROUP BY `period`, `year` ORDER BY `year`, `period` ASC";
  104. return $this->getAll($sSql, $aBindings);
  105. }
  106. public function getAccountsByTermsStatUnsubscribe($iDateFrom, $iDateTo, $sTerms = "")
  107. {
  108. $CNF = &$this->_oConfig->CNF;
  109. $aBindings = array(
  110. 'datefrom' => $iDateFrom,
  111. 'dateto' => $iDateTo
  112. );
  113. $sSql = "SELECT DATE(FROM_UNIXTIME(`tu`.`unsubscribed`)) AS `period`, YEAR(FROM_UNIXTIME(`tu`.`unsubscribed`)) AS `year`, COUNT(*) AS `count` FROM `sys_accounts` AS `ta` INNER JOIN `" . $CNF['TABLE_UNSUBSCRIBE'] . "` AS `tu` ON `tu`.`account_id`=`ta`.`id` " . $sTerms . " WHERE `tu`.`unsubscribed` >= :datefrom AND `tu`.`unsubscribed` <= :dateto GROUP BY `period`, `year` ORDER BY `year`, `period` ASC";
  114. return $this->getAll($sSql, $aBindings);
  115. }
  116. public function getAccountsByTermsStatInitValue($iDateFrom, $sTerms)
  117. {
  118. $aBindings = array(
  119. 'datefrom' => $iDateFrom
  120. );
  121. $sQuery = "SELECT COUNT(`ta`.`id`) AS `count` FROM `sys_accounts` AS `ta` " . $sTerms . " WHERE `ta`.`added` < :datefrom ";
  122. return $this->getOne($sQuery, $aBindings);
  123. }
  124. public function getAccountsByTermsStatInitValueUnsubscribe($iDateFrom, $sTerms)
  125. {
  126. $CNF = &$this->_oConfig->CNF;
  127. $aBindings = array(
  128. 'datefrom' => $iDateFrom
  129. );
  130. $sQuery = "SELECT COUNT(`tu`.`id`) AS `count` FROM `sys_accounts` AS `ta` INNER JOIN `" . $CNF['TABLE_UNSUBSCRIBE'] . "` AS `tu` ON `tu`.`account_id`=`ta`.`id` " . $sTerms . " WHERE `tu`.`unsubscribed` < :datefrom ";
  131. return $this->getOne($sQuery, $aBindings);
  132. }
  133. public function addLetter($iCampaignId, $sEmail)
  134. {
  135. $iTime = time();
  136. $sCode = md5($iCampaignId . $sEmail . $iTime);
  137. $CNF = &$this->_oConfig->CNF;
  138. $aBindings = array(
  139. 'campaign_id' => $iCampaignId,
  140. 'email' => $sEmail,
  141. 'date_sent' => $iTime,
  142. 'code' => $sCode,
  143. );
  144. $this->query("INSERT INTO `" . $CNF['TABLE_LETTERS'] . "` (`" . $CNF['FIELD_CAMPAIGN_ID'] . "`, `" . $CNF['FIELD_EMAIL'] . "`, `" . $CNF['FIELD_DATE_SENT'] . "`, `" . $CNF['FIELD_HASH'] . "`) VALUES (:campaign_id, :email, :date_sent, :code)", $aBindings);
  145. return $sCode;
  146. }
  147. public function updateDateSeenForLetter($sCode)
  148. {
  149. $CNF = &$this->_oConfig->CNF;
  150. $aBindings = array(
  151. 'code' => $sCode,
  152. 'date_seen' => time()
  153. );
  154. $this->query("UPDATE `" . $CNF['TABLE_LETTERS'] . "` SET `" . $CNF['FIELD_DATE_SEEN'] . "` = :date_seen WHERE `" . $CNF['FIELD_HASH'] . "` = :code", $aBindings);
  155. }
  156. public function deleteCampaignData($iCampaignId)
  157. {
  158. $CNF = &$this->_oConfig->CNF;
  159. $aBindings = array(
  160. 'campaign_id' => $iCampaignId
  161. );
  162. $this->query("DELETE FROM `" . $CNF['TABLE_LETTERS'] . "` WHERE `" . $CNF['FIELD_CAMPAIGN_ID'] . "` = :campaign_id", $aBindings);
  163. $this->query("DELETE FROM `" . $CNF['TABLE_LINKS'] . "` WHERE `" . $CNF['FIELD_CAMPAIGN_ID'] . "` = :campaign_id", $aBindings);
  164. $this->query("DELETE FROM `" . $CNF['TABLE_UNSUBSCRIBE'] . "` WHERE `" . $CNF['FIELD_CAMPAIGN_ID'] . "` = :campaign_id", $aBindings);
  165. }
  166. public function getClicksByCampaignId ($iCampaignId)
  167. {
  168. $CNF = &$this->_oConfig->CNF;
  169. $sQuery = $this->prepare ("SELECT `" . $CNF['FIELD_LINK'] . "`, `" . $CNF['FIELD_TITLE'] . "`, COUNT( `" . $CNF['FIELD_ID'] . "`) AS `click_count`, MAX( `" . $CNF['FIELD_DATE_CLICK'] . "`) AS `last_click` FROM `" . $CNF['TABLE_LINKS'] . "` WHERE `" . $CNF['FIELD_CAMPAIGN_ID'] . "` = ? AND `" . $CNF['FIELD_DATE_CLICK'] . "` > 0 GROUP BY `" . $CNF['FIELD_LINK'] . "`, `" . $CNF['FIELD_TITLE'] . "` ORDER BY COUNT( `" . $CNF['FIELD_ID'] . "`) DESC", $iCampaignId);
  170. return $this->getAll($sQuery);
  171. }
  172. public function getStatByCampaignId ($iCampaignId)
  173. {
  174. $CNF = &$this->_oConfig->CNF;
  175. $aBindings = array(
  176. 'campaign_id' => $iCampaignId
  177. );
  178. $q = "
  179. SELECT COUNT(*) AS `count`, 'total' AS `title` FROM `" . $CNF['TABLE_LETTERS'] . "` WHERE `" . $CNF['FIELD_CAMPAIGN_ID'] . "` = :campaign_id UNION
  180. SELECT COUNT(*), 'seen' FROM `" . $CNF['TABLE_LETTERS'] . "` WHERE `" . $CNF['FIELD_CAMPAIGN_ID'] . "` = :campaign_id AND `" . $CNF['FIELD_DATE_SEEN'] . "` > 0 UNION
  181. SELECT COUNT(*), 'clicked' FROM `" . $CNF['TABLE_LETTERS'] . "` WHERE `" . $CNF['FIELD_CAMPAIGN_ID'] . "` = :campaign_id AND `" . $CNF['FIELD_DATE_CLICK'] . "` > 0 UNION
  182. SELECT COUNT(*), 'unsubscribed' FROM `" . $CNF['TABLE_UNSUBSCRIBE'] . "` WHERE `" . $CNF['FIELD_CAMPAIGN_ID'] . "` = :campaign_id
  183. ";
  184. return $this->getPairs($q, 'title', 'count', $aBindings);
  185. }
  186. public function getLetterByCode ($sCode)
  187. {
  188. $CNF = &$this->_oConfig->CNF;
  189. $sQuery = $this->prepare ("SELECT * FROM `" . $CNF['TABLE_LETTERS'] . "` WHERE `" . $CNF['FIELD_HASH'] . "` = ?", $sCode);
  190. return $this->getRow($sQuery);
  191. }
  192. public function addLink($sLetterHash, $sLink, $sTitle, $iCampaignId)
  193. {
  194. $CNF = &$this->_oConfig->CNF;
  195. $sCode = md5($sLetterHash . $sLink . $sTitle);
  196. $aBindings = array(
  197. 'letter_hash' => $sLetterHash,
  198. 'hash' => $sCode,
  199. 'link' => $sLink,
  200. 'title' => $sTitle,
  201. 'campaign_id' => $iCampaignId,
  202. );
  203. $this->query("INSERT INTO `" . $CNF['TABLE_LINKS'] . "` (`" . $CNF['FIELD_LETTER_HASH'] . "`, `" . $CNF['FIELD_HASH'] . "`, `" . $CNF['FIELD_LINK'] . "`, `" . $CNF['FIELD_TITLE'] . "`, `" . $CNF['FIELD_CAMPAIGN_ID'] . "`) VALUES (:letter_hash, :hash, :link, :title, :campaign_id)", $aBindings);
  204. return $sCode;
  205. }
  206. public function updateDateClickForLink($sCode)
  207. {
  208. $CNF = &$this->_oConfig->CNF;
  209. $aBindings = array(
  210. 'code' => $sCode,
  211. 'date_click' => time()
  212. );
  213. $this->query("UPDATE `" . $CNF['TABLE_LINKS'] . "` SET `" . $CNF['FIELD_DATE_CLICK'] . "` = :date_click WHERE `" . $CNF['FIELD_HASH'] . "` = :code", $aBindings);
  214. $aData = $this->getRow("SELECT * FROM `" . $CNF['TABLE_LINKS'] . "` WHERE `" . $CNF['FIELD_HASH'] . "` = :code", array('code' => $sCode));
  215. if (isset($aData[$CNF['FIELD_LETTER_HASH']]) && isset($aData[$CNF['FIELD_LINK']])){
  216. $aBindings['code'] = $aData[$CNF['FIELD_LETTER_HASH']];
  217. if ($aData[$CNF['FIELD_LETTER_HASH']] != '')
  218. $this->query("UPDATE `" . $CNF['TABLE_LETTERS'] . "` SET `" . $CNF['FIELD_DATE_CLICK'] . "` = :date_click WHERE `" . $CNF['FIELD_HASH'] . "` = :code", $aBindings);
  219. return $aData[$CNF['FIELD_LINK']];
  220. }
  221. return '';
  222. }
  223. public function updateUnsubscribe($iAccountId, $iValue, $iCampaignId)
  224. {
  225. $CNF = &$this->_oConfig->CNF;
  226. if ($iValue != 1){
  227. $aBindings = array(
  228. 'account_id' => $iAccountId,
  229. 'campaign_id' => $iCampaignId,
  230. 'date_unsubscribed' => time()
  231. );
  232. $this->query("INSERT INTO `" . $CNF['TABLE_UNSUBSCRIBE'] . "` (`" . $CNF['FIELD_DATE_UNSUBSCRIBED'] . "`, `" . $CNF['FIELD_ACCOUNT_ID'] . "`, `" . $CNF['FIELD_CAMPAIGN_ID'] . "`) VALUES (:date_unsubscribed, :account_id, :campaign_id)", $aBindings);
  233. }
  234. else{
  235. $aBindings = array(
  236. 'account_id' => $iAccountId
  237. );
  238. $this->query("DELETE FROM `" . $CNF['TABLE_UNSUBSCRIBE'] . "` WHERE `" . $CNF['FIELD_ACCOUNT_ID'] . "` = :account_id", $aBindings);
  239. }
  240. }
  241. public function deleteOldCampagns($iDayBefore)
  242. {
  243. $CNF = &$this->_oConfig->CNF;
  244. $aBindings = array(
  245. 'time_from' => (time() - $iDayBefore * 86400)
  246. );
  247. $aTmp = $this->getColumn("SELECT `" . $CNF['FIELD_ID'] . "` FROM `" . $CNF['TABLE_CAMPAIGNS'] . "` WHERE `" . $CNF['FIELD_DATE_SENT'] . "` < :time_from AND `" . $CNF['FIELD_DATE_SENT'] . "` > 0", $aBindings);
  248. if (count($aTmp) > 0){
  249. $sIdList = $this->implode_escape($aTmp);
  250. $this->query("DELETE FROM `" . $CNF['TABLE_LETTERS'] . "` WHERE `" . $CNF['FIELD_CAMPAIGN_ID'] . "` IN (" . $sIdList . ")", []);
  251. $this->query("DELETE FROM `" . $CNF['TABLE_LINKS'] . "` WHERE `" . $CNF['FIELD_CAMPAIGN_ID'] . "` IN (" . $sIdList . ")", []);
  252. $this->query("DELETE FROM `" . $CNF['TABLE_UNSUBSCRIBE'] . "` WHERE `" . $CNF['FIELD_CAMPAIGN_ID'] . "` IN (" . $sIdList . ")", []);
  253. $this->query("DELETE FROM `" . $CNF['TABLE_CAMPAIGNS'] . "` WHERE `" . $CNF['FIELD_ID'] . "` IN (" . $sIdList . ")", []);
  254. }
  255. }
  256. }
  257. /** @} */