Saya sedang membangun ulang beberapa halaman sebuah situs klien lewat PHP, dan bagian dari proses itu mendaftarkan puluhan ikon SVG ke Media Library secara programatik. Bukan upload manual satu per satu lewat dashboard, tapi lewat kode: baca file SVG dari tema, panggil wp_insert_attachment(), simpan ID-nya, lalu pakai ID itu sebagai ikon di widget Elementor. Semua tampak jalan. Halaman render, ikon muncul, tidak ada yang patah di depan mata pengunjung.
Masalahnya baru kelihatan waktu saya buka debug.log. Setiap halaman yang memakai ikon-ikon itu memuntahkan baris yang sama, berulang-ulang:
PHP Warning: Undefined array key "file" in /wp-includes/media.php on line ...Satu halaman bisa memuntahkan warning ini belasan kali, sekali untuk tiap ikon. Log yang tadinya bersih membengkak jadi ratusan baris sehari. Dan karena WP_DEBUG_DISPLAY masih hidup di staging, notice PHP itu ikut nyembur di atas sebagian ikon dan merusak layout. Frontend "jalan", tapi jelas ada yang salah di dalam.
Jalan-jalan buntu
Reaksi pertama saya salah sasaran. Karena yang muncul SVG, saya langsung curiga plugin yang menangani dukungan SVG. Saya nonaktifkan sementara, warning-nya tetap ada. Berarti bukan itu.
Tersangka kedua: Elementor, karena ikon-ikon itu memang dipakai di dalam widget-nya. Tapi menyalahkan Elementor terasa terlalu gampang, dan mematikan Elementor sama saja dengan mematikan setengah situs. Bukan solusi.
Karena warning-nya menunjuk file WP core, wp-includes/media.php, saya buka baris yang ditunjuk. Di situ ada akses ke $meta['file'] di dalam alur wp_get_attachment_metadata(). Ini kuncinya: warning Undefined array key "file" itu bahasa PHP 8 untuk "kamu membaca key array yang tidak ada". Jadi pertanyaan sebenarnya bukan "kenapa media.php rusak", tapi "kenapa metadata attachment saya tidak punya key file".
Akar masalah
Di sinilah teka-tekinya terurai. wp_insert_attachment() ternyata tidak selengkap yang saya kira. Fungsi itu membuat post attachment dan mengisi _wp_attached_file, yaitu path relatif file-nya, tapi ia TIDAK mengisi _wp_attachment_metadata. Untuk gambar raster, langkah kedua itu biasanya dikerjakan oleh wp_generate_attachment_metadata(), yang menghasilkan array berisi file, width, height, dan daftar ukuran turunan. Karena saya cuma memanggil wp_insert_attachment() lalu berhenti di situ, metadata itu tidak pernah ada.
Untuk SVG, banyak orang memang sengaja melewati wp_generate_attachment_metadata() karena SVG bukan raster: tidak ada dimensi piksel untuk dihitung, tidak ada thumbnail untuk digenerate. Jadi terasa wajar untuk skip. Tapi konsekuensinya, _wp_attachment_metadata untuk tiap SVG itu kosong.
Lalu Elementor masuk. Saat sebuah widget memakai image_size custom, Elementor memanggil wp_get_attachment_metadata() untuk attachment itu, lalu langsung mengakses $meta['file'] untuk menghitung path. Metadata-nya kosong, key file tidak ada, dan PHP 8 menembakkan Undefined array key "file" dari dalam media.php, setiap kali, untuk tiap ikon, di tiap render. Bukan Elementor yang bug, bukan media.php yang rusak. Yang kurang adalah metadata yang seharusnya saya tulis sendiri setelah mendaftarkan attachment.
Perbaikannya
Perbaikannya lugas begitu akar masalahnya jelas: setelah tiap pendaftaran attachment programatik, tulis _wp_attachment_metadata secara eksplisit, dan pastikan key file ada serta cocok dengan _wp_attached_file.
$attached_file_path = get_post_meta( $att_id, '_wp_attached_file', true );
update_post_meta( $att_id, '_wp_attachment_metadata', array(
'file' => $attached_file_path, // harus sama dengan _wp_attached_file
'width' => 0,
'height' => 0,
'mime-type' => 'image/svg+xml',
) );Kunci yang gampang kelewat: nilai file di metadata harus sama persis dengan nilai _wp_attached_file. Kalau beda, WordPress bakal bingung mencocokkan path, dan kamu bisa dapat masalah baru. Untuk SVG, width dan height boleh 0 karena memang tidak dihitung. Yang penting key-nya ada supaya $meta['file'] tidak lagi undefined.
Untuk file raster seperti PNG dan JPG, jangan tulis metadata manual seperti di atas. Panggil fungsi bawaan WordPress yang menghitung semuanya dengan benar:
require_once ABSPATH . 'wp-admin/includes/image.php';
$metadata = wp_generate_attachment_metadata( $att_id, get_attached_file( $att_id ) );
wp_update_attachment_metadata( $att_id, $metadata );wp_generate_attachment_metadata() tidak ter-load di frontend secara default, makanya perlu require_once file wp-admin/includes/image.php dulu. Fungsi ini yang mengisi file, width, height, plus semua ukuran turunan, jadi untuk raster inilah cara yang benar, bukan menulis array manual.
Saya jalankan perbaikan ini untuk seluruh aset yang didaftarkan program: 37 SVG lewat penulisan metadata eksplisit, dan 5 PNG lewat wp_generate_attachment_metadata(). Setelah itu debug.log bersih, notice di layout hilang, dan tidak ada satu pun Undefined array key "file" yang tersisa.
Yang saya bawa pulang
wp_insert_attachment()tidak mengisi_wp_attachment_metadata. Ia cuma bikin post attachment dan_wp_attached_file.- Kalau daftar attachment secara programatik, kamu yang bertanggung jawab menulis metadata-nya sendiri.
- Untuk SVG, tulis
_wp_attachment_metadatamanual dengan keyfileyang cocok dengan_wp_attached_file;widthdanheightboleh 0. - Untuk raster, pakai
wp_generate_attachment_metadata()setelahrequire_oncewp-admin/includes/image.php, jangan tulis array manual. - Warning
Undefined array key "file"diwp-includes/media.phphampir selalu berarti metadata attachment kosong, bukan bug WP core atau Elementor. - Jangan matikan
WP_DEBUGcuma untuk menyembunyikan notice. Notice itu justru memberi tahu ada attachment yang setengah jadi.
