Come installare un modulo che include una versione diversa di Symfony?


17

Sono sviluppatore e manutentore del progetto CiviCRM. Abbiamo provato a realizzare una versione Drupal 8 CiviCRM e abbiamo fatto molta strada. Stiamo battendo la testa contro le nostre tastiere collettive cercando di immaginare un grosso blocco per il progetto.

CiviCRM usa Symfony da un po 'di tempo e la versione inclusa è diversa da quella fornita con Drupal.

Possiamo installare CiviCRM con Drupal 8, ma dopo averlo installato, non possiamo installare nessun altro modulo Drupal.

Credo che si riduce a una situazione in cui la versione CiviCRM di Symfony viene caricata prima della versione Drupal, e questo causa problemi.

Qualcuno sa di un modulo Drupal 8 che include una versione diversa di Symfony rispetto a quella fornita con Drupal?

Di recente mi sono imbattuto nel progetto Ludwig. Questo modulo consente la registrazione di spazi dei nomi in una classe che si estendeServiceProviderBase .

Sarebbe possibile per la versione Drupal 8 del modulo CiviCRM di includere un file CivicrmServiceProvider.php, che definisce una CivicrmServiceProviderclasse e un register()metodo che aggiunge uno spazio dei nomi contenitore per consentire che funzioni?

Molti file CiviCRM hanno usedichiarazioni come Drupal che iniziano con Symfony, come qui .

In realtà abbiamo inserito CiviCRM Core nella cartella doc_root / libraries di Drupal e utilizziamo il modulo libraries.

Questo è il repository per il modulo CiviCRM Drupal versione 8.x , se qualcuno vuole vedere cosa abbiamo ottenuto finora. Se qualcuno ha l'elisir magico per questo, posso dirti che ci sarebbero molte persone felici nella nostra comunità. Quindi, se sai come aiutarci, per favore fallo.

CiviCRM si installa e le pagine di CiviCRM funzionano. Ciò che non funziona è che dopo l'installazione di CiviCRM, non è possibile installare altri moduli tramite la pagina admin / modules. Per quanto ne so questa è l'unica cosa che è rotta. Anche l'installazione di moduli con Drush, dopo l'installazione di CiviCRM, funziona.

Il tentativo di installare un altro modulo dopo l'installazione di CiviCRM provoca il seguente errore:

Errore irreversibile PHP: chiamata al metodo indefinito Symfony \ Component \ DependencyInjection \ Definition :: setFactory () in /var/www/html/civi-for-d8/core/lib/Drupal/Core/DependencyInjection/YamlFileLoader.php on line 206

Questo è in Drupal 8.3.5. Il tentativo di installare CiviCRM per Drupal 8 in un'istanza pulita di Drupal 8.4-dev provoca il seguente errore:

Drupal \ Component \ Serialization \ Exception \ InvalidDataTypeException: l'indicatore riservato "@" non può avviare un semplice scalare; devi citare lo scalare alla riga 8 (vicino a "argomenti: [@string_translation, @ civicrm.page_state]"). in Drupal \ Component \ Serialization \ YamlSymfony :: decode () (riga 40 di /var/www/html/drupal84/core/lib/Drupal/Component/Serialization/YamlSymfony.php).


Su cellulare, ma quale versione di Symfony? 8.4 utilizzerà 3.x, un salto da v2.
Matt Glaman,

Siamo alla versione 2.5.0 in CiviCRM
jackrabbithanna,

Alcuni documenti relativi al problema: issues.civicrm.org/jira/browse/CRM-17652 .... Una persona riferisce di non aver visto il problema, ma non ne sono sicuro, tutti gli altri che provano a ricevere un errore come riportato qui
jackrabbithanna,

4
Non penso sia possibile. Drupal 8.4 in realtà è già passato a Symfony3 anche se ci sono ancora discussioni simili relative a Drush, che ha lo stesso problema. Non è possibile caricare due diverse versioni di symfony, o interrompi la tua integrazione o rompi Drupal. Forse symfony3 non sarà ancora in 8.4, ma il supporto di sicurezza per symfony2 finirà prima del supporto di sicurezza di Drupal8, quindi a un certo punto, dovremo cambiare
Berdir,

1
@Berdir che potrebbe dare una buona risposta?
Clive

Risposte:


8

Quindi, penso che se CiviCRM fosse installato in Drupal 8 tramite compositore (cioè composer require civicrm/civicrm-corenella radice Drupal) e l'uso di Symfony da parte di CiviCRM fosse compatibile con Symfony 2.8 o 3.x (cioè non usando funzionalità deprecate), questo potrebbe funzionare.

Ciò farebbe installare tutto nella directory del fornitore di Drupal, invece di averne due, e significherebbe che CiviCRM userebbe la versione di Symfony in Drupal 8. Ma se CiviCRM fosse compatibile con le versioni successive di Symfony (anche se includesse una versione precedente di Drupal 6 e 7 e altri CMS) dovrebbe andare bene.

Penso?

AGGIORNATO: Sì, funziona - l'ho provato. :-) Originariamente avevo pubblicato il seguito nella coda di emissione di CiviCRM ( CRM-17652 ), ma ripubblicando qui per completezza.

La grande idea:

Poiché il compositore è abbastanza nuovo per molte persone, cercherò di andare passo dopo passo, da alcune cose di alto livello fino a un modo in cui potrebbe essere fatto in CiviCRM:

  • Composer consente alle applicazioni di richiedere le librerie di cui ha bisogno (e le librerie, ovviamente, possono richiedere altre librerie).
  • Le librerie hanno un file composer.json che dice di quali altre librerie ha bisogno e con quali versioni è compatibile (ma non necessariamente una singola versione specifica - di solito un intervallo di versioni, come ad esempio ^2.4.3un minimo di 2.4.3 e fino a (ma non incluso) 3.0.0)
  • Le applicazioni hanno un composer.json che descrive allo stesso modo le librerie necessarie e la compatibilità con una gamma di versioni, ma la gamma è davvero di aiuto con l'aggiornamento. Un'applicazione avrà anche un composer.lock che è un insieme specifico di singole versioni
  • Le librerie possono anche avere un composer.lock per i propri test o distribuzioni (come costruire il tarball di rilascio con le dipendenze raggruppate), ma questo viene ignorato quando un'applicazione richiede la libreria data (vedi https://getcomposer.org/doc/02 -libraries.md # lock-file )
  • Quando un'applicazione vuole richiedere una nuova libreria, il compositore trova un'intersezione di compatibilità della versione tra tutte le cose che l'applicazione richiede (comprese tutte le librerie già installate e le loro dipendenze) e la nuova libreria, eventualmente facendo alcuni aggiornamenti per allineare tutto ( o errore se non riesce a trovare un mix compatibile di versioni)
  • In questo caso, CiviCRM è una libreria e un particolare sito Drupal 8 è l'applicazione (il core stesso di Drupal è una libreria)
  • CiviCRM potrebbe dire che "richiede" Symfony ^2.5nel suo composer.json, il che significa che è compatibile con le versioni da 2.5.0 a (ma non incluse) 3.0.0
  • Quando un sito Drupal 8 desidera utilizzare CiviCRM, l'amministratore del sito utilizza composer require civicrm/civicrm-coreper richiedere la libreria CiviCRM e tutte le sue dipendenze. Se CiviCRM è compatibile con Symfony 2.8 (come usato in Drupal 8.3.x) tutto verrà installato e funzionerà perfettamente, usando il singolo Symfony 2.8 di Drupal. Tutte le dipendenze finiscono nella directory del fornitore di Drupal.
  • Tuttavia, CiviCRM potrebbe mantenere Symfony 2.5 nel suo compositore.lock, il che significa che i test lo userebbero, e i tarball per Drupal 6 & 7 e altri CMS raggrupperebbero Symfony 2.5

La proposta:

  1. Aggiorna il composer.json di CiviCRM in modo che possa essere utilizzato come libreria da CMS basati su compositori come Drupal 8 (ma probabilmente altri potrebbero spostarsi in quel modo in futuro - il compositore sta diventando abbastanza popolare)
  2. Assicurati che il core CiviCRM sia compatibile con Symfony 2.8 e 3.0 (usati rispettivamente da Drupal 8.3.xe 8.4.x) ma mantieni la versione "ufficialmente supportata" (attualmente Symfony 2.5) in composer.lock per i test e il tarball per la distribuzione. Essere compatibili con più versioni di Symfony potrebbe non essere così difficile come sembra: esistono diverse librerie compatibili con Symfony 2.8 e 3.0. Potrebbe trattarsi solo di evitare metodi / classi / caratteristiche deprecati! Il composer.json dovrà essere aggiornato per riflettere questo
  3. Usa il compositore per installare la libreria CiviCRM su Drupal 8 anziché copiarla nella directory delle librerie. Questo sta diventando il modo normale di installare librerie PHP di terze parti in Drupal 8 (questo è ampiamente utilizzato da Drupal Commerce, ad esempio)

Per i CMS basati su compositori, penso davvero che questa sia la strada giusta. Mentre questo problema sta attualmente interessando Symfony e Drupal, poiché la comunità PHP inizia a utilizzare sempre più librerie di terze parti tramite il compositore, ciò potrebbe benissimo influenzare altri CMS con conflitti di altre versioni.

Alcuni codici funzionanti per testare:

Quindi, come promesso, in realtà ho fatto in modo che questo funzionasse in misura limitata :-) Sto arrivando totalmente a questo punto di vista Drupal / Composer / Symfony - Non ho molta esperienza con CiviCRM, quindi probabilmente c'è modi migliori per eseguire il mio processo di seguito. Accolgo con favore qualsiasi consiglio!

  1. Scarica e installa Drupal 8.3.5 (o l'ultimo sviluppatore di Drupal 8.4.x!)
  2. Vai nella directory principale nella shell ed esegui questi comandi per installare CiviCRM tramite il compositore: https://gist.github.com/dsnopek/56311dbea347874e75180883efabb620
  3. Se si utilizza Apache, rimuovere il file del fornitore / .htacess. Questa è una misura di sicurezza di Drupal, che impedisce il caricamento di risorse come CSS / JS. Ciò richiederà una collaborazione con il progetto Drupal per trovare una soluzione adeguata perché rimuovere del tutto questo file è una cattiva idea sulla produzione. Vedi: vendor / .htaccess che blocca gli asset CSS / JS dalle librerie del compositore .
  4. Vai nella directory / modules e fai git clone https://github.com/dsnopek/civicrm-drupal.git --branch composer-library
  5. Vai alla pagina "Estendi" ( /admin/modules) e installa il modulo CiviCRM
  6. Svuota la cache di Drupal tramite Drush ( drush cr)
  7. Disconnettersi e riconnettersi per CRM-19878
  8. CiviCRM funziona! :-)

Dopo tutto questo, CiviCRM sta usando Symfony 2.8 di Drupal e le dipendenze nella directory del fornitore di Drupal e non sta caricando nulla dalla propria directory del fornitore. Huzzah!

Ho provato ad abilitare il modulo "Telefono" che non ha funzionato prima di queste modifiche (vedere i miei passaggi per la riproduzione ), ma funziona perfettamente con esse. :-)


Quindi, ecco una domanda relativa a tutto questo, usando il compositore .... è possibile avere un pacchetto che usa Symfony 2.8, e un altro pacchetto usa Symfony 3.2 ....
jackrabbithanna,

Esiste una resistenza istituzionale piuttosto difficile a CiviCRM che richiede sempre di utilizzare la versione di Symfony utilizzata da Drupal 8/9.
jackrabbithanna,

1
"usando il compositore .... è possibile che un pacchetto usi Symfony 2.8 e un altro pacchetto usi Symfony 3.2" -> No, PHP non può avere due classi con lo stesso nome. Questa non è davvero una cosa da compositore.
David Snopek,

"C'è una resistenza istituzionale piuttosto difficile a CiviCRM richiesta per usare sempre quale versione di Symfony è usata da Drupal 8/9" -> Tutto ciò che sarebbe necessario per il core CiviCRM a monte è che il codice sia compatibile con il successivo Symfony usato in Drupal. Non dovrebbe raggrupparlo o usarlo per impostazione predefinita, basta essere compatibili, ad es. evitare metodi / classi / caratteristiche deprecati.
David Snopek,

Capisco perché uno sarebbe interessato a gestire le due versioni principali di Symfony fianco a fianco - SemVer sorta implica la necessità. Ma penso sia importante che ampie strisce di componenti di Symfony siano simili in v2 / v3 e che l'integrazione di Civi di v2 sia stata piuttosto modesta. Quindi sono ottimista sull'avere o ottenere il codice PHP che è compatibile con entrambi. IMHO, il vero lavoro sta aggiornando il canale di distribuzione e la struttura delle directory.
Tim Otten,

5

Non penso sia possibile.

Drupal 8.4 in realtà è già passato a Symfony 3 anche se ci sono ancora discussioni simili relative a Drush, che ha lo stesso problema. vedi Drush 8.x non installa Drupal 8.4.xe Drush master non installa Drupal 8.3.x e i componenti di Symfony vengono aggiornati alla 3.2.6

Non è possibile caricare due diverse versioni di symfony, o interrompi la tua integrazione o rompi Drupal. Forse symfony3 non sarà ancora in 8.4, ma il supporto di sicurezza per symfony2 finirà prima del supporto di sicurezza di Drupal8, quindi a un certo punto dovremo cambiare.


Bene ..... Tutto funziona tranne l'installazione di moduli da admin / moduli .... l'installazione di moduli con Drush funziona ... Tutte le pagine di CiviCRM funzionano. Quindi non sono convinto che sia impossibile. Perché sarebbe impossibile?
jackrabbithanna,

1
Non è possibile caricare due versioni diverse della stessa classe contemporaneamente, ciò non è possibile. L'errore sembra esattamente quello che mi aspetto che accada. Sei riuscito a caricare prima la versione 2.5 della classe Definition e poi Drupal si interrompe perché si aspetta che esista un metodo che in realtà non esiste. E le differenze aumenteranno man mano che Drupal passa a Symfony 3. Non capisco bene perché sei bloccato con 2.5, 2.8 è un aggiornamento minore e dovrebbe essere retrocompatibile (ma non viceversa come hai scoperto). Quindi dovresti essere in grado di aggiornare CiviCRM per richiedere 2.8?
Berdir,

1
Come ho già detto nel mio commento, ho assunto che non ti piacerebbe che io rispondessi, ma questo non lo cambia. Nessuno di quei progetti che menzioni usano symfony (joomal sembra usare una manciata di componenti che potrebbero non essere in conflitto ma che eventualmente alla fine), quindi non puoi confrontarlo. È tecnicamente impossibile caricare due versioni in conflitto della stessa classe, nulla può cambiarlo. Ecco perché le dipendenze sono un business complesso e perché esiste il compositore. Invece di usare le librerie, dovresti probabilmente cercare di usare il compositore e rendere CiviCRM compatibile con più versioni di symfony
Berdir,

2
Inoltre, il supporto per la sicurezza di Symfony 2.5 è terminato nel 2015 secondo symfony.com/roadmap?version=2.5#checker , il che significa che CiviCRM è basato su una versione di Symfony non sicura e obsoleta. Questo da solo dovrebbe essere sufficiente per convincerli che è necessario un aggiornamento, almeno alla versione 2.8, non riguarda solo Drupal8.
Berdir,

1
@DavidSnopek, quello che hai scritto nella tua risposta è fondamentalmente quello che ho menzionato nei miei commenti, ma fintanto che composer.json di CiviCRM specifica "~ 2.5.0" per i suoi componenti di symfony, non funzionerà. Vedi github.com/civicrm/civicrm-core/blob/master/composer.json . Quindi la mia risposta "non puoi usare due versioni diverse" è ancora corretta IMHO, puoi solo migliorare / aggiornare i contorni della versione in civicrm e quindi installarlo attraverso il compositore e usare la stessa versione.
Berdir,

1

Teoricamente gli unici problemi qui sono la posizione del file e lo spazio dei nomi della classe. Sfortunatamente gli unici strumenti che conosco in compositore per farlo non ti consentono di specificare per VERSIONE, solo per nome del pacchetto.

Hai provato a configurarlo come un caricatore automatico completamente separato?


Puoi spiegarci più in dettaglio cosa intendi?
jackrabbithanna,

getcomposer.org/doc/faqs/… è come eseguire la posizione personalizzata. Ho visto gente borsare un progetto solo per renderlo possibile ... Anche getcomposer.org/doc/06-config.md#prepend-autoloader per l'opzione di mantenere separato il caricatore automatico del compositore. Alla fine il caricatore automatico è solo un file php, quindi potresti scrivere il tuo caricatore automatico che decide quale includere da includere in base a qualunque fattore ti piaccia.
Ohthehugemanatee,


Sia chiaro, ATM non esiste un metodo di installazione basato sul compositore per installare Civi con D8. Forse avevo pensato che fosse un modo per farlo. Questo era l'oggetto di ServiceProvider menzionato nella domanda, come aggiungere uno spazio dei nomi PSR-4 a Drupal per puntare alla libreria CiviCRM ... Se lo facessi, Civi dovrebbe cambiare tutti i suoi file da 'usa Symfony \ .... 'per' usare Civicrm \ Symfony \ .. '? Perdonate la mia ignoranza del compositore per favore.
jackrabbithanna,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.