web-dev-qa-db-fra.com

403 Erreur lors du collage de texte dans Custom Metabox Textarea

J'espère que tout le monde passe une bonne journée!

Je suis en train de créer cette question, car je suis resté bloqué sur cette question toute la journée et j’ai besoin de quelques conseils amicaux.

J'ai créé un élément de métabox personnalisé répéteur pour un type de publication personnalisé appelé Proposition. Le répéteur fonctionne bien et enregistre le contenu et l’affiche comme je le souhaite. Cependant, lorsque je colle du contenu dans textarea, une page d'erreur 403 est projetée lorsque vous mettez à jour ou publiez le message et que l'option MORE MORE est répétée.

La partie étrange est que lorsque vous ajoutez simplement du texte à la zone de texte et que vous ne collez pas le contenu, tout fonctionne correctement. Évidemment, c'est un problème que je dois résoudre avant de publier le plugin dans le monde. Voici le code que j'ai. Si vous remarquez que quelque chose ne va pas, merci de me le faire savoir afin que je puisse l'améliorer car je suis assez nouveau dans le domaine du développement backend.

<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
Kevin W.

J'ai jeté un coup d'œil sur votre code et je l'ai mis à jour pour y inclure les procédures d'évacuation et d'hygiène appropriées. Je soupçonne que le problème aurait pu provenir du manque d’évasion. J'ai également appliqué un certain formatage et les meilleures pratiques WP, mais sinon, le code est le même.

/**
 * 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
}

Lors de la sauvegarde des données metabox, wp_kses_post() sera appliqué à chaque élément du tableau $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 );
}

Par souci d’exhaustivité, voici le code qui enregistre le type de message 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 );
}

et la meta box:

/**
 * 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' );
1
Dave Romsey