Bagaimana cara menambahkan bidang unggahan gambar langsung ke panel tulis khusus?

62

Saya telah menambahkan halaman baru di bawah "Halaman" di admin wordpress, dan menambahkan beberapa bidang khusus. Saya juga ingin dapat menambahkan bidang gambar unggahan ke editor halaman - apakah ada cara untuk melakukan ini melalui bidang khusus?

Atau ada arah berbeda yang harus saya ambil jika saya membutuhkan kemampuan ini?

Akan
sumber
periksa plugin tdo-bentuk, mungkin ini adalah solusi mudah
bueltge
Pertanyaan ini mungkin terkait: wordpress.stackexchange.com/questions/4291/…
hakre

Jawaban:

108

Bagi siapa saja yang ingin tahu lebih banyak tentang mengunggah file, inilah primer cepat yang mencakup topik-topik utama dan poin-poin menyakitkan. Ini ditulis dengan WordPress 3.0 pada kotak Linux dalam pikiran, dan kode hanyalah gambaran dasar untuk mengajarkan konsep. Saya yakin beberapa orang di sini dapat menawarkan saran untuk perbaikan implementasi.

Uraikan Pendekatan Dasar Anda

Setidaknya ada tiga cara untuk mengaitkan gambar dengan posting: menggunakan bidang post_meta untuk menyimpan jalur gambar, menggunakan bidang post_meta untuk menyimpan ID perpustakaan media gambar (lebih lanjut tentang itu nanti), atau menetapkan gambar ke posting sebagai lampiran . Contoh ini akan menggunakan bidang post_meta untuk menyimpan ID pustaka media gambar. YMMV.

Pengodean Multipart

Secara default, buat & edit formulir WordPress tidak memiliki enctype. Jika Anda ingin mengunggah file, Anda perlu menambahkan "enctype = 'multipart / form-data'" ke tag form - jika tidak, koleksi $ _FILES tidak akan bisa didorong sama sekali. Di WordPress 3.0, ada kaitannya dengan itu. Dalam beberapa versi sebelumnya (tidak yakin dengan spesifik) Anda harus mengganti tag form.

function xxxx_add_edit_form_multipart_encoding() {

    echo ' enctype="multipart/form-data"';

}
add_action('post_edit_form_tag', 'xxxx_add_edit_form_multipart_encoding');

Buat Kotak Meta dan Unggah Bidang

Saya tidak akan terlalu jauh membuat kotak meta karena sebagian besar dari Anda mungkin sudah tahu cara melakukannya, tetapi saya hanya akan mengatakan bahwa Anda hanya perlu kotak meta sederhana dengan bidang file di dalamnya. Dalam contoh di bawah ini saya telah memasukkan beberapa kode untuk mencari gambar yang ada, dan menampilkannya jika ada. Saya juga menyertakan beberapa fungsi kesalahan / umpan balik sederhana yang melewati kesalahan menggunakan bidang post_meta. Anda ingin mengubahnya untuk menggunakan kelas WP_Error ... itu hanya untuk demonstrasi.

function xxxx_render_image_attachment_box($post) {

    // See if there's an existing image. (We're associating images with posts by saving the image's 'attachment id' as a post meta value)
    // Incidentally, this is also how you'd find any uploaded files for display on the frontend.
    $existing_image_id = get_post_meta($post->ID,'_xxxx_attached_image', true);
    if(is_numeric($existing_image_id)) {

        echo '<div>';
            $arr_existing_image = wp_get_attachment_image_src($existing_image_id, 'large');
            $existing_image_url = $arr_existing_image[0];
            echo '<img src="' . $existing_image_url . '" />';
        echo '</div>';

    }

    // If there is an existing image, show it
    if($existing_image_id) {

        echo '<div>Attached Image ID: ' . $existing_image_id . '</div>';

    } 

    echo 'Upload an image: <input type="file" name="xxxx_image" id="xxxx_image" />';

    // See if there's a status message to display (we're using this to show errors during the upload process, though we should probably be using the WP_error class)
    $status_message = get_post_meta($post->ID,'_xxxx_attached_image_upload_feedback', true);

    // Show an error message if there is one
    if($status_message) {

        echo '<div class="upload_status_message">';
            echo $status_message;
        echo '</div>';

    }

    // Put in a hidden flag. This helps differentiate between manual saves and auto-saves (in auto-saves, the file wouldn't be passed).
    echo '<input type="hidden" name="xxxx_manual_save_flag" value="true" />';

}



