Хуки в PHP — расширение функций и контроллеров ядра¶
Содержание
Общая информация¶
Многие функции и методы CS-Cart имеют специальные хуки.
Хуки позволяют модифицировать и расширять возможности платформы с помощью модуля.
С помощью хука можно:
- Изменять входящие параметры функции
- Дополнять логику работы функции
- Влиять на результат работы функции
- Выполнять собственную функцию при выполнении стандартной функции
Хуки расположены в функциях и методах ядра CS-Cart.
Общий принцип использования и работы с хуками:
- Определились с необходимыми изменениями стандартной функциональности
- Нашли подходящий хук, рядом с местом необходимых изменений, вам обязательно встретятся хуки в процессе п. 1
- Подключились к хуку своим модулем и внесли нужные изменения.
Доступно очень много хуков:
Как выглядит и как использовать хук?¶
Хуки в PHP выглядят так:
fn_set_hook('hook_name', $param1, $param2, $param3, $param4);
Чтобы подключиться к хуку, вам необходимо:
Инициализировать подключение к хуку.
В своём модуле откройте или создайте файл
app/addons/[id_модуля]/init.php
.В данный файл добавьте функцию:
<?php if (!defined('BOOTSTRAP')) { die('Access denied'); } fn_register_hooks( 'hook_name' );
Если используте несколько хуков, передавайте названия хуков через запятую:
fn_register_hooks( 'hook_name', 'hook_name_2', 'hook_name_3', );
Откройте или создайте файл
app/addons/[id_модуля]/func.php
.Создайте функцию, которая будет выполняться в хуке.
Функция должна иметь название вида:
fn_[id_модуля]_[название_хука]($[параметры_хука_через_запятую])
В функции будут доступны все параметры передаваемые в хук.
Чтобы функция могла влиять на параметры (изменять снаружи), их необходимо передавать как ссылки (
&$param
)// Создаём функцию, которая подключится к хуку. function fn_[id_модуля]_hook_name(&$param1, &$param2, &$param3, &$param4) { // Изменяем нужный параметр $param1 = 'новое значение'; }
Живой пример¶
Предположим, что нам нужно добавить какую то новую информацию о товаре, если товара нет на складе.
Функция fn_get_product_data()
получает информацию о товаре для карточки товара (и много ещё где используется). Данная функция находится в файле app/functions/fn.catalog.php
.
Она имеет 3 хука:
// В начале функции, все входящие параметры доступны.
fn_set_hook('get_product_data_pre', $product_id, $auth, $lang_code, $field_list, $get_add_pairs, $get_main_pair, $get_taxes, $get_qty_discounts, $preview, $features, $skip_company_condition);
// В середине функции, перед SQL запросом, чтобы можно было расширить SQL запрос.
fn_set_hook('get_product_data', $product_id, $field_list, $join, $auth, $lang_code, $condition);
// В конце, доступен результат работы функции — массив с данными о товара $product_data
fn_set_hook('get_product_data_post', $product_data, $auth, $preview, $lang_code);
Подключимся к последнему хуку и добавим нужную нам информацию с помощью модуля “Мои изменения”:
Создадим файл
app/addons/my_changes/init.php
, чтобы инициализировать подключение к хуку.Добавим в него код:
<?php if (!defined('BOOTSTRAP')) { die('Access denied'); } fn_register_hooks( 'get_product_data_post' );
Создадим функцию для подключения к хуку.
Создадим файл
app/addons/my_changes/func.php
Добавим новую функцию, которая сработает в хуке:
<?php if (!defined('BOOTSTRAP')) { die('Access denied'); } // Создаём функцию, которая подключится к хуку. function fn_my_changes_get_product_data_post(&$product_data, $auth, $preview, $lang_code) { if ($product_data <= 0) { $product_data['new_info'] = 'Bam Bam Bigelow'; } }
Включим модуль “Мои изменения”.
Всё.
Важно
Как проверить что оно работает?
Используйте функцию fn_print_r($product_data);
до хука, после хука или внутри хука. Она распечатает на экран содержимое массива.
Как я могу использовать именно этот пример?
Создайте новую вкладку с SMARTY блоком для карточки товара. В данном SMARTY блоке вы можете использовать информацию из массива {$product_data}, в том числе вашу новую информацию, например, для каких либо условий.
Разграничение редакций¶
Функционал хуков ядра необходим для правильной реализации архитектуры различных редакций. Сейчас редакций две: ULTIMATE
(CS-Cart) и MULTIVENDOR
.
Хуки, которыми будут расширяться редакции, необходимы, чтобы избежать услвоий по типу:
if (PRODUCT_EDITION == 'MVE') {
do_something
Также хуки позволят при сборке релизов исключать лишний код. Например при сборке ULTIMATE
-редакции нам не нужны функции, которые относятся к Multi-Vendor. Подключаемые файлы располагаются там же где и остальные функции. Сейчас редакций две, поэтому файла только два:
app
└── functions
├── fn.multivendor.php
└── fn.ultimate.php
Пример: допустим, у нас в ядре есть функция fn_place_order
, в которой регистрируется хук:
fn_set_hook('place_order', $cart, $allow);
Нам нужно расширить данную функцию в Multi-Vendor. Таким образом, в файле /app/functions/fn.multivendor.php создаем функцию:
function fn_mve_place_order(...) {
..
do_somtehing
..
//
fn_set_hook('mve_pre_place_order', $cart, $allow);
}
Код для определенной редакции¶
Для того, чтобы писать код, который должнен появиться только в определенной редакции, нужно использовать конструкцию {if "EDITION"|fn_allowed_for}{/if}
, где EDITION
заменяется на ULTIMATE
или MULTIVENDOR
:
{if "ULTIMATE,MULTIVENDOR"|fn_allowed_for}
Some code
{/if}
Или же использовать отрицание:
{if !"MULTIVENDOR"|fn_allowed_for}
Some code
{/if}
Первая часть кода означает, что этот код появится в перечисленных редакциях, вторая же часть — что код НЕ появится в этих редакциях
Хуки в PHP скриптах¶
Версионные теги так же используют фукнцию fn_allowed_for
:
if (fn_allowed_for('ULTIMATE')) {
... some code ...
}