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

Опубликовано Опубликовано в рубрике prestashop, Руководство разработчика PrestaShop, Русская документация PrestaShop 1.6, Создание модулей PrestaShop

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

Структура файла для модуля PrestaShop

 

Модуль состоит из большого количества файлов, все они хранятся в папке, которая имеет то же имя, что и модуль, и эта папка, в свою очередь, хранится в /modules В корневой папке главной папки PrestaShop: /modules/name_of_the_module/.

Ниже приведены возможные файлы и папки для модуля PrestaShop 1.6:

Файл/имя папки
Описание
Детали
name_of_the_module.php Основной файл. Основной файл PHP должен иметь то же имя, что и корневая папка модуля.
Например, для модуля BlockCMS:

  • Имя папки: /modules/blockcms
  • Основное имя файла: /modules/blockcms/blockcms.php
config.xml Файл конфигурации кэша. Если он еще не существует, этот файл автоматически генерируется PrestaShop, когда модуль будет установлен впервые.
logo.gif or logo.jpg (up to v1.4)
logo.png (v1.5+)
Файлы значков, представляющие этот модуль в бэк-офисе PrestaShop 1.4: 16*16 pixels Gif or Jpeg file.
PrestaShop 1.5: 32*32 pixels PNG file.
Если ваш модуль работает как с PrestaShop 1.4, так и с PrestaShop 1.5+, вы должны иметь как logo.gif так и logo.png файл.
/views Эта папка содержит файлы View
/views/templates Эта папка содержит файлы шаблонов вашего модуля (.tpl).  Если модуль должен работать с PrestaShop 1.4, файлы шаблонов следует размещать либо непосредственно в корневой папке модуля, либо в /template папке в корневой папке модуля.
/views/templates/admin Подпапка для файлов шаблонов, используемых контроллерами администрирования модуля.
/views/templates/front Подпапка для файлов шаблонов, используемых контроллерами фронт-офиса модуля.
/views/templates/hook Подпапка для файлов шаблонов, используемых хуками модуля.
/views/css Подпапка для используемых файлов CSS. Если модуль должен работать с PrestaShop 1.4, файлы CSS должны быть помещены в /css папку в корневой папке модуля.
/views/js Подпапка для файлов JavaScript. Если модуль должен работать с PrestaShop 1.4, файлы JavaScript должны быть помещены в /js папку в корневой папке модуля.
/views/img Подпапка для файлов изображений. Если модуль должен работать с PrestaShop 1.4, файлы JavaScript должны быть помещены в /img папку в корневой папке модуля.
/controllers Эта папка содержит файлы Controller. Вы можете использовать те же пути подпапок, что и для файлов View.
Например, /modules/bankwire/controllers/front/payment.php .
/override Подпапка для кода, переопределяющего класс. Это очень полезно, когда вам нужно изменить часть кода PrestaShop по умолчанию. Поскольку вы не должны этого делать в ядре, вы можете переопределить код по умолчанию здесь.
Например, /modules/gsitemap/override/classes/Shop.php extends the default ShopCore class.
/translations Подпапка для файлов перевода. fr.phpen.phpes.php, etc.
/themes/[theme_name]/modules Подпапка для переопределения файлов .tpl и файлов языков, если это необходимо. Эта папка необходима во время модификации существующего модуля, так что вы можете адаптировать ее, не касаясь исходных файлов. Примечательно, что он позволяет обрабатывать файлы шаблонов модуля различными способами, в зависимости от текущей темы.
/upgrade Подпапка для файлов обновления При выпуске новой версии модуля старшему может потребоваться обновление его данных или файлов. Это можно сделать с помощью этой папки.

Для базового модуля необходимы только три первых: основной файл, файл конфигурации кэша (который в любом случае автогенерируется PrestaShop) и файл значка. Все остальные можно использовать, если необходимо, но модуль может работать без них.
Модуль может также содержать сколько угодно файлов и папок: /css/img/js, итд.

Если вы хотите использовать внешнюю библиотеку, ее следует поместить в выделенную папку.

Эта папка может использовать одно из этих имен: ‘lib’, ‘libs’, ‘libraries’, ‘sdk’, ‘vendor’, ‘vendors’.

