You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WordPress 6.0+ Gallery Metabox无法保存新增图片问题求助

修复WordPress 6.0+中自定义媒体上传框无法保存图片的问题

问题症状

自定义Meta Box中的「Add Image」按钮添加图片后,点击保存文章,图片ID无法存入自定义字段post_banner_img,但手动在隐藏字段输入图片ID可正常保存。

问题根源

  1. 缺少安全验证(Nonce):WordPress 6.0+强化了后台操作的安全校验,未添加nonce的Meta Box数据可能被拦截。
  2. JS字段更新方式错误:使用attr('value', ...)修改隐藏字段值,而非val(),导致表单提交时无法传递最新值。
  3. JS语法错误:代码中存在未声明的变量引用,导致媒体选择器的选择逻辑执行失败。
  4. 媒体选择器回调逻辑不兼容:WordPress 6.0+的媒体库API有细微调整,原代码的附件遍历逻辑存在疏漏。

修复步骤

  • 添加Nonce验证,符合WordPress安全规范
  • 替换JS字段更新方法为val(),确保表单能提交最新值
  • 修复JS语法错误,优化附件ID拼接逻辑
  • 对保存的数据进行清理过滤,保证格式正确

完整修复代码

// Add Meta Box to post
add_action( 'add_meta_boxes', 'multi_media_uploader_meta_box' );

function multi_media_uploader_meta_box() {
    add_meta_box( 'my-post-box', 'Media Field', 'multi_media_uploader_meta_box_func', 'post', 'normal', 'high' );
}

function multi_media_uploader_meta_box_func($post) {
    // 添加Nonce验证字段
    wp_nonce_field( 'banner_img_meta_box_nonce', 'banner_img_nonce' );
    
    $banner_img = get_post_meta($post->ID,'post_banner_img', true);
    ?>
    <style type="text/css">
        .multi-upload-medias ul li .delete-img { position: absolute; right: 3px; top: 2px; background: aliceblue; border-radius: 50%; cursor: pointer; font-size: 14px; line-height: 20px; color: red; }
        .multi-upload-medias ul li { width: 120px; display: inline-block; vertical-align: middle; margin: 5px; position: relative; }
        .multi-upload-medias ul li img { width: 100%; }
    </style>

    <table cellspacing="10" cellpadding="10">
        <tr>
            <td>Banner Image</td>
            <td>
                <?php echo multi_media_uploader_field( 'post_banner_img', $banner_img ); ?>
            </td>
        </tr>
    </table>

    <script type="text/javascript">
        jQuery(function($) {

            $('body').on('click', '.wc_multi_upload_image_button', function(e) {
                e.preventDefault();

                var button = $(this),
                custom_uploader = wp.media({
                    title: 'Insert image',
                    button: { text: 'Use this image' },
                    multiple: true 
                }).on('select', function() {
                    var attech_ids = [];
                    var attachments = custom_uploader.state().get('selection');
                    
                    attachments.each(function(attachment) {
                        attech_ids.push(attachment.id);
                        if (attachment.attributes.type == 'image') {
                            $(button).siblings('ul').append('<li data-attechment-id="' + attachment.id + '"><a href="' + attachment.attributes.url + '" target="_blank"><img class="true_pre_image" src="' + attachment.attributes.url + '" /></a><i class="dashicons dashicons-no delete-img"></i></li>');
                        } else {
                            $(button).siblings('ul').append('<li data-attechment-id="' + attachment.id + '"><a href="' + attachment.attributes.url + '" target="_blank"><img class="true_pre_image" src="' + attachment.attributes.icon + '" /></a><i class="dashicons dashicons-no delete-img"></i></li>');
                        }
                    });

                    var existing_ids = $(button).siblings('.attechments-ids').val();
                    var new_ids = existing_ids ? existing_ids.split(',').concat(attech_ids) : attech_ids;
                    // 去重并转为字符串
                    new_ids = [...new Set(new_ids)].join(',');
                    
                    $(button).siblings('.attechments-ids').val(new_ids);
                    $(button).siblings('.wc_multi_remove_image_button').show();
                })
                .open();
            });

            $('body').on('click', '.wc_multi_remove_image_button', function() {
                $(this).hide().prev().val('').prev().html('Add Media');
                $(this).parent().find('ul').empty();
                return false;
            });

            $(document).on('click', '.multi-upload-medias ul li i.delete-img', function() {
                var ids = [];
                $(this).parent().remove();
                $('.multi-upload-medias ul li').each(function() {
                    ids.push($(this).attr('data-attechment-id'));
                });
                $('.multi-upload-medias').find('input[type="hidden"]').val(ids.join(','));
            });
        });
    </script>

    <?php
}


function multi_media_uploader_field($name, $value = '') {
    $image_str = '';
    $image_size = 'full';
    $display = 'none';
    $value = array_filter(explode(',', $value)); // 过滤空值

    if (!empty($value)) {
        foreach ($value as $values) {
            if ($image_attributes = wp_get_attachment_image_src($values, $image_size)) {
                $image_str .= '<li data-attechment-id=' . esc_attr($values) . '><a href="' . esc_url($image_attributes[0]) . '" target="_blank"><img src="' . esc_url($image_attributes[0]) . '" /></a><i class="dashicons dashicons-no delete-img"></i></li>';
            }
        }
    }

    if($image_str){
        $display = 'inline-block';
    }

    return '<div class="multi-upload-medias"><ul>' . $image_str . '</ul><a href="#" class="wc_multi_upload_image_button button">Add Media</a><input type="hidden" class="attechments-ids ' . esc_attr($name) . '" name="' . esc_attr($name) . '" id="' . esc_attr($name) . '" value="' . esc_attr(implode(',', $value)) . '" /><a href="#" class="wc_multi_remove_image_button button" style="display:' . esc_attr($display) . '">Remove media</a></div>';
}

// Save Meta Box values.
add_action( 'save_post', 'wc_meta_box_save' );

function wc_meta_box_save( $post_id ) {
    if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
        return; 
    }

    // 验证Nonce
    if ( !isset( $_POST['banner_img_nonce'] ) || !wp_verify_nonce( $_POST['banner_img_nonce'], 'banner_img_meta_box_nonce' ) ) {
        return;
    }

    if( !current_user_can( 'edit_post', $post_id ) ){
        return; 
    }
    
    if( isset( $_POST['post_banner_img'] ) ){
        $clean_ids = array_filter(explode(',', sanitize_text_field($_POST['post_banner_img'])));
        update_post_meta( $post_id, 'post_banner_img', implode(',', $clean_ids) );
    } else {
        // 字段为空时删除元数据
        delete_post_meta( $post_id, 'post_banner_img' );
    }
}

修复说明

  • Nonce验证:添加后台操作安全校验,适配WordPress 6.0+的安全机制
  • JS值更新优化:改用val()方法修改隐藏字段,确保表单提交最新图片ID列表
  • 语法错误修复:移除无效变量声明,优化附件ID拼接逻辑,避免重复ID和无效逗号
  • 数据清理:对提交的ID进行过滤和清理,保证存储数据格式正确

内容的提问来源于stack exchange,提问作者Marisa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 15:55:35