Хуки в PHP — расширение функций и контроллеров ядра

Общая информация

Многие функции и методы CS-Cart имеют специальные хуки.

Хуки позволяют модифицировать и расширять возможности платформы с помощью модуля.

С помощью хука можно:

  • Изменять входящие параметры функции
  • Дополнять логику работы функции
  • Влиять на результат работы функции
  • Выполнять собственную функцию при выполнении стандартной функции

Хуки расположены в функциях и методах ядра CS-Cart.

Общий принцип использования и работы с хуками:

  1. Определились с необходимыми изменениями стандартной функциональности
  2. Нашли подходящий хук, рядом с местом необходимых изменений, вам обязательно встретятся хуки в процессе п. 1
  3. Подключились к хуку своим модулем и внесли нужные изменения.

Доступно очень много хуков:

База хуков ядра (на английском).

Как выглядит и как использовать хук?

Хуки в PHP выглядят так:

fn_set_hook('hook_name', $param1, $param2, $param3, $param4);

Чтобы подключиться к хуку, вам необходимо:

  1. Инициализировать подключение к хуку.

    В своём модуле откройте или создайте файл 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',
    );
    
  2. Откройте или создайте файл 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);

Подключимся к последнему хуку и добавим нужную нам информацию с помощью модуля “Мои изменения”:

  1. Создадим файл app/addons/my_changes/init.php, чтобы инициализировать подключение к хуку.

    Добавим в него код:

    <?php
    
    if (!defined('BOOTSTRAP')) { die('Access denied'); }
    
    fn_register_hooks(
        'get_product_data_post'
    );
    
  2. Создадим функцию для подключения к хуку.

    Создадим файл 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';
    
        }
    
    }
    
  3. Включим модуль “Мои изменения”.

Всё.

Важно

Как проверить что оно работает?

Используйте функцию fn_print_r($product_data); до хука, после хука или внутри хука. Она распечатает на экран содержимое массива.

Как я могу использовать именно этот пример?

Создайте новую вкладку с SMARTY блоком для карточки товара. В данном SMARTY блоке вы можете использовать информацию из массива {$product_data}, в том числе вашу новую информацию, например, для каких либо условий.