Resim yükleme alanını doğrudan özel bir yazı paneline nasıl ekleyebilirim?


62

WordPress admin'de "Sayfalar" ın altına yeni bir sayfa ekledim ve birkaç özel alan ekledim. Ayrıca, sayfa düzenleyiciye bir yükleme resmi alanı ekleyebilmeyi isterdim - bunu özel alanlar aracılığıyla yapmanın bir yolu var mı?

Yoksa bu yeteneğe ihtiyacım olursa almam gereken farklı bir yön var mı?


tdo-forms eklentisini kontrol edin, belki de bu kolay bir çözümdür
bueltge

Bu soru muhtemelen ilişkilidir: wordpress.stackexchange.com/questions/4291/…
hakre

Yanıtlar:


108

Dosya yükleme hakkında daha fazla bilgi edinmek isteyen herkes için, işte ana konuları ve ağrı noktalarını kapsayan hızlı bir astar. Bu, Linux kutusundaki WordPress 3.0 ile akılda tutulur ve kod kavramları öğretmek için sadece temel bir bakış açısıdır. Eminim ki buradaki bazı kişiler uygulamada iyileştirmeler için önerilerde bulunabilirler.

Temel Yaklaşımınızı Anahatla

Görüntüleri yayınlarla ilişkilendirmenin en az üç yolu vardır: görüntü yolunu saklamak için bir post_meta alanı kullanarak, görüntünün medya kitaplığı kimliğini (sonradan daha fazlası için) depolamak için bir post_meta alanı kullanarak veya görüntünün ek olarak ataması . Bu örnek, görüntünün medya kitaplığı kimliğini saklamak için bir post_meta alanı kullanır. YMMV.

Çok Partili Kodlama

Varsayılan olarak, WordPress 'oluşturma ve düzenleme formları üzerinde hiçbir metin yoktur. Bir dosya yüklemek istiyorsanız, form etiketine bir "enctype = 'multipart / form-data'" eklemeniz gerekir - aksi takdirde $ _FILES koleksiyonu hiç bir şekilde itilmez. WordPress 3.0'da bunun için bir kanca var. Daha önceki bazı sürümlerde (özelliklerden emin değilsiniz) form etiketinin yerine dize koymanız gerekir.

