CoderNotes - заметки программиста

Публикации  »  PHP
Бесплатный хостинг + SSL-сертификат

Зарегистрируйте домен и получите 2 месяца бесплатного хостинга и SSL-сертификат на 1 год в подарок

Подробнее
GeekBrains

Написание модификатора для OpenCart

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

Изначально, история появления модификаторов началась с vQmod в версии 1.5 opencart-а, а затем его усовершенствовали и преобразовали в OCMOD, который стал постоянным стандартным функционалом OpenCart-а начиная с 2.1 версии. Итак, попробую дать определение понятию модификатор в OpenCart.

Модификатор в OpenCart - это модуль представляющий собой XML-файл, содержащий набор инструкций о том в каких оригинальных файлах OpenCart-а, в каких местах, какой код нужно заменить, добавить или удалить. OpenCart при выполнении инструкций xml-файла создает копии исходных файлов в специальную директорию (кэш модификаторов) и вносит изменения в этих копиях. В результате, при работе сайта используются измененные файлы, а не оригиналы.

Модификатор OCMOD может быть как самостоятельным модулем, изменяющим или дополняющим стандартный функционал, так и входить в состав полноценного модуля с дополнительными php, twig и другими файлами. О написании полного модуля читайте в предыдущей статье.

Имена файлов и директории

Имя файла модификатора - должно быть задано в соответствии с шаблоном <имя_файла>.ocmod.xml , где вместо <имя_файла> вы пишите свое название. Таким образом имя файла всегда должно заканчиваться ".ocmod.xml", иначе система не "увидит" модификатор и проигнорирует его.
Исключение: когда предполагается использовать модификатор в составе полного модуля в виде архива - в этом случае имя файла-модификатора в архиве должно быть install.xml.

Расположение файла модификатора - папка system в корне сайта. Файл-модификатор так же можно загрузить в базу данных на постоянное размещение с помощью загрузки расширений. Тем не менее, во время разработки удобнее записать файл в system и редактировать его там, проверяя какой получается результат, а когда разработка завершена, модификатор загружают как модуль в базу данных.

Расположение кэша модификаторов - папка /storage/modification с такой же структурой, как корень сайта. Т.е. если вы сделали модификатор для файла /admin/controller/catalog/product.php то его измененная копия будет находится в /storage/modification/admin/controller/catalog/product.php. В нем вы и увидите те изменения которые производит ваш модификатор.

Расположение логов - папка /storage/logs В ней есть 2 основных лог-фала: ocmod.log - который показывает как обрабатывались файлы-модификаторы, в какой последовательности и как выполнялись инструкции и лог-файл error.log - который содержит ошибки, произошедшие при преобразовании.

Обновление кэша модификаторов

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

Обновление кэша модификаторов

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

Синтаксис модификатора OCMOD

Файл модификатора OCMOD должен содержать общую описательную часть и инструкции по изменению файлов. Начну разбор синтаксиса с простого примера, который добавляет слово "Test" в шапке администраторского раздела:

<?xml version="1.0" encoding="utf-8"?>
<modification>
  <name>Test</name>                <!-- Название модификатора -->
  <code>Test</code>                <!-- Уникальный код модификатора -->
  <version>1.0</version>           <!-- Версия -->
  <author>Test</author>            <!-- Автор -->
  <link>http://www.test.ru</link>  <!-- Сайт разработчика -->

<file path="admin/view/template/common/header.twig">  <!-- Какой файл будет модифицироваться -->
  <operation>
    <search>                           <!-- Найти код в файле -->
      <![CDATA[
        <div class="container-fluid">
      ]]>
    </search>
    <add position="after">             <!-- Добавление модификации (после найденного кода) -->
      <![CDATA[
        <p>Тест</p>
      ]]>
    </add>
  </operation>
</file>

</modification>

Итак, данный пример модификатора меняет файл header.twig. Он находит строчку "<div class="container-fluid">" и после нее добавляет "<p>Тест</p>".

В одном xml-файле может быть любое количество секций <file> и соответственно, мы можем менять множество файлов одним модификатором.

Разберем каждый тег модификатора и его возможности поподробнее.

File

Указывает в каком файле или файлах нужно внести изменения. Обязательный атрибут path содержит путь до изменяемого файла. Может указывать на один файл или на несколько. Для указания нескольких файлов используется символ "|". Например, внести изменения в action.php и в loader.php

<file path="system/engine/action.php|system/engine/loader.php">

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

<file path="system/engine/{action,loader}.php">

Так же можно использовать символы "*" и "?", чтобы указать путь по "маске". Часто бывает полезно для модификации файлов-шаблонов.

<file path="catalog/view/theme/*/template/product/product.twig">

Т.к. мы не знаем заранее, какие именно темы установлены в OpenCart, мы указали "*" после "theme" и тогда будут модифицироваться все product.twig во всех темах.

Operation

Указывает начало секции производимой модификации. Внутри File секций <operation> может быть несколько. Т.е мы можем делать сразу несколько изменений в одном файле. Тег Operation может иметь необязательный атрибут error, который может принимать значения:

  • skip - в случае ошибки пропустить текущую секцию <operation> и перейти к следующей <operation>
  • log (по-умолчанию) - в случае ошибки пропустить всю секцию <file> и перейти к следующему <file>
  • abort - в случае ошибки прервать все модификации в xml-файле

Например, найти в файле header.twig текст "navbar-rightnav" и если его нет, тогда пропустить и перейти к следующей операции и найти "navbar-right":

<file path="admin/view/template/common/header.twig">
  <operation error="skip">
    <search><![CDATA[ navbar-rightnav ]]></search>
    <add position="after"><![CDATA[
       <li>Test1</li>
    ]]></add>
  </operation>
  <operation error="skip">
    <search><![CDATA[ navbar-right ]]></search>
    <add position="after"><![CDATA[
       <li>Test2</li>
    ]]></add>
  </operation>
</file>

Если не указывать атрибут error="skip", тогда на первом поиске текста "navbar-rightnav" вся секция <file> была бы прервана и проигнорирована.

Search

Указывает какой текст необходимо найти в текущей операции. Есть несколько правил использования тега:

  • Тег Search может быть использован только 1 раз внутри секции Operation.
  • Поиск можно делать только 1 строки целиком или части строки (нельзя искать несколько строк одновременно).
  • Искомый текст необходимо размещать между <![CDATA[ и ]]>.
  • Пробелы и переносы строки до искомого текста и после искомого текста игнорируются (поэтому искомый текст можно написать или сразу после CDATA или с новой строки после CDATA, как больше нравится), если только не указан атрибут trim="false" (описание ниже).
  • Изменения выполняются над всеми найденными в файле строками (или частями строк), если только не указан атрибут index (описание ниже).

Специальные теги <![CDATA[ и ]]> - используются в xml-файлах для указания любых символьных данных, что означает, что между ними может находиться какой угодно текст, содержащий скобки, значи больше, меньше и другие, в т.ч. и php-код, html-код и т.д.

Для более точного определения места внесения изменений в теге Search могут использоваться атрибуты:

  • index - указывает в каком по-порядку найденном тексте сделать изменения. Т.е. если в файле искомый текст встречается несколько раз, тогда index позволяет указать номер найденного по порядку текста (0 - первый найденный текст, 1 - второй и т.д.) Можно так же указать несколько номеров через запятую.
  • trim - указывает игнорировать (true) или нет (false) пробелы и переносы строк до и после искомого текста.
  • regex - если установлено значении true, значит искомый текст представляет собой регулярное выражение для поиска.

