» » Управление своими модулями для CMS c использованием composer

 

Управление своими модулями для CMS c использованием composer

Автор: admin от 8-11-2018, 17:05, посмотрело: 26

Здравствуйте, друзья! Появление популярного менеджера зависимостей в PHP — является одним из важнейших событий в жизни PHP-сообщества. Composer разделил время на "до" — когда наши самописные библиотеки лежали в zip-архивах или просто разбросаны по папкам и копировались "ручками", лишь в единичных случаях, использовался git или PEAR, и "после" — когда мы начали использовать composer. Но что делать если вы работаете с определенной CMS, а она не "знает" что такое composer?

статью.



После того как Вы создали свой модуль (для примера пока пустой) и разместили его код на GitHub, Вам необходимо зарегистрировать модуль на сайте packagist.org. Packagist предложит Вам настроить хуки GitHub так, чтобы при попадании изменений в репозиторий, на packagist.org обновлялись сведения о модуле.



Часть вторая. Установка. Самое интересное тут



Вы, точно, очень хорошо знакомы с той CMS с которой работаете, а значит знаете все тонкости установки модулей в ней. В 1С-Битрикс установка модулей проходит в 2 этапа:




  • размещение исходного кода модуля в определенной директории /local/modules/.

  • Вызов функции RegisterModule(.). Как правило все действия установки модуля описываются в методе DoInstall класса, отвечающего за установку и удаления модуля. /local/modules/./install/index.php



Часть два один. Прячем пакеты в надежное место



По-умолчанию composer устанавливает все пакеты в каталог /vendor если композер размещен в корне проекта, и не выполняет никаких хуков в Ваших пакетах. Но это легко изменить.



Нам необходимо в корне проекта разместить файл composer.json:



{
    "name": "sites/<sitename>",
    "description": "<SiteName>",
    "authors": [
        {
            "name": "<developerName>",
            "email": "<developerEmail>"
        }
    ],
    "minimum-stability": "dev",
    "require": {},
    "config": {
        "vendor-dir": "local/vendor"
    }
}

В 1C-Битрикс код, написанный разработчиками, обычно, размещают в директории /local. Поэтому мы перенесли туда папку vendor записью в секции config. Теперь все пакеты сторонних разработчиков будут размещаться там. Но наши модули необходимо размещать в директории /local/modules/., что-же делать?


Часть два два. Плагин установки модулей


У composer есть несколько типов пакетов, один из которых composer-plugin — это расширения для самого композера. Чтобы наши модули устанавливались так, как этого требует CMS нам нужно написать свой плагин. Для этого создаем отдельный проект и в его корне размещаем composer.json:


{
  "name": "<my_name>/installer",
  "description": "Plugin for custom installing",
  "type": "composer-plugin",
  "license": "MIT",
  "homepage": "<link to homepage github>",
  "version": "0.0.1",
  "authors": [
    {
      "name": "<name>",
      "email": "<email>"
    }
  ],
  "require": {
    "composer-plugin-api": "^1.0"
  },
  "require-dev": {
    "composer/composer": "^1.0"
  },
  "autoload": {
    "psr-4": { "<my_name>installer": "" }
  },
  "extra": {
    "class": "<my_name>installerPlugin"
  }
}

В этом файле есть 3 ключевых момента:



  • "type": "composer-plugin" — говорит композеру, что это плагин

  • autoload — описывает правила автозагрузки классов

  • extra — указывает какой класс является плагином


Плагин будет состоять из двух классов:



  • непосредственно сам плагин. Он будет добавлять в composer собственный инсталлятор

  • инсталлятор, который и будет заниматься установкой модулей


Плагин выполняет просто добавление инсталлятора (файл: Plugin.php)


namespace company_nameinstaller;

use ComposerComposer;
use ComposerEventDispatcherEventSubscriberInterface;
use ComposerIOIOInterface;
use ComposerPluginPluginInterface;

