Apakah mungkin untuk memaksa kait pembaruan modul Anda untuk berjalan?

18

Saya adalah pembuat modul Date iCal, dan versi utama baru yang sedang saya kerjakan (3.x) memerlukan pembaruan skema dua bagian untuk pengguna yang menginstal 2.x. Saya telah menulis kait pembaruan yang membuat perubahan ini, tetapi jika salah satu pengguna saya gagal menjalankan skrip pembaruan basis data, mereka akan mendapatkan pesan kesalahan yang berkaitan dengan importir umpan iCal mereka.

Solusi yang tepat bagi mereka untuk menjalankan skrip pembaruan ... tetapi jika mereka hanya masuk dan secara manual mengubah importir mereka untuk menghilangkan pesan, importir mereka akan tetap rusak secara permanen (karena bagian kedua dari pembaruan skema tidak akan telah dieksekusi).

Jadi, apakah ada cara untuk menampilkan pesan kepada pengguna yang belum menjalankan pembaruan? Atau entah bagaimana secara paksa mengeksekusi kait pembaruan saat pertama kali memuat halaman terjadi ketika 3.x diinstal secara berlebihan pada 2.x?

coredumperror
sumber
2
Saya akan membayangkan Anda bisa melakukan variable_set()dalam fungsi pembaruan Anda yang menetapkan variabel ketika berhasil dijalankan yang bisa Anda lihat di dalamnya _preprocess_page()tetapi Anda akan melihatnya setiap kali jadi tidak yakin bagaimana kinerjanya yang ramah ini.
Jimajamma

Jawaban:

4

memperluas komentar dari Jimajamma:

lakukan variable_set()di fungsi pembaruan Anda yang menetapkan variabel ketika berhasil dijalankan yang bisa Anda lihat di dalam _preprocess_page ()

dan alih-alih memeriksa ini pada setiap pemuatan halaman, lakukan hanya jika menjelajahi area admin dan jika versi yang terinstal adalah 3.0 (3.1, 3.2, bunuh centang itu jika Anda berhenti mendukung versi lama sebagai jalur peningkatan).

Selain itu memanfaatkan hook_requirements untuk memberikan umpan balik pada halaman laporan status:

Periksa persyaratan pemasangan dan lakukan pelaporan status.
(...)
Fase 'runtime' tidak terbatas pada persyaratan instalasi murni tetapi juga dapat digunakan untuk informasi status yang lebih umum seperti tugas pemeliharaan dan masalah keamanan.

Andre Baumeier
sumber
15

Ada beberapa cara untuk memaksa pembaruan modul.

  1. Memanggil fungsi pembaruan secara langsung.

    $sandbox = [];
    module_load_include('install', 'FOO');
    FOO_update_7001($sandbox);
  2. Menyetel ulang versi skema ke tempat tujuan dan menjalankan pembaruan lagi seperti biasa.

    drupal_set_installed_schema_version('module_name', '7000');

    Atau setel ulang untuk hanya menjalankan kembali skema pembaruan terbaru:

    drupal_set_installed_schema_version('foo', drupal_get_installed_schema_version('foo') - 1);

    Catatan:

    • Ini dapat ditempatkan di hook_install, jadi selama proses pembaruan semua kait pembaruan berurutan akan dieksekusi.
    • Untuk menggunakan fungsi ini di luar file instalasi, Anda harus memasukkan Drupal install.incterlebih dahulu dan file instalasi modul, misalnya

      require_once DRUPAL_ROOT . '/includes/install.inc';
      module_load_include('install', 'foo');
    • Pertimbangkan ini_set('max_execution_time', 0);untuk menambahkan pembaruan pemasangan yang lebih lama untuk mencegah waktu tunggu PHP.
  3. Menggunakan drush. Temukan beberapa contoh di bawah ini:

    • drush eval 'module_load_include('install', 'foo'); $s = []; foo_update_7001($s);'
    • drush sqlq "UPDATE system SET schema_version = 7000 WHERE name = 'foo'" && drush -y updb
kenorb
sumber
1
Oh bagus, aku tidak tahu drupal_set_installed_schema_version(). Itu akan sangat berguna untuk men-debug kait pembaruan!
coredumperror
1
Jadi masalah utama dengan memasukkannya ke dalam hook_install()menjalankan pembaruan batch lama (kotak pasir). Dalam situasi ideal, harus ada cara untuk memicu pembaruan dengan cara yang sama seperti update.phpmemulai kembali utas PHP untuk mencegah waktu habis. Ide semut bagaimana melakukan itu?
Alex Skrypnyk
@ Alex. Desain dapat Anda tambahkan ini_set('max_execution_time', 0);sebelum memicu pembaruan.
kenorb
1

(Ulang ke jawaban)

Anda dapat "SELECT schema_version FROM system" untuk mendeteksi apakah pembaruan telah dilakukan. Jika tidak, maka tolak untuk menjalankan (dengan pesan kesalahan).

pengguna18099
sumber
Harap tulis ulang jawaban Anda, dan coba berikan contoh penggunaan.
Елин Й.
Abaikan komentar ini.
coredumperror
Saya khawatir itu tidak akan berhasil, karena fungsionalitas yang dimaksud adalah plugin untuk modul lain, dan saya tidak dapat mencegah modul itu membiarkan pengguna mengacaukan importir mereka.
coredumperror
Anda tidak dapat memeriksa versi skema modul yang ingin Anda pantau untuk pembaruan?
user18099
0

Saya setuju dengan saran di atas - satu-satunya tambahan saya akan menyelidiki "Pemicu dan Tindakan" juga - tampaknya Anda memerlukan tindakan (beri tahu pengguna atau jalankan pembaruan) untuk terjadi ketika pemicu (pengguna memeriksa halaman admin, dll) ditarik . Untuk menggunakan contoh lihat modul Contoh, ada aksi dan kode contoh pemicu. :)

mechhfly
sumber
0

function MYMODULE_install() { $functions = get_defined_functions(); foreach ($functions['user'] as $function) { if (strpos($function, 'MYMODULE_update_') === 0) { call_user_func($function); } } }

Alex Skrypnyk
sumber