Закладки без регистрации opencart 2-3

Закладки без регистрации opencart 2-3

Что бы получить работающий список закладок без регистрации нужно будет внести изменения в контроллер - /catalog/controller/account/wishlist.php

В результате получим отображение списка закладок и возможность удаления товаров и списка. Сам список будет взят из сессии (по-умолчанию только из базы с привязкой к пользователю)

Начнем. Откроем /catalog/controller/account/wishlist.php и внесем правки (все в порядке изменений в файле):

Убираем проверку авторизации

В самом начале файла комментируем строки (должно получиться так):

/*if (!$this->customer->isLogged()) {
$this->session->data['redirect'] = $this->url->link('account/wishlist', '', true);
$this->response->redirect($this->url->link('account/login', '', true));
}*/

Возможность удаления из закладок

Чуть дальше находим:

// Remove Wishlist
$this->model_account_wishlist->deleteWishlist($this->request->get['remove']);

Здесь добавим проверку - авторизован ли посетитель, если нет возьмем из сессии список закладок, кроме товара из запроса на удаление, почистим закладки и запишем обратно получившийся результат:

if ($this->customer->isLogged()) {
	$this->model_account_wishlist->deleteWishlist($this->request->get['remove']);
} else {
	$prods = $this->session->data['wishlist'];
	$this->session->data['wishlist'] = '';
	foreach ($prods as $prod) if ($prod != $this->request->get['remove']) {
		$this->session->data['wishlist'][] = $prod;
	}
}

Получение товаров из закладок

Здесь все по аналогии с удалением, работаем с закладками в сессии. Находим:

$results = $this->model_account_wishlist->getWishlist();

Меняем на следующий код:

$results = array();
if ($this->customer->isLogged()) {
	$results = $this->model_account_wishlist->getWishlist();
} else if (!empty($this->session->data['wishlist'])) {
	$prods = $this->session->data['wishlist'];
	foreach ($prods as $prod) {
		$results[]['product_id'] = $prod;
	}
}

Далее необходимо сделать еще одну правку, в /catalog/controller/common/header.php

Находим:

$data['text_wishlist'] = sprintf($this->language->get('text_wishlist'), (isset($this->session->data['wishlist']) ? count($this->session->data['wishlist']) : 0));

Меняем на:

$data['text_wishlist'] = sprintf($this->language->get('text_wishlist'), (!empty($this->session->data['wishlist']) ? count($this->session->data['wishlist']) : 0));

Изменение уведомления при добавлении

В стандартном уведомлении при добавлении закладок говорится о том, что необходимо выполнить вход или зарегистрироваться для сохранения закладок, но по сути это уже не нужно. Есть два варианта для изменений - можно в языковом файле изменить текст, или в контроллере закладок вывести одинаковый текст, тот что для зарегистрированных пользователей - для всех

Языковой файл можно найти по пути /catalog/language/ru-ru/account/wishlist.php, здесь нужно изменить 'text_login'.

Что касается правок в контроллере (все тот же wishlist.php), здесь нужно найти функцию add() и в ней проверку на регистрацию.

if ($this->customer->isLogged()) {
......
$json['success'] = sprintf($this->language->get('text_success'), $this->url->link('product/product', 'product_id=' . (int)$this->request->post['product_id']), $product_info['name'], $this->url->link('account/wishlist'));
......
} else {
......
$json['success'] = sprintf($this->language->get('text_login'), $this->url->link('account/login', '', true), $this->url->link('account/register', '', true), $this->url->link('product/product', 'product_id=' . (int)$this->request->post['product_id']), $product_info['name'], $this->url->link('account/wishlist'));
......
}

Здесь нужно код для второго 'success' (для гостей) заменить первым (для зарегистрированных).

Сказать $пасибо

