[wp-trac] [WordPress Trac] #41953: Improved Meta Box Save Hook

WordPress Trac noreply at wordpress.org
Fri Sep 22 07:55:39 UTC 2017


#41953: Improved Meta Box Save Hook
-----------------------------+-----------------------------
 Reporter:  Nenad Obradovic  |      Owner:
     Type:  feature request  |     Status:  new
 Priority:  normal           |  Milestone:  Awaiting Review
Component:  General          |    Version:  4.8.2
 Severity:  normal           |   Keywords:
  Focuses:                   |
-----------------------------+-----------------------------
 Hi,

 This is suggestion how to reduce some conditionals for saving meta boxes
 with function for example. Below is code of meta box save function with
 all conditions for security and inside that function we always write some
 core condition for security that can be separated in one or more core
 functions to do that for us, so we can just call that function.

 {{{
 if ( ! function_exists( 'save_admin_meta_boxes' ) ) {
         /**
          * Saves admin meta box to postmeta table
          *
          * @param $post_id int - id of post that meta box is being saved
          * @param $post WP_Post - current post object
          */
         function save_admin_meta_boxes( $post_id, $post ) {

                 // If we're doing an auto save, bail
                 if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
                         return;
                 }

                 // If default wp nonce isn't there, bail
                 if ( ! isset( $_POST['_wpnonce'] ) ) {
                         return;
                 }

                 // If current user can't edit this post, bail
                 if ( ! current_user_can( 'edit_post', $post_id ) ) {
                         return;
                 }

                 // If current post type are not in list, bail
                 $post_types = apply_filters(
 'wp_allowed_post_types_for_meta_boxes', array( 'post', 'page' ) );

                 if ( ! in_array( $post->post_type, $post_types ) ) {
                         return;
                 }

                 // If our nonce isn't there, or we can't verify it, bail
                 $meta_boxes  = apply_filters( 'add_meta_boxes_filter',
 array() );
                 $nonce_array = array();

                 if ( is_array( $meta_boxes ) && ! empty( $meta_boxes ) ) {
                         foreach ( $meta_boxes as $meta_box ) {
                                 $nonce_array[] = 'extensive_vc_meta_box_'
 . esc_attr( $meta_box ) . '_save';
                         }
                 }

                 if ( is_array( $nonce_array ) && count( $nonce_array ) ) {
                         foreach ( $nonce_array as $nonce ) {
                                 if ( ! isset( $_POST[ $nonce ] ) || !
 wp_verify_nonce( $_POST[ $nonce ], $nonce ) ) {
                                         return;
                                 }
                         }
                 }

                 // Make sure your data is set before trying to save it
                 global $meta_boxes_options;

                 foreach ( $meta_boxes_options as $key => $value ) {
                         $field_key = $_POST[ $key ];

                         if ( isset( $field_key ) && trim( $field_key !==
 '' ) ) {
                                 update_post_meta( $post_id, $key,
 esc_html( $field_key ) );
                         } else {
                                 delete_post_meta( $post_id, $key );
                         }
                 }
         }

         add_action( 'save_post', 'save_admin_meta_boxes', 10, 2 );
 }
 }}}

 Example function with that conditionals

 {{{
 if ( ! function_exists( 'wp_meta_boxes_security_check' ) ) {
         /**
          * Check is meta box secure and valid for saving
          *
          * @param $post_id int - id of post that meta box is being saved
          * @param $post WP_Post - current post object
          *
          * @return boolean
          */
         function wp_meta_boxes_security_check( $post_id, $post ) {
                 $return_value = true;

                 // If we're doing an auto save, bail
                 if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
                         $return_value = false;
                 }

                 // If default wp nonce isn't there, bail
                 if ( ! isset( $_POST['_wpnonce'] ) ) {
                         $return_value = false;
                 }

                 // If current user can't edit this post, bail
                 if ( ! current_user_can( 'edit_post', $post_id ) ) {
                         $return_value = false;
                 }

                 // If current post type are not in list, bail
                 $post_types = apply_filters(
 'wp_allowed_post_types_for_meta_boxes', array( 'post', 'page' ) );

                 if ( ! in_array( $post->post_type, $post_types ) ) {
                         $return_value = false;
                 }

                 return $return_value;
         }
 }
 }}}

 and then finally code for saving meta boxes will be

 {{{
 if ( ! function_exists( 'save_admin_meta_boxes' ) ) {
         /**
          * Saves admin meta box to postmeta table
          *
          * @param $post_id int - id of post that meta box is being saved
          * @param $post WP_Post - current post object
          */
         function save_admin_meta_boxes( $post_id, $post ) {

                 // If meta box doesn't paste check, bail
                 if ( ! wp_meta_boxes_security_check( $post_id, $post ) ) {
                         return;
                 }

                 // If our nonce isn't there, or we can't verify it, bail
                 $meta_boxes  = apply_filters( 'add_meta_boxes_filter',
 array() );
                 $nonce_array = array();

                 if ( is_array( $meta_boxes ) && ! empty( $meta_boxes ) ) {
                         foreach ( $meta_boxes as $meta_box ) {
                                 $nonce_array[] = 'extensive_vc_meta_box_'
 . esc_attr( $meta_box ) . '_save';
                         }
                 }

                 if ( is_array( $nonce_array ) && count( $nonce_array ) ) {
                         foreach ( $nonce_array as $nonce ) {
                                 if ( ! isset( $_POST[ $nonce ] ) || !
 wp_verify_nonce( $_POST[ $nonce ], $nonce ) ) {
                                         return;
                                 }
                         }
                 }

                 // Make sure your data is set before trying to save it
                 global $meta_boxes_options;

                 foreach ( $meta_boxes_options as $key => $value ) {
                         $field_key = $_POST[ $key ];

                         if ( isset( $field_key ) && trim( $field_key !==
 '' ) ) {
                                 update_post_meta( $post_id, $key,
 esc_html( $field_key ) );
                         } else {
                                 delete_post_meta( $post_id, $key );
                         }
                 }
         }

         add_action( 'save_post', 'save_admin_meta_boxes', 10, 2 );
 }
 }}}

 Also I added some filter for allowed post types inside that function

 {{{
 $post_types = apply_filters( 'wp_allowed_post_types_for_meta_boxes',
 array( 'post', 'page' ) );
 }}}

 which allows authors to easily add their own custom post type with meta
 boxes for saving.

 Best regards,
 Nenad

--
Ticket URL: <https://core.trac.wordpress.org/ticket/41953>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list