Выберите наиболее подходящую для вашей библиотеки (действительно, «библиотеки» не имеют того же значения, что и «sdk»). У вас может быть более одной такой папки, например /lib и /sdk.

Соглашение о коде в PrestaShop

Прежде чем вы начнете писать код для своего модуля PrestaShop, вы должны знать, что команда PrestaShop использует определенный набор правил кодирования (или стандартов кодирования, норм кодирования и т.д.).
Как видно из Википедии, «Соглашения о кодировании — это набор руководящих принципов для конкретного языка программирования, которые рекомендуют стиль, методы и методы программирования для каждого аспекта частичной программы, написанной на этом языке» и «Хорошие процедуры, хорошая методология и хорошие Стандарты кодирования могут использоваться для управления проектом таким образом, чтобы качество было максимально улучшено, а общее время разработки и затраты на разработку и обслуживание были сведены к минимуму ».
(См http://en.wikipedia.org/wiki/Coding_conventions).

Собственные стандарты PrestaShop доступны на этой странице: http://doc.prestashop.com/display/PS16/Coding+Standards. Вы должны прочитать его, чтобы убедиться, что код, который вы пишете, соответствует общему коду проекта PrestaShop. PHPCodeSniffer может помочь вам убедиться, что вы правильно следуете стандарту.

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

Давайте создадим простой первый модуль; Это позволит нам лучше описать его структуру. Назовем его «My module».

Сначала создайте папку модуля в /modules папке. Она должна иметь то же имя, что и модуль, без пробела, только буквенно-цифровые символы, дефис и подчеркивание, все в нижнем регистре: /mymodule.

Эта папка должна содержать основной файл, файл PHP с тем же именем, что и папка, которая будет обрабатывать большую часть вызовов: mymodule.php.

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

Постоянный текст

Главный mymodule.php файл должен начинаться со следующего текста:

<?php   
if (!defined('_PS_VERSION_')) {
  exit;
}

Это проверяет наличие постоянно существующей константы PrestaShop (номер версии), и если она не существует, она останавливает загрузку модуля. Единственная цель этого — не допустить, чтобы злоумышленники загружали этот файл напрямую.

Обратите внимание, что в соответствии с требованиями стандартов кодирования PrestaShop (см. выше) мы не используем закрывающий тег PHP.

Главный класс

Основной файл должен содержать основной класс модуля (вместе с другими классами, если необходимо). PrestaShop использует объектно-ориентированное программирование, а также его модули.

Этот класс должен иметь то же имя, что и модуль и его папка, в CamelCase (see http://en.wikipedia.org/wiki/CamelCase). В нашем примере: MyModule.
Кроме того, этот класс должен расширить Module класс, чтобы наследовать все его методы и атрибуты.

mymodule.php
<?php
if (!defined('_PS_VERSION_')) {
  exit;
}
class MyModule extends Module
{
}

Он может также расширить любой класс, полученный из Module, для конкретных потребностей: PaymentModuleModuleGridEngineModuleGraph, итд.

На этом этапе, если вы поместите папку модуля в /modules папку, модуль уже можно увидеть на странице «Модули» в бэк-офисе, в разделе «Другие модули», хотя и без реального имени или эскиза.

Метод конструктора

Теперь давайте заполним блок кода класса основными строками конструктора. Конструктор — это функция в классе, которая автоматически вызывается при создании нового экземпляра класса. В случае PrestaShop класс конструктора является первым методом, который вызывается, когда модуль загружается PrestaShop. Поэтому это лучшее место для установки большинства его значений.

mymodule.php
<?php
if (!defined('_PS_VERSION_')) {
  exit;
}
class MyModule extends Module
{
  public function __construct()
  {
    $this->name = 'mymodule';
    $this->tab = 'front_office_features';
    $this->version = '1.0.0';
    $this->author = 'Firstname Lastname';
    $this->need_instance = 0;
    $this->ps_versions_compliancy = array('min' => '1.6''max' => _PS_VERSION_); 
    $this->bootstrap = true;
    parent::__construct();
    $this->displayName = $this->l('My module');
    $this->description = $this->l('Description of my module.');
    $this->confirmUninstall = $this->l('Are you sure you want to uninstall?');
    if (!Configuration::get('MYMODULE_NAME')) {
      $this->warning = $this->l('No name provided');
    }
  }
}

Давайте рассмотрим каждую строку из этой первой версии MyModule class…

public function __construct()

Эта строка определяет функцию-конструктор класса.

$this->name = 'mymodule';
$this->tab = 'front_office_features';
$this->version = '1.0';
$this->author = 'Firstname Lastname';

В этом разделе назначается несколько атрибутов экземпляру класса (this):

  • ‘name’ attribute. Эти атрибуты служат внутренним идентификатором. Значение ДОЛЖНО совпадать с именем папки модуля. Не используйте специальные символы или пробелы и печатайте в нижнем регистре.
  • ‘tab’ attribute. Заголовок раздела, который должен содержать этот модуль в списке модулей PrestaShop. Вы можете использовать существующее имя, например seofront_office_features или analytics_stats, или своим. В этом случае с вашим идентификатором будет создан новый раздел. Мы выбрали «front_office_features» потому что этот первый модуль будет в основном влиять на интерфейс.
    Вот список доступных атрибутов «Tab» и их соответствующий раздел на странице «Модули»:

    «Tab» attribute
    Module section
    administration Administration
    advertising_marketing Advertising & Marketing
    analytics_stats Analytics & Stats
    billing_invoicing Billing & Invoices
    checkout Checkout
    content_management Content Management
    dashboard Dashboard
    emailing E-mailing
    export Export
    front_office_features Front Office Features
    i18n_localization I18n & Localization
    market_place Market Place
    merchandizing Merchandizing
    migration_tools Migration Tools
    mobile Mobile
    others Other Modules
    payments_gateways Payments & Gateways
    payment_security Payment Security
    pricing_promotion Pricing & Promotion
    quick_bulk_update Quick / Bulk update
    search_filter Search & Filter
    seo SEO
    shipping_logistics Shipping & Logistics
    slideshows Slideshows
    smart_shopping Smart Shopping
    social_networks Social Networks
  • ‘version’ attribute. Номер версии для модуля, отображаемый в списке модулей. Это строка, так что вы можете использовать такие вариации, как «1.0b», «3.07 beta 3» или «0.94 (не для использования в пром варианте)».
  • ‘author’ attribute. Это отображается как есть в списке модулей PrestaShop.

Продолжим следующую строку в этом блоке кода:

$this->need_instance = 0;
$this->ps_versions_compliancy = array('min' => '1.5''max' => '1.6');
$this->bootstrap = true;

В этом разделе рассматриваются отношения с модулем и его средой (а именно PrestaShop):

  • need_instance. Указывает, следует ли загружать класс модуля при отображении страницы «Модули» в бэк-офисе. Если установлено значение 0, модуль не будет загружен и поэтому будет тратить меньше ресурсов на создание страницы «Модули». Если вашему модулю необходимо отобразить предупреждающее сообщение на странице «Модули», вы должны установить этот атрибут в 1.
  • ps_versions_compliancy. Указывает, какая версия PrestaShop совместима с этим модулем. В приведенном выше примере мы явно пишем, что этот модуль будет работать только с PrestaShop 1.5.x и другой основной версией.
  • bootstrap. Указывает, что файлы шаблонов модуля были созданы с использованием BootStrap PrestaShop 1.6 — и поэтому PrestaShop не должен пытаться обернуть шаблон с помощью вспомогательных тегов.

Затем мы вызываем метод конструктора из родительского класса PHP:

parent::__construct();

Это вызывает много действий PrestaShop, о которых вам не нужно знать в данный момент.
Вызов метода родительского constuctor должен выполняться после создания $this->name переменной и перед любым использованием $this->l() метода перевода.

Следующий раздел посвящен текстовым строкам, которые инкапсулированы в метод перевода PrestaShop, l():

$this->displayName = $this->l('My module');
$this->description = $this->l('Description of my module.');
$this->confirmUninstall = $this->l('Are you sure you want to uninstall?');
if (!Configuration::get('MYMODULE_NAME')) {
    $this->warning = $this->l('No name provided.');
}

Эти линии соответственно значат:

  • Имя модуля, которое будет отображаться в списке модулей бэк-офиса.
  • Описание модуля, которое будет отображаться в списке модулей бэк-офиса.
  • Сообщение, спрашивающее у администратора, действительно ли он хочет удалить модуль. Используется в коде установки.
  • Предупреждение о том, что модуль не имеет MYMODULE_NAME установленного значения в БД (этот последний пункт относится к нашему примеру, мы увидим позже).

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

Теперь перейдите в свой бэк-офис на странице «Модули»: модуль отображается в списке модулей, с его полной информацией — и без значка на данный момент.

Вы можете установить модуль, но он ничего не делает.

Когда вы нажимаете кнопку «Установить» для своего модуля, на экране появится окно модуля, в котором говорится, что ваш модуль не доверен.

Единственный способ сделать ваш модуль Trusted — это распространять его на рынке PrestaShop Addons (с уникальным идентификационным ключом) или стать партнером PrestaShop.
Другие доверенные модули являются родными.

Чтобы установить модуль, нажмите «Продолжить установку» на этом экране.

Сделаем install() и uninstall() методы

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

install() и uninstall() Методы позволяют контролировать, что происходит, когда администратор магазина устанавливает или удаляет модуль. Они должны быть включены в блок кода основного класса (в нашем примере — класс MyModule </ code>) - на том же уровне, что и метод конструктора.

Метод install()

Вот минимум для install() метода:

public function install()
{
  if (!parent::install()) {
    return false;
  }
  return true;
}

В этом первом и чрезвычайно упрощенном воплощении этот метод делает необходимый минимум: возвращает true, возвращаемый Module классом install() методом, который возвращает либо true если модуль правильно установлен, или false в противном случае. Как бы то ни было, если бы мы не создали этот метод, метод superclass был бы вызван в любом случае, что бы сделало бы конечный результат идентичным.
Тем не менее, мы должны упомянуть об этом методе, потому что он будет полезен, когда мы должны будем выполнить проверки и действия во время процесса установки модуля: создание таблиц SQL, копирование файлов, создание переменных конфигурации и т.д.

Так, например, как вы можете расширить install() метод для выполнения проверок при установке. В следующем примере во время установки мы выполним следующие задачи:

  • Убедились, что функция Multistore включена, и если да, установили текущий контекст для всех магазинов при этой установке PrestaShop.
  • Убедились, что установлен родительский класс модуля.
  • Убедились, что модуль можно подключить к leftColumn хуку.
  • Убедились, что модуль можно подключить к header хуку.
  • Создали MYMODULE_NAME настройки конфигурации, установив значение «my friend».
public function install()
{
  if (Shop::isFeatureActive()) {
    Shop::setContext(Shop::CONTEXT_ALL);
  }
  if (!parent::install() ||
    !$this->registerHook('leftColumn') ||
    !$this->registerHook('header') ||
    !Configuration::updateValue('MYMODULE_NAME''my friend')
  ) {
    return false;
  }
  return true;
}

Если какая-либо из строк в блоке тестирования ошибочна, метод возвращает false и установка не происходит.

uninstall() метод

Здесь минимум для uninstall() метода:

public function uninstall()
{
  if (!parent::uninstall()) {
    return false;
  }
  
  return true;
}

Основываясь на этом, мы хотим, чтобы uninstall() метод удалял данные, добавленные в базу данных во время установки ( MYMODULE_NAME конфигурационные установки). Этот метод будет выглядеть так:

public function uninstall()
{
  if (!parent::uninstall() ||
    !Configuration::deleteByName('MYMODULE_NAME')
  ) {
    return false;
  }
  return true;
}

Объект Configuration

Как видите, наши три блока кода (__construct()install() и uninstall()) используют новый объект, Configuration.

Это специальный объект PrestaShop, созданный для того, чтобы помочь разработчикам управлять настройками своего модуля. Он сохраняет эти настройки в базе данных PrestaShop без необходимости использования SQL-запросов. В частности, этот объект обрабатывает данные из ps_configuration таблицы БД.

Основные методы

До сих пор мы использовали три метода, к которым мы добавим четвертый в списке ниже:

  • Configuration::get('myVariable'): извлекает определенное значение из базы данных.
  • Configuration::getMultiple(array('myFirstVariable', 'mySecondVariable', 'myThirdVariable')): извлекает несколько значений из базы данных и возвращает массив PHP.
  • Configuration::updateValue('myVariable', $value): обновляет существующую переменную базы данных с новым значением. Если переменная еще не существует, она создает ее с этим значением.
  • Configuration::deleteByName('myVariable'): удаляет переменную базы данных.

Есть еще много таких, как getInt() или hasContext(), Но эти четыре — те, которые вы будете использовать больше всего.

Обратите внимание, что при использовании updateValue(), содержимое $value Может быть любым, будь то строка, число, сериализованный массив PHP или объект JSON. Пока вы правильно кодируете функцию обработки данных, все идет. Например, вот как обрабатывать массив PHP, используя Configuration объект:

// Storing a serialized array.
Configuration::updateValue('MYMODULE_SETTINGS', serialize(array(truetruefalse)));
// Retrieving the array.
$configuration_array = unserialize(Configuration::get('MYMODULE_SETTINGS'));

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

Multistore

По умолчанию все эти методы работают в пределах контекста текущего хранилища, независимо от того, использует ли PrestaShop многопользовательскую функцию или нет.

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

  • id_lang: Позволяет принудительно использовать язык, с которым вы хотите работать.
  • id_shop_group: Позволяет указать группу магазинов целевого хранилища.
  • id_shop: Позволяет указать идентификатор целевого хранилища.

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

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

Получение внешних значений из таблицы данных ps_configuration

Вы не ограничены своими собственными переменными: PrestaShop сохраняет все свои собственные настройки конфигурации в ps_configuration таблице. Есть буквально сотни настроек, и вы можете получить к ним доступ так же легко, как и доступ к своим собственным. Например:

  • Configuration::get('PS_LANG_DEFAULT'): Получает идентификатор для языка по умолчанию
  • Configuration::get('PS_TIMEZONE'): Получает имя текущего часового пояса, в стандартном формате TZ (see: http://en.wikipedia.org/wiki/List_of_tz_database_time_zones).
  • Configuration::get('PS_DISTANCE_UNIT'): Извлекает единицу расстояния по умолчанию («km» for kilometers, etc.).
  • Configuration::get('PS_SHOP_EMAIL'): Получает основной контактный адрес электронной почты.
  • Configuration::get('PS_NB_DAYS_NEW_PRODUCT'): Извлекает количество дней, в течение которых товар считается новым «New» by PrestaShop.

Покопайтесь в ps_configuration таблице, чтобы обнаружить множество других настроек!

Shop объект

Другие install()строки это:

if (Shop::isFeatureActive()) {
  Shop::setContext(Shop::CONTEXT_ALL);
}

Как было сказано ранее, здесь мы проверяем, что функция Multistore включена, и если да, ставим текущий контекст для всех магазинов при этой установке PrestaShop.

Объект «Shop» помогает вам управлять многопользовательской функцией. Мы не будем погружаться в особенности, но просто покажем два метода, которые используются в этом примере кода:

  • Shop::isFeatureActive(): Это просто проверяет, активна ли многопользовательская функция или нет, и в настоящее время активировано не менее двух хранилищ
  • Shop::setContext(Shop::CONTEXT_ALL): Это изменяет контекст, чтобы применить ближайшие изменения ко всем существующим хранилищам, а не только к текущему хранилищу.

Контекст более подробно объясняется в главе «Использование контекстного объекта» руководства для разработчиков.

Файл иконки

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

Файл значков должен соответствовать этим требованиям:

Установка модуля

Теперь, когда все основы находятся на месте, перезагрузите страницу «Модулей» бэк-офиса, в разделе «Функции фронт-офиса» вы должны найти свой модуль. Установите его (или удалите его, если он уже установлен).

Во время установки модуля PrestaShop автоматически создает небольшой config.xml файл в папке модуля, в котором хранится информация о конфигурации. Вы должны быть очень осторожны при редактировании вручную.
PrestaShop также добавляет строку в ps_module SQL таблицу во время установки модуля: