OpenCart 3. Написание модификаторов

OpenCart – cms, написанная на PHP и реализующая MVC шаблон проектирования. Специализирован данный движок под создание интернет-магазинов. С коробки вы получаете голый интернет-магазин: набор опций для продажи товаров без всего того, в чем нуждается современный сайт – социальные ссылки, метрика и т.д. Но все это исправимо по средству большого количества модулей…

Немного о модулях

OpenCart – это расширяемый модулями движок для сайтов. Каждый модуль это набот файлов котроллеров, моделей, шаблонов и локализации. Также, в состав модуля входят модификаторы – install.php, install.sql и modificator-name.ocmod.xml(два первых упразднены в версии 3)ю Файловая структура модуля выглядит следующим образом

module-name.ocmod.zip
    upload
        файлы модуля
    modificator-name.ocmod.xml(необязательный)

Я не причастен к разработке этого движка(во всяком случаи – пока что), но думаю, что install.php и install.sql упразднили по причине того, что их функционал с успехом можно запихнуть в метод install() контроллера модуля – который есть”обязательной программой” для любого модуля.

Модификатор это?

Как я уже сказал – OpenCart расширяемая модулями система, однако модули(чаще всего) требуют внедрения кастомного кода в существующие файлы. С этой целью была разработана система модификации VQMod, которая эволюционировала с второйверсии в OCMod. В целом, смысл таков: при применении файла-модификатора происходит чтение указанного файла в строку, применение модификаций и сохранение этой строки, как нового файла(по пути system/modification).

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

Правила написания инструкций

Прежде всего – модификатор это XML файл, а все подобные файлы начинаются с представления

<?xml version="1.0" encoding="utf-8"?>

далее указываем системе что это именно модификатор – ставим парный тег modification

<modification>
    
</modification>

Первое, что здесь нужно указать это информация об авторе модификации и ее идентификация в системе

<name>Название модификатора</name>
<version>1.0</version>
<code>ID модификатора</code>
<author>Имя автора модификатора</author>
<link>ссылка на сайт автора</link>

После этой, “представительской” информации, следуют сами инструкции по тому, какой файл читать, что искать и что с этим делать.

В общем – указатель на файл – парный тег file

<file path="путь к файлу">
    
</file>

понятно, что атрибут path содержит путь к модифицируемому файлу. Следующий шаг – открытие парного тега operation. Можно было б решить, что это бессмысленный тег, однако – каждая замена в пределах одного файла – отдельная операция. А замен в одном файле может быть много

<operation error="skip|abort">
    
</operation>

не обязательный атрибут error указывает на действие которое нужно выполнить при не нахождении искомого: skip пропустить текущую операцию, abort – прервать модификацию вовсе. Тег search указывает на искомую строку/регулярное выражение

<search trim="true|flase" index="0|1|2...">
    <![CDATA[строка/регулярка]]>
</search>

атрибут trim(опционален) отвечает за игнорирование пробелов, index – также необязателен, указывает на номер вхождения(если их несколько).

И наконец, сама строка для внедрения

<add position="before|after|replace" trim="true|flase" offset="0|1|2..">
    <![CDATA[строка]]>
</add>

здесь trim тоже что и ранее, position это действие: вставить до, после, или вовсе заменить; offset – смещение по строкам от вхождения.

Полный файл модификатора выглядит так

<?xml version="1.0" encoding="utf-8"?>
<modification>
    <file path="путь к файлу 1">
        <operation error="skip|abort">
            <search trim="true|flase" index="0|1|2...">
                <![CDATA[строка/регулярка]]>
            </search>
            <add position="before|after|replace" trim="true|flase" offset="0|1|2..">
                <![CDATA[строка]]>
            </add>
        </operation>
        ...
    </file>
    ...
</modification>

И еще, малость не забыл – если есть модификатор, но нет модуля – структура zip-архива все равно должна быть как у модуля, но папка upload пустая.