OpenCart для разработчиков

Вступление

В статье описаны базовые принципы работы OpenCart с моими заметками по их работе. Не пытайтесь заучить содержимое статьи, это не инструкция. Цель этой статьи — дать базовые знания для людей, которые интересуются этой системой управления сайтом (CMS).

Знаю, зачастую люди пытаются собирать сайты на ней самостоятельно, без базовых знаний программирования, но Вам необходимо знать PHP и понимать объектно ориентированное программирование для понимания этой статьи.

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

Руководство

Для понимания работы CMS OpenCart следует знать о такой схеме разделения данных приложения, как MVC. С ее описания я и начну данную статью.

0. Понимание MVC.

MVC это схема разделения данных, при которой приложение разделяется на несколько частей, каждая из которых выполняет свою роль в нем. Эти части называются

  • Модель (Model),
  • Представление (View),
  • Контроллер (Controller).

Модель отвечает за данные в ОpenСart в этих файлах хранятся классы, методы которых добавляют/получают/обновляют/удаляют данные с базы данных, обращения к API и так далее. Модели отвечают за данные всей системы.

Представление отвечает за контент (html, который видит пользователь). В OpenCart 2.3 все представления имели расширение .tpl, начиная с 3.0 версии — в представлениях используется шаблонизатор twig.

Контроллер в OpenCart, служит для обработки действий пользователя. В нем формируется вывод представлений, с данными, которые возвращают модели приложения. Так-же контроллер обрабатывает формы пользователей, проверяя данные перед их сохранением в базу данных.

На самом деле OpenCart использует схему разделения MVC-L, где L — Language (Язык). В языковых файлах хранятся массивы с переводами определенных строк.

Функциональность системы разделяется на пользовательскую часть и на админ часть, для каждой из которых в системе создана папка.

Для пользовательской части:

/catalog/controllerсодержит все контроллеры
/catalog/modelсодержит все модели
/catalog/viewсодержит все представления

Для админ части:

/admin/controllerсодержит все контроллеры
/admin/modelсодержит все модели
/admin/viewсодержит все преставления

Подробнее о каждой из частей будет описано ниже.

1. Дополнительные библиотеки в OpenCart

Понимание OpenCart следует начинать с библиотек. 

  • Библиотеки необходимы для того, чтобы избавиться от дублирования кода в системе,
  • Работать с библиотеками можно в любом классе, который наследуется от классов Controller и Model,
  • Все системные библиотеки можно найти в папке «/system/library»,
  • Для доступа к объектам используется синтаксис:
$this->library_name

Для лучшего понимания приведу небольшой пример: 

Необходимо получить доступ к товарам, которые находятся в корзине, для этого мы используем класс Cart, инициализация которого находится здесь: system/library/cart/cart.php

Поскольку использование объекта разрешается в любом классе, который наследуется от Controller или Model, то в любом из таких классов можно вызвать метод для получения всех товаров, которые находятся в корзине $this->cart->getProducts()

Ниже представлены основные файлы библиотек с описаниям того, за что они отвечают:

system/library/cart/cart.php — Отвечает за товары в корзине. Имеет методы для добавления / удаления / обновления  / получения данных о товарах, которые находятся в корзине;

system/library/cart/currency.php — Отвечает за работу с ценой. OpenCart поддерживает мультивалютность. Имеет методы для конвертации валюты и получения информации о текущей валюте.

system/library/cart/customer.php — Отвечает за пользователей. Имеет методы для авторизации / регистрации пользователей, проверки их на вход, получения информации о текущем пользователе

system/library/cart/user.php — Отвечает за пользователей админ панели. Все то-же что и customer, только для тех пользователей, которые имеют доступ в админ панель.

system/library/language.php — Отвечает за файлы переводов. Используется практически в каждом контроллере. Имеет методы для получения строк из массивов переводов.

system/library/image.php — Отвечает за работу с изображениями. Умеет изменять размер, работать с метаданными изображений.

system/library/mail.php — Отвечает за отправку писем. 

2. Как работают маршруты в OpenCart

В URL OpenCart есть параметр route, по которому можно понять какой из контроллеров обрабатывает текущую страницу.

Чаще всего, параметр route имеет вид  route=aaa/bbb, что значит тот факт, что текущую страницу обработал контроллер bbb.php, который можно найти в папке /controller/aaa. Если параметр route состоит из трех частей, то последняя часть даст понять название метода, который обработал текущую страницу (по умолчанию этот метод называется index, и он не указывается в маршруте).