function xxxx_setup_meta_boxes() {

    // Add the box to a particular custom content type page
    add_meta_box('xxxx_image_box', 'Upload Image', 'xxxx_render_image_attachment_box', 'post', 'normal', 'high');

}
add_action('admin_init','xxxx_setup_meta_boxes');

Menangani File Upload

Ini yang besar - sebenarnya menangani unggahan file dengan mengaitkan ke tindakan save_post. Saya telah menyertakan fungsi yang sangat banyak dikomentari di bawah ini, tetapi saya ingin mencatat dua fungsi utama WordPress yang digunakannya:

wp_handle_upload () melakukan semua keajaiban, baik, menangani unggahan. Anda hanya memberikan referensi ke bidang Anda dalam array $ _FILES, dan array opsi (jangan terlalu khawatir tentang hal ini - satu-satunya hal penting yang perlu Anda atur adalah test_form = false. Percayalah pada saya). Namun, fungsi ini tidak menambahkan file yang diunggah ke perpustakaan media. Itu hanya mengunggah dan mengembalikan jalur file baru (dan, mudahnya, URL lengkap juga). Jika ada masalah, itu mengembalikan kesalahan.

wp_insert_attachment () menambahkan gambar ke perpustakaan media, dan menghasilkan semua thumbnail yang sesuai. Anda cukup memberikan array opsi (judul, status posting, dll), dan jalur LOCAL (bukan URL) ke file yang baru saja Anda unggah. Hal yang hebat tentang menempatkan gambar Anda di perpustakaan media adalah bahwa Anda dapat dengan mudah menghapus semua file nanti dengan memanggil wp_delete_attachment dan meneruskannya dengan ID perpustakaan media item tersebut (yang saya lakukan dalam fungsi di bawah). Dengan fungsi ini, Anda juga harus menggunakan wp_generate_attachment_metadata () dan wp_update_attachment_metadata (), yang melakukan apa yang Anda harapkan - menghasilkan metadata untuk item media.

function xxxx_update_post($post_id, $post) {

    // Get the post type. Since this function will run for ALL post saves (no matter what post type), we need to know this.
    // It's also important to note that the save_post action can runs multiple times on every post save, so you need to check and make sure the
    // post type in the passed object isn't "revision"
    $post_type = $post->post_type;

    // Make sure our flag is in there, otherwise it's an autosave and we should bail.
    if($post_id && isset($_POST['xxxx_manual_save_flag'])) { 

        // Logic to handle specific post types
        switch($post_type) {

            // If this is a post. You can change this case to reflect your custom post slug
            case 'post':

                // HANDLE THE FILE UPLOAD

                // If the upload field has a file in it
                if(isset($_FILES['xxxx_image']) && ($_FILES['xxxx_image']['size'] > 0)) {

                    // Get the type of the uploaded file. This is returned as "type/extension"
                    $arr_file_type = wp_check_filetype(basename($_FILES['xxxx_image']['name']));
                    $uploaded_file_type = $arr_file_type['type'];

                    // Set an array containing a list of acceptable formats
                    $allowed_file_types = array('image/jpg','image/jpeg','image/gif','image/png');

                    // If the uploaded file is the right format
                    if(in_array($uploaded_file_type, $allowed_file_types)) {

                        // Options array for the wp_handle_upload function. 'test_upload' => false
                        $upload_overrides = array( 'test_form' => false ); 

                        // Handle the upload using WP's wp_handle_upload function. Takes the posted file and an options array
                        $uploaded_file = wp_handle_upload($_FILES['xxxx_image'], $upload_overrides);

                        // If the wp_handle_upload call returned a local path for the image
                        if(isset($uploaded_file['file'])) {

                            // The wp_insert_attachment function needs the literal system path, which was passed back from wp_handle_upload
                            $file_name_and_location = $uploaded_file['file'];

                            // Generate a title for the image that'll be used in the media library
                            $file_title_for_media_library = 'your title here';

                            // Set up options array to add this file as an attachment
                            $attachment = array(
                                'post_mime_type' => $uploaded_file_type,
                                'post_title' => 'Uploaded image ' . addslashes($file_title_for_media_library),
                                'post_content' => '',
                                'post_status' => 'inherit'
                            );

                            // Run the wp_insert_attachment function. This adds the file to the media library and generates the thumbnails. If you wanted to attch this image to a post, you could pass the post id as a third param and it'd magically happen.
                            $attach_id = wp_insert_attachment( $attachment, $file_name_and_location );
                            require_once(ABSPATH . "wp-admin" . '/includes/image.php');
                            $attach_data = wp_generate_attachment_metadata( $attach_id, $file_name_and_location );
                            wp_update_attachment_metadata($attach_id,  $attach_data);

                            // Before we update the post meta, trash any previously uploaded image for this post.
                            // You might not want this behavior, depending on how you're using the uploaded images.
                            $existing_uploaded_image = (int) get_post_meta($post_id,'_xxxx_attached_image', true);
                            if(is_numeric($existing_uploaded_image)) {
                                wp_delete_attachment($existing_uploaded_image);
                            }

                            // Now, update the post meta to associate the new image with the post
                            update_post_meta($post_id,'_xxxx_attached_image',$attach_id);

                            // Set the feedback flag to false, since the upload was successful
                            $upload_feedback = false;


                        } else { // wp_handle_upload returned some kind of error. the return does contain error details, so you can use it here if you want.

                            $upload_feedback = 'There was a problem with your upload.';
                            update_post_meta($post_id,'_xxxx_attached_image',$attach_id);

                        }

                    } else { // wrong file type

                        $upload_feedback = 'Please upload only image files (jpg, gif or png).';
                        update_post_meta($post_id,'_xxxx_attached_image',$attach_id);

                    }

                } else { // No file was passed

                    $upload_feedback = false;

                }

                // Update the post meta with any feedback
                update_post_meta($post_id,'_xxxx_attached_image_upload_feedback',$upload_feedback);

            break;

            default:

        } // End switch

    return;

} // End if manual save flag

    return;

}
add_action('save_post','xxxx_update_post',1,2);

