Wie installiere ich ein Modul, das eine andere Version von Symfony enthält?

17

Ich bin Entwickler und Betreuer des CiviCRM-Projekts. Wir haben versucht, eine Drupal 8-Version von CiviCRM zu erstellen, und es ist ein langer Weg zurückgelegt. Wir schlagen unsere Köpfe gegen unsere kollektiven Tastaturen und versuchen, einen Hauptblocker für das Projekt zu finden.

CiviCRM verwendet Symfony seit einiger Zeit und die enthaltene Version unterscheidet sich von der mit Drupal gelieferten Version.

Wir können CiviCRM mit Drupal 8 installieren, aber nachdem Sie es installiert haben, können wir kein anderes Drupal-Modul mehr installieren.

Ich glaube, es läuft auf eine Situation hinaus, in der die CiviCRM-Version von Symfony vor der Drupal-Version geladen wird, was zu Problemen führt.

Kennt jemand ein Drupal 8-Modul, das eine andere Version von Symfony enthält als das, das mit Drupal geliefert wird?

Kürzlich bin ich auf das Ludwig-Projekt gestoßen. Dieses Modul ermöglicht die Registrierung von Namespaces in einer Klasse, die erweitert wirdServiceProviderBase .

Könnte die Drupal 8-Version des CiviCRM-Moduls eine CivicrmServiceProvider.php-Datei enthalten, die eine CivicrmServiceProviderKlasse definiert , und eine register()Methode, die einen Containernamensraum hinzufügt, damit dies funktioniert?

Viele CiviCRM-Dateien enthalten useAnweisungen wie Drupal, die mit Symfony beginnen, wie hier .

Wir legen CiviCRM Core tatsächlich im Drupal-Ordner doc_root / libraries ab und verwenden das Bibliotheksmodul.

Dies ist das Repo für die CiviCRM Drupal Modul 8.x Version , wenn jemand schauen möchte, was wir bisher haben. Wenn jemand das magische Elixier dafür hat, kann ich Ihnen sagen, dass es in unserer Gemeinde viele glückliche Menschen geben würde. Wenn Sie also wissen, wie Sie uns helfen können, tun Sie dies bitte.

CiviCRM wird installiert und die CiviCRM-Seiten funktionieren. Was nicht funktioniert ist, dass wir nach der Installation von CiviCRM keine weiteren Module über die Seite admin / modules installieren können. Soweit ich weiß, ist das das einzige, was kaputt ist. Auch die Installation von Modulen mit Drush nach der Installation von CiviCRM funktioniert.

Der Versuch, ein anderes Modul nach der Installation von CiviCRM zu installieren, führt zu folgendem Fehler:

Schwerwiegender PHP-Fehler: Rufen Sie die undefinierte Methode Symfony \ Component \ DependencyInjection \ Definition :: setFactory () in /var/www/html/civi-for-d8/core/lib/Drupal/Core/DependencyInjection/YamlFileLoader.php in Zeile 206 auf

Das ist in Drupal 8.3.5. Der Versuch, CiviCRM für Drupal 8 in einer sauberen Drupal 8.4-dev-Instanz zu installieren, führt zu folgendem Fehler:

Drupal \ Component \ Serialization \ Exception \ InvalidDataTypeException: Der reservierte Indikator "@" kann keinen einfachen Skalar starten. Sie müssen den Skalar in Zeile 8 (in der Nähe von "arguments: [@string_translation, @ civicrm.page_state]") angeben. in Drupal \ Component \ Serialization \ YamlSymfony :: decode () (Zeile 40 von /var/www/html/drupal84/core/lib/Drupal/Component/Serialization/YamlSymfony.php).