Например:

Вы находитесь на странице route=aaa/bbb/ccc, что символизирует о том, что метод, который обработал эту страницу называется public function ccc(), находится он в папке /controller/aaa/, в файле bbb.php

3. Понимание языков

  • Все языки хранятся в папке /catalog/language/(или/admin/language) в подпапке с названием языка. 
  • Языков может быть несколько, каждый отдельный язык храниться в отдельной подпапке.

Содержимое подпапок состоит из:

  1. Языкового массива, который доступен на любой странице (в любом route) (обычно это файл с названием языка, например en.php)
  2. Папок отдельных страниц — для отдельных страниц, зачастую, используется отдельный текст, папки называются аналогично route, файлы — аналогично названиям контроллеров, которые подключают язык с конкретной папки;
  3. Иконки языка (имеет то-же название, что и языковой массив, с расширением png).

Объяснение: 

Страница товара имеет маршрут product/product, по этому текст для этой страницы будет находиться в файле, /catalog/language/en/product/product.php (обратите внимание как имя файла и подпапка соответствуют маршруту, понимая маршруты будет гораздо проще работать с OpenCart)

Мы разобрались с тем, где находятся языковые файлы, осталось понять как с ними работать:

  • Вся работа с языковыми файлами происходит в контроллере.
  • Для загрузки языка следует использовать метод load() из класса language $this->language->load('product/product');
  • После чего, для извлечения текста из массива по ключу можно использовать метод get() $var = $this->language->get('text_instock');

Значение переменной  назначается в языковом файле, о котором мы говорили выше. В этом файле должен храниться ассоциативныймассив $_, в котором должен быть доступентекст с ключем text_instock

Если соответствующего ключа не будет в языковых файлах, функция get() вернет передаваемую строку (text_instock).

Таким образом, если в файле /catalog/language/en/product/product.php есть строка$_['text_instock']     = ‘In Stock’;

Это значит, что переменная $var из нашего примера имеет значение «In Stock», если нет — значение «text_instock»

Пример (порядок добавления своей строки):

  1. Добавляем файл перевода в языковой файл catalog/language/ru-ru/header.php
    $_['text_hello_world'] = 'Привет мир!';
  2. Добавляем вывод в контроллере catalog/controller/common/header.php
    $data['hello_world'] = $this->language->get('hello_world');
  3. Выводим строку в catalog/view/theme/название темы/common/header.tpl
    <h1><?php echo $hello_world; ?></h1>
  4. Не забывайте обновить кеш модификаторов

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

4. Контроллеры

Контроллеры загружаются на основе значения параметра route и работают по достаточно прозрачному принципу.

Все контроллеры находятся в папке /catalog/controller/. По предыдущему примеру, страница товара, которая имеет route=product/product будет обрабатываться контроллером   /catalog/controller/product/product.php (снова обратите внимание на то, как имя файла и подпапка соответствуют параметру route)

Если Вы откроете файл /catalog/controller/product/product.php, обратите внимание на то, как он называется — ControllerProductProduct. Да, название снова соответсвует маршруту, по которому срабатывает данный контроллер. По умолчанию в контроллере срабатывает метод index(). Другие методы можно также вызвать из параметра route. Например, route=product/product/doMyOwnMethod будет обработан методом public doMyOwnMethod() класса ControllerProductProduct. 

Все public методы доступны для запуска параметром route, private и protected — нет.

4.1. Как работают переменные в контроллерах

Все переменные в контроллерах OpenCart, которые необходимо передавать в представление (view) следует помещать в ассоциативный массив $data.

В файле представлений переменные из массива будут доступны по значению ключа (для понимания этого — почитайте как работает функция extract() в php)

Например: 

В контроллере присвоим переменную:

$data[‘hello_world’] = ‘hello world’;

Для вывода этой переменной в файле преставления — следует использовать эту переменную:

$hello_world

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

5. Представления

Представления очень сильно изменились с момента релиза OpenCart 3. Здесь я опишу о том, как они работали OpenCart 2 и OpenCart 1.5

Представления (view), как и контроллеры сгруппированы по папкам на основе маршрута (хотя здесь их группировка — не особо важна и несет больше эстетический смысл, так как они могут подключаться из любого контроллера). 

