Контроллер newsletter подписчик попадает во все списки

Скажите, а почему сделано так, что при подписке через контроллер newsletter подписчик попадает во все списки рассылок? Зачем?

1 лайк

Даниил, подскажите, пожалуйста. Мне надо добавить в середину контроллера модуля newsletter.php свой код, что мне сделать? post и pre мне не подходят. override по аналогии с tpl не работает.

[quote name='densvi' timestamp='1438286569' post='225031']

Даниил, подскажите, пожалуйста. Мне надо добавить в середину контроллера модуля newsletter.php свой код, что мне сделать? post и pre мне не подходят. override по аналогии с tpl не работает.

[/quote]


  1. Делаем свой мод модулем.
  2. Форму отправляем на свой мод.
  3. В форму добавляем поля которые будут передавать id списков.
  4. В функции подписываем только на списки из формы.



    P.S. перенёс в “Сделай сам”

[quote name='dbazhenov' timestamp='1438320852' post='225052']

  1. Делаем свой мод модулем.
  2. Форму отправляем на свой мод.
  3. В форму добавляем поля которые будут передавать id списков.
  4. В функции подписываем только на списки из формы.



    P.S. перенёс в “Сделай сам”

    [/quote]



    Правильно ли я понял:
  1. делаем свой контроллер (к примеру, my_news), в своём модуле (my_change, к примеру), в нём будет что-то типа mode = 'subscribe_add'
  2. там и делаем всё что нам нужно, а в tpl - ки где идет отправка формы меняем через override на свои tpl куда и пишем отправку формы на наш новый контроллер



    Всё так?
  1. Сейчас контроллер называется newsletter.php

    а) Создаём в модуле newsletter.post.php

    в) в нём своё mode = 'my_add_subscribe'


  2. Любая tpl форма отправляется на какой то controller.mode , он прописан в форме, поменяйте на ваш. Можно модулем создать свой блок.



    Вы про какой шаблон вообще? Можно путь или скрин.
1 лайк

[quote name='dbazhenov' timestamp='1438321696' post='225055']

  1. Сейчас контроллер называется newsletter.php

    а) Создаём в модуле newsletter.post.php

    в) в нём своё mode = 'my_add_subscribe'


  2. Любая tpl форма отправляется на какой то controller.mode , он прописан в форме, поменяйте на ваш. Можно модулем создать свой блок.



    Вы про какой шаблон вообще? Можно путь или скрин.

    [/quote]



    /templates/addons/rus_theme_style/blocks/static_templates/subscribe_advanced.tpl

[quote name=‘densvi’ timestamp=‘1438322281’ post=‘225056’]

/templates/addons/rus_theme_style/blocks/static_templates/subscribe_advanced.tpl

[/quote]



Ну и сделайте такой же в своём модуле :)



Контроллер поменять тут:

dispatch[newsletters.add_subscriber]



Новое поле c id листа добавить тут:

Так в общем-то и сделал :)



Сложность (запутался уже просто) была с контроллером. Теперь всё встало на свои места



Спасибо, Даниил

Вопрос снят

Если вдруг кто-то еще озабочен вопросом «Как подписать пользователя не на все рассылки, а только на определенные», то делюсь своим решением.

1. Создаем файл /app/addons/my_changes/controllers/frontend/newsletters.pre.php

Вместо аддона my_changes можете использовать свой аддон.

2. В созданный файл newsletters.pre.php копируем обработчик режима 'add_subscriber' из /app/addons/newsletters/controllers/frontend/newsletters.php

Поскольку в зависимости от версии CS-Cart там может быть немного разный код, скопируйте код из своей версии. Ниже пример из версии 4.3.6