Jackrabbithanna
quelle
Auf dem Handy, aber welche Version von Symfony? 8.4 verwendet 3.x, einen Sprung von v2.
Matt Glaman
Wir sind bei Version 2.5.0 in CiviCRM
Jackrabbithanna
Dokumentation des Problems: issues.civicrm.org/jira/browse/CRM-17652 .... Eine Person meldet, dass er das Problem nicht gesehen hat, aber ich bin mir nicht sicher, alle anderen, die es versuchen, erhalten einen Fehler Wie dort berichtet
Jackrabbithanna
4
Ich denke nicht, dass das möglich ist. Drupal 8.4 ist eigentlich schon auf Symfony3 umgestiegen, obwohl es immer noch ähnliche Diskussionen zu drush gibt, die das gleiche Problem haben. Es ist nicht möglich, zwei verschiedene Symfony-Versionen zu laden, entweder Sie brechen Ihre Integration oder Sie brechen Drupal. Vielleicht ist symfony3 noch nicht in Version 8.4, aber die Sicherheitsunterstützung für symfony2 endet noch vor der Sicherheitsunterstützung für Drupal8. Irgendwann müssen wir also wechseln
Berdir
1
@Berdir könnte das eine gute Antwort sein?
Clive

Antworten:

8

Ich denke also, wenn CiviCRM über Composer (dh composer require civicrm/civicrm-coreim Drupal-Stammverzeichnis) in Drupal 8 installiert würde und die Verwendung von Symfony durch CiviCRM mit Symfony 2.8 oder 3.x kompatibel wäre (dh keine veraltete Funktionalität verwenden würde), könnte dies funktionieren.

Dies würde alles im Herstellerverzeichnis von Drupal installieren, anstatt zwei zu haben, und würde bedeuten, dass CiviCRM die Symfony-Version in Drupal 8 verwenden würde. Aber wenn CiviCRM mit späteren Symfony-Versionen kompatibel wäre (selbst wenn es eine ältere Version für Drupal enthalten würde) 6 & 7 und andere CMS) sollte es in Ordnung sein.

Ich glaube?

AKTUALISIERT: Ja, es funktioniert - ich habe es versucht. :-) Ich habe das Folgende ursprünglich in der CiviCRM -Problemwarteschlange ( CRM-17652 ) gepostet , aber der Vollständigkeit halber hier erneut gepostet .

Die große Idee:

Da der Komponist für viele Leute ziemlich neu ist, werde ich versuchen, Schritt für Schritt voranzukommen, von einigen hochrangigen Komponisten bis hin zu einer Möglichkeit, wie dies in CiviCRM geschehen könnte:

  • Mit Composer können Anwendungen die benötigten Bibliotheken benötigen (und Bibliotheken können natürlich auch andere Bibliotheken benötigen).
  • Bibliotheken haben eine composer.json-Datei, in der angegeben ist, welche anderen Bibliotheken sie benötigen und mit welchen Versionen sie kompatibel sind (jedoch nicht unbedingt eine bestimmte Einzelversion - normalerweise eine Reihe von Versionen, wie z. B. ^2.4.3mindestens 2.4.3 und höher (jedoch nicht) einschließlich) 3.0.0)
  • Anwendungen haben eine composer.json, die die benötigten Bibliotheken und die Kompatibilität mit einer Reihe von Versionen auf ähnliche Weise beschreibt, aber die Reihe ist wirklich hilfreich bei der Aktualisierung. Eine Anwendung verfügt auch über eine composer.lock-Datei, die eine bestimmte Reihe von einzelnen Versionen enthält
  • Bibliotheken können auch eine composer.lock für ihre eigenen Tests oder Distributionen haben (wie das Erstellen des Release-Tarballs mit den gebündelten Abhängigkeiten), dies wird jedoch ignoriert, wenn eine Anwendung die angegebene Bibliothek benötigt (siehe https://getcomposer.org/doc/02) -libraries.md # lock-file )
  • Wenn eine Anwendung eine neue Bibliothek benötigen möchte, findet Composer einen Schnittpunkt der Versionskompatibilität zwischen allen von der Anwendung benötigten Dingen (einschließlich aller bereits installierten Bibliotheken und ihrer Abhängigkeiten) und der neuen Bibliothek. oder Fehler, wenn keine kompatible Mischung von Versionen gefunden werden kann)
  • In diesem Fall ist CiviCRM eine Bibliothek, und eine bestimmte Drupal 8-Site ist die Anwendung (der Drupal-Kern selbst ist eine Bibliothek).
  • CiviCRM könnte sagen, dass es Symfony ^2.5in seiner composer.json "benötigt", was bedeutet, dass es mit den Versionen 2.5.0 bis (aber ohne) 3.0.0 kompatibel ist
  • Wenn eine Drupal 8-Site CiviCRM verwenden möchte, benötigt der Site-Administrator composer require civicrm/civicrm-coredie CiviCRM-Bibliothek und alle zugehörigen Abhängigkeiten. Wenn CiviCRM mit Symfony 2.8 kompatibel ist (wie in Drupal 8.3.x verwendet), wird alles installiert und funktioniert einwandfrei, wenn Sie das einzelne Symfony 2.8 von Drupal verwenden. Alle Abhängigkeiten landen im Herstellerverzeichnis von Drupal.
  • CiviCRM könnte jedoch Symfony 2.5 in seiner composer.lock behalten, was bedeutet, dass die Tests dies verwenden würden und die Tarballs für Drupal 6 & 7 und andere CMS Symfony 2.5 bündeln würden