Izin, Kepemilikan dan Keamanan

Jika Anda mengalami kesulitan mengunggah, itu mungkin ada hubungannya dengan izin. Saya bukan ahli konfigurasi server, jadi tolong perbaiki saya jika bagian ini miring.

Pertama, pastikan folder wp-content / unggah Anda ada, dan dimiliki oleh apache: apache. Jika demikian, Anda harus dapat mengatur izin ke 744 dan semuanya seharusnya berfungsi. Kepemilikan itu penting - bahkan menyetel izin ke 777 terkadang tidak akan membantu jika direktori tidak dimiliki dengan benar.

Anda juga harus mempertimbangkan membatasi jenis file yang diunggah dan dieksekusi menggunakan file htaccess. Ini mencegah orang dari mengunggah file yang bukan gambar, dan dari mengeksekusi skrip yang disamarkan sebagai gambar. Anda mungkin harus Google ini untuk info yang lebih otoritatif, tetapi Anda dapat melakukan pembatasan jenis file sederhana seperti ini:

<Files ^(*.jpeg|*.jpg|*.png|*.gif)>
order deny,allow
deny from all
</Files>
MathSmath
sumber
Terima kasih banyak MathSmath! Apa yang saya butuhkan. Saya berharap saya bisa memberikan pujian lebih banyak untuk jawaban ini!
Michal Mau
Penjelasan yang bagus! Satu-satunya hal yang saya akan sangat menghargai Anda memperluas adalah bagaimana membuat file yang diunggah tertentu tidak dapat diakses dari publik. Dengan kata lain, jika Anda ingin membuat jenis posting tertentu di mana semua file yang diunggah hanya dapat diakses oleh pengguna dengan kemampuan tertentu. Bisakah Anda jelaskan hal ini?
NetConstructor.com
3
Bagi siapa pun yang ingin mengunggah file di frontend, Anda harus memasukkan kode berikut untuk memiliki akses ke fungsi wp_handle_upload ():if ( ! function_exists( 'wp_handle_upload' ) ) require_once( ABSPATH . 'wp-admin/includes/file.php' );
Nick Budden
@ NetConstructor.com Saya sarankan Anda membuat pertanyaan karena itu sangat di luar cakupan jawaban ini.
hitautodestruct
0

Kode yang disediakan @MathSmath benar. Namun, jika Anda menangani banyak bidang unggahan, atau ingin mengunggah banyak file, maka Anda harus banyak memodifikasinya.

Selain itu, ia tidak menggunakan perpustakaan media WordPress untuk mengunggah file (yang melakukan semua pekerjaan kotor di belakang layar).

Saya sarankan Anda melihat sebuah plugin seperti Meta Box . Plugin mendukung kedua cara untuk mengunggah file:

  • Melalui HTML5 input[type="file"], yang menggunakan kode serupa di atas (lihat dokumen ) dan
  • Melalui WordPress Media Library (lihat dokumen ).

Ini dapat membantu Anda mengurangi upaya penulisan dan pemeliharaan kode, terutama ketika Anda ingin membuat banyak unggahan.

Penafian: Saya penulis Meta Box.

Anh Tran
sumber