Как работает корзина Opencart?

shopcart_opencart

Корзина в OpenCart, как много в этом слове…
сколько готовых модулей, сколько вопросов в интернетах, сколько головных болей, сколько заказов на freelance…

Как правило, все хотят урезать корзину, убрать лишние шаги. Но что-бы править корзину на OpenCart, нужно знать как она работает. Не найдя в интернетах (даже в официальной документации) информацию на этот счет, я решил стать первым и «перебрать косточки» корзине. Прочтя данный пост вы получите полное представление о внутреннем устройстве корзины на OpenCart. Делитесь этим постом с окружающими.

P.S. Данный пост писался по анализу исходного кода OpenCart 2.x.

Меньше слов, ближе к делу.

Определимся, какие в OpenCart есть страницы связанные с осуществлением заказа, есть страница:

  • «корзина» это страница где вы мы можете посмотреть ваш текущий заказ (перейти к разделу поста)
  • «оформление заказа» это страница где вы оформляете свой заказ, вы указываете свои данные, выбираете способ доставки, способ оплаты и т.п.

С «корзиной» все в порядке, в ней мы можем отредактировать заказ (удалить товары, изменить их количество).

cart

А вот «оформление заказа» в OpenCart своей громоздкостью меня раздражает (думаю многих), для окончательного оформления заказа, приходится выполнять много действий по заполнению полей и выбора способов оплаты/доставки.  Как следствие, в интернете появилось много платных (меньше бесплатных) модулей для OpenCart «упрощенной корзины», которая состоит из списка товаров, поля ввода «фамилии», «e-mail» и «телефона». Периодически мне также приходят заказы, на «упрощение корзины» в OpenCart.

checkout

«Корзина» и «оформление заказа» в OpenCart это прежде всего директория \catalog\controller\checkout

Пока в ней нас интересует два файла:

  • cart.php
  • checkout.php

 

 

cart.php

 

За «корзину» отвечает контроллер «cart.php», который состоит из методов:

index() – Метод формирует данные и выводит «корзину»  через файл представления default/template/checkout/cart.tpl

add() – Метод добавляет товар в корзину. Принимает post параметры

  • product_id — идентификационный номер продукта
  • quantity — количество товара
  • option — список опций
  • recurring_id — идентификационный номер периодичности (если используются профили периодичности, которые позволяет например через определенное время выставлять счет покупателю)

Когда вы нажимаете на «Купить» на странице описания товара (или на странице списка товаров в категории) срабатывает javascript обработчик, который шлет параметры product_id и quantity в метод add() контроллера cart.php, в результате чего он возвращает ответ (json) о состояние (добавлен товар в корзину или нет).

cart_button

edit() – Метод изменяет количество товара в корзине. Принимает только post параметр «quantity». Когда вы нажимаете кнопку «Обновить» в корзине, javascript обработчик отсылает число из  поля «Количество» в метод edit() контроллера cart.php.

quantity

remove() – Метод удаляет товар из корзины. Принимает post параметр «key», который представляет собой id номер позиции в корзине для вашей сесии, он определяет в таблице oc_cart: id сессии, id товара, опции, количество и дату.

При нажатие на кнопку «удалить» (выделил синим), javascript обработчик отправляет методу remove() параметр key.

cart_del

Подытожим выше описанное

cart_principle

Контроллер cart.php, позволяет добавлять товар в корзину с помощью add(), позволяет редактировать количество товара с помощью edit(), позволяет удалять позиции из корзины с помощью remove() и позволяет выводить саму корзину с помощью index().

 

 

checkout.php

 

За «оформление заказа» отвечает контроллер «checkout.php», который состоит из методов:

index() – метод формирует данные и выводит страницу «оформление заказа» с помощью файла представления default/template/checkout/checkout.tpl. Фактически это вывод страницы оформления с шагами.

country() – метод принимает номер страны и выдает список регионов.