Der Antrag:

  1. Aktualisieren Sie die Datei composer.json von CiviCRM, damit sie von komponistenbasierten CMS wie Drupal 8 als Bibliothek verwendet werden kann (andere könnten sich jedoch in Zukunft auf diese Weise bewegen - Composer wird immer beliebter).
  2. Stellen Sie sicher, dass der CiviCRM-Core mit Symfony 2.8 und 3.0 (verwendet von Drupal 8.3.x bzw. 8.4.x) kompatibel ist. Behalten Sie jedoch die "offiziell unterstützte" Version (derzeit Symfony 2.5) im composer.lock zum Testen und den Tarball zum Verteilen bei. Die Kompatibilität mit mehreren Symfony-Versionen ist möglicherweise nicht so schwierig wie es sich anhört - es gibt eine Reihe von Bibliotheken, die mit Symfony 2.8 und 3.0 kompatibel sind. Es kann nur darum gehen, veraltete Methoden / Klassen / Features zu vermeiden! Die Datei composer.json muss aktualisiert werden, um dies widerzuspiegeln
  3. Verwenden Sie Composer, um die CiviCRM-Bibliothek auf Drupal 8 zu installieren, anstatt sie in das Bibliotheksverzeichnis zu kopieren. Dies wird zur normalen Methode für die Installation von PHP-Bibliotheken von Drittanbietern in Drupal 8 (dies wird beispielsweise von Drupal Commerce in großem Umfang verwendet).

Für Komponisten-basierte CMS denke ich wirklich, dass dies der richtige Weg ist. Während dieses Problem derzeit Symfony und Drupal betrifft, da die PHP-Community immer mehr Bibliotheken von Drittanbietern über Composer verwendet, kann dies durchaus Auswirkungen auf andere CMS mit anderen Versionskonflikten haben.

Ein paar funktionierende Codes zum Testen:

Also, wie versprochen, habe ich dies tatsächlich in begrenztem Umfang zum Laufen gebracht :-) Ich komme aus der Sicht von Drupal / Composer / Symfony völlig darauf zurück - ich habe nicht viel Erfahrung mit CiviCRM, also gibt es wahrscheinlich einige bessere Möglichkeiten, um meinen Prozess unten zu tun. Ich freue mich über jeden Rat!

  1. Downloaden und installieren Sie Drupal 8.3.5 (oder den neuesten Entwickler von Drupal 8.4.x!)
  2. Gehen Sie in das Stammverzeichnis der Shell und führen Sie diese Befehle aus, um CiviCRM über den Composer zu installieren: https://gist.github.com/dsnopek/56311dbea347874e75180883efabb620
  3. Wenn Sie Apache verwenden, entfernen Sie die Hersteller- / .htacess-Datei. Dies ist eine Sicherheitsmaßnahme von Drupal, die das Laden von Ressourcen wie CSS / JS verhindert. Dies erfordert eine gewisse Zusammenarbeit mit dem Drupal-Projekt, um eine geeignete Lösung zu finden, da das Entfernen dieser Datei insgesamt eine schlechte Idee für die Produktion ist. Siehe: vendor / .htaccess blockiert CSS / JS-Assets aus Composer-Bibliotheken .
  4. Gehen Sie in das Verzeichnis / modules und machen Sie git clone https://github.com/dsnopek/civicrm-drupal.git --branch composer-library
  5. Gehen Sie zur Seite "Erweitern" ( /admin/modules) und installieren Sie das CiviCRM-Modul
  6. Drupal-Cache über Drush löschen ( drush cr)
  7. Melden Sie sich per CRM-19878 ab und wieder an
  8. CiviCRM funktioniert! :-)

Nach all dem verwendet CiviCRM Symfony 2.8 von Drupal und die Abhängigkeiten in Drupals Herstellerverzeichnis und lädt nichts aus seinem eigenen Herstellerverzeichnis. Huzzah!

Ich habe getestet, ob das "Telefon" -Modul aktiviert ist, was vor diesen Änderungen fehlgeschlagen ist (siehe meine Schritte zum Reproduzieren ), aber es funktioniert einwandfrei. :-)

David Snopek
quelle
Hier ist eine Frage, die sich auf all das bezieht: Verwenden von Composer ... ist es möglich, dass ein Paket Symfony 2.8 verwendet und ein anderes Paket Symfony 3.2 ...
jackrabbithanna
Es gibt ziemlich schwierige institutionelle Widerstände dagegen, dass CiviCRM immer die Version von Symfony verwendet, die Drupal 8/9 unterstützt.
Jackrabbithanna
1
"using composer .... ist es möglich, dass ein Paket Symfony 2.8 verwendet und ein anderes Paket Symfony 3.2" -> Nein, PHP kann nicht zwei Klassen mit demselben Namen haben. Das ist eigentlich keine Komponistensache.
David Snopek
"Es gibt einen ziemlich schwierigen institutionellen Widerstand dagegen, dass CiviCRM immer die Version von Symfony verwendet, die Drupal 8/9 unterstützt." -> Für den CiviCRM-Kern im Upstream ist nur erforderlich, dass der Code mit dem in Drupal später verwendeten Symfony kompatibel ist . Es müsste nicht gebündelt oder standardmäßig verwendet werden, sondern nur kompatibel sein, d. H. Vermeiden Sie veraltete Methoden / Klassen / Features.
David Snopek
Ich verstehe, warum man die beiden Hauptversionen von Symfony nebeneinander betreiben möchte - SemVer impliziert die Notwendigkeit. Ich halte es jedoch für wichtig, dass viele Symfony-Komponenten in Version 2/3 ähnlich sind und dass Civis Integration von Version 2 recht bescheiden war. Daher bin ich optimistisch, PHP-Code zu haben oder zu erhalten, der mit beiden kompatibel ist. IMHO, die eigentliche Arbeit ist die Aktualisierung der Vertriebskanal- und Verzeichnisstruktur.
Tim Otten
5

Ich denke nicht, dass das möglich ist.

Drupal 8.4 ist eigentlich schon auf Symfony 3 umgestiegen, obwohl es noch ähnliche Diskussionen zum Thema Drush gibt, die das gleiche Problem haben. siehe Drush 8.x installiert Drupal 8.4.x nicht und Drush Master installiert Drupal 8.3.x nicht und Symfony-Komponenten werden auf 3.2.6 aktualisiert

Es ist nicht möglich, zwei verschiedene Symfony-Versionen zu laden, entweder Sie brechen Ihre Integration oder Sie brechen Drupal. Vielleicht ist symfony3 noch nicht in Version 8.4, aber die Sicherheitsunterstützung für symfony2 endet noch vor der Sicherheitsunterstützung für Drupal8. Irgendwann müssen wir also wechseln.

