WordPress管理面板中的简单上传表单字段

Posted

技术标签:

【中文标题】WordPress管理面板中的简单上传表单字段【英文标题】:Simple Upload Form Field in Admin Panel for WordPress 【发布时间】:2012-10-04 06:30:48 【问题描述】:

根据 Nicolas Kuttler 的Simple upload field for WordPress,可以创建自定义上传表单字段。但是,引入的代码只是函数。我想知道如何使用它。

有人可以提供一个可行的例子吗?如果代码提供上传文件的功能,那么代码是否属于该页面对我来说并不重要。我希望能够通过管理面板上传文件。

[编辑]

我想上传图片以外的文件,包括文本文件和 xml。我也想在没有javascript的情况下实现它。目前还没有发布有效的答案。 (到目前为止,我很欣赏发布的信息作为答案。)

提前致谢。


建议的sample plugin 不允许用户与上传框进行交互。我附上了下面的截图。

【问题讨论】:

你应该在你正在制作的现有 Wordpress 插件中实现它,它并不意味着作为一个独立的东西工作。如果您需要为您的网站上传文件,请使用内置的媒体管理器。 @desbest 我想在现有的 WordPress 插件中实现它。但是,引入的代码只是函数。所以我想知道如何使用它。 【参考方案1】:

如果您想了解有关文件上传的更多信息,这里有一个涵盖主要主题和痛点的快速入门。这是在 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 类...这只是为了演示。

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

        echo '<div>Attached Image ID: ' . $existing_image . '</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() 将图像添加到媒体库,并生成所有适当的缩略图。您只需将一组选项(标题、帖子状态等)和本地路径(不是 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,并且一切都应该正常工作。所有权很重要——如果目录没有正确拥有,即使将 perms 设置为 777 有时也无济于事。

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

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

【讨论】:

【参考方案2】:

将所有代码添加到functions.php 文件中。 然后在你想要的主题文件中进行函数调用。

例如,如果您想在页面模板中,请拨打电话

<div> <?php fileupload('form'); ?> </div>

【讨论】:

我想在插件中实现它。问题是除非有一个工作示例,否则我无法弄清楚如何调用它。 @Neil_John_Dsouza For example if you want in the page template, make the call &lt;div&gt; &lt;?php fileupload('form'); ?&gt; &lt;/div&gt; - 它似乎不起作用。看fileupload()函数的代码,前提是用在table标签中。另外我不确定参数$label 的用途。另外,第二个函数fileupload_process() 没有在任何地方使用。

以上是关于WordPress管理面板中的简单上传表单字段的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Wordpress 管理面板中创建自定义 HTML 表单?

Wordpress:在管理员选项页面中上传图片

更新面板 webcontrol 所需的表单字段

如何检查当前页面是不是是wordpress中的插件管理面板

插件管理页面中的 Ajax 表单不起作用

php 禁用WordPress管理面板中的主题和插件编辑器