function xxxx_add_edit_form_multipart_encoding() {

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

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

Meta Kutusu Oluştur ve Alanını Yükle

Muhtemelen çoğunuz zaten nasıl yapılacağını zaten bildiğinizden dolayı meta kutuları oluşturmak için fazla ileri gitmeyeceğim, ama sadece içinde dosya alanı olan basit bir meta kutuya ihtiyacınız olduğunu söyleyeceğim. Aşağıdaki örnekte, mevcut bir görüntüyü aramak ve varsa onu görüntülemek için bazı kodlar ekledim. Ayrıca, bir post_meta alanı kullanarak hataları ileten bazı basit hata / geribildirim işlevlerini de ekledim. Bunu WP_Error sınıfını kullanmak için değiştirmek isteyeceksiniz ... bu sadece tanıtım amaçlı.

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');

Dosya Yükleme İşlemini Kullanma

Bu büyük olanıdır - aslında dosya yükleme işlemini save_post eylemine asılarak gerçekleştirir. Aşağıya ağır biçimde yorumlanmış bir işlevi ekledim, ancak kullandığı iki temel WordPress işlevini not etmek istiyorum:

wp_handle_upload () , yükleme işleminin tüm sihrini yapar. Sadece $ _FILES dizisindeki alanınıza ve bir dizi seçeneğe (bu konular hakkında çok fazla endişe etmeyin - ayarlamanız gereken tek önemli test_form = false. Ancak bu işlev, yüklenen dosyayı medya kütüphanesine eklemez. Sadece yükleme işlemini yapar ve yeni dosyanın yolunu döndürür (ve ayrıca URL'nin tamamını da). Bir sorun varsa, bir hata verir.

wp_insert_attachment () , görüntüyü medya kütüphanesine ekler ve tüm uygun küçük resimleri oluşturur. Sadece yüklediğiniz dosyaya bir dizi seçenek (başlık, posta durumu, vb.) Ve YEREL yol (URL değil) iletirsiniz. Resimlerinizi medya kütüphanesine yerleştirmenin en iyi yolu, daha sonra wp_delete_attachment'i arayarak ve öğenin medya kütüphanesi kimliğini (aşağıdaki fonksiyonda yapıyorum) ileterek kolayca tüm dosyaları silebilmenizdir. Bu işlevle, tam olarak beklediğiniz şeyi yapan wp_generate_attachment_metadata () ve wp_update_attachment_metadata () kullanmanız gerekir - medya öğesi için meta veri oluşturur.

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);

İzinler, Mülkiyet ve Güvenlik

Yüklemekte sorun yaşıyorsanız, izinlerle ilgili olabilir. Sunucu yapılandırma konusunda uzman değilim, bu yüzden bu kısım riskli ise beni düzeltin.

Öncelikle, wp-content / uploads klasörünüzün var olduğundan ve apache: apache'ye ait olduğundan emin olun. Eğer öyleyse, izinleri 744 olarak ayarlayabilmelisin ve her şey sadece işe yaramalı. Sahiplik önemlidir - hatta 777'ye izin vermek bile, dizinin düzgün bir şekilde sahip olmaması durumunda bazen yardımcı olmaz.

Ayrıca bir htaccess dosyası kullanarak yüklenen ve yürütülen dosya türlerini de sınırlandırmanız gerekir. Bu, insanların görüntü olmayan dosyaları yüklemelerini ve görüntü olarak gizlenen komut dosyalarını çalıştırmalarını önler. Muhtemelen daha yetkili bilgiler için bu google gerekir, ancak bu gibi sınırlayıcı basit dosya türünü yapabilirsiniz:

<Files ^(*.jpeg|*.jpg|*.png|*.gif)>
order deny,allow
deny from all
</Files>

Çok teşekkür ederim MathSmath! Tam ihtiyacım olan şey. Keşke bu cevaba daha çok övgüde bulunabilseydim!
Michal Mau

Mükemmel açıklama! Genişlemenizi takdir edeceğim SADECE, belirli yüklenen dosyaların halka nasıl erişilemez hale getirileceği. Başka bir deyişle, yüklenen tüm dosyalara yalnızca belirli bir özelliğe sahip kullanıcılar tarafından erişilebilen belirli bir yazı türü oluşturmak istiyorsanız. Lütfen bunu biraz açıklayabilir misiniz?
NetConstructor.com

3
Ön uçta dosya yüklemek isteyen herkes için, wp_handle_upload () işlevine erişebilmek için aşağıdaki kodu eklemeniz gerekir:if ( ! function_exists( 'wp_handle_upload' ) ) require_once( ABSPATH . 'wp-admin/includes/file.php' );
Nick Budden

@ NetConstructor.com Bu cevabın kapsamı dışında kalan bir soru oluşturmanızı öneriyorum.
hitautodestruct

0

@MathSmath'ın sağladığı kod doğrudur. Ancak, birçok yükleme alanını yönetiyorsanız veya birden fazla dosya yüklemek isterseniz, o zaman çok fazla değiştirmeniz gerekir.

Ayrıca, dosyaları yüklemek için WordPress medya kitaplığını kullanmaz (bu, sahnenin arkasındaki tüm kirli işleri yapar).

Meta Box gibi bir eklentiye göz atmanı öneririm . Eklenti dosya yüklemek için her iki yolu da destekler:

  • input[type="file"]Yukarıdakilere benzer bir kod kullanan HTML5 aracılığıyla (bkz. Dokümanlar )
  • WordPress Media Library ile (bkz. Dokümanlar ).

Özellikle birden fazla yükleme oluşturmak istediğinizde, kodu yazma ve sürdürme çabalarını azaltmanıza yardımcı olabilir.

Yasal Uyarı: Ben Meta Box'ın yazarıyım.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.