Berdir
quelle
Nun ..... Alles funktioniert außer der Installation von Modulen von admin / modules .... die Installation von Modulen mit Drush funktioniert ... Alle CiviCRM-Seiten funktionieren. Ich bin also nicht davon überzeugt, dass es unmöglich ist. Warum sollte es unmöglich sein?
Jackrabbithanna
1
Sie können nicht zwei verschiedene Versionen derselben Klasse gleichzeitig laden, das ist nicht möglich. Der Fehler klingt genau so, wie ich es erwartet hätte. Sie haben es geschafft, zuerst die 2.5-Version der Definitionsklasse zu laden, und dann bricht Drupal ab, weil erwartet wird, dass eine Methode existiert, die es tatsächlich nicht gibt. Und die Unterschiede werden größer, wenn Drupal zu Symfony 3 wechselt. Ich verstehe nicht ganz, warum Sie mit 2.5, 2.8 nicht weiterkommen und abwärtskompatibel sein sollten (aber nicht umgekehrt, wie Sie herausfanden). Sie sollten also in der Lage sein, CiviCRM so zu aktualisieren, dass 2.8 erforderlich ist?
Berdir
1
Wie ich in meinem Kommentar erwähnt habe, bin ich davon ausgegangen, dass ich Ihnen nicht antworten möchte, aber das ändert nichts daran. Keines der Projekte, die Sie erwähnen, verwendet Symfony (Joomal verwendet anscheinend eine Handvoll Komponenten, die möglicherweise nicht in Konflikt stehen, aber letztendlich auch in Konflikt geraten). Sie können das also nicht vergleichen. Es ist technisch unmöglich, zwei in Konflikt stehende Versionen derselben Klasse zu laden. Daran kann nichts geändert werden. Das ist der Grund, warum Abhängigkeiten ein komplexes Geschäft sind und warum Komponisten existieren. Anstatt Bibliotheken zu verwenden, sollten Sie sich wahrscheinlich mit der Verwendung von Composer befassen und CiviCRM mit mehreren Symfony-Versionen kompatibel machen
Berdir,
2
Die Sicherheitsunterstützung für Symfony 2.5 wurde gemäß symfony.com/roadmap?version=2.5#checker im Jahr 2015 eingestellt. Dies bedeutet, dass CiviCRM auf einer unsicheren und veralteten Symfony-Version basiert. Das allein sollte ausreichen, um sie davon zu überzeugen, dass ein Update notwendig ist, zumindest auf Version 2.8, es geht nicht nur um Drupal8.
Berdir
1
@DavidSnopek richtig, was Sie in Ihrer Antwort geschrieben haben, ist im Grunde das, was ich auch in meinen Kommentaren erwähnt habe, aber solange composer.json von CiviCRM "~ 2.5.0" für seine Symfony-Komponenten spezifiziert, wird das nicht funktionieren. Siehe github.com/civicrm/civicrm-core/blob/master/composer.json . Also meine Antwort "Sie können nicht zwei verschiedene Versionen verwenden" ist IMHO immer noch richtig. Sie können nur die Versionsbeschränkungen in civicrm verbessern / aktualisieren und sie dann über den Composer installieren und dieselbe Version verwenden.
Berdir
1

Theoretisch sind hier nur der Dateispeicherort und der Klassennamensraum von Bedeutung. Leider können Sie die einzigen Tools, die mir in Composer bekannt sind, nicht pro VERSION, sondern nur pro Paketnamen angeben.

Haben Sie versucht, es als vollständig separaten Autoloader einzurichten?

Ohthehugemanatee
quelle
Können Sie genauer erklären, was Sie meinen?
Jackrabbithanna
Unter getcomposer.org/doc/faqs/… erfahren Sie, wie Sie den benutzerdefinierten Speicherort festlegen . Ich habe gesehen, wie Leute ein Projekt gabelten, nur um dies zu ermöglichen . Am Ende ist der Autoloader nur eine PHP-Datei, so dass Sie Ihren eigenen Autoloader schreiben können, der je nach den von Ihnen gewünschten Faktoren entscheidet, welchen er enthält.
Ohthehugemanatee
Ebenfalls relevant: stackoverflow.com/questions/30000063/…
Ohthehugemanatee
Klar, ATM gibt es keine composer-basierte Installationsmethode, um Civi mit D8 zu installieren. Ich hatte zwar vielleicht das war ein Weg, um dies zu erreichen. Darum ging es bei dem in der Frage erwähnten ServiceProvider-Objekt, beispielsweise darum, Drupal einen PSR-4-Namespace hinzuzufügen, um auf die CiviCRM-Bibliothek zu verweisen. .... 'um' Civicrm \ Symfony \ .. 'zu verwenden? Verzeihen Sie meine Unkenntnis der Komponisten.
Jackrabbithanna