Comment installer un module qui inclut une version différente de Symfony?

17

Je suis développeur et mainteneur du projet CiviCRM. Nous avons essayé de créer une version Drupal 8 CiviCRM, et nous avons parcouru un long chemin. Nous nous battons la tête contre nos claviers collectifs en essayant de trouver un bloqueur majeur pour le projet.

CiviCRM utilise Symfony depuis un certain temps, et la version incluse est différente de celle fournie avec Drupal.

Nous pouvons installer CiviCRM avec Drupal 8, mais après l'avoir installé, nous ne pouvons installer aucun autre module Drupal.

Je crois que cela se résume à une situation où la version CiviCRM de Symfony se charge d'une manière ou d'une autre avant la version Drupal, et cela pose des problèmes.

Quelqu'un connaît-il un module Drupal 8 qui inclut une version différente de Symfony que celle livrée avec Drupal?

Récemment, j'ai rencontré le projet Ludwig. Ce module permet l'enregistrement des espaces de noms dans une classe qui s'étendServiceProviderBase .

Serait-il possible pour la version Drupal 8 du module CiviCRM d'inclure un fichier CivicrmServiceProvider.php, qui définit une CivicrmServiceProviderclasse et unregister() méthode qui ajoute un espace de noms de conteneur pour permettre à cela de fonctionner?

De nombreux fichiers CiviCRM ont des useinstructions comme Drupal commençant par Symfony, comme ici .

Nous avons en fait mis CiviCRM Core dans le dossier Drupal doc_root / bibliothèques, et utilisons le module de bibliothèques.

Ceci est le repo pour la version 8.x du module CiviCRM Drupal , si quelqu'un veut regarder ce que nous avons obtenu jusqu'à présent. Si quelqu'un a l'élixir magique pour cela, je peux vous dire qu'il y aurait beaucoup de gens heureux dans notre communauté. Donc, si vous savez comment nous aider, n'hésitez pas.

CiviCRM s'installe et les pages CiviCRM fonctionnent. Ce qui ne fonctionne pas, c'est qu'après l'installation de CiviCRM, nous ne pouvons pas installer d'autres modules via la page admin / modules. Pour autant que je sache, c'est la seule chose qui est cassée. L'installation de modules avec Drush, après l'installation de CiviCRM, fonctionne également.

Essayer d'installer un autre module après l'installation de CiviCRM provoque l'erreur suivante:

Erreur fatale PHP: appel à la méthode non définie Symfony \ Component \ DependencyInjection \ Definition :: setFactory () dans /var/www/html/civi-for-d8/core/lib/Drupal/Core/DependencyInjection/YamlFileLoader.php sur la ligne 206

C'est dans Drupal 8.3.5. Essayer d'installer CiviCRM pour Drupal 8 dans une instance propre de Drupal 8.4-dev provoque l'erreur suivante:

Drupal \ Component \ Serialization \ Exception \ InvalidDataTypeException: l'indicateur réservé "@" ne peut pas démarrer un scalaire simple; vous devez citer le scalaire à la ligne 8 (près de "arguments: [@string_translation, @ civicrm.page_state]"). dans Drupal \ Component \ Serialization \ YamlSymfony :: decode () (ligne 40 de /var/www/html/drupal84/core/lib/Drupal/Component/Serialization/YamlSymfony.php).

jackrabbithanna
la source
Sur mobile, mais quelle version de Symfony? 8.4 utilisera 3.x, un saut de v2.
Matt Glaman
Nous sommes à la version 2.5.0 dans CiviCRM
jackrabbithanna
Une documentation du problème: issues.civicrm.org/jira/browse/CRM-17652 .... Une personne signale qu'il n'a pas vu le problème, mais je n'en suis pas sûr, tous ceux qui essaient d'obtenir une erreur comme rapporté là
jackrabbithanna
4
Je ne pense pas que ce soit possible. Drupal 8.4 est en fait déjà passé à Symfony3 bien qu'il y ait encore des discussions similaires liées à drush, qui a le même problème. Il n'est pas possible de charger deux versions symfony différentes, soit vous interrompez votre intégration, soit vous interrompez Drupal. Peut-être que symfony3 ne sera pas encore en 8.4, mais le support de sécurité pour symfony2 prendra fin avant le support de sécurité Drupal8, donc à un moment donné, nous devrons changer
Berdir
1
@Berdir qui pourrait faire une bonne réponse?
Clive

Réponses:

8

Donc, je pense que si CiviCRM était installé dans Drupal 8 via le composeur (c'est-à-dire composer require civicrm/civicrm-coredans la racine Drupal) et que CiviCRM utilisait Symfony était compatible avec Symfony 2.8 ou 3.x (c'est-à-dire sans utiliser de fonctionnalité obsolète), cela pourrait fonctionner.

