Opencart - Установка И Удаление Расширений С Помощью Хуков

Тема в разделе "Общие вопросы", создана пользователем admin, 11 май 2018.

  1. TopicStarter Overlay
    Offline

    admin Команда форума Администратор

    Сообщения:
    2.605
    Симпатии:
    114.762
    Репутация:
    180
    Если вы разработчик модулей, то вам часто в ежедневной работе приходится создавать кастомные схемы в OpenCart. Такая возможность уже предусмотрена, как и в других фреймворках, в виде различных хуков в архитектуре модулей. Сегодня мы поговорим о том, как происходит в OpenCart установка расширений, и какую роль играют в этом хуки.

    Прежде чем перейти к хукам, давайте познакомимся с концепцией расширений в OpenCart. Если смотреть поверхностно, то это расширения в OpenCart, позволяющие расширить функциональность OpenCart. Устанавливая расширение, вы добавляете функции в front end часть магазина, будь то простая галерея изображений или какая-то забавная функция drag-and-drop.

    По предоставляемой функциональности расширения делятся на логические группы. Например, расширение payment добавляет новые способы оплаты на страницу оформления заказа на front end. Кроме того, данное расширение защищает от мошенников и позволяет определять спам в магазине. Перейдите на back end и откройте список в меню Extensions – это список расширений различного типа, поддерживаемых в OpenCart.

    Вы удивитесь, но module также является видом расширения в OpenCart. Все расширения построены по общему принципу экосистемы OpenCart. Хуки позволяют выполнять определенные действия на основе определенных событий. Это может быть, например, запуск хука установки во время активации модуля или очистка от мусора во время удаления.

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

    Код, представленный в уроке, относится к последней версии OpenCart. На момент написания это стабильная версия 2.1.0.2.

    Жизненный цикл хука установки
    В этом разделе мы узнаем, зачем нужен хук install. Откройте файл admin/controller/extension/module.php в текстовом редакторе и найдите метод install. Метод должен выглядеть примерно так:

    Код:
    <?php
      ...
      public function install() {
    $this->load->language('extension/module');
    $this->document->setTitle($this->language->get('heading_title'));
    $this->load->model('extension/extension');
    $this->load->model('extension/module');
    if ($this->validate()) {
    $this->model_extension_extension->install('module', $this->request->get['extension']);
    $this->load->model('user/user_group');
    $this->model_user_user_group->addPermission($this->user->getGroupId(), 'access', 'module/' . $this->request->get['extension']);
    $this->model_user_user_group->addPermission($this->user->getGroupId(), 'modify', 'module/' . $this->request->get['extension']);
    // Call install method if it exists
    $this->load->controller('module/' . $this->request->get['extension'] . '/install');
    $this->session->data['success'] = $this->language->get('text_success');
    $this->response->redirect($this->url->link('extension/module', 'token=' . $this->session->data['token'], 'SSL'));
    }
    $this->getList();
      }
      ...
    ?>
    Это общий хук install для модуля, который будет вызываться при любой попытке установить любой модуль через back end. Разберем важные части метода.

    Сперва метод загружает файлы модели, необходимые для последующих действий. Метод $this->model_extension_extension->install обеспечивает добавление записи в базу данных для определенного модуля.

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

    Далее вызывается метод install устанавливаемого модуля. Не путайте с методом install, в котором мы находимся прямо сейчас. Будет вызван метод install конкретного модуля, если метод существует.

    Например, если попробовать установить модуль Log In with PayPal, будет вызван метод install, определенный в файле admin/controller/module/pp_login.php, как показано ниже.

    Код:
    <?php
      ...
      public function install() {
    $this->load->model('extension/event');
    $this->model_extension_event->addEvent('pp_login', 'post.customer.logout', 'module/pp_login/logout');
      }
      ...
    ?>
    Начиная с OpenCart 2.x, было добавлено несколько потрясающих функций. Одна из них event-observer. С ее помощью можно добавлять события, относящиеся к определенным модулям, а другие модули могут установить обозреватели, которые будут ждать эти события и при их срабатывании запускать некий код. Именно это продемонстрировано в методе install выше. Метод добавляет кастомное событие post.customer.logout!

    С модулем Log In with PayPal все просто, но иногда если необходимо создать кастомную схему или что-то похожее, нужно больше. Давайте найдем метод install из расширения оплаты PayPal Express Checkout. Откройте файл admin/controller/payment/pp_express.php.

    Код:
    <?php
      ...
      public function install() {
    $this->load->model('payment/pp_express');
    $this->model_payment_pp_express->install();
      }
      ...
    ?>
    Сначала метод загружает соответствующий файл модели и с его помощью вызывает метод install модели. Правило №1 – если хотите манипулировать схемой, код писать необходимо в методе install модели, а не напрямую в метод install контроллера.

    Теперь давайте быстро взглянем на метод install файла модели admin/model/payment/pp_express.php.

    Код:
    <?php
      ...
      public function install() {
    $this->db->query("
    CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "paypal_order` (
    `paypal_order_id` int(11) NOT NULL AUTO_INCREMENT,
    `order_id` int(11) NOT NULL,
    `date_added` DATETIME NOT NULL,
    `date_modified` DATETIME NOT NULL,
    `capture_status` ENUM('Complete','NotComplete') DEFAULT NULL,
    `currency_code` CHAR(3) NOT NULL,
    `authorization_id` VARCHAR(30) NOT NULL,
    `total` DECIMAL( 10, 2 ) NOT NULL,
    PRIMARY KEY (`paypal_order_id`)
    ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
    $this->db->query("
    CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "paypal_order_transaction` (
    `paypal_order_transaction_id` int(11) NOT NULL AUTO_INCREMENT,
    `paypal_order_id` int(11) NOT NULL,
    `transaction_id` CHAR(20) NOT NULL,
    `parent_transaction_id` CHAR(20) NOT NULL,
    `date_added` DATETIME NOT NULL,
    `note` VARCHAR(255) NOT NULL,
    `msgsubid` CHAR(38) NOT NULL,
    `receipt_id` CHAR(20) NOT NULL,
    `payment_type` ENUM('none','echeck','instant', 'refund', 'void') DEFAULT NULL,
    `payment_status` CHAR(20) NOT NULL,
    `pending_reason` CHAR(50) NOT NULL,
    `transaction_entity` CHAR(50) NOT NULL,
    `amount` DECIMAL( 10, 2 ) NOT NULL,
    `debug_data` TEXT NOT NULL,
    `call_data` TEXT NOT NULL,
    PRIMARY KEY (`paypal_order_transaction_id`)
    ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
      }
      ...
    ?>
    Наконец, есть что рассказать! Как видите, здесь с помощью API баз данных OpenCart создается несколько кастомных MySQL таблиц. Таким образом можно применять изменения к базе данных через метод install модели.

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

    Жизненный цикл хука удаления
    В отличие от предыдущего раздела, в этом мы разберем хук uninstall. Пойдем аналогичным процессом, как для метода install из предыдущего раздела. Откройте файл admin/controller/extension/module.php и найдите хук uninstall.

    Код:
    <?php
      ...
      public function uninstall() {
    $this->load->language('extension/module');
    $this->document->setTitle($this->language->get('heading_title'));
    $this->load->model('extension/extension');
    $this->load->model('extension/module');
    if ($this->validate()) {
    $this->model_extension_extension->uninstall('module', $this->request->get['extension']);
    $this->model_extension_module->deleteModulesByCode($this->request->get['extension']);
    $this->load->model('setting/setting');
    $this->model_setting_setting->deleteSetting($this->request->get['extension']);
    // Call uninstall method if it exists
    $this->load->controller('module/' . $this->request->get['extension'] . '/uninstall');
    $this->session->data['success'] = $this->language->get('text_success');
    $this->response->redirect($this->url->link('extension/module', 'token=' . $this->session->data['token'], 'SSL'));
    }
    $this->getList();
      }
      ...
    ?>
    Код должен уже быть знаком, так как по большей части он шаблонный. Важно начать с вызова метода uninstall, который удаляет запись текущего удаляемого расширения из MySQL таблицы extension.

    Далее вызывается deleteModulesByCode, который удаляет модулю, относящиеся к расширению. Этот метод реализован только для этого типа module расширения. В других расширениях типа payment, shipping, fraud и т.д. вы его не найдете.

    Так сделано потому, что вы можете продублировать все модули для создания нескольких объектов. Например, можно отображать разные модули banner на разных страницах. С другой стороны, нет смысла дублировать расширения другого вида. Как пример, для расширения PayPal на front end доступен только один объект.

    Далее вызывается метод deleteSetting , который удаляет переменные настроек модуля. В конце вызывается метод uninstall удаляемого модуля.

    Откроем файл admin/controller/module/pp_login.php, посмотрим как выглядит метод uninstall.

    Код:
    <?php
      ...
      public function uninstall() {
    $this->load->model('extension/event');
    $this->model_extension_event->deleteEvent('pp_login');
      }
      ...
    ?>
    Просто, так ведь? Метод просто отменяет действия метода install модуля Log In with PayPal. Помните, мы создали новое событие post.customer.logout во время установки. Его-то нам и нужно удалить, чтобы не оставить никакого мусора от модуля.

    Давайте посмотрим на метод uninstall расширения PayPal Express Checkout, мы же прошлись по методу install в предыдущем разделе. Найдите следующий код в файле admin/controller/payment/pp_express.php.

    Код:
    <?php
      ...
      public function uninstall() {
    $this->load->model('payment/pp_express');
    $this->model_payment_pp_express->uninstall();
      }
      ...
    ?>
    Все довольно ожидаемо – метод загружает модель и вызывает метод uninstall. Поэтому давайте откроем файл admin/model/payment/pp_express.php и взглянем на метод uninstall там.

    Код:
    <?php
      ...
      public function uninstall() {
    $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "paypal_order_transaction`;");
    $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "paypal_order`;");
      }
      ...
    ?>
    Мы просто удаляем MySQL таблицы, созданные ранее. Нам ведь не нужны эти вопросы «как ты мог оставить этот мусор?».

    Надеюсь, мне удалось понятно рассказать про жизненные циклы хуков install и uninstall в OpenCart. В следующем и последнем разделе еще раз вспомним концепции, изученные сегодня в простом, но работающем кастомном модуле. О таких вещах полезно помнить.

    Создание/удаление кастомной схемы через хуки install/uninstall
    В этом разделе мы создадим админский модуль demo, который будет создавать новую схему во время установки и удалять ее во время удаления.

    Сначала создайте языковой файл, чтобы модуль подтянулся в back end. Создайте файл admin/language/english/module/demo.php со следующим кодом.

    Код:
    <?php
    // Heading
    $_['heading_title'] = 'Demo Module';
    Далее необходимо создать файл модели с реальным и интересным кодом. Файл модели должен быть в admin/model/module/demo.php. Он создает MySQL таблицу demo в методе install и удаляет таблицу в методе uninstall.

    Код:
    <?php
    class ModelModuleDemo extends Model {
      public function install() {
    $this->db->query("
    CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "demo` (
    `demo_id` int(11) NOT NULL AUTO_INCREMENT,
    `name` VARCHAR(100) NOT NULL,
    PRIMARY KEY (`demo_id`)
    ) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci;");
      }
      public function uninstall() {
    $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "demo`;");
      }
    }
    Создайте контроллер admin/controller/module/demo.php со следующим кодом.

    Код:
    <?php
    class ControllerModuleDemo extends Controller {
      public function install() {
    $this->load->model('module/demo');
    $this->model_module_demo->install();
      }
      public function uninstall() {
    $this->load->model('module/demo');
    $this->model_module_demo->uninstall();
      }
    }
    Все просто – загружается модель, вызываются соответствующие методы в зависимости от выполняемого действия.

    Попробуйте сами. Модуль Demo Module должен отобразиться в Extensions > Modules. Установите его, после чего в back end создастся MySQL таблица demo. Не забудьте удалить эту таблицу.

    Заключение
    Сегодня мы обсудили важный аспект процесс установки OpenCart – хуки install и uninstall. Мы подробно разобрали устройство хуков, а в последней части статьи создали простой модуль для подтверждения работы концепции.