Комментарии ()

  1. Артур 13 августа 2019, 12:10
    0

    Здравствуйте, после удаления из закладок такие ошибки
    Warning: count(): Parameter must be an array or an object that implements Countable in /home/site.ua/www/system/storage/modification/catalog/controller/common/footer.php on line 30Warning: count(): Parameter must be an array or an object that implements Countable in /home/site.ua/www/catalog/controller/common/menu.php on line 47

    1. Владимир 13 августа 2019, 15:031
      0

      Смотрите файлы, что находится в указанных строках. Закладки здесь непричем (footer.php, menu.php — сюда разве правки вносили?).

      1. Артур 13 августа 2019, 18:28
        0

        с этими решил… просто выводил избранные в эти места и там нужно было тоже заменить получение товаров из закладок… но при удалении из избранного все равно ошибка…
        Fatal error: Uncaught Error: [] operator not supported for strings in /home/imperiazolota.ua/www/catalog/controller/account/wishlist.php:29 Stack trace: #0 /home/imperiazolota.ua/www/system/storage/modification/system/engine/action.php(79): ControllerAccountWishList->index() #1 /home/imperiazolota.ua/www/catalog/controller/startup/router.php(25): Action->execute(Object(Registry)) #2 /home/imperiazolota.ua/www/system/storage/modification/system/engine/action.php(79): ControllerStartupRouter->index() #3 /home/imperiazolota.ua/www/system/engine/router.php(67): Action->execute(Object(Registry)) #4 /home/imperiazolota.ua/www/system/engine/router.php(56): Router->execute(Object(Action)) #5 /home/imperiazolota.ua/www/system/framework.php(168): Router->dispatch(Object(Action), Object(Action)) #6 /home/imperiazolota.ua/www/system/startup.php(104): require_once('/home/imperiazo...') #7 /home/imperiazolota.ua/www/index.php(19): start('catalog') #8 {main} thrown in /home/imperiazolota.ua/www/catalog/controller/account/wishlist.php on line 29

        1. Артур 13 августа 2019, 18:56
          0

          вот проверил, когда один товар в избранном то нормально, а когда больше 1-го тогда ошибка, и после успешного удаления одного товара из избранного, потом при добавлении ошибка json

          1. LoGwi-N 12 октября 2019, 13:15
            0

            в wishlist.php нужно поменять

            $this->session->data['wishlist'] = '';
            на
            $this->session->data['wishlist'] = array();

      2. Elena El 08 августа 2019, 15:22
        0

        Все сделала, как указано выше, но все равно кидает на страницу авторизации

        1. Elena El 06 августа 2019, 02:10
          0

          Здравствуйте, помогите пожалуйста с версией opencart 3.0.

          1. Владимир 08 августа 2019, 14:571
            0

            Здравствуйте! А что не получается?

            1. Elena El 08 августа 2019, 15:22
              0

              Все сделала, как указано выше, но все равно кидает на страницу авторизации

              1. Владимир 08 августа 2019, 15:54
                0

                А кеш модификаторов почищен?
                строки вначале /catalog/controller/account/wishlist.php закомментированы? (после этого уже не должно быть никакого перенаправления)

              2. Андрей 20 февраля 2019, 21:00
                0

                Спасибо заработало, кроме сообщения о добавлении товара, пробовал 2 варианта, менял в языковом файле (просто копировал с text_success в text_login) так и заменял в контроллере text_login на text_success

                В итоге получалось: Вы добавили ИМЯ_САЙТА/index.php?route=account/login в Закладки!

                Что не так? Версия Opencart 2.3

                1. Владимир 20 февраля 2019, 23:481
                  0

                  Там же нужно менять success для гостей на success для зарегистрированных. Попробуйте еще раз, или пришлите файлы на почту vl@onenv.ru

                  1. Андрей 21 февраля 2019, 07:56
                    0

                    Я заменил:

                    $json['success'] = sprintf($this->language->get('text_login'), $this->url->link('account/login', '', true), $this->url->link('account/register', '', true), $this->url->link('product/product', 'product_id=' . (int)$this->request->post['product_id']), $product_info['name'], $this->url->link('account/wishlist'));
                    на
                    $json['success'] = sprintf($this->language->get('text_success'), $this->url->link('product/product', 'product_id=' . (int)$this->request->post['product_id']), $product_info['name'], $this->url->link('account/wishlist'));
                    теперь нормально отображается, УРАААА!!!
                    Спасибо, большое!

                    Видимо я неправильно понял, мне кажется понятнее записать так: заменить этот код на этот, а то я понял что нужно просто «text_login» на «text_success» заменить :-)

                2. Yaroslav 09 декабря 2018, 22:33
                  0

                  Спасибо, на 2.3.0 работает.
                  А как сделать чтобы при добавлении в закладки возле иконки высвечивалась толькоцыфра к-ва товара.
                  в файле /checkout/cart.php я удалил записть. Но корректно показывает к-во, только после обновления

                  1. Владимир 10 декабря 2018, 03:06
                    0

                    Все визуальные изменения при добавлении в common.js
                    найдите

                    $('#wishlist-total').attr('title', json['total']);
                    Вообще при добавлении как раз только цифра и должна меняться… нужно смотреть что не так. Можете еще в комментариях здесь же посмотреть, от 14 июля и ниже, там как раз по визуальной части

                  2. Сергей Соловьев 09 декабря 2018, 18:41
                    0

                    Владимир, спасибо за интересное решение.
                    Подскажите, пожалуйста, не думали как решить перенос гостевых закладок в аккаунт и сохранение их в личном кабинете после регистрации\авторизации покупателя?

                    1. великий_и_ужасный 05 ноября 2018, 18:37
                      0

                      До чего же подача кода отвратительна (
                      ru.wikipedia.org/wiki/Стандарт_оформления_кода

                      1. Владимир 05 ноября 2018, 20:11
                        0

                        здесь куски кода в несколько строчек… что заменить, куда добавить… вполне понятно

                      2. Альфред 18 июля 2018, 22:301
                        +1

                        Спасибо! Отлично работает, устал искать такой модуль, а тут бесплатно) Кстати, что-бы полностью работало на opencart 3 самый последний пункт тоже нужно добавить, а то у вас написано, что это надо только для opencart 2. Иначе счетчик не будет обновляться.

                        1. Владимир 19 июля 2018, 00:38
                          0

                          Спасибо, исправил

                        2. Александр 16 июля 2018, 16:221
                          0

                          Владимир, не могли бы вы мне оставить свою почту? Хочется раз и навсегда покончить с закладками? P.S. Вопросик это я, я просто зарегистрировался :)

                          1. Владимир 16 июля 2018, 20:38
                            0

                            Моя почта vl@onenv.ru. Правок, кажется, не много осталось совсем

                          2. Вопросик 15 июля 2018, 01:44
                            +1

                            Спасибо еще раз, Владимир! Вы очень помогли!!! Буду частенько заходить к Вам почитывать какие нибудь статьи!

                            1. Вопросик 15 июля 2018, 01:471
                              0

                              Блин теперь другая проблема ): Покрашенное сердце, не сохраняет свой цвет. Грешу на js. как сохранить этот цвет после перехода на другую страницу, без понятия ):

                              1. Владимир 15 июля 2018, 02:311
                                +1

                                проверять есть ли в закладках товар через php нужно, при выводе. т.е. в контроллере категории/модуля нужно получить id товаров из закладок и проверить есть ли там нужный…
                                после

                                $results = $this->model_catalog_product->getProducts($filter_data);
                                добавим
                                if ($this->customer->isLogged()) {
                                $this->load->model('account/wishlist');
                                $w_list = $this->model_account_wishlist->getWishlist();
                                } else {
                                $w_list = $this->session->data['wishlist'];
                                }
                                далее перед $data['products'][] = array(
                                if (in_array($result['product_id'], $w_list)) {
                                $wl_class = 'wl-add';
                                } else {
                                $wl_class = '';
                                }
                                ну и в самом массиве products
                                'wl_class'  => $wl_class,
                                и вот это уже в шаблоне использовать
                                <?php echo $product['wl_class']; ?>
                                для гостей проверил, а вот для зарегистрированных не проверял

                                1. Вопросик 15 июля 2018, 12:30
                                  0

                                  Отлично работает! Только почему то если на страницу товара добавлять, Undefined variable и указывает в ошибке путь system/storage и так далее. Есть вероятность что я криво сделал, но вроде все должно быть хорошо

                                  1. Владимир 15 июля 2018, 13:53
                                    +1

                                    Скорее всего… Это в самом товаре, или в связанных? в контроллере для самого товара класс через data[] нужно назнчить, может где то здесь проблема…

                                    1. Вопросик 16 июля 2018, 01:411
                                      0

                                      Возможно. Буду смотреть. теперь возникла новая проблема. Если все сделать как вы сказали для модулей special.tpl и latest.tpl почему то возникает такая проблема:

                                      Это при условии, что не один товар не добавлен в избранное.
                                      Если добавить в закладки и обновить страницу, тогда все окей, ошибок нет.

                                      Warning: in_array() expects parameter 2 to be array, string given in /home/jollyvap/public_html/system/storage/modification/catalog/controller/extension/module/special.php on line 90

                                      1. Владимир 16 июля 2018, 01:51
                                        +1

                                        учитывая что файл в кэше, там может быть конфликт с неким модулем… взглянуть бы на сам файл

                                        1. Вопросик 16 июля 2018, 01:53
                                          0

                                          какой именно? special.php?

                                          1. Вопросик 16 июля 2018, 01:591
                                            0

                                            yadi.sk/d/Q90WZgE53ZCp3L

                                            Вот то что в систем это модификатор
                                            То что в controller это оригинал

                                            Только что без обновления всех модификаторов, удлалил эти 2 файла вот такая ерунда:

                                            Warning: in_array() expects parameter 2 to be array, string given in /home/jollyvap/public_html/catalog/controller/extension/module/special.php on line 67

                                            1. Владимир 16 июля 2018, 02:09
                                              +1

                                              Это вылазит если нет товаров в закладках. в категориях так же. Нужно немного поменять:

                                              if ($this->customer->isLogged()) {
                                              $this->load->model('account/wishlist');
                                              $w_list = $this->model_account_wishlist->getWishlist();
                                              } else if ($this->session->data['wishlist']) {
                                              $w_list = $this->session->data['wishlist'];
                                              } else {
                                              $w_list = array();
                                              }

                                              1. Вопросик 16 июля 2018, 02:30
                                                0

                                                Да действительно работает! Владимир, что бы я без Вас делал? :)

                                                Кстати на страницу товара таким же образом добавлять?
                                                Вчера добавлял, на кнопке в классах, было написано «Undefined variable». Или для товара своя система добавления?

                                                1. Владимир 16 июля 2018, 03:19
                                                  +1

                                                  там немного по другому. если есть ошибки, пришлите контроллер товара, посмотрю

                                                  1. Вопросик 16 июля 2018, 14:051
                                                    0

                                                    Владимир, вчера делал все было окей, никакой ошибки, сейчас захожу:

                                                    Notice: Undefined index: wishlist in /home/jollyvap/public_html/system/storage/modification/catalog/controller/extension/module/special.php on line 61
                                                    ругается на:
                                                    } else if ($this->session->data['wishlist']) {
                                                    что я мог не так написать?

                                                    Вся фишка в чем: Если зайди на страницу и будет такая ошибка, то нужно добавить товар в избранное, затем удалить его оттуда и если опять лазать по сайту, этой ошибки больше нет.

                                                    1. Владимир 16 июля 2018, 20:37
                                                      0

                                                      } else if (!empty($this->session->data['wishlist'])) {
                                                      Это я забыл про вариант когда закладки еще совсем не добавлялись

                                                      1. Александр 16 июля 2018, 20:51
                                                        0

                                                        Да получилось! Для страницы товара сделал тоже самое, что и для категории, модулей, пока ошибок не наблюдаю. Спасибо Владимир!!!

                                                2. Vlad44 23 августа 2019, 14:42
                                                  0

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

                                                  1. Владимир 23 августа 2019, 18:47
                                                    0

                                                    А замену 'success' делали? самый последний пункт

                                2. Вопросик 14 июля 2018, 12:22
                                  0

                                  А можно еще такой вопрос, можно ли как то отметить кнопку закладок, после добавления?
                                  К примеру, понравился товар, нажал сердечко, покрасился в другой цвет?
                                  Пытаюсь сделать в common.js, но я ничего там не понимаю ): или хотя бы как класс нужный задать ТОЛЬКО понравившемуся товару а не всем?

                                  1. Владимир 14 июля 2018, 14:291
                                    0

                                    Добавить класс при добавлении закладки просто. В common.js найдите

                                    $('#wishlist-total').attr('title', json['total']);
                                    И добавьте здесь класс, как то так:
                                    $('#wishlist-total').attr('title', json['total']).addClass('wl-added');
                                    Проверок здесь никаких не нужно, все равно только в плюс. Теперь нужно сохранить класс при обновлении страниц, удалить если товаров в закладках не осталось… здесь сложнее. Нужен контроллер «controller/common/header.php», вот этот код:
                                    if ($this->customer->isLogged()) {
                                    $this->load->model('account/wishlist');
                                    $data['text_wishlist'] = sprintf($this->language->get('text_wishlist'), $this->model_account_wishlist->getTotalWishlist());
                                    } else {
                                    $data['text_wishlist'] = sprintf($this->language->get('text_wishlist'), (!empty($this->session->data['wishlist']) ? count($this->session->data['wishlist']) : 0));
                                    }
                                    Добавим в $data класс в зависимости количества товаров. В итоге будет так:
                                    if ($this->customer->isLogged()) {
                                    $this->load->model('account/wishlist');
                                    $count_wl = $this->model_account_wishlist->getTotalWishlist();
                                    } else if (!empty($this->session->data['wishlist'])) {
                                    $count_wl = count($this->session->data['wishlist']);
                                    } else {
                                    $count_wl = 0;
                                    }
                                    $data['text_wishlist'] = sprintf($this->language->get('text_wishlist'), $count_wl);
                                    if ($count_wl > 0) {
                                    $data['class_wishlist'] = 'wl-added';
                                    } else {
                                    $data['class_wishlist'] = '';
                                    }
                                    Теперь осталось в header.tpl добавить назначенный класс. Для ссылки с id=«wishlist-total» добавить:
                                    class="<?php echo $class_wishlist; ?>"

                                    1. Вопросик 15 июля 2018, 00:511
                                      0

                                      А если нужно добавить в категории, и в модули latest.tpl и special.tpl? Я так понимаю нужно в контроллере вставить тоже самое что и в голову?
                                      Ну то есть, в данный момент, работает так: Добавляю товар в закладки, красится сердечко которое подсчитывает общее количество добавленных в избранное.
                                      А можно ли как то сделать так что бы допустим я на любой странице где есть товар и где выводится кнопка добавления в избранное, при нажатии этой кнопки, сердце только для этого товара добавлялся?

                                      ну к примеру сейчас так:

                                      это в голове кнопка сердца

                                      а у товара который добавил нету:


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

                                      if (json['success']) {
                                      $('#content').parent().before('<div class="alert alert-success"><i class="fa fa-check-circle"></i> ' + json['success'] + ' <button type="button" class="close" data-dismiss="alert">×</button></div>');
                                      }


                                      Вот и думал, что может можно как то поменять? К примеру получить ид товара и для этого товара грубо говоря добавлять класс?

                                      Сейчас чутка посидел подумал додумался до такого:
                                      в catalog.tpl где кнопка добавления в избранное добавил уникальный ид
                                      id="<?php echo $product['product_id']; ?>"
                                      теперь в common.js
                                      вместо:
                                      $('#content').parent().before('<div class="alert alert-success"><i class="fa fa-check-circle"></i> ' + json['success'] + ' <button type="button" class="close" data-dismiss="alert">×</button></div>');
                                      написал
                                      $('#' + 'product_id').addClass('wl-add');
                                      пробывал и так
                                      $('#' + product_id).addClass('wl-add');
                                      но все равно не добавляет ):

                                      1. Вопросик 15 июля 2018, 01:35
                                        0

                                        Нашел в чем косяк, теперь добавляет для добавленного товара нужный мне класс для кнопки с лайком :)))

                                        $('#'+product_id+'').addClass('wl-add');

                                        1. Владимир 15 июля 2018, 01:41
                                          0

                                          id="<?php echo $product['product_id']; ?>"
                                          лучше вот так:
                                          id="p-<?php echo $product['product_id']; ?>"
                                          уже не помню как там с идентификаторами, но с классами есть проблемы если они только из цифр

                                          тогда можно делать так:
                                          $('#p-' + product_id).addClass('wl-add');
                                          переменная не в кавычках

                                          1. Вопросик 15 июля 2018, 01:48
                                            0

                                            Пробовал 2 вариантом, не срабатывал ):

                                    2. Вопросик 11 июля 2018, 22:151
                                      0

                                      Отличный вариант! Только если, нет товаров в закладках появляется ошибка «Invalid argument supplied for foreach()»
                                      Решил проблему вот так:

                                      $data['products'] = array();
                                      
                                      		$results = array();
                                      			if ($this->customer->isLogged()) {
                                      			$results = $this->model_account_wishlist->getWishlist();
                                      		} else if (isset($this->session->data['wishlist'])) {
                                      			$prods = $this->session->data['wishlist'];
                                      			if(isset($prods) && is_array($prods)) foreach ($prods as $prod) {
                                      				$results[]['product_id'] = $prod;
                                      			}
                                      		}
                                      
                                      //добавил if(isset($prods) && is_array($prods)) перед foreach 
                                      Вопрос теперь другой. Если добавить товар в закладки, подсчитывается сумма всех товаров в закладках, НО если удалить все товары, то 0 почему то не ставится и остается 1, как будто еще товар остался, при этом страница закладок пустая. Как решить проблему?

                                      1. Владимир 12 июля 2018, 00:10
                                        0

                                        Проверял на opencart 3, там все корректно и так, под опенкарт 2 нужно немного подправить…
                                        1. controller/account/wishlist.php
                                        вместо

                                        } else if (isset($this->session->data['wishlist'])) {
                                        нужно
                                        } else if (!empty($this->session->data['wishlist'])) {
                                        2. controller/common/header.php
                                        вместо
                                        $data['text_wishlist'] = sprintf($this->language->get('text_wishlist'), (isset($this->session->data['wishlist']) ? count($this->session->data['wishlist']) : 0));
                                        нужно
                                        $data['text_wishlist'] = sprintf($this->language->get('text_wishlist'), (!empty($this->session->data['wishlist']) ? count($this->session->data['wishlist']) : 0));
                                        (проверяем на пустоту, а не существование)

                                        1. Вопросик 12 июля 2018, 12:38
                                          0

                                          ВОУ! Работает!!! Спасибо Вам, Владимир!!!