Пример: добавить пункт меню "ТЕСТ".

  <file path="admin/controller/common/column_left.php">
    <operation>
      <search index="0" trim="true"><![CDATA[
        $data['menus'][] = array(
      ]]></search>
      <add position="before"><![CDATA[
        $data['menus'][] = array(
          'id'       => 'menu-test',
          'icon'     => 'fa-play',
          'name'     => 'TEST',
          'href'     => '#'
        );
      ]]></add>
    </operation>
  </file>

В данном примере находим первое "$data['menus'][] = array(" и перед ним добавляем свой код.

Add

Тег содержит текст, который будет добавлен до/после найденного или на который будет заменен найденный текст.

Так же как и тег Search, должен содержать <![CDATA[ и ]]> между которыми пишется текст кода, который будет добавляться/заменяться.

В теге Add могут использоваться атрибуты:

  • position - может принимать значения:
    • replace (по умолчанию) - замена найденного текста
    • before - добавить текст перед найденным текстом
    • after - добавить текст после найденного текста
  • offset - означает смещение относительно найденного текста на указанное количество строк. Если position="before", тогда смещение будет вверх от найденного текста, если position="after" или position="replace", тогда смещение будет вниз от найденного текста.
  • trim - указывает игнорировать (true) или нет (false) пробелы и переносы строк до и после искомого текста.

Пример: Добавить слово "Test" в админ-панели в списке товаров.

  <file path="admin/view/template/catalog/product_list.twig">
    <operation>
      <search index="1" trim="true"><![CDATA[
        panel-body
      ]]></search>
      <add position="after" offset="1" trim="true"><![CDATA[
        <p>Test</p>
      ]]></add>
    </operation>
  </file>

Находим 2-й по порядку текст "panel-body" (первый - это фильтр справа от товаров, а второй - сам список товаров) и затем добавляем код "<p>Test</p>" на одну строку ниже найденного текста.

Обратите внимание: position="before" и position="after" добавляют код не в середину строки, где было найдено "panel-body", а в следующую (или предыдущую) строку. Если нужно сделать добавление в середине строки, следует использовать position="replace" и повторив тот же самый найденный текст мы добавляем свой.

Пример: Добавить текст перед версией opencart-а в футере

  <file path="admin/view/template/common/footer.twig">
    <operation>
      <search><![CDATA[
        {{ text_version }}
      ]]></search>
      <add position="replace" trim="true"><![CDATA[
        <p>Test</p>{{ text_version }}
      ]]></add>
    </operation>
  </file>

Создав модификатор OCMOD в OpenCart-е можно изменить практически всю систему, расширить ее возможности, при этом исходные файлы не будут затронуты и вы можете всё вернуть в первоначальный вид, просто убрав файл-модификатор (или отключив его, если он был загружен в базу данных).

Категория: PHP

Книги по теме:

Посмотреть все книги по программированию

Комментарии к статье:

19.04.19   Гость А если хочется заменить не 3 буквы на 5 букв, а к примеру заменить родной метод на свой, то как это идеологически правильно сделать?
19.04.19   Гость Полагаю, можно просто переименовать оригинальный метод во что-то вроде method_original или method_old и добавить свой.
06.06.19   Гость +++
30.12.19   Александр Спасибо за материал !
23.03.20   Дмитрий <code>Test</code> <!-- Уникальный код модификатора -->

Зачем это нужно?
23.03.20   Гость Это код модификатора, он в базу данных заносится в таблицу oc_modification.
03.06.20   Леонид Не совсем понятно, куда необходимо положить файл в случае, если я хочу его интегрировать в составе модуля. Вот я написал модуль... Ок... Куда мне подложить модификатор, если я хочу, чтобы в составе модуля загрузился еще и модификатор?
03.06.20   Гость В корне архива с модулем, не забыв его переименовать в install.xml
11.07.21   Гость А если необходимо удалить 3-ри строки одновременно?
-------------------- пример ------------------------
{% if not product.quantity_indicator %}
<div class="product-data__item stock"><span>{{ text_stock }}</span></div>
{% endif %}
25.08.22   Евгений Статья супер, с помощью её Я изменил модуль от OpenCart 2.x для работы в OpenCart 3.x
Спасибо автору!
03.12.22   Гость А как сделать невидимым определенный код?
03.12.22   Гость или удалить
18.01.23   Гость "А как сделать невидимым определенный код?"

Как вариант закомментировать (в TWIG: {# тут спрятанный код #} , в PHP: /*тут спрятанный код */ )
16.04.23   Гость нЯюц
20.05.23   инкогнито Спасибо за усилия при написании! :)

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

Комментарии отключены.