Такие файлы находятся внутри папок тем и имеют расширение .tpl (.twig для OpenCart 3+)

Внутри этих файлов находиться html код, разбавленный выводом php переменных (что формируются и передаются в массиве $data в контроллере)

5.1 Как подключить вывод преставления (view) в контроллере

Для того, чтобы подключить view следует использовать библиотеку response совместно с библиотекой load

$this->response->setOutput($this->load->view('account/account', $data));

Метод view библиотеки load подключает файл представления (в него так-же передается массив с данными, которые можно использовать внутри)

Метод setOutput библиотеки response — непосредственно выводит содержимое подготавливает данные вывода (в нашем случае это html код).

5.2 Как работают темы (шаблоны) в OpenCart 

Шаблон в OpenCart это файл, папка с файлами представлений, которая переопределяет стандартную тему OpenCart.

Список всех шаблонов можно увидеть в папке catalog/view/theme

По умолчанию, OpenCart имеет один шаблон (default). Редактировать файлы этого шаблона — так себе идея. Дело в том, что стандартный шаблон реализует все функциональности, которые есть в OpenCart. Отредактировав стандартный шаблон часть функциональностей может быть утеряна.
Кроме того — если в кастомном (который создаете Вы) шаблоне не будет файла view, который подключает контроллер для вывода —  этот файл будет взят из default шаблона, таким образом Вам удасться избежать ошибок. 

6. Модели 

Что касается моделей в OpenCart — все их файлы находятся в папках catalog/model (admin/model), но в отличии от контроллеров, которые группируются на основе маршрута — файлы моделей группируются на основе функции, за которую они отвечаю

  • Подключить модель можно с помощью кода
    $this->load->model(‘folder/file’);
  • Код выше подключит модель к текущему контроллеру, а методы модели станут доступными в объекте
    $this->model_folder_file
  • Вызывать можно только публичные методы модели.

Например:

Загрузим модель, которая отвечает за работу с изображениями:

$this->load->model(‘tool/image’);

Вызовем метод, который изменит размер изображения до 300×200 и сохранит его в кэш

$this->model_tool_image->resize('image.png', 300, 200);

6.1 SQL запросы в моделях OpenCart

Так, как модель отвечает за получение данных — все SQL запросы следует прописывать именно в ней. 

Я предполагаю что у читателя уже есть представление о SQL запросах, по этому опишу особенности OpenCart по части работы с ними: 

  • Все SQL запросы выполняются с помощью библиотеки db и ее метода query
    $this->db->query($sql_query); 

Внутри SQL запроса, зачастую, можно увидеть константу DB_PREFIX, которая содержит префикс базы данных (префикс задается при установке)

Вот пример запроса в OpenCart: 

$query = $this->db->query("SELECT DISTINCT * FROM " . DB_PREFIX . "currency WHERE code = '" . $this->db->escape($currency) . "'");

Метод escape — это обертка для функции mysql_real_escape_string(), которая экранирует специальные символы в строках

После выполения запроса, переменная $query будет содержать объект SELECT запроса, в котором

$result->row содержит данные первой строки

$result->rows содержит массив результатов строки, подходящий для  foreach

$result->num_rows вернет количество результатов, которые входя в выборку

После выполнения запроса можно использовать метод, который вернет идентификатор вставленной строки (для INSERT) $this->db->getLastId()

7. Обертки для переменных

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

в phpв OpenCart
$_GET$this->request->get
$_POST$this->request->post
$_COOKIE$this->request->cookie
$_FILES$this->request->files
$_REQUEST$this->request->request
$_SERVER$this->request->server

Вывод

К сожалению у этой CMS нет должной документации для разработчиков, но его код достаточно понятен. Я надеюсь что эта статья станет хорошим началом изучения CMS OpenCart для начинающих разработчиков.

Anatolii Koziura

Антураж-куражмонтаж в мире web разработки.

8 thoughts to “OpenCart для разработчиков”

  1. Спасибо! Наконец то понял как определить контроллер отвечающий за вывод на конкретной странице.

  2. Большое спасибо за статью, вынес для себя максимально инфы, но не совсем понятно было по поводу model(с изображением) в практике

    1. Рад помочь)
      Не зависимо от того, какая модель использовалась бы в примере, суть в том, чтобы показать как модель подключается в контроллере и как ее вызвать. Думаю, стоит заглянуть в файл модели tool/image, чтобы понять что произошло в контроллере 🙂

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *