Apakah mungkin mengaitkan ke acara variabel_set ()?

8

Saya ingin melacak acara perubahan sistem, untuk membuatnya dapat dikembalikan. Saat memeriksa variable_set (), saya melihat tidak ada kait yang disediakan untuk acara itu. Apakah ada cara bagi saya untuk melakukan ini?

Saya dapat mengubah untuk menghubungkan ke formulir pengaturan, tetapi ada banyak bentuk pengaturan untuk dilacak, jika saya dapat menghubungkan ke variabel_set () secara langsung, kode menjadi lebih sederhana.

Saya juga dapat melacak perubahan variabel dengan fitur + modul yang lebih kuat, tetapi lebih baik jika admin Drupal dapat menelusuri riwayat variabel tanpa menyentuh kode.

Andy Truong
sumber

Jawaban:

11

Tampaknya tidak mungkin hanya menggunakan Drupal, yang berarti:

variable_set()itu sendiri tidak meminta kait, tetapi menggunakan db_merge(). Fungsi itu menggunakan MergeQuerykelas. Sekarang, akan menyenangkan untuk dihubungkan hook_query_alter(), tetapi hanya berfungsi untuk kelas kueri yang mengimplementasikan QueryAlterableInterfaceantarmuka. Sayangnya, antarmuka ini sekarang hanya diimplementasikan oleh SelectQuerydan SelectQueryExtenderkelas, bukan oleh MergeQuerykelas.

Perhatikan bahwa meskipun Anda akan menemukan cara untuk membuat kelas anak MergeQuery, yang akan mengimplementasikan QueryAlterableInterface, dan membuat Drupal menggunakannya. hook_query_alter()hanya berfungsi pada kueri yang memiliki tag, dan variable_set()tidak menandai kuerinya, jadi kailnya tidak akan digunakan, kecuali jika Anda ingin meretas inti. Tetapi jika ya, Anda tidak perlu semua itu, Anda bisa meretas panggilan hook.

Jika Anda merasa hardcore, Anda dapat menggunakan pendekatan PHP yang lebih tidak langsung: $confadalah array global variabel konfigurasi; Anda dapat menulis modul yang akan menggantinya dengan objek yang bertindak seperti array, seperti dijelaskan pada Stack Overflow . Untuk menjadikannya pengganti yang baik, Anda perlu menerapkan ArrayAccess. Tarik semua nilai dari yang asli $confke objek Anda. Kemudian, dalam ArrayAccess::offsetSet()mengimplementasikan logika logging Anda.

Mołot
sumber
Saya lupa tentang jawaban lama saya ini dan saya sudah menemukan cara melakukan hampir semua hal dengan $confwaktu itu: D Semoga jawaban saya yang diperbarui akan membantu seseorang.
Mołot
Saya terkesan! : D
Letharion
@Letharion Terima kasih :) Suatu ketika saya menyukai sihir "object acting as ..." di PHP, dan saya masih ingat sedikit tentangnya;)
Mołot
6

Anda bisa menggunakan pemicu basis data, yang akan lebih cepat dari kode.

Berikut ini adalah dokumen MySQL .

  1. buat tabel untuk menyimpan nilai lama

    CREATE TABLE variable_backup
    (
        name varchar(128) not null,
        value longblob,
        updated datetime not null,
        primary key (name, updated)
    );
    
  2. buat pemicu Anda, satu untuk disisipkan dan satu untuk pembaruan:

    CREATE TRIGGER backup_variable_update BEFORE UPDATE ON variable
        FOR EACH ROW
            INSERT INTO variable_backup (name, value, type, updated) VALUES (OLD.name, OLD.value, "update", NOW());
    
    CREATE TRIGGER backup_variable_insert BEFORE INSERT ON variable
        FOR EACH ROW
            INSERT INTO variable_backup (name, value, type, updated) VALUES (NEW.name, NEW.value, "insert", NOW());
    

Sekarang semua pembaruan dan sisipan Anda akan mencatat nilai-nilai lama di variable_backup.

Scott Joudry
sumber
Saya suka itu, rapi dan sederhana. Mungkin lebih cepat dari metode saya juga. Lebih terbatas, tetapi cukup untuk melakukan apa yang dibutuhkan OP, jika ia memiliki akses MySQL yang memadai.
Mołot
Saya suka cara ini. Tapi saya pikir kita perlu melacak informasi agen pengguna juga
Andy Truong
Saya ragu bahwa informasi akan tersedia untuk database.
Scott Joudry
@AndyTruong info itu tidak akan ada di database, maaf. Saya mencoba untuk melihat-lihat tetapi tidak mungkin untuk menebaknya dengan data di tabel sesi, dan hanya kueri pemilihan yang dapat diubah sehingga tidak ada cara untuk menambahkannya. Jadi metode "hardcore" saya ada untuk Anda. Semoga Anda berhasil menerapkannya, jika tidak - ajukan pertanyaan baru yang menghubungkannya, dan berkomentar bahwa Anda melakukannya.
Mołot
5

Seperti yang Anda lihat di kode sumber, variable_set()tidak ada permintaan untuk kait atau perubahan, misalnya tidak ada module_invoke_all()atau drupal_alter()panggilan di sana.

function variable_set($name, $value) {
  global $conf;

  db_merge('variable')->key(array('name' => $name))->fields(array('value' => serialize($value)))->execute();

  cache_clear_all('variables', 'cache_bootstrap');

  $conf[$name] = $value;
}

Namun, Anda mungkin dapat mendengarkan db_merge()kueri dengan ditempatkan khusus hook_query_alter()dan melakukan beberapa pemrosesan tambahan di sana, tetapi, seperti yang ditunjukkan oleh Molot, hook_query_alter()tampaknya tidak mungkin dapat menargetkan db_merge()kueri.

Sebagai alternatif, Anda mungkin dapat snapshot cron tabel variabel untuk membandingkannya dengan revisi sebelumnya dari tabel itu, atau menerapkan beberapa bentuk penyimpanan revisi variabel lain untuk dibandingkan.

David Thomas
sumber
1
Jika hook_query_alter dapat digunakan pada permintaan ini, saya ingin melihat caranya. Di 8 QueryAlterableInterfacememang diimplementasikan dengan Querysendirinya. Namun dalam 8 manajemen konfigurasi tetap dibangun kembali. Dan dalam 7 hanya query pilih yang ditandai yang dapat diubah sejauh yang saya lihat. Tapi mungkin aku melewatkan sesuatu?
Mołot
1
Tidak, Anda benar, hook_query_alter adalah dugaan, tetapi tidak layak di D7 dalam kasus ini, terima kasih.
David Thomas
0

Saya membuka tiket Permintaan Fitur di Drupal.org untuk membuat kait untuk mencegat pengaturan dan menghapus variabel sistem, dan saya menyerahkan ulasan inti patch untuk ini! Tolong lihat:

https://www.drupal.org/project/drupal/issues/2934718

Eric Jenkins
sumber