customfield() – метод принимает номер группы клиента при регистрации и возвращает дополнительные поля для заполнения.

Наглядно, как работает оформление заказа в OpenCart можно изобразить так.

checkout_principle

Когда вы заходите на страницу оформления заказа, ваш браузер запрашивает метод index() контроллера checkout.php, в результате вы получаете шаблон checkout.tpl, который, после своей загрузки,  автоматически вызывает контроллер login.php. Рамкой я обозначил данный момент, т.к. в нем заключается вся суть оформления заказа. Методы country() и customfield() несут вспомогательную роль.

Контроллер login.php работает с некоторым количеством контроллеров, назовем их ядром страницы оформления заказа (обозначил овалом), но об этом позже. Сейчас достаточно знать, что каждый из контроллеров в «ядре» отвечает за свой шаг при оформление заказа и использует свой файл представления за вывод содержимого шага.

На некотором шаге происходит запрос к методу country() для вывода списка регионов согласно выбранной стране, на некотором другом шаге происходит запрос к customfield() для вывода дополнительных полей при регистрации (что это, будет рассказано позже).

Это взгляд из далека, для более полного понимания читайте ниже.

 

 

index()

 

Это сложная часть поста, для более полного понимания,  я решил прокомментировать фрагменты php кода метода index() контроллера checkout.php. Желательно, что бы вы также открыли файл catalog/controller/checkout/checkout.php для своей версии OpenCart и проводили аналогию (если содержимое контроллеров будут отличаться).

Итак начало метода index()

Данный код, нужен для проверки, имеет ли корзина товар, достигнуто ли минимальное требование количества, если требования не выполняются, то нас отправляют на контроллер cart.php, т.е. просто на страницу корзины. Этот фрагмент не особо интересен, т.к. нет его необходимости править при сокращение «оформления заказа» в OpenCart.

Далее идет, подключение языкового файла checkout/checkout.php :

Установки заголовка страницы из параметра «heading_title» выше подключенного языкового файла:

Подключение js и css файлов

Формирование массива «хлебных крошек»

Далее определяются переменные для файла представления, данные берутся из языкового файла.

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

Данный код определяет вошел ли в свою учетную запись покупатель или нет.

В зависимости от значений logged и account в представление

catalog\view\theme\default\template\checkout\checkout.tpl будет выбран вариант шага №2 при оформление покупки. Он может быть двух вариантов:

«Шаг 2: Профиль & Платежная информация»

Для случая, когда покупатель не зарегистрирован, в шаге №2, ему необходимо зарегистрироваться, ввести о себе данные и пароль.

checkout_step_2

или

«Шаг 2: Платежная информация»

Для случае, если посетитель уже авторизовался

checkout_step_2_v2

В данном варианте, платежные данные это данные аккаунта, но посетитель может использовать и свой произвольный адрес.

Далее следует переменная, которая определяет, будут ли в оформление шаги, связанные с доставкой или нет. Т.е. будет ли шаг 3 «адрес доставки» и шаг 4 «способ доставки».

Значение данной переменной берется из настроек (выделил красным) в карточке товара, на вкладке «данные».

setting_shiping

Повторюсь, файл представления оформления заказа (catalog/view/theme/default/template/checkout/checkout.tpl) в зависимости от флага в shipping_required выводит или не вывод шаг №4 и шаг №5.

show_shiping

Теперь важный момент, если вы посмотрите в checkout.tpl, то вы заметите, что шаблон в основном состоит из div контейнеров шагов оформления, и важно то, что содержимого у них нет, например:

Откуда берется содержимое шагов? Ведь переменная shipping_required и аналогичные ей из контроллера checkout.php, определяет выводить данный div или нет?

Оказывается, когда вы нажимаете на каждом шаге кнопку button_next

запускается javascript обработчик (определен в шаблоне checkout.tpl), который выполняет ajax запрос к контроллерам, а они в свою очередь возвращают tpl шаблон, с содержимым шага.