if (!defined('BOOTSTRAP')) { die('Access denied'); }

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// Add email to maillist
if ($mode == 'add_subscriber') {
if (empty($_REQUEST['subscribe_email']) || fn_validate_email($_REQUEST['subscribe_email']) == false) {
fn_set_notification('E', __('error'), __('error_invalid_emails', array(
'[emails]' => $_REQUEST['subscribe_email']
)));
} else {
// First check if subscriber's email already in the list
$subscriber = db_get_row("SELECT * FROM ?:subscribers WHERE email = ?s", $_REQUEST['subscribe_email']);
if (empty($subscriber)) {
$_data = array(
'email' => $_REQUEST['subscribe_email'],
'timestamp' => TIME,
);
$subscriber_id = db_query("INSERT INTO ?:subscribers ?e", $_data);
$subscriber = db_get_row("SELECT * FROM ?:subscribers WHERE subscriber_id = ?i", $subscriber_id);
} else {
$subscriber_id = $subscriber['subscriber_id'];
}
// update subscription data. If there is no any registration autoresponders, we set confirmed=1
// so user doesn't need to activate subscription
list($lists) = fn_get_mailing_lists();
fn_update_subscriptions($subscriber_id, array_keys($lists), NULL, fn_get_notification_rules(true));
fn_set_notification('N', __('congratulations'), __('text_subscriber_added'));
fn_emails_provide_coupon();
/*} else {
fn_set_notification('E', __('error'), __('error_email_already_subscribed'));
}*/
}
}
return array(CONTROLLER_STATUS_REDIRECT);
}

3. Найдите в скопированном коде такую строку:

list($lists) = fn_get_mailing_lists();

Эта строка получает перечень списков рассылки, в которые попадёт емейл нового подписчика.

По умолчанию выбираются все активные списки подписчиков и пользователь добавляется во все сразу.

Мне было нужно, чтобы пользователь добавлялся только в те списки, которые доступны ему при регистрации или на чекауте. При этом, без хардкода: я делаю магазины для клиентов, потому не могу делать кастомный код для каждого.

Решение — заменить эту строку на вот такую:

list($lists) = fn_get_mailing_lists(array('checkout' => true));

//Так вы подписываете посетителя только на те списки, которые ему доступны на чекауте.

list($lists) = fn_get_mailing_lists(array('registration' => true));

//Или на те списки, которые ему доступны при регистрации.

4. Чтобы запретить последующее исполнение обработчика режима 'add_subscriber' в оригинальном контроллере newsletters.php, добавьте в конец своего обработчика return array(CONTROLLER_STATUS_REDIRECT,fn_url());

Тем самым пользователь после подписки окажется на той же самой странице.

Вот что у вас должно получиться в newsletters.pre.php (изменения по сравнению с оригиналом 4.3.6 выделил болдом):

<?php
if (!defined('BOOTSTRAP')) { die('Access denied'); }
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// Add email to maillist
if ($mode == 'add_subscriber') {
if (empty($_REQUEST['subscribe_email']) || fn_validate_email($_REQUEST['subscribe_email']) == false) {
fn_set_notification('E', __('error'), __('error_invalid_emails', array(
'[emails]' => $_REQUEST['subscribe_email']
)));
} else {
// First check if subscriber's email already in the list
$subscriber = db_get_row("SELECT * FROM ?:subscribers WHERE email = ?s", $_REQUEST['subscribe_email']);
if (empty($subscriber)) {
$_data = array(
'email' => $_REQUEST['subscribe_email'],
'timestamp' => TIME,
);
$subscriber_id = db_query("INSERT INTO ?:subscribers ?e", $_data);
$subscriber = db_get_row("SELECT * FROM ?:subscribers WHERE subscriber_id = ?i", $subscriber_id);
} else {
$subscriber_id = $subscriber['subscriber_id'];
}
// update subscription data. If there is no any registration autoresponders, we set confirmed=1
// so user doesn't need to activate subscription
list($lists) = fn_get_mailing_lists(array('checkout' => true));
fn_update_subscriptions($subscriber_id, array_keys($lists), NULL, fn_get_notification_rules(true));
fn_set_notification('N', __('congratulations'), __('text_subscriber_added'));
fn_emails_provide_coupon();
}
}
return array(CONTROLLER_STATUS_REDIRECT,fn_url());
}

?>

Удачи!

1 лайк

А как быть если у вас есть AJAX обращение к контроллеру?
функция fn_do_call_request из модуля call_requests будет видна в контроллере во фронте в в другом модуле?