class Plugin implements PluginInterface
{
    public function activate(Composer $composer, IOInterface $io)
    {
        $composergetInstallationManager()addInstaller(new Bitrix($io, $composer));
    }
}

Далее сам инсталятор (класс company_nameinstallerBitrix). Класс должен наследоваться от ComposerInstallerLibraryInstaller и содержать следующие методы:



  • supports — возвращает true если инсталлятор поддерживает данный тип пакетов

  • getInstallPath — возвращает путь, по которому необходимо разместить исходный код пакета

  • install/uninstall/update — хуки установки/удаления/обновления пакета


Все наши модули будут иметь тип bitrix-module и именно с ними должен работать инсталятор.


public function supports($packageType)
{
    return $packageType === 'bitrix-module';
}

Я решил сохранить целостность имени модуля (оно состоит из company_name и mod_name разделенных точкой) и именую пакеты /. или /.. Если мы возьмем имя пакета и разобьем по слешу, то вторая часть и будет именем модуля


public function getInstallPath(PackageInterface $package)
{
    $name = explode("/", $packagegetName());
    return "local/modules/{$name[1]}/";
}

Методы initBitrix и getModule реализуют работу с API 1C-Битрикс для установки модуля. Метод update реализуется исходя из того, какая у Вас CMS и как вы выпускаете обновления модулей и как планируете их выполнять (файл: Bitrix.php).


namespace company_nameinstaller;

use ComposerInstallerLibraryInstaller;
use ComposerPackagePackageInterface;
use ComposerRepositoryInstalledRepositoryInterface;

class Bitrix extends LibraryInstaller
{

    public function supports($packageType)
    {
        return $packageType === 'bitrix-module';
    }

    public function install(InstalledRepositoryInterface $repo, PackageInterface $package)
    {
        parent::install($repo, $package);
        $name = explode("/", $packagegetName());
        $thisinitBitrix();
        $module = $thisgetModule($name[1]);
        $moduleDoInstall();
    }

    public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $package)
    {
        $name = explode("/", $packagegetName());
        $thisinitBitrix();
        $module = $thisgetModule($name[1]);
        $moduleDoUninstall();
        parent::uninstall($repo, $package);
    }

    public function getInstallPath(PackageInterface $package)
    {
        $name = explode("/", $packagegetName());
        return "local/modules/{$name[1]}/";
    }

    protected function initBitrix()
    {
        $_SERVER['DOCUMENT_ROOT'] = __DIR__ . "/../../../../";
        define('STOP_STATISTICS', true);
        define("NO_KEEP_STATISTIC", "Y");
        define("NO_AGENT_STATISTIC","Y");
        define("NOT_CHECK_PERMISSIONS", true);
        require_once($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php');
        $GLOBALS['APPLICATION']RestartBuffer();
    }

    protected function getModule($module)
    {
        include_once $_SERVER['DOCUMENT_ROOT'] . "/local/modules/" . $module . "/install/index.php";
        $class = str_replace(".", "_", $module);
        $module = new $class();
        return $module;
    }

}

После того, как вы проверили работу плагина, код можно заливать на GitHub и регистрировать в Packagist.


Часть два три. Модуль


Вернемся к самому модулю, который мы упомянули в первой части. а точнее к его composer.json.


{
    "name": "<my_name>/<company_name>.<mod_mame>",
    "type": "bitrix-module",
    "description": "Описание самого модуля",
    "version": "1.0.0",
    "time": "11.09.2018",
    "minimum-stability": "dev",
    "license": "MIT",
    "homepage": "<link to homepage github>",
    "authors": [
        {
            "name": "<name>",
            "email": "<email>"
        }
    ],
    "require": {
        "<my_name>/installer": "*"
    }
}

Имя модуля должно соответствовать требованиям CMS, тип должен быть указан тот, с которым работает инсталлятор (в нашем случае bitrix-module) и в зависимостях у модуля должен быть плагин (секция require). После создания самого модуля и проверки его работы заливаем его код на GitHub и регистрируем в Packagist.


Часть два четыре. использование


Напомню, что сам проект (сайт) имеет примерно следующий composer.json


{
    "name": "sites/<sitename>",
    "description": "<SiteName>",
    "authors": [
        {
            "name": "<developerName>",
            "email": "<developerEmail>"
        }
    ],
    "minimum-stability": "dev",
    "require": {},
    "config": {
        "vendor-dir": "local/vendor"
    }
}

теперь мы можем перечислить в секции require все необходимые нам модули или вызвать команду


composer require "<my_name>/<company_name>.<mod_mame>" "*"

В полной мере ощутить полезность проделанной работы можно, если Вам предстоит, например, добавить в проект модуль авторизации с отправкой пароля в SMS


Управление своими модулями для CMS c использованием composer


Сам модуль содержит код, который отвечает за логику авторизации, включать в него код отправки SMS не стоит, ведь отправку SMS выполняют и другие модули, например модуль уведомлений, значит SMS лучше сделать отдельным модулем, чтобы его код не дублировать. Так же и REST сервис. Его тоже могут использовать другие модули. И при всей этой непростой схеме, когда ваш модуль тянет за собой еще четыре, его установка остаётся всё такой же простой. Просто выполните одну команду:


composer require "<my_name>/<company_name>.<mod_mame>" "*"

А что и в какой последовательности скачивать и устанавливать позвольте решить композеру.


Часть третья. Приватные модули


Друзья, если во всем вышеописанном Вам не нравится, что Ваши модули будут в открытом доступе, то мы сейчас это быстро исправим. чтобы организовать приветное хранение модулей вам понадобится два инструмента:



  • GitLab — это аналог GitHub который Вы можете скачать и установить на свои сервера.

  • Satis — это генератор репозитория, с которым сможет работать композер.


Для начала установите GitLab и перенесите в него исходные коды Ваших модулей. после установите Satis и опишите все ваши модули в satis.json


{
    "name": "ropoName",
    "homepage": "https://composer.<company_name>.ru/",
    "repositories": [
        { 
            "type": "vcs",  
            "url": "https://gitlab.<company_name>.ru/<my_name>/installer"
        },
        { 
            "type": "vcs",  
            "url": "https://gitlab.<company_name>.ru/<my_name>/<company_name>.<mod_name>"
        }
    ],
    "config": {
        "gitlab-domains": [
            "gitlab.<company_name>.ru"
        ],
        "gitlab-token": {
            "gitlab.<company_name>.ru": "GitLab Token"
        }
    },
    "require-all": true
}

В GitLab нужно создать токен, которому будет доступно api и указать его в satis.json. После всех этих манипуляций выполните команду:


php bin/satis build satis.json ./web

И в папке web получите статический репозиторий, который можно опубликовать по адресу https://composer..ru/.


composer.json сайта будет отличатся лишь тем, что в нем будет присутствовать секция repositories


{
    "name": "sites/<sitename>",
    "description": "<SiteName>",
    "authors": [
        {
            "name": "<developerName>",
            "email": "<developerEmail>"
        }
    ],
    "minimum-stability": "dev",
    "require": {},
    "config": {
        "vendor-dir": "local/vendor"
    },
    "repositories": [
        {
            "type": "composer",
            "url": "https://composer.<company_name>.ru/"
        }
    ]
}


Послесловие



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



Источник: Хабр / Интересные публикации

Категория: Программирование

Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь.
Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.

Добавление комментария

Имя:*
E-Mail:
Комментарий:
Полужирный Наклонный текст Подчеркнутый текст Зачеркнутый текст | Выравнивание по левому краю По центру Выравнивание по правому краю | Вставка смайликов Выбор цвета | Скрытый текст Вставка цитаты Преобразовать выбранный текст из транслитерации в кириллицу Вставка спойлера
Введите два слова, показанных на изображении: *