Вопрос, к каким контроллерам происходит ajax запрос?

Все зависит от шага, чья эта кнопка…

На этом моменте я остановлюсь поподробнее, если вы загляните в директорию catalog/controller/checkout, то вы увидите следующие файлы контроллеров.

controllers_checkout

 

Я дам краткое пояснение, кто за что отвечает.

Повторюсь, как я говорил ранее, контроллер cart.php отвечает за корзину, а checkout.php за оформление заказа. Все остальные файлы отвечают за вывод информации того или иного шага при оформление заказа.

Рассмотрим остальные:

login.php – отвечает за шаг №1 «Способ оформление заказа», где пользователь выбирает будет он регистрироваться или нет, или он хочет войти в личный кабинет. За внешний вид отвечает файл представления login.tpl.

step_1_checkout

registr.php – отвечает за шаг №2 «Профиль & Платежная информация», где пользователь вводит данные для регистрации. За внешний вид отвечает файл представления registr.tpl.

step_2_checkout

guest.php – отвечает также за шаг №2 «Платежная информация», если пользователь выбрал на предыдущем шаге «Оформить заказ без регистрации». Отличается тем, что отсутствует поле ввода пароля. За внешний вид отвечает файл представления guest.tpl.

step_2_2_checkout

payment_address.php – отвечает также за шаг №2, если пользователь на предыдущем шаге №2 «Платежная информация» убрал галку «Мой адрес доставки совпадает с платежным» и нажал «Продолжить». Пользователь или соглашается с введённым на предыдущем шаге адресе или вводит новый адрес.

За внешний вид отвечает файл представления payment_address.tpl.

step_2_3_checkout

Возможно это баг OpenCart. Иногда бывает так, что, когда вы уберете галку «Мой адрес доставки совпадает с платежным» и нажмете «Продолжить» разворачивается шаг №3 вместо обновленного шага №2. В это случае вы можете, его сами развернуть.

shipping_address.php – отвечает за шаг №3 «Адрес доставки», где пользователь любо соглашается с ранее введённым адресом или вводит новый. За внешний вид отвечает файл представления shipping_address.tpl.

step_3_checkout

guest_shipping.php – отвечает за шаг №3 «Адрес доставки», но для пользователя без регистрации. Пользователь вводит адрес доставки, за внешний вид отвечает guest_shipping.tpl.

step_3_2_checkout

shipping_method.php – отвечает за шаг №4 «Способ доставки», где пользователь выбирает предложенные ему способы доставки. За внешний вид отвечает файл shipping_method.tpl.

step_4_checkout

payment_method.php – отвечает за шаг №5 «Способ оплаты», где пользователь выбирает доступные ему способы оплаты. За внешний вид отвечает файл payment_method.tpl.

step_5_checkout

confirm.php – отвечает за шаг №6 «Подтверждение заказа», где пользователю демонстрируется список товара на оформление с итоговой стоомостью. За внешний вид отвечает confirm.tpl.

step_6_checkout

Нажимая на «Подтверждение заказа» данные отправляются в метод confirm() контроллера payment/cod. В случае успеха, вызывается контроллер success.php, который в свою очередь выводит результат через шаблон catalog/view/theme/default/template/common/success.tpl

result_checkout

 

Что бы представлять ситуацию полностью я изобразил вот такую схему:

checkout_struct

 

У каждого контроллера для каждого шага, есть два метода:

index() для вывода файла представления (для получения шаблона) и save() для приема информации с файла представления.

 

Продолжаем просматривать далее checkout.php.

Далее определяются контроллеры для вывода левой, правой части и т.п. Данный фрагмент кода, есть в любом «корневом» контроллере.

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

 

 

Следующим метод сountry()

 

