Bonjour mes amis! L'émergence d'un gestionnaire de dépendances populaire en PHP est l'un des événements les plus importants de la vie de la communauté PHP. Le compositeur a divisé le temps en «avant» - lorsque nos bibliothèques auto-écrites étaient dans des archives zip ou simplement dispersées dans des dossiers et copiées par des «stylos», seulement dans de rares cas Git ou PEAR était utilisé et «après» lorsque nous avons commencé à utiliser Composer. Mais que faire si vous travaillez avec un CMS spécifique, mais qu'il ne "sait" pas ce qu'est le compositeur?
Préface
Je travaille en tant que chef d'équipe dans un petit studio Web et il y a environ un an, j'ai dû reconsidérer l'approche de l'utilisation des meilleures pratiques dans mon équipe. Pour le développement de projets, dont plus de 70% des fonctionnalités peuvent être qualifiées de standard (site web, boutique en ligne), nous utilisons 1C-Bitrix. Comme tous les CMS 1C-Bitrix populaires, il a une structure modulaire et prend en charge l'installation de modules tiers. Cela semble bon, mais en réalité c'est un peu différent. Vous pouvez développer vos propres modules et les stocker dans l'archive en copiant les codes source dans les dossiers nécessaires et en installant les modules un par un dans le panneau de contrôle, ou vous pouvez publier les modules sur le site 1C-Bitrix Marketplace prévu à cet effet. Pour publier les modules, il vous suffit de conclure un accord de partenariat et de signer un accord qui décrira votre responsabilité. Et nous ne parlons pas de dépendances des modules et de l'installation de la chaîne de dépendances.
Ce problème à un degré ou à un autre est inhérent à tous les CMS développés «avant». Il démotive le développement de petits modules (il nous semble que «cette fonctionnalité simple» ne doit pas être transformée en module), et nécessite une documentation séparée.
Dans cet article, je vais vous expliquer comment organiser le stockage et l'utilisation des meilleures pratiques au sein d'une équipe / entreprise. Cela sera intéressant pour ceux qui ont rencontré un problème similaire, ceux qui développent des sites Web à l'aide de CMS, ceux qui développent leur propre CMS et ceux qui développent simplement des projets en PHP. C'est parti!
Première partie Placement public de modules
La première tâche qui doit être résolue est de savoir où stocker les modules. Les codes sources des modules peuvent être stockés dans n'importe quel référentiel git, mercurial ou svn. Pour les modules publics, je recommande GitHub. Sur GitHub, vous aurez la possibilité de visualiser facilement le code source et de maintenir la documentation au format Markdown. Pour utiliser Composer, vous devez créer et remplir le fichier composer.json. Cela peut être fait dans l'éditeur, dans votre IDE, ou en appelant la commande init du compositeur. Ci-après, je ne vais pas me plonger dans les fonctionnalités de base et les commandes Composer, si vous êtes nouveau dans Composer, lisez cet article .
Après avoir créé votre module (par exemple, il est vide pour l'instant) et publié son code sur GitHub, vous devez enregistrer le module sur packagist.org . Packagist vous proposera de configurer les hooks GitHub afin que lorsque les modifications arrivent dans le référentiel, les informations sur le module soient mises à jour sur packagist.org.
Deuxième partie L'installation Le plus intéressant ici
Vous êtes, bien sûr, très familier avec le CMS avec lequel vous travaillez, ce qui signifie que vous connaissez toutes les subtilités de l'installation des modules. Dans 1C-Bitrix, l'installation des modules se déroule en 2 étapes:
- placer le code source du module dans un répertoire spécifique
<project_dir>/local/modules/<company_name>.<mod_mame>
- Appelez la fonction RegisterModule (<company_name>. <mod_mame>). En règle générale, toutes les actions d'installation de module sont décrites dans la méthode DoInstall de la classe responsable de l'installation et de la suppression du module.
<project_dir>/local/modules/<company_name>.<mod_mame>/install/index.php
La deuxième partie en est une. Cacher des colis dans un endroit sûr
Par défaut, composer installe tous les packages dans le répertoire <project_dir>/vendor
si le composeur se trouve à la racine du projet et n'exécute aucun hook dans vos packages. Mais c'est facile à changer.
Nous devons placer le fichier composer.json à la racine du projet:
{ "name": "sites/<sitename>", "description": "<SiteName>", "authors": [ { "name": "<developerName>", "email": "<developerEmail>" } ], "minimum-stability": "dev", "require": {}, "config": { "vendor-dir": "local/vendor" } }
Dans 1C-Bitrix, le code écrit par les développeurs est généralement placé dans le répertoire <project_dir>/local
. Par conséquent, nous y avons déplacé le dossier du vendor
par une entrée dans la section config . Désormais, tous les packages tiers y seront hébergés. Mais nos modules doivent être placés dans le répertoire <project_dir>/local/modules/<company_name>.<mod_mame>
, que dois-je faire?
Deuxième partie deux. Plugin d'installation des modules
Composer dispose de plusieurs types de packages, dont l'un composeur-plugin est une extension pour le compositeur lui-même. Pour que nos modules soient installés comme requis par le CMS, nous devons écrire notre propre plugin. Pour ce faire, créez un projet distinct et placez composer.json à sa racine:
{ "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>\\installer\\Plugin" } }
Il y a 3 points clés dans ce fichier:
- "type": "composer-plugin" - indique au compositeur qu'il s'agit d'un plugin
- chargement automatique - décrit les règles pour les classes de chargement automatique
- extra - indique quelle classe est le plugin
Le plugin comprendra deux classes:
- le plugin lui-même. Il ajoutera son propre installateur au compositeur
- installateur, qui sera engagé dans l'installation des modules
Le plugin ajoute simplement le programme d'installation (fichier: Plugin.php )
namespace company_name\installer; use Composer\Composer; use Composer\EventDispatcher\EventSubscriberInterface; use Composer\IO\IOInterface; use Composer\Plugin\PluginInterface; class Plugin implements PluginInterface { public function activate(Composer $composer, IOInterface $io) { $composer->getInstallationManager()->addInstaller(new Bitrix($io, $composer)); } }
Ensuite, le programme d'installation lui-même ( company_name\installer\Bitrix
). La classe doit hériter de Composer\Installer\LibraryInstaller
et contenir les méthodes suivantes:
- supports - renvoie true si le programme d'installation prend en charge ce type de package
- getInstallPath - retourne le chemin où vous souhaitez placer le code source du package
- installation / désinstallation / mise à jour - hooks d' installation / désinstallation / mise à jour du package
Tous nos modules seront du type module Bitrix et l'installateur devrait travailler avec eux.
public function supports($packageType) { return $packageType === 'bitrix-module'; }
J'ai décidé de préserver l'intégrité du nom du module (il se compose de nom_entreprise et nom_mod séparés par un point) et de nommer les packages <my_name>/<company_name>.<mod_mame>
ou <company_name>/<company_name>.<mod_mame>
. Si nous prenons le nom du package et le cassons avec une barre oblique, la deuxième partie sera le nom du module
public function getInstallPath(PackageInterface $package) { $name = explode("/", $package->getName()); return "local/modules/{$name[1]}/"; }
Les méthodes initBitrix et getModule implémentent le travail avec l'API 1C-Bitrix pour installer le module. La méthode de mise à jour est implémentée en fonction du CMS dont vous disposez et de la façon dont vous publiez les mises à jour des modules et de la façon dont vous prévoyez de les exécuter (fichier: Bitrix.php ).
namespace company_name\installer; use Composer\Installer\LibraryInstaller; use Composer\Package\PackageInterface; use Composer\Repository\InstalledRepositoryInterface; 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("/", $package->getName()); $this->initBitrix(); $module = $this->getModule($name[1]); $module->DoInstall(); } public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $package) { $name = explode("/", $package->getName()); $this->initBitrix(); $module = $this->getModule($name[1]); $module->DoUninstall(); parent::uninstall($repo, $package); } public function getInstallPath(PackageInterface $package) { $name = explode("/", $package->getName()); 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; } }
Après avoir vérifié le plugin, le code peut être téléchargé sur GitHub et enregistré auprès de Packagist.
Deuxième partie trois. Module
Revenons au module lui-même, que nous avons mentionné dans la première partie. ou plutôt à son compositeur.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": "*" } }
Le nom du module doit être conforme aux exigences du CMS, le type doit être spécifié avec lequel l'installateur travaille (dans notre cas, module bitrix ) et dans les dépendances le module doit avoir un plug-in (section obligatoire). Après avoir créé le module lui-même et vérifié son fonctionnement, remplissez son code sur GitHub et enregistrez-le auprès de Packagist.
Deuxième partie quatre. utilisation de
Permettez-moi de vous rappeler que le projet (site) lui-même a approximativement le compositeur.json suivant
{ "name": "sites/<sitename>", "description": "<SiteName>", "authors": [ { "name": "<developerName>", "email": "<developerEmail>" } ], "minimum-stability": "dev", "require": {}, "config": { "vendor-dir": "local/vendor" } }
maintenant nous pouvons lister dans la section require tous les modules dont nous avons besoin ou appeler la commande
composer require "<my_name>/<company_name>.<mod_mame>" "*"
Vous pouvez pleinement ressentir l'utilité du travail effectué si vous devez, par exemple, ajouter un module d'autorisation au projet avec l'envoi d'un mot de passe par SMS

Le module lui-même contient un code qui est responsable de la logique d'autorisation, vous ne devez pas y inclure le code d'envoi de SMS, car d'autres modules, par exemple, le module de notification, envoient également des SMS, il est préférable de faire de SMS un module distinct afin que son code ne se duplique pas. Le service REST aussi. Il peut également être utilisé par d'autres modules. Et avec tout ce schéma compliqué, lorsque votre module en tire quatre de plus, son installation reste tout aussi simple. Exécutez simplement une commande:
composer require "<my_name>/<company_name>.<mod_mame>" "*"
Et quoi et dans quel ordre télécharger et installer, laissez le compositeur décider.
Troisième partie. Modules privés
Amis, si, dans tout ce qui précède, vous n'aimez pas que vos modules soient dans le domaine public, nous le corrigerons rapidement. Pour organiser le bon stockage des modules, vous aurez besoin de deux outils:
- GitLab est un analogue de GitHub que vous pouvez télécharger et installer sur vos serveurs.
- Satis est un générateur de référentiel avec lequel le compositeur peut travailler.
Pour commencer, installez GitLab et transférez-y les codes sources de vos modules. puis installez Satis et décrivez tous vos modules dans 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 }
Dans GitLab, vous devez créer un jeton pour lequel api sera disponible et le spécifier dans satis.json . Après toutes ces manipulations, exécutez la commande:
php bin/satis build satis.json ./web
Et dans le dossier Web , obtenez un référentiel statique, qui peut être publié sur https: // composer . <nom_entreprise> .ru /.
composer.json du site ne différera que par le fait qu'il aura une section de référentiels
{ "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/" } ] }
Postface
Mes amis, j'espère vraiment que cet article vous a été utile. Peu importe le CMS que vous utilisez, vous serez en mesure d'organiser correctement le stockage de votre code, vous le documenterez strictement, vous pourrez diviser les modules "épais" en de nombreuses dépendances de formatage "minces", et vous cesserez d'avoir des difficultés à installer ou à mettre à jour les modules. Bonne chance