이미지 업로드 필드를 사용자 정의 쓰기 패널에 직접 추가하려면 어떻게해야합니까?


62

워드 프레스 관리자의 "페이지"아래에 새 페이지를 추가하고 몇 가지 사용자 정의 필드를 추가했습니다. 또한 페이지 편집기에 업로드 이미지 필드를 추가하고 싶습니다. 사용자 정의 필드를 통해이를 수행 할 수있는 방법이 있습니까?

아니면이 능력이 필요하다면 다른 방향으로 가야합니까?


tdo-forms 플러그인을 확인하십시오. 아마도 이것이 쉬운 해결책
bueltge

이 질문은 아마 관련이 있습니다 : wordpress.stackexchange.com/questions/4291/…
hakre

답변:


108

파일 업로드에 대해 더 알고 싶은 사람은 다음과 같은 주요 주제와 문제점을 다루는 간단한 입문서를 참조하십시오. 이것은 Linux 상자에 WordPress 3.0으로 작성되었으며 코드는 개념을 가르치기위한 기본 개요 일뿐입니다. 여기에있는 사람들은 구현 개선에 대한 조언을 제공 할 수 있다고 확신합니다.

기본 접근 방식 개요

post_meta 필드를 사용하여 이미지 경로를 저장하거나 post_meta 필드를 사용하여 이미지의 미디어 라이브러리 ID를 저장하거나 (나중에 자세히 설명) 이미지를 첨부 파일로 게시물에 할당하는 방법에는 이미지를 게시물과 연결하는 방법이 최소한 세 가지 있습니다. . 이 예제는 post_meta 필드를 사용하여 이미지의 미디어 라이브러리 ID를 저장합니다. YMMV.

멀티 파트 인코딩

기본적으로 WordPress의 양식 만들기 및 편집에는 enctype이 없습니다. 파일을 업로드하려면 "enctype = 'multipart / form-data'"를 양식 태그에 추가해야합니다. 그렇지 않으면 $ _FILES 컬렉션이 전혀 적용되지 않습니다. WordPress 3.0에는 그에 대한 갈고리가 있습니다. 일부 이전 버전 (구체적으로 확실하지 않음)에서는 양식 태그를 문자열로 바꿔야합니다.

function xxxx_add_edit_form_multipart_encoding() {

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

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

메타 박스 및 업로드 필드 생성

메타 상자를 만드는 데 대해서는 아직 다루지 않을 것입니다. 대부분의 사람들은 이미 그 방법을 알고있을 것입니다. 그러나 파일 필드가있는 간단한 메타 상자 만 있으면됩니다. 아래 예에서는 기존 이미지를 찾고 이미지가 있으면 표시하는 코드를 포함 시켰습니다. post_meta 필드를 사용하여 오류를 전달하는 간단한 오류 / 피드백 기능도 포함 시켰습니다. WP_Error 클래스를 사용하도록 이것을 변경하고 싶을 것입니다. 데모 용입니다.

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

파일 업로드 처리

이것은 save_post 액션에 연결하여 실제로 파일 업로드를 처리하는 것입니다. 아래에 크게 주석 처리 된 기능이 포함되어 있지만 사용하는 두 가지 주요 WordPress 기능에 주목하고 싶습니다.

wp_handle_upload () 는 업로드 처리의 모든 마법을 수행합니다. $ _FILES 배열의 필드에 대한 참조와 옵션 배열을 전달하면됩니다 (이에 대해 너무 걱정하지 마십시오. 설정 해야하는 유일한 중요한 것은 test_form = false입니다. 나를 믿으십시오). 그러나이 기능은 업로드 된 파일을 미디어 라이브러리에 추가하지 않습니다. 업로드 만하고 새 파일의 경로 (및 전체 URL도)를 반환합니다. 문제가 있으면 오류를 반환합니다.

wp_insert_attachment () 는 이미지를 미디어 라이브러리에 추가하고 적절한 축소판을 모두 생성합니다. 방금 업로드 한 파일에 옵션 (제목, 게시물 상태 등) 및 LOCAL 경로 (URL이 아님)를 전달합니다. 미디어 라이브러리에 이미지를 넣는 것의 가장 좋은 점은 wp_delete_attachment를 호출하고 항목의 미디어 라이브러리 ID (아래 기능에서 수행하고 있음)를 전달하여 나중에 모든 파일을 쉽게 삭제할 수 있다는 것입니다. 이 기능을 사용하면 미디어 항목에 대한 메타 데이터를 생성하는 wp_generate_attachment_metadata () 및 wp_update_attachment_metadata ()를 사용해야합니다.

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

권한, 소유권 및 보안

업로드하는 데 문제가 있으면 권한과 관련이있을 수 있습니다. 서버 구성 전문가가 아니므로이 부분이 이상한 경우 수정하십시오.

먼저 wp-content / uploads 폴더가 존재하고 apache : apache가 소유하고 있는지 확인하십시오. 그렇다면 사용 권한을 744로 설정하면 모든 것이 제대로 작동합니다. 소유권은 중요합니다. 디렉토리를 제대로 소유하지 않으면 perm을 777로 설정해도 도움이되지 않는 경우가 있습니다.

또한 htaccess 파일을 사용하여 업로드 및 실행되는 파일 유형을 제한하는 것을 고려해야합니다. 이렇게하면 사람들이 이미지가 아닌 파일을 업로드하거나 이미지로 위장한 스크립트를 실행할 수 없습니다. 좀 더 권위있는 정보를 얻으려면이 구글을 사용해야하지만 다음과 같이 간단한 파일 형식 제한을 수행 할 수 있습니다.

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

많은 MathSmath 감사합니다! 내가 필요한 것만 이 답변에 더 많은 찬사를 전할 수 있기를 바랍니다!
Michal Mau

훌륭한 설명! 확장 해 주시면 감사하겠습니다. 특정 업로드 된 파일을 공개적으로 액세스 할 수 없게 만드는 방법입니다. 다시 말해, 특정 기능을 가진 사용자 만 업로드 된 모든 파일에 액세스 할 수있는 특정 포스트 유형을 작성하려는 경우입니다. 이것에 대해 자세히 설명해 주시겠습니까?
NetConstructor.com

3
프런트 엔드에 파일을 업로드하려는 사람은 wp_handle_upload () 함수에 액세스하려면 다음 코드를 포함해야합니다.if ( ! function_exists( 'wp_handle_upload' ) ) require_once( ABSPATH . 'wp-admin/includes/file.php' );
Nick Budden

@ NetConstructor.com이 답변의 범위를 벗어난 질문을 작성하는 것이 좋습니다.
hitautodestruct 12

0

@MathSmath가 제공 한 코드가 맞습니다. 그러나 많은 업로드 필드를 처리하거나 여러 파일을 업로드하려면 많이 수정해야합니다.

또한 파일을 업로드하는 데 WordPress 미디어 라이브러리를 사용하지 않습니다 (이후의 모든 더러운 작업을 수행합니다).

Meta Box 와 같은 플러그인을 살펴 보는 것이 좋습니다 . 플러그인은 파일을 업로드하는 두 가지 방법을 모두 지원합니다.

  • input[type="file"]위의 유사한 코드를 사용하는 HTML5를 통해 ( docs 참조 )
  • 워드 프레스 미디어 라이브러리를 통해 ( 문서 참조 )

특히 여러 개의 업로드를 만들려는 경우 코드 작성 및 유지 관리 노력을 줄일 수 있습니다.

면책 조항 : 저는 Meta Box의 저자입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.