Метод сountry() получает country_id, это номер страны в выпадающем списке (select) «Страна» на вкладке «платежной информации». При изменения select-а запускается javascript обработчик, который формирует GET запрос с параметром «country_id» и шлет его контроллеру:
index.php?route=checkout/checkout/country&country_id=значение_с_select

Структурно в HTML обработчик располагается в 2-ом div-e «panel panel-default» в div-e «panel-group».

step_2_country

Метод сountry() принимает «country_id» и передает его в качестве аргумента метода getCountry() модели localisation/country.  Далее метод сountry()  делает запрос к БД (конкретно к таблицам oc_zone и oc_country) и возвращает json ответ с полями.

Обработчик разворачивает поле zone в option «Регион / Область»

step_2_country_2

 

 

Метод customfield()

 

Метод используется customfield() данный метод редко, могу только сказать, что он использует метод getCustomFields модели account/custom_field, который обращается к таблицам в БД:

  • custom_field
  • custom_field_customer_group

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

Для этого в настройках выбираем вкладку «Группа клиентов».

gropus_clients

Создаем группу, далее заполняем поле название, описание.

gropus_clients_2

В настройках -> опции где «Аккаунт» отмечаем галкой новую группу клиентов.

new_group

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

checkout_select_group

И для каждой группы можно создать дополнительное поле, например для группы «Новая группа» при регистрации нужно добавить поле с датой. Для этого нужно зайти на вкладку «Настраиваемые поля»

checkout_region_for_groups

Добавить поле

checkout_setting_area

Задать, что поле будет иметь тип «даты» с именем «Тестовое поле» и отметить группы клиентов, для которых его нужно отображать, и для кого оно обязательно при заполнение. Отметим, что данное поле нужно показывать для «Новой группы».

Теперь при регистрации, если пользователь выберет «Новая группа» он увидит новое поле «Тестовое поле» с датой.

checkout_new_area

К чему этот длинный разговор о группах клиентов?

Дело в том, что метод customfield() отвечает за вывод дополнительных полей. Т.е. когда пользователь нажимает на одну из radio кнопок, происходит запрос к контроллеру customfield(), который в свою очередь отвечает, какие поля вывести.




Буду признателен если вы поделитесь данным постом

Комментарии
  1. Ya_Oslik пишет:

    Добрый день, уважаемый Инженер. Прежде всего хочу сказать большое спасибо за Ваш блог, для человека(меня) имеющего технический склад ума но ранее не работавшего с опенкартом, он стал настоящим спасением, всё коротко и по делу. Было бы неплохо ещё добавить дату написания статьи=) В данный момент я пытаюсь разобраться как раз с оформлением заказа, и хочу задать вопрос будут ли у Вас ещё статьи по данной теме? Например с более подробным разбором checkout.tpl и его скриптов или же про то куда контроллеры оформляющии заказ отправляют данные (как я понял на данном этапе вся инфа сохраняется куда-то в $this->session->data) точнее меня волнует какие данные необходимы для заказа если пересобрать оформление самому.
    И небольшое исправление, у Вас написано что по клику на «Подтверждение заказа» вызывается метод контроллера cod, но выбор контроллера зависит от метода оплаты, например если выбрать оплата квитанцией сбербанка то данные отправятся по url: ‘index.php?route=extension/payment/sberbank_transfer/confirm’,

  2. admin пишет:

    Добрый вечер Ya_Oslik!
    Приятно слышать такие теплые слова, стараюсь писать посты без воды, для людей, а не для сео =)

    Планировал писать следующий пост, продолжение данного, в котором я расскажу как корзину «резать», тема очень популярна. Почему то, никто не хочет описать данную проблему, попробую быть первым)
    Сейчас завал с работой, думаю это будет ближе к весне.

    Уважаемый Ya_Oslik я постараюсь ответить на ваш вопрос в течение завтрашнего дня (если успею), много работы очень.



Ваш комментарий


Ответ в цифрах

 
© s-engineer.ru, 2012-2017 | Все права защищены