在自定义Metabox纹理区域中粘贴文本时出现403错误

时间:2018-12-12 作者:Kevin W.

我希望每个人都有一个伟大的一天!

我提出这个问题是因为我整天都在这个问题上,我需要一些友好的建议。

我已经为一个名为Proposal的自定义帖子类型创建了一个repeater自定义元框项。转发器工作正常,正在保存内容并按我的意愿显示。然而,当我将内容粘贴到文本区域时,当你更新或发布帖子时,它会抛出一个403错误页面,并且有多个重复选项。

奇怪的是,你只需将文本添加到文本区域,而不粘贴内容,一切正常。显然,这是我在向世界发布插件之前需要解决的问题。这是我的密码。如果您注意到任何错误,请让我知道,以便我可以改进它,因为我是后端开发的新手。

<div id="wpp_meta_inner">
<?php
//get the saved meta as an array
$service = get_post_meta($post->ID,\'service\',false);
$service_title = get_post_meta($post->ID, \'wpp_service_title\', true);
?>
    <div>

          <div class="wpp-input-container">
              <label><?php _e(\'Title\') ?></label>
              <input type="text" name="wpp_service_title" id="wpp_service_title" value="<?php echo $service_title; ?>" />
              <p><?php _e(\'Will display default "Scope of Services" if empty.\') ?></p>
          </div>

          <div class="wpp-input-container">
              <label class="wpp-label-repeater"><?php _e(\'Service Items\') ?></label>
              <?php
              wp_nonce_field ( \'c_nonce_field\', \'c_wpnonce\');
                  $c = 0;
                  if ( count( $service ) > 0 ) {
                      if(!empty($service)) {
                          foreach( $service as $service_item_val ) {
                              foreach( $service_item_val as $service_item ) {
                                  if ( isset( $service_item[\'title\'] ) || isset( $service_item[\'service_item\'] ) ) {
                                      printf( \'<div class="wpp-repeater-wrapper service">Title: <input class="wpp-repeater-input service" type="text" name="service[%1$s][title]" value="%2$s" />Description: <textarea class="wpp-repeater-input service" name="service[%1$s][service_item]" data-gramm_editor="false" value="">%3$s</textarea><span class="wpp-item-remove service">%4$s</span></div>\', $c, $service_item[\'title\'], $service_item[\'service_item\'], __( \'Remove\' ) );
                                      $c = $c +1;
                                  }
                              }
                          }
                      }
                  }
              ?>
              <span id="services_here"></span>
              <div class="wpp-item-add services" style="visibility: hidden; margin-bottom: -20px;"><?php _e(\'Add Item\'); ?></div>
              <div class="wpp-item-add services add-button"><?php _e(\'Add Service\'); ?></div>
              </div>

    </div>

    <script>
    var $ =jQuery.noConflict();
    $(document).ready(function() {
        var count = <?php echo $c; ?>;
        $(".wpp-item-add.services").click(function() {
            count = count + 1;
            $(\'#services_here\').append(\'<div class="wpp-repeater-wrapper service">Title: <input class="wpp-repeater-input service" type="text" name="service[\'+count+\'][title]" value="" placeholder="" />Description: <textarea class="wpp-repeater-input service" name="service[\'+count+\'][service_item]" data-gramm_editor="false" value="" placeholder=""></textarea><span class="wpp-item-remove service">Remove</span></div>\' );
            return false;
        });
        $(".wpp-item-remove.service").live(\'click\', function() {
            $(this).parent().remove();
        });
    });
    </script>

</div>

<?php }
/* When the post is saved, saves our data */
function wpp_save_services_data( $post_id ) {
if(defined("DOING_AJAX") AND DOING_AJAX)
  return;
  if(!current_user_can(\'edit_post\', $post_id ))
  return;
  if(!isset($_POST[\'c_wpnonce\']) || !wp_verify_nonce( $_POST[\'c_wpnonce\'], \'c_nonce_field\'))
  return;
  $allowed_html = array(
          \'a\' => array(
              \'href\' => array()
          ));
  $service = $_POST[\'service\'];
  update_post_meta ($post_id, \'wpp_service_title\', wp_kses( $_POST[\'wpp_service_title\'], $allowed_html));
  update_post_meta ($post_id,\'service\',$service);
 }

1 个回复
最合适的回答,由SO网友:Dave Romsey 整理而成

我仔细查看了你的代码,并对其进行了更新,以包括适当的逃生和卫生设施。我怀疑这个问题可能是由于没有逃脱。我还应用了一些格式和WP最佳实践,但在其他方面代码是相同的。

/**
 * Meta box display callback.
 *
 * @param WP_Post $post Current post object.
 */
function wpse_metabox_callback( $post ) {
    $service_title = get_post_meta( $post->ID, \'wpp_service_title\', true );
    $service       = get_post_meta( $post->ID, \'service\', false ); // get as an array ?>

    <div id="wpp_meta_inner">
    <div>
            <div class="wpp-input-container">
                <label><?php esc_html_e( \'Title\', \'textdomain\' ); ?></label>
                <input type="text" name="wpp_service_title" id="wpp_service_title" value="<?php echo esc_attr( $service_title ); ?>" />
                <p><?php esc_html_e( \'Will display default "Scope of Services" if empty.\', \'textdomain\' ); ?></p>
            </div>

            <div class="wpp-input-container">
                <label class="wpp-label-repeater"><?php _e( \'Service Items\', \'textdomain\' ); ?></label>
                <?php
                    wp_nonce_field( \'c_nonce_field\', \'c_wpnonce\' );
                    $c = 0;
                    if ( count( $service ) > 0 ) {
                        if ( ! empty( $service ) ) {
                            foreach( $service as $service_item_val ) {
                                foreach( $service_item_val as $service_item ) {
                                    if ( isset( $service_item[\'title\'] ) || isset( $service_item[\'service_item\'] ) ) {
                                        printf(
                                            \'<div class="wpp-repeater-wrapper service">\' .
                                                \'Title: <input class="wpp-repeater-input service" type="text" name="service[%1$s][title]" value="%2$s" />\' .
                                                \'Description: <textarea class="wpp-repeater-input service" name="service[%1$s][service_item]" data-gramm_editor="false" value="">%3$s</textarea><span class="wpp-item-remove service">%4$s</span>\' . 
                                            \'</div>\',
                                            esc_attr( $c ),
                                            esc_html( $service_item[\'title\'] ),
                                            esc_textarea( $service_item[\'service_item\'] ),
                                            esc_html( __( \'Remove\', \'textdomain\' ) )
                                        );
                                        $c += 1;
                                    }
                                }
                            }
                        }
                    }
                ?>
                <span id="services_here"></span>
                <div class="wpp-item-add services" style="visibility: hidden; margin-bottom: -20px;"><?php esc_html_e( \'Add Item\', \'textdomain\' ); ?></div>
                <div class="wpp-item-add services add-button"><?php esc_html_e( \'Add Service\', \'textdomain\' ); ?></div>
            </div>
        </div>

        <script>
            var $ =jQuery.noConflict();
            $(document).ready(function() {
                    var count = <?php echo esc_js( $c ); ?>;
                    $(".wpp-item-add.services").click(function() {
                            count = count + 1;
                            $(\'#services_here\').append(\'<div class="wpp-repeater-wrapper service">Title: <input class="wpp-repeater-input service" type="text" name="service[\'+count+\'][title]" value="" placeholder="" />Description: <textarea class="wpp-repeater-input service" name="service[\'+count+\'][service_item]" data-gramm_editor="false" value="" placeholder=""></textarea><span class="wpp-item-remove service">Remove</span></div>\' );
                            return false;
                    });
                    $(".wpp-item-remove.service").live(\'click\', function() {
                            $(this).parent().remove();
                    });
            });
        </script>
    </div><?php
}
保存metabox数据时,wp_kses_post() 将应用于$services 阵列:

/**
 * Sanitize and save metabox data.
 */
add_action( \'save_post\', \'wpse_save_meta_box\' );
function wpse_save_meta_box( $post_id ) {
    if ( defined( \'DOING_AJAX\' ) AND DOING_AJAX ) {
        return;
    }

    if ( ! current_user_can( \'edit_post\', $post_id ) ) {
        return;
    }

    if ( ! isset( $_POST[\'c_wpnonce\'] ) || ! wp_verify_nonce( $_POST[\'c_wpnonce\'], \'c_nonce_field\' ) ) {
        return;
    }

    $allowed_html = array (
        \'a\' => array(
            \'href\' => array()
    ) );

    $service = isset( $_POST[\'service\'] ) && ! empty( $_POST[\'service\'] ) ? array_map( \'wp_kses_post\', $_POST[\'service\'] ) : array();

    update_post_meta( $post_id, \'wpp_service_title\', wp_kses( $_POST[\'wpp_service_title\'], $allowed_html ) );
    update_post_meta( $post_id, \'service\', $service );
}
为了完整起见,下面是注册proposal 岗位类型:

/**
 * Register proposal post type.
 */
add_action( \'init\', \'wpse_register_post_type_proposal\' );
function wpse_register_post_type_proposal() {
    $args = [
            \'label\'             => __( \'Proposals\', \'textdomain\' ),
            \'public\'             => true,
            \'publicly_queryable\' => true,
            \'show_ui\'            => true,
            \'show_in_menu\'       => true,
            \'query_var\'          => true,
            \'rewrite\'            => [ \'slug\' => \'proposal\' ],
            \'capability_type\'    => \'post\',
            \'has_archive\'        => true,
            \'hierarchical\'       => false,
            \'menu_position\'      => null,
            \'supports\'           => [ \'title\', \'editor\', \'author\', \'thumbnail\', \'excerpt\', \'comments\' ],
    ];
    register_post_type( \'proposal\', $args );
}
和元框:

/**
 * Register meta box
 */
function wpse_register_meta_boxes() {
    add_meta_box( \'meta-box-id\', __( \'My Meta Box\', \'textdomain\' ), \'wpse_metabox_callback\', \'proposal\' );
}
add_action( \'add_meta_boxes\', \'wpse_register_meta_boxes\' );

相关推荐

列出分类法:如果分类法没有POST,就不要列出分类法--取决于定制的POST-META?

这可能很难解释,我不知道是否有解决办法!?我有一个名为“wr\\u event”的自定义帖子类型和一个名为“event\\u type”的分层自定义分类法。自定义帖子类型有一个元框,用于event_date 并且与此帖子类型关联的所有帖子都按以下方式排序event_date. 我在循环中有一个特殊的条件来查询event_date 已经发生了-在这种情况下,它没有显示,但只列在我的档案中。就像你可以使用wp_list_categories() 我编写了一个自定义函数,它以完全相同的方式列出所有分类术语。现在