如何将图像上传域直接添加到自定义编写面板?

时间:2010-11-19 作者:Will

我在wordpress管理员的“Pages”下添加了一个新页面,并添加了几个自定义字段。我还想能够添加一个上传图像字段到页面编辑器-有没有一些方法可以通过自定义字段做到这一点?

或者,如果我需要这种能力,我需要采取不同的方向吗?

2 个回复
最合适的回答,由SO网友:MathSmath 整理而成

对于任何想了解更多文件上传信息的人,这里有一本快速入门,涵盖了主要主题和难点。这是用WordPress 3.0在Linux机器上编写的,代码只是传授概念的基本概述。我相信这里的一些人可以为改进实施提供建议。

概述您的基本方法

将图像与帖子关联至少有三种方法:使用post\\u元字段存储图像路径,使用post\\u元字段存储图像的媒体库ID(稍后将详细介绍),或将图像作为附件分配给帖子。此示例将使用post\\u元字段存储图像的媒体库ID.YMMV。

多部分编码默认情况下,WordPress“创建(&H);编辑表单没有enctype。如果要上载文件,需要在表单标记中添加“enctype=\'multipart/form data\'”,否则$\\u 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\\u元字段传递错误。您需要将此更改为使用WP\\U错误类。。。这只是为了示范。

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\\u post操作来处理文件上传。我在下面包含了一个评论颇多的函数,但我想指出它使用的两个关键字Press函数:

wp_handle_upload() 处理上传的所有魔法。您只需将引用传递给$\\u FILES数组中的字段,以及一个选项数组(不要太担心这些选项——您需要设置的唯一重要的选项是test\\u form=false。相信我)。但是,此功能不会将上载的文件添加到媒体库中。它只需上传并返回新文件的路径(以及完整的URL)。如果有问题,它将返回一个错误。

wp_insert_attachment() 将图像添加到媒体库,并生成所有适当的缩略图。您只需将一组选项(标题、帖子状态等)和本地路径(而不是URL)传递给刚刚上载的文件。将图像放入媒体库的好处在于,您可以稍后通过调用wp\\u delete\\u attachment并将项目的媒体库ID传递给它(我正在下面的函数中执行此操作),轻松删除所有文件。使用此函数,您还需要使用wp\\u generate\\u attachment\\u metadata()和wp\\u update\\u attachment\\u 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,并且一切正常。所有权很重要——如果目录所有权不正确,即使将perms设置为777有时也没有帮助。

您还应该考虑限制使用htaccess文件上载和执行的文件类型。这会阻止人们上载非图像文件,以及执行伪装为图像的脚本。您可能应该在谷歌上搜索更权威的信息,但您可以像这样进行简单的文件类型限制:

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

SO网友:Anh Tran

@MathSmath提供的代码是正确的。但是,如果要处理许多上载字段,或者要上载多个文件,则必须对其进行大量修改。

此外,它没有利用WordPress媒体库上传文件(这会在幕后完成所有脏活)。

我建议你看看像这样的插件Meta Box. 该插件支持两种上传文件的方式:

通过HTML5input[type="file"], 它使用了上面类似的代码(请参见docs) 和通过WordPress媒体库(参见docs).它可以帮助您减少编写和维护代码的工作量,尤其是当您想要创建多个上载时。

免责声明:我是Meta Box的作者。

结束

相关推荐

WP-ADMIN似乎正在重定向

我的w-admin登录有一个奇怪的问题。这是从我升级到3.0以后才开始的,当我转到wp admin时,登录表单显示正常,但当我输入用户名并通过时,每次都会再次显示登录表单。使用密码恢复功能会导致电子邮件未找到错误。我知道用户名密码和电子邮件是正确的,b/c我可以访问mysql数据库,我可以看到值(至少用户名和电子邮件) 有人知道会出什么问题吗