Files
b2b.redline.com.pl/modules/newsletterpro/classes/NewsletterProSend.php
2025-06-24 14:14:35 +02:00

607 lines
17 KiB
PHP

<?php
/**
* Since 2013 Ovidiu Cimpean.
*
* Ovidiu Cimpean - Newsletter Pro © All rights reserved.
*
* DISCLAIMER
*
* Do not edit, modify or copy this file.
* If you wish to customize it, contact us at addons4prestashop@gmail.com.
*
* @author Ovidiu Cimpean <addons4prestashop@gmail.com>
* @copyright Since 2013 Ovidiu Cimpean
* @license Do not edit, modify or copy this file
*
* @version Release: 4
*/
class NewsletterProSend extends ObjectModel
{
public $id_newsletter_pro_tpl_history;
public $template;
public $active;
public $state;
public $emails_count;
public $emails_success;
public $emails_error;
public $emails_completed;
public $error_msg;
public $date;
/**
* The states are available in javascript
* If there are changes at this states, is required to change also the javascript file view/js/send_manager.js.
*/
const STATE_DEFAULT = 0;
const STATE_PAUSE = 1;
const STATE_IN_PROGRESS = 2;
const STATE_DONE = 3;
/**
* Variables.
*/
public $progress_success = 0;
public $progress_errors = 0;
public static $definition = [
'table' => 'newsletter_pro_send',
'primary' => 'id_newsletter_pro_send',
'fields' => [
'id_newsletter_pro_tpl_history' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true],
'template' => ['type' => self::TYPE_STRING, 'validate' => 'isString', 'required' => true],
'active' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool'],
'state' => ['type' => self::TYPE_INT, 'validate' => 'isInt'],
'emails_count' => ['type' => self::TYPE_INT, 'validate' => 'isInt'],
'emails_error' => ['type' => self::TYPE_INT, 'validate' => 'isInt'],
'emails_success' => ['type' => self::TYPE_INT, 'validate' => 'isInt'],
'emails_completed' => ['type' => self::TYPE_INT, 'validate' => 'isInt'],
'error_msg' => ['type' => self::TYPE_HTML, 'validate' => 'isString'],
'date' => ['type' => self::TYPE_DATE, 'validate' => 'isDateFormat'],
],
];
public function __construct($id = null)
{
parent::__construct($id);
}
public static function newInstance($id = null)
{
return new self($id);
}
public static function getActiveId()
{
return (int) Db::getInstance()->getValue('
SELECT `id_newsletter_pro_send`
FROM `'._DB_PREFIX_.'newsletter_pro_send`
WHERE `active` = 1
AND `id_newsletter_pro_send` = (
SELECT MAX(`id_newsletter_pro_send`)
FROM `'._DB_PREFIX_.'newsletter_pro_send`
)
');
}
public function updateProgress()
{
$result = Db::getInstance()->execute('
UPDATE `'._DB_PREFIX_.'newsletter_pro_send`
SET
`emails_success` = `emails_success` + '.(int) $this->progress_success.',
`emails_error` = `emails_error` + '.(int) $this->progress_errors.',
`emails_completed` = `emails_completed` + '.((int) $this->progress_success + (int) $this->progress_errors).'
WHERE `id_newsletter_pro_send` = '.(int) $this->id.'
');
$this->progress_success = 0;
$this->progress_errors = 0;
return $result;
}
public function updateDefaults($ignore = [])
{
$fields = [
'id_newsletter_pro_tpl_history' => (int) $this->id_newsletter_pro_tpl_history,
'template' => pSQL($this->template),
'active' => (int) $this->active,
'state' => (int) $this->state,
'emails_count' => (int) $this->emails_count,
'date' => pSQL($this->date),
];
if (!empty($ignore)) {
foreach ($ignore as $key) {
if (isset($fields[$key])) {
unset($fields[$key]);
}
}
}
return $this->updateFields($fields);
}
public function updateAll($ignore = [])
{
return $this->updateProgress() && $this->updateDefaults($ignore);
}
public function progressSuccess()
{
++$this->progress_success;
}
public function progressErrors()
{
++$this->progress_errors;
}
public function statePause()
{
$this->state = self::STATE_PAUSE;
$this->active = 1;
return $this->updateFields([
'state' => $this->state,
'active' => $this->active,
]);
}
public function stateDone()
{
$this->state = self::STATE_DONE;
$this->active = 0;
return $this->updateFields([
'state' => $this->state,
'active' => $this->active,
]);
}
public function stateInProgress()
{
$this->state = self::STATE_IN_PROGRESS;
$this->active = 1;
return $this->updateFields([
'state' => $this->state,
'active' => $this->active,
]);
}
public function stateDefault()
{
$this->state = self::STATE_DEFAULT;
$this->active = 1;
return $this->updateFields([
'state' => $this->state,
'active' => $this->active,
]);
}
public function setState($state)
{
$this->state = $state;
return $this->updateFields([
'state' => $this->state,
]);
}
private function getStepsIdsCallback($row)
{
return !empty($row) ? $row['id_newsletter_pro_send_step'] : false;
}
public function getStepsIds($step_active = false, $limit = 0)
{
$results = Db::getInstance()->executeS('
SELECT `id_newsletter_pro_send_step`
FROM `'._DB_PREFIX_.'newsletter_pro_send_step`
WHERE `id_newsletter_pro_send` = '.(int) $this->id.'
'.($step_active ? ' AND `step_active` = 1' : '').'
ORDER BY `id_newsletter_pro_send_step`
'.($limit > 0 ? ' LIMIT '.(int) $limit : '').'
');
return array_map([$this, 'getStepsIdsCallback'], $results);
}
public function markNewsletterAsDone($time = 120)
{
$id = (int) Db::getInstance()->getValue('
SELECT `id_newsletter_pro_send`
FROM `'._DB_PREFIX_.'newsletter_pro_send_step`
WHERE `id_newsletter_pro_send` = '.(int) $this->id.'
AND id_newsletter_pro_send_step = (SELECT MAX(`id_newsletter_pro_send_step`)
FROM `'._DB_PREFIX_.'newsletter_pro_send_step`
WHERE `id_newsletter_pro_send` = '.(int) $this->id.')
AND DATE_ADD(`date_modified`, INTERVAL '.(int) $time.' SECOND) <= NOW()
');
if ((int) $id > 0) {
return (int) Db::getInstance()->update('newsletter_pro_send', [
'state' => NewsletterProSend::STATE_DONE,
'active' => 0,
], '`id_newsletter_pro_send` = '.(int) $id);
}
return false;
}
public function getCurrentStepId()
{
$id = (int) Db::getInstance()->getValue('
SELECT `id_newsletter_pro_send_step`
FROM `'._DB_PREFIX_.'newsletter_pro_send_step`
WHERE `id_newsletter_pro_send` = '.(int) $this->id.'
AND `step_active` = 1
ORDER BY `id_newsletter_pro_send_step`
');
return $id;
}
public function getStepsIdAndConnectionsId($step_active = false, $closed_connection = false, $limit = 0)
{
$results = Db::getInstance()->executeS('
SELECT
ss.`id_newsletter_pro_send_step`,
sc.`id_newsletter_pro_send_connection`,
sc.`state`
FROM `'._DB_PREFIX_.'newsletter_pro_send_step` ss
LEFT JOIN `'._DB_PREFIX_.'newsletter_pro_send_connection` sc
ON (
ss.`id_newsletter_pro_send_connection` = sc.`id_newsletter_pro_send_connection`
)
WHERE ss.`id_newsletter_pro_send` = '.(int) $this->id.'
'.($step_active ? ' AND ss.`step_active` = 1' : '').'
ORDER BY ss.`id_newsletter_pro_send_step`
');
$ids = [];
foreach ($results as $row) {
if ($closed_connection) {
if (NewsletterProSendConnection::STATE_CLOSE == (int) $row['state']) {
$ids[(int) $row['id_newsletter_pro_send_step']] = (int) $row['id_newsletter_pro_send_connection'];
}
} else {
$ids[(int) $row['id_newsletter_pro_send_step']] = (int) $row['id_newsletter_pro_send_connection'];
}
}
if ($limit > 0) {
$slice_ids = [];
foreach ($ids as $id_step => $id_connection) {
if (count($slice_ids) < $limit) {
$slice_ids[$id_step] = $id_connection;
break;
}
}
return $slice_ids;
}
return $ids;
}
public function getFirstFreeStepIdAndOpenConnection()
{
$result = Db::getInstance()->getRow('
SELECT ss.`id_newsletter_pro_send_step`,
sc.`id_newsletter_pro_send_connection`
FROM `'._DB_PREFIX_.'newsletter_pro_send_step` ss
INNER JOIN `'._DB_PREFIX_.'newsletter_pro_send_connection` sc
ON (
ss.`id_newsletter_pro_send_connection` = sc.`id_newsletter_pro_send_connection`
AND sc.`state` = 0
)
WHERE ss.`id_newsletter_pro_send` = '.(int) $this->id.'
AND ss.`step_active` = 1
AND sc.`script_uid` IS NULL
ORDER BY ss.`id_newsletter_pro_send_step`
');
if (empty($result)) {
return 0;
}
Db::getInstance()->execute('
UPDATE `'._DB_PREFIX_.'newsletter_pro_send_connection`
SET `state` = 1, `script_uid` = "'.pSQL(NewsletterProSendConnection::getScriptUid()).'"
WHERE id_newsletter_pro_send_connection = '.(int) $result['id_newsletter_pro_send_connection'].'
AND `state` = 0
AND `script_uid` IS NULL;
');
if (!Db::getInstance()->Affected_Rows()) {
return 0;
}
NewsletterProShutdown::register([$this, 'shutdownDbCloseConnection'], [(int) $result['id_newsletter_pro_send_connection']]);
return (int) $result['id_newsletter_pro_send_step'];
}
public function shutdownDbCloseConnection($id_connection)
{
Db::getInstance()->execute('
UPDATE `'._DB_PREFIX_.'newsletter_pro_send_connection`
SET `state` = 0, `script_uid` = NULL
WHERE id_newsletter_pro_send_connection = '.(int) $id_connection.'
AND `state` = 1
AND `script_uid` = "'.pSQL(NewsletterProSendConnection::getScriptUid()).'"
');
if (Db::getInstance()->Affected_Rows()) {
return true;
}
return false;
}
public function getInfo()
{
return Db::getInstance()->getRow('
SELECT `active`, `state`
FROM `'._DB_PREFIX_.'newsletter_pro_send`
WHERE `id_newsletter_pro_send` = '.(int) $this->id.'
');
}
public function isActive()
{
$value = (int) Db::getInstance()->getValue('
SELECT `active`
FROM `'._DB_PREFIX_.'newsletter_pro_send`
WHERE `id_newsletter_pro_send` = '.(int) $this->id.'
');
$this->active = $value;
return $value;
}
public function getState()
{
$value = (int) Db::getInstance()->getValue('
SELECT `state`
FROM `'._DB_PREFIX_.'newsletter_pro_send`
WHERE `id_newsletter_pro_send` = '.(int) $this->id.'
');
$this->state = (int) $value;
return $this->state;
}
public function isPause($state = null)
{
$state = isset($state) ? $state : $this->getState();
return self::STATE_PAUSE == $state;
}
public function isDefault($state = null)
{
$state = isset($state) ? $state : $this->getState();
return self::STATE_DEFAULT == $state;
}
public function isInProgress($state = null)
{
$state = isset($state) ? $state : $this->getState();
return self::STATE_IN_PROGRESS == $state;
}
public function isDone($state = null)
{
$state = isset($state) ? $state : $this->getState();
return self::STATE_DONE == $state;
}
public function updateFields($fields = [], $override_values = true)
{
if ($override_values) {
foreach ($fields as $field => $value) {
$this->{$field} = $value;
}
}
return Db::getInstance()->update('newsletter_pro_send', $fields, '`id_newsletter_pro_send` = '.(int) $this->id, 0, true);
}
public function getEmailsToSend($limit = null)
{
if (!isset($limit)) {
$limit = (int) NewsletterPro::getInstance()->step;
}
$steps_id = $this->getStepsIds(true);
$emails = [];
if ($steps_id) {
foreach ($steps_id as $id) {
$send_step = NewsletterProSendStep::newInstance($id);
$emails_to_send = $send_step->getEmailsToSend();
$emails = array_merge($emails, $emails_to_send);
if (count($emails) >= $limit) {
$emails = array_slice($emails, 0, $limit);
break;
}
}
}
return $emails;
}
public function getEmailsSent($limit = null, $get_errors = true, $reverse = false, $get_last_emails = false)
{
if (!isset($limit)) {
$limit = (int) NewsletterPro::getInstance()->step;
}
$steps_id = $this->getStepsIds(true);
if ($get_last_emails) {
$steps_id = array_reverse($this->getStepsIds(false));
}
return $this->getEmailsSentDefault($steps_id, $limit, $get_errors, $reverse);
}
private function getEmailsSentDefault($steps_id, $limit = null, $get_errors = true, $reverse = false)
{
$emails = [];
$emails_error = [];
if ($steps_id) {
foreach ($steps_id as $id) {
$send_step = NewsletterProSendStep::newInstance($id);
$emails_sent = $send_step->getEmailsSent(0, $reverse);
if ($get_errors) {
$error_msg = $send_step->getErrorMsg();
foreach ($error_msg as $errors) {
foreach ($errors as $error => $emails_e) {
foreach ($emails_e as $email_e) {
$emails_error[$email_e][] = $error;
$emails_error[$email_e] = array_unique($emails_error[$email_e]);
}
}
}
}
$emails = array_merge($emails, $emails_sent);
if (count($emails) >= $limit) {
$emails = array_slice($emails, 0, $limit);
break;
}
}
}
if ($get_errors) {
foreach ($emails as $key => $item) {
if (isset($emails_error[$item['email']])) {
$emails[$key]['errors'] = $emails_error[$item['email']];
} else {
$emails[$key]['errors'] = [];
}
}
}
return $emails;
}
public function getRemaining()
{
$remaining = (int) $this->emails_count - (int) $this->emails_completed;
if ($remaining >= 0) {
return $remaining;
}
return 0;
}
public static function getLastId()
{
return (int) Db::getInstance()->getValue('
SELECT MAX(`id_newsletter_pro_send`)
FROM `'._DB_PREFIX_.'newsletter_pro_send`
WHERE 1
');
}
public function shutdown()
{
NewsletterProShutdown::register([$this, 'registerShutdown']);
return $this;
}
public function registerShutdown()
{
if (0 == count($this->getStepsIds(true))) {
$this->state = NewsletterProSend::STATE_DONE;
$this->active = 0;
$this->updateAll();
} elseif ($this->isInProgress()) {
$this->state = NewsletterProSend::STATE_DEFAULT;
$this->updateAll();
} else {
$this->updateAll(['state', 'active']);
}
}
public static function exportPrivacy($email)
{
$response = new NewsletterProPrivacyDataResponse(NewsletterProPrivacyDataResponse::TYPE_EXPORT, 'newsletter_pro_send', $email);
try {
// nothing to export
} catch (Exception $e) {
$response->addException($e);
}
return $response;
}
public static function privacySerach($email)
{
$response = new NewsletterProPrivacyDataResponse(NewsletterProPrivacyDataResponse::TYPE_SEARCH, 'newsletter_pro_send', $email);
try {
$count = (int) Db::getInstance()->getValue('
SELECT COUNT(*) FROM `'._DB_PREFIX_.'newsletter_pro_send`
WHERE `error_msg` REGEXP "'.pSQL(preg_quote($email)).'[^A-Za-z0-9]"
');
$response->addToCount($count);
} catch (Exception $e) {
$response->addException($e);
}
return $response;
}
public static function clearPrivacy($email)
{
$response = new NewsletterProPrivacyDataResponse(NewsletterProPrivacyDataResponse::TYPE_CLEAR, 'newsletter_pro_send', $email);
try {
if (Db::getInstance()->update('newsletter_pro_send', [
'error_msg' => serialize([]),
], '`error_msg` REGEXP "'.pSQL(preg_quote($email)).'[^A-Za-z0-9]"')) {
$response->addToCount(Db::getInstance()->Affected_Rows());
}
} catch (Exception $e) {
$response->addException($e);
}
return $response;
}
}