Cela aurait tout installé dans le répertoire des fournisseurs de Drupal, plutôt que d'en avoir deux, et cela signifierait que CiviCRM utiliserait la version Symfony dans Drupal 8. Mais si CiviCRM était compatible avec les versions ultérieures de Symfony (même s'il regroupait une ancienne version pour Drupal 6 & 7 et autres CMS) ça devrait aller.

Je pense?

MISE À JOUR: Oui, cela fonctionne - je l'ai essayé. :-) J'ai initialement publié ce qui suit dans la file d'attente des problèmes de CiviCRM ( CRM-17652 ), mais je le republie ici pour être complet.

La grande idée:

Étant donné que le compositeur est assez nouveau pour beaucoup de gens, je vais essayer d'aller pas à pas, de certains trucs de compositeur de haut niveau jusqu'à une façon de le faire dans CiviCRM:

  • Composer permet aux applications d'exiger les bibliothèques dont il a besoin (et les bibliothèques, bien sûr, peuvent nécessiter d'autres bibliothèques).
  • Les bibliothèques ont un fichier composer.json qui indique de quelles autres bibliothèques il a besoin et avec quelles versions il est compatible (mais pas nécessairement une version unique spécifique - généralement une gamme de versions, comme celle ^2.4.3qui dit un minimum de 2.4.3 et jusqu'à (mais pas y compris) 3.0.0)
  • Les applications ont un composer.json qui décrit de la même manière les bibliothèques nécessaires et la compatibilité avec une gamme de versions, mais la gamme est vraiment pour aider à la mise à jour. Une application aura également un composer.lock qui est un ensemble spécifique de versions individuelles
  • Les bibliothèques peuvent également avoir un composer.lock pour leurs propres tests ou distributions (comme la création de l'archive tar avec les dépendances regroupées), mais cela est ignoré lorsqu'une application nécessite la bibliothèque donnée (voir https://getcomposer.org/doc/02 -libraries.md # fichier-verrou )
  • Lorsqu'une application souhaite exiger une nouvelle bibliothèque, composer trouve une intersection de compatibilité de version entre tout ce dont l'application a besoin (y compris toutes les bibliothèques déjà installées et leurs dépendances) et la nouvelle bibliothèque, en faisant éventuellement des mises à jour pour que tout soit aligné ( ou erreur s'il ne trouve pas un mélange compatible de versions)
  • Dans ce cas, CiviCRM est une bibliothèque, et un site Drupal 8 particulier est l'application (le noyau Drupal lui-même est une bibliothèque)
  • CiviCRM pourrait dire qu'il "nécessite" Symfony ^2.5dans son composer.json, ce qui signifie qu'il est compatible avec les versions 2.5.0 jusqu'à (mais sans inclure) 3.0.0
  • Lorsqu'un site Drupal 8 souhaite utiliser CiviCRM, l'administrateur du site utilise composer require civicrm/civicrm-corepour exiger la bibliothèque CiviCRM et toutes ses dépendances. Si CiviCRM est compatible avec Symfony 2.8 (comme utilisé dans Drupal 8.3.x), tout s'installera et fonctionnera correctement, en utilisant le seul Symfony 2.8 de Drupal. Toutes les dépendances finissent dans le répertoire des fournisseurs de Drupal.
  • Cependant, CiviCRM pourrait conserver Symfony 2.5 dans son composer.lock, ce qui signifie que les tests l'utiliseraient, et les tarballs pour Drupal 6 & 7 et d'autres CMS regrouperaient Symfony 2.5

La proposition:

  1. Mettez à jour le composer.json de CiviCRM afin qu'il puisse être utilisé comme bibliothèque par des CMS basés sur le compositeur comme Drupal 8 (mais probablement d'autres pourraient évoluer de cette façon à l'avenir - le compositeur devient très populaire)
  2. Assurez-vous que le noyau CiviCRM est compatible avec Symfony 2.8 et 3.0 (utilisé par Drupal 8.3.x et 8.4.x respectivement) mais conservez la version "officiellement prise en charge" (actuellement Symfony 2.5) dans le composer.lock pour les tests et l'archive tar pour la distribution. Être compatible avec plusieurs versions de Symfony peut ne pas être aussi difficile qu'il y paraît - il existe un certain nombre de bibliothèques compatibles avec Symfony 2.8 et 3.0. Il s'agit peut-être simplement d'éviter les méthodes / classes / fonctionnalités obsolètes! Le compositeur.json devra être mis à jour pour refléter cela
  3. Utilisez Composer pour installer la bibliothèque CiviCRM sur Drupal 8 plutôt que de copier dans le répertoire des bibliothèques. Cela devient la manière normale d'installer des bibliothèques PHP tierces dans Drupal 8 (ceci est largement utilisé par Drupal Commerce, par exemple)

Pour les CMS basés sur des compositeurs, je pense vraiment que c'est la bonne façon. Bien que ce problème affecte actuellement Symfony et Drupal, alors que la communauté PHP commence à utiliser de plus en plus de bibliothèques tierces via Composer, cela pourrait très bien affecter d'autres CMS avec d'autres conflits de version.

Un code de travail à tester:

Donc, comme promis, je l'ai fait fonctionner à un degré limité :-) J'y arrive totalement du point de vue Drupal / Composer / Symfony - je n'ai pas une tonne d'expérience CiviCRM, donc il y a probablement de meilleures façons de faire mon processus ci-dessous. Je me réjouis de tout conseil!

  1. Téléchargez et installez Drupal 8.3.5 (ou la dernière version de Drupal 8.4.x!)
  2. Allez dans le répertoire racine du shell et exécutez ces commandes pour installer CiviCRM via composer: https://gist.github.com/dsnopek/56311dbea347874e75180883efabb620
  3. Si vous utilisez Apache, supprimez le fichier fournisseur / .htacess. Il s'agit d'une mesure de sécurité de Drupal, qui empêche le chargement de ressources comme CSS / JS. Cela nécessitera une certaine collaboration avec le projet Drupal pour trouver une solution appropriée, car la suppression complète de ce fichier est une mauvaise idée en production. Voir: vendeur / .htaccess bloquant les ressources CSS / JS des bibliothèques de compositeur .
  4. Allez dans le répertoire / modules et faites git clone https://github.com/dsnopek/civicrm-drupal.git --branch composer-library
  5. Accédez à la page "Étendre" ( /admin/modules) et installez le module CiviCRM
  6. Vider le cache drupal via Drush ( drush cr)
  7. Déconnectez-vous et reconnectez-vous selon CRM-19878
  8. CiviCRM fonctionne! :-)

Après tout cela, CiviCRM utilise Symfony 2.8 de Drupal et les dépendances dans le répertoire des fournisseurs de Drupal, et ne charge rien à partir de son propre répertoire de fournisseurs. Huzzah!

J'ai testé l'activation du module "Téléphone" qui a échoué avant ces changements (voir mes étapes pour reproduire ), mais fonctionne très bien avec eux. :-)

David Snopek
la source
Voici donc une question liée à tout cela, en utilisant composer .... est-il possible qu'un package utilise Symfony 2.8, et un autre package utilise Symfony 3.2 ....
jackrabbithanna
Il y a une résistance institutionnelle assez difficile à ce que CiviCRM soit obligé de toujours utiliser quelle version de Symfony que Drupal 8/9 fait.
jackrabbithanna
1
"en utilisant composer .... est-il possible qu'un seul package utilise Symfony 2.8, et un autre package utilise Symfony 3.2" -> Non, PHP ne peut pas avoir deux classes avec le même nom. Ce n'est pas vraiment un truc de compositeur.
David Snopek
"Il y a une résistance institutionnelle assez difficile à ce que CiviCRM soit obligé de toujours utiliser quelle version de Symfony que Drupal 8/9 fait" -> Tout ce qui serait requis du noyau CiviCRM en amont est que le code est compatible avec le Symfony plus tard utilisé dans Drupal. Il n'aurait pas à le regrouper ou à l'utiliser par défaut, il suffit d'être compatible, c'est-à-dire. éviter les méthodes / classes / fonctionnalités obsolètes.
David Snopek
Je comprends pourquoi on serait intéressé à exécuter les deux versions principales de Symfony côte à côte - SemVer sorta implique la nécessité. Mais je pense qu'il est important que de larges pans de composants Symfony soient similaires en v2 / v3, et que l'intégration de Civi en v2 ait été assez modeste. Je suis donc optimiste quant à la possibilité ou à la réalisation d'un code PHP compatible avec les deux. À mon humble avis, le vrai travail consiste à mettre à jour le canal de distribution et la structure des répertoires.
Tim Otten
5

Je ne pense pas que ce soit possible.

Drupal 8.4 est en fait déjà passé à Symfony 3 bien qu'il y ait encore des discussions similaires liées à drush, qui a le même problème. voir Drush 8.x n'installe pas Drupal 8.4.x et Drush master n'installe pas Drupal 8.3.x et les composants Symfony sont mis à jour vers 3.2.6

Il n'est pas possible de charger deux versions symfony différentes, soit vous interrompez votre intégration, soit vous interrompez Drupal. Peut-être que symfony3 ne sera pas encore en 8.4, mais le support de sécurité pour symfony2 prendra fin avant le support de sécurité Drupal8, donc à un moment donné, nous devrons changer.

Berdir
la source
Eh bien ..... Tout fonctionne sauf l'installation de modules à partir d'admin / modules .... l'installation de modules avec Drush fonctionne ... Toutes les pages CiviCRM fonctionnent. Je ne suis donc pas convaincu que ce soit impossible. Pourquoi serait-ce impossible?
jackrabbithanna
1
Vous ne pouvez pas charger deux versions différentes de la même classe en même temps, ce n'est pas possible. L'erreur ressemble exactement à ce à quoi je m'attendrais. Vous avez réussi à charger d'abord la version 2.5 de la classe Definition, puis Drupal se casse car il s'attend à ce qu'une méthode existe qui n'existe pas. Et les différences vont s'accentuer lorsque Drupal passe à Symfony 3. Je ne comprends pas très bien pourquoi vous êtes bloqué avec 2.5, 2.8 est une mise à jour mineure et devrait être rétrocompatible (mais pas l'inverse comme vous l'avez découvert). Vous devriez donc être en mesure de mettre à jour CiviCRM pour exiger la version 2.8?
Berdir
1
Comme je l'ai mentionné dans mon commentaire, j'ai supposé que vous n'aimeriez pas que je réponde, mais cela ne change rien. Aucun de ces projets que vous mentionnez n'utilise symfony (joomal semble utiliser une poignée de composants qui pourraient ne pas entrer en conflit mais éventuellement le faire éventuellement), vous ne pouvez donc pas comparer cela. Il est techniquement impossible de charger deux versions conflictuelles de la même classe, rien ne peut changer cela. C'est pourquoi les dépendances sont une entreprise complexe et pourquoi le compositeur existe. Au lieu d'utiliser des bibliothèques, vous devriez probablement envisager d'utiliser Composer et de rendre CiviCRM compatible avec plusieurs versions de
Symfony
2
De plus, la prise en charge de la sécurité pour Symfony 2.5 a pris fin en 2015 selon symfony.com/roadmap?version=2.5#checker , ce qui signifie que CiviCRM est construit sur une version symfony non sécurisée et obsolète. Cela seul devrait suffire à les convaincre qu'une mise à jour est nécessaire, au moins pour la version 2.8, il ne s'agit pas seulement de Drupal8.
Berdir
1
@DavidSnopek à droite, ce que vous avez écrit dans votre réponse est également ce que j'ai mentionné dans mes commentaires, mais tant que composer.json des spécificités CiviCRM "~ 2.5.0" pour ses composants symfony, cela ne fonctionnera pas. Voir github.com/civicrm/civicrm-core/blob/master/composer.json . Donc ma réponse "vous ne pouvez pas utiliser deux versions différentes" est toujours correcte à mon humble avis, vous ne pouvez qu'améliorer / mettre à jour les contraintes de version dans civicrm puis l'installer via composer et utiliser la même version.
Berdir
1

Théoriquement, les seuls problèmes ici sont l'emplacement du fichier et l'espace de noms de classe. Malheureusement, les seuls outils que je connaisse dans composer pour le faire ne vous permettent pas de spécifier par VERSION, juste par nom de package.

Avez-vous essayé de le configurer en tant que chargeur automatique complètement séparé?

Ohthehugemanatee
la source
Pouvez-vous expliquer plus en détail ce que vous voulez dire?
jackrabbithanna
getcomposer.org/doc/faqs/… est de savoir comment faire l'emplacement personnalisé. J'ai vu des gens créer un projet juste pour rendre cela possible ... Aussi getcomposer.org/doc/06-config.md#prepend-autoloader pour l'option de garder l'autochargeur du composeur séparé. En fin de compte, l'autochargeur n'est qu'un fichier php, vous pouvez donc écrire votre propre autochargeur qui décide lequel inclure en fonction des facteurs que vous aimez.
Ohthehugemanatee
Également pertinent: stackoverflow.com/questions/30000063/…
Ohthehugemanatee
Soyez clair, ATM, il n'y a pas de méthode d'installation basée sur le compositeur pour installer Civi avec D8. Je pensais que c'était peut-être une façon d'y parvenir. C'était l'objet de ServiceProvider mentionné dans la question, comme l'ajout d'un espace de noms PSR-4 à Drupal pour pointer vers la bibliothèque CiviCRM ... Si je le faisais, Civi aurait-il besoin de modifier tous ses fichiers à partir de 'utiliser Symfony \ .... 'à' utiliser Civicrm \ Symfony \ .. '? Pardonnez mon ignorance des pls du compositeur.
jackrabbithanna