Bagaimana cara menginstal modul yang menyertakan versi Symfony yang berbeda?


17

Saya seorang pengembang dan pemelihara untuk proyek CiviCRM. Kami telah mencoba untuk membuat CiviCRM versi Drupal 8, dan telah berhasil. Kami memukul kepala kami dengan keyboard kolektif kami mencoba mencari penghalang utama untuk proyek ini.

CiviCRM telah menggunakan Symfony untuk sementara waktu, dan versi yang disertakan berbeda dari apa yang dikirimkan dengan Drupal.

Kita dapat menginstal CiviCRM dengan Drupal 8, tetapi setelah Anda menginstalnya, kami tidak dapat menginstal modul Drupal lainnya.

Saya percaya ini bermuara pada situasi di mana entah bagaimana versi CiviCRM dari Symfony dimuat sebelum versi Drupal, dan ini menyebabkan masalah.

Adakah yang tahu tentang modul Drupal 8 yang menyertakan versi Symfony yang berbeda dari modul yang dikirimkan bersama Drupal?

Baru-baru ini saya berlari melintasi proyek Ludwig. Modul ini memungkinkan pendaftaran ruang nama di kelas yang diperluasServiceProviderBase .

Apakah mungkin untuk versi Drupal 8 dari modul CiviCRM untuk menyertakan file CivicrmServiceProvider.php, yang mendefinisikan CivicrmServiceProviderkelas, dan register()metode yang menambahkan namespace wadah untuk memungkinkan ini berfungsi?

Banyak file CiviCRM memiliki usepernyataan seperti Drupal yang dimulai dengan Symfony, seperti di sini .

Kami benar-benar memasukkan CiviCRM Core ke folder Drupal doc_root / libraries, dan menggunakan modul libraries.

Ini adalah repo untuk modul 8.vi CiviCRM Drupal modul , jika seseorang ingin melihat apa yang kami dapatkan sejauh ini. Jika seseorang memiliki ramuan ajaib untuk ini, saya dapat memberitahu Anda akan ada banyak orang bahagia di komunitas kami. Jadi, jika Anda tahu cara membantu kami, silakan lakukan.

CiviCRM menginstal, dan halaman CiviCRM berfungsi. Yang tidak berfungsi adalah bahwa setelah CiviCRM diinstal, kami tidak dapat menginstal modul lain melalui halaman admin / modul. Sejauh yang saya tahu itulah satu-satunya hal yang rusak. Juga memasang modul dengan Drush, setelah menginstal CiviCRM, tidak berfungsi.

Mencoba menginstal modul lain setelah CiviCRM diinstal menyebabkan kesalahan berikut:

Kesalahan PHP fatal: Panggilan ke metode yang tidak ditentukan Symfony \ Component \ DependencyInjection \ Definition :: setFactory () di /var/www/html/civi-for-d8/core/lib/Drupal/Core/DependencyInjection/YamlFileLoader.php pada baris 206

Itu dalam Drupal 8.3.5. Mencoba menginstal CiviCRM untuk Drupal 8 ke dalam instance Drupal 8.4-dev yang bersih menyebabkan kesalahan berikut:

Drupal \ Component \ Serialization \ Exception \ InvalidDataTypeException: Indikator yang dicadangkan "@" tidak dapat memulai skalar biasa; Anda perlu mengutip skalar di baris 8 (dekat "argumen: [@string_translation, @ civicrm.page_state]"). dalam Drupal \ Component \ Serialization \ YamlSymfony :: decode () (baris 40 dari /var/www/html/drupal84/core/lib/Drupal/Component/Serialization/YamlSymfony.php).


Di ponsel, tetapi versi Symfony apa? 8.4 akan menggunakan 3.x, lompatan dari v2.
Matt Glaman

Kami berada di versi 2.5.0 di CiviCRM
jackrabbithanna

Beberapa dokumentasi masalah: issues.civicrm.org/jira/browse/CRM-17652 .... Satu orang melaporkan dia tidak melihat masalah, tapi saya tidak yakin tentang itu, semua orang yang mencoba mendapatkan kesalahan seperti yang dilaporkan di sana
jackrabbithanna

4
Saya rasa ini tidak mungkin. Drupal 8.4 sebenarnya sudah beralih ke Symfony3 meskipun masih ada diskusi serupa terkait dengan drush, yang memiliki masalah yang sama. Tidak mungkin memuat dua versi symfony yang berbeda, baik Anda memutus integrasi Anda atau Anda merusak Drupal. Mungkin symfony3 belum akan masuk dalam 8,4, tetapi dukungan keamanan untuk symfony2 akan berakhir sebelum dukungan keamanan Drupal8, jadi pada titik tertentu, kita harus beralih
Berdir

1
@Erdir yang mungkin membuat jawaban yang bagus?
Clive

Jawaban:


8

Jadi, saya pikir jika CiviCRM dipasang ke Drupal 8 melalui komposer (mis. composer require civicrm/civicrm-coreDi root Drupal) dan CiviCRM menggunakan Symfony kompatibel dengan Symfony 2.8 atau 3.x (mis. Tidak menggunakan fungsi yang sudah ketinggalan zaman), ini bisa bekerja.

Ini akan mendapatkan semua yang diinstal di direktori vendor Drupal, daripada memiliki dua, dan itu berarti CiviCRM akan menggunakan versi Symfony di Drupal 8. Tetapi jika CiviCRM kompatibel dengan versi Symfony yang lebih baru (bahkan jika itu bundel versi yang lebih lama untuk Drupal 6 & 7 dan CMS lainnya) harus baik-baik saja.

Kupikir?

DIPERBARUI: Ya, itu berfungsi - saya mencobanya. :-) Saya awalnya memposting di bawah ini dalam antrian masalah CiviCRM ( CRM-17652 ), tetapi memposting ulang di sini untuk kelengkapan.

Ide besar:

Karena komposer cukup baru bagi banyak orang, saya akan mencoba untuk selangkah demi selangkah, dari beberapa komposer tingkat tinggi sampai ke satu cara yang dapat dilakukan di CiviCRM:

  • Komposer memungkinkan aplikasi untuk membutuhkan perpustakaan yang dibutuhkan (dan perpustakaan, tentu saja, dapat membutuhkan perpustakaan lain).
  • Perpustakaan memiliki file composer.json yang mengatakan perpustakaan apa yang dibutuhkannya dan versi apa yang kompatibel dengannya (tetapi belum tentu versi tunggal yang spesifik - biasanya berbagai versi, seperti ^2.4.3yang mengatakan minimum 2,4.3 dan lebih tinggi (tetapi tidak termasuk) 3.0.0)
  • Aplikasi memiliki composer.json yang juga menggambarkan pustaka yang diperlukan dan kompatibilitas dengan berbagai versi, tetapi jangkauannya benar-benar membantu dengan pembaruan. Sebuah aplikasi juga akan memiliki composer.lock yang merupakan kumpulan spesifik dari masing-masing versi
  • Perpustakaan juga dapat memiliki komposer. Buka pengujian atau distribusi mereka sendiri (seperti membangun tarball rilis dengan dependensi yang dibundel), tetapi ini diabaikan ketika aplikasi membutuhkan perpustakaan yang diberikan (lihat https://getcomposer.org/doc/02 -libraries.md # lock-file )
  • Ketika sebuah aplikasi ingin membutuhkan pustaka baru, komposer menemukan persimpangan kompatibilitas versi antara semua hal yang diperlukan aplikasi (termasuk semua pustaka yang telah diinstal dan dependensinya) dan pustaka baru, mungkin melakukan beberapa pembaruan untuk membuat semuanya berbaris ( atau kesalahan jika tidak dapat menemukan campuran versi yang kompatibel)
  • Dalam hal ini, CiviCRM adalah perpustakaan, dan situs Drupal 8 tertentu adalah aplikasinya (inti Drupal sendiri adalah perpustakaan)
  • CiviCRM bisa mengatakan itu "membutuhkan" Symfony ^2.5di composer.json yang berarti itu kompatibel dengan versi 2.5.0 hingga (tetapi tidak termasuk) 3.0.0
  • Ketika situs Drupal 8 ingin menggunakan CiviCRM, admin situs menggunakan composer require civicrm/civicrm-coreperpustakaan CiviCRM dan semua dependensinya. Jika CiviCRM kompatibel dengan Symfony 2.8 (seperti yang digunakan dalam Drupal 8.3.x) semuanya akan diinstal dan berfungsi dengan baik, menggunakan single Symfony 2.8 dari Drupal. Semua dependensi berakhir di direktori vendor Drupal.
  • Namun, CiviCRM dapat menyimpan Symfony 2.5 di komposernya .lock, yang berarti tes akan menggunakannya, dan tarball untuk Drupal 6 & 7 dan CMS lain akan membundel Symfony 2.5

Proposal:

  1. Perbarui composer.json dari CiviCRM sehingga dapat digunakan sebagai perpustakaan oleh CMS berbasis komposer seperti Drupal 8 (tetapi mungkin orang lain bisa bergerak seperti itu di masa depan - komposer menjadi cukup populer)
  2. Pastikan inti CiviCRM kompatibel dengan Symfony 2.8 dan 3.0 (masing-masing digunakan oleh Drupal 8.3.x dan 8.4.x) tetapi simpan versi "yang didukung secara resmi" (saat ini Symfony 2.5) di composer.lock untuk pengujian dan tarball untuk distribusi. Kompatibel dengan beberapa versi Symfony mungkin tidak sesulit kedengarannya - ada sejumlah perpustakaan di luar sana yang kompatibel dengan Symfony 2.8 dan 3.0. Mungkin hanya masalah menghindari metode / kelas / fitur usang! Komposer.json perlu diperbarui untuk mencerminkan ini
  3. Gunakan komposer untuk menginstal perpustakaan CiviCRM pada Drupal 8 daripada menyalin ke direktori perpustakaan. Ini menjadi cara normal untuk menginstal perpustakaan PHP pihak ketiga di Drupal 8 (ini digunakan secara luas oleh Drupal Commerce, misalnya)

Untuk CMS berbasis komposer, saya benar-benar berpikir ini adalah The Right Way. Sementara masalah ini saat ini mempengaruhi Symfony dan Drupal, karena komunitas PHP mulai menggunakan lebih banyak perpustakaan pihak ketiga melalui komposer, ini bisa sangat mempengaruhi CMS lain dengan konflik versi lainnya.

Beberapa kode kerja yang akan diuji:

Jadi, seperti yang dijanjikan, saya benar-benar membuat ini bekerja pada tingkat yang terbatas :-) Saya benar-benar datang pada ini dari perspektif Drupal / Komposer / Symfony - Saya tidak punya banyak pengalaman CiviCRM, jadi mungkin ada beberapa cara yang lebih baik untuk melakukan proses saya di bawah ini. Saya menyambut setiap saran!

  1. Unduh dan pasang Drupal 8.3.5 (atau pengembang Drupal 8.4.x!) Terbaru
  2. Pergilah ke direktori root di shell dan jalankan perintah ini untuk menginstal CiviCRM melalui komposer: https://gist.github.com/dsnopek/56311dbea347874e75180883efabb620
  3. Jika Anda menggunakan Apache, hapus file vendor / .htacess. Ini adalah langkah keamanan dari Drupal, yang mencegah sumber daya seperti CSS / JS dimuat. Ini akan memerlukan beberapa kolaborasi dengan proyek Drupal untuk mencari solusi yang tepat karena menghapus file ini sama sekali adalah ide yang buruk pada produksi. Lihat: vendor / .htaccess memblokir aset CSS / JS dari perpustakaan komposer .
  4. Masuk ke direktori / modules dan lakukan git clone https://github.com/dsnopek/civicrm-drupal.git --branch composer-library
  5. Buka halaman "Perpanjang" ( /admin/modules) dan instal modul CiviCRM
  6. Hapus cache drupal melalui Drush ( drush cr)
  7. Logout dan log in lagi per CRM-19878
  8. CiviCRM bekerja! :-)

Setelah semua ini, CiviCRM menggunakan Symfony 2.8 dari Drupal dan dependensi dalam direktori vendor Drupal, dan tidak memuat apa pun dari direktori vendor itu sendiri. Sabas!

Saya diuji mengaktifkan modul "Telepon" yang gagal sebelum perubahan ini (lihat langkah saya untuk mereproduksi ), tetapi berfungsi dengan baik dengan mereka. :-)


Jadi, inilah pertanyaan yang berkaitan dengan semua ini, menggunakan komposer .... apakah mungkin untuk memiliki satu paket menggunakan Symfony 2.8, dan paket lain menggunakan Symfony 3.2 ....
jackrabbithanna

Ada resistensi institusional yang cukup sulit bagi CiviCRM yang diminta untuk selalu menggunakan versi Symfony apa yang dilakukan oleh Drupal 8/9.
jackrabbithanna

1
"Menggunakan komposer .... apakah mungkin untuk memiliki satu paket menggunakan Symfony 2.8, dan paket lain menggunakan Symfony 3.2" -> Tidak, PHP tidak dapat memiliki dua kelas dengan nama yang sama. Ini bukan komposer.
David Snopek

"Ada resistensi institusional yang cukup sulit bagi CiviCRM yang diharuskan untuk selalu menggunakan versi Symfony apa yang dilakukan Drupal 8/9" -> Yang diperlukan dari inti CiviCRM hulu adalah bahwa kode tersebut adalah kompatibel dengan Symfony yang nantinya digunakan dalam Drupal. Itu tidak harus bundel atau menggunakannya secara default, cukup kompatibel, yaitu. hindari metode / kelas / fitur yang sudah usang.
David Snopek

Saya mengerti mengapa orang tertarik menjalankan dua versi utama Symfony secara berdampingan - SemVer agak menyiratkan perlunya. Tapi saya pikir penting bahwa petak besar komponen Symfony serupa di v2 / v3, dan integrasi Civi terhadap v2 cukup sederhana. Jadi saya optimis memiliki atau mencapai kode PHP yang kompatibel dengan keduanya. IMHO, pekerjaan sebenarnya adalah memperbarui saluran distribusi dan struktur direktori.
Tim Otten

5

Saya rasa ini tidak mungkin.

Drupal 8.4 sebenarnya sudah beralih ke Symfony 3 meskipun masih ada diskusi serupa terkait dengan drush, yang memiliki masalah yang sama. lihat Drush 8.x tidak menginstal Drupal 8.4.x dan Drush master tidak menginstal Drupal 8.3.x dan komponen Symfony diperbarui ke 3.2.6

Tidak mungkin memuat dua versi symfony yang berbeda, baik Anda memutus integrasi Anda atau Anda merusak Drupal. Mungkin symfony3 belum dalam 8,4, tetapi dukungan keamanan untuk symfony2 akan berakhir sebelum dukungan keamanan Drupal8, jadi pada beberapa titik, kita harus beralih.


Yah ..... Semuanya berfungsi kecuali menginstal modul dari admin / modul .... menginstal modul dengan Drush tidak berfungsi ... Semua halaman CiviCRM berfungsi. Jadi saya tidak yakin itu tidak mungkin. Mengapa itu tidak mungkin?
jackrabbithanna

1
Anda tidak dapat memuat dua versi berbeda dari kelas yang sama secara bersamaan, itu tidak mungkin. Kesalahannya terdengar persis seperti apa yang saya harapkan terjadi. Anda berhasil memuat versi 2.5 dari kelas Definisi pertama dan kemudian Drupal jeda karena mengharapkan metode yang ada sebenarnya tidak. Dan perbedaannya akan semakin besar ketika Drupal beralih ke Symfony 3. Saya tidak begitu mengerti mengapa Anda terjebak dengan 2.5, 2.8 adalah pembaruan kecil dan harus kompatibel ke belakang (tapi bukan sebaliknya seperti yang Anda ketahui). Jadi, Anda harus dapat memperbarui CiviCRM hingga membutuhkan 2,8?
Berdir

1
Seperti yang saya sebutkan di komentar saya, saya berasumsi bahwa Anda tidak akan suka saya menjawab, tetapi itu tidak mengubahnya. Tidak satu pun dari proyek yang Anda sebutkan menggunakan symfony (joomal tampaknya menggunakan beberapa komponen yang mungkin tidak bertentangan tetapi mungkin pada akhirnya), jadi Anda tidak dapat membandingkannya. Secara teknis tidak mungkin memuat dua versi yang saling bertentangan dari kelas yang sama, tidak ada yang bisa mengubah itu. Itu sebabnya dependensi adalah bisnis yang kompleks dan mengapa komposer ada. Alih-alih menggunakan perpustakaan, Anda mungkin harus melihat ke dalam menggunakan komposer dan membuat CiviCRM kompatibel dengan beberapa versi symfony
Berdir

2
Juga, dukungan keamanan untuk Symfony 2.5 berakhir pada 2015 menurut symfony.com/roadmap?version=2.5#checker , yang berarti CiviCRM dibangun di atas versi symfony yang tidak aman dan ketinggalan zaman. Itu saja harus cukup untuk meyakinkan mereka bahwa pembaruan diperlukan, setidaknya untuk versi 2.8, ini bukan hanya tentang Drupal8.
Berdir

1
@ DavidvidSnopek benar, apa yang Anda tulis dalam jawaban Anda pada dasarnya adalah apa yang saya sebutkan di komentar saya juga, tetapi selama composer.json dari CiviCRM menentukan "~ 2.5.0" untuk komponen symfonynya, itu tidak akan bekerja. Lihat github.com/civicrm/civicrm-core/blob/master/composer.json . Jadi jawaban saya "Anda tidak dapat menggunakan dua versi yang berbeda" adalah IMHO yang benar, Anda hanya dapat meningkatkan / memperbarui versi yang ada dalam civicrm lalu menginstalnya melalui komposer dan menggunakan versi yang sama.
Berdir

1

Secara teoritis satu-satunya masalah di sini adalah lokasi file dan namespace kelas. Sayangnya satu-satunya alat yang saya tahu di komposer untuk melakukan itu jangan biarkan Anda menentukan per VERSION, cukup per nama paket.

Sudahkah Anda mencoba menyetelnya sebagai autoloader yang benar-benar terpisah?


Bisakah Anda menjelaskan secara lebih rinci apa yang Anda maksud?
jackrabbithanna

getcomposer.org/doc/faqs/… adalah cara melakukan lokasi kustom. Saya telah melihat orang-orang membayar proyek hanya untuk memungkinkan ini ... Juga getcomposer.org/doc/06-config.md#prepend-autoloader untuk opsi untuk menjaga autoloader komposer terpisah. Pada akhirnya autoloader hanyalah sebuah file php, jadi Anda bisa menulis autoloader Anda sendiri yang memutuskan mana yang akan dimasukkan tergantung pada faktor apa pun yang Anda suka.
Ohthehugemanatee


Yang jelas, ATM tidak ada metode instalasi berbasis komposer untuk menginstal Civi dengan D8. Meskipun saya mungkin salah satu cara untuk mencapai ini. Itulah yang menjadi objek ServiceProvider yang disebutkan dalam pertanyaan itu, seperti menambahkan namespace PSR-4 ke Drupal untuk menunjuk ke perpustakaan CiviCRM ... Jika saya melakukan ini, Civi perlu mengubah semua file dari 'use Symfony \ .... 'untuk' menggunakan Civicrm \ Symfony \ .. '? Maafkan ketidaktahuan saya tentang komposer.
jackrabbithanna
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.