Make WordPress Core


Ignore:
Timestamp:
12/02/2016 12:01:51 AM (8 years ago)
Author:
westonruter
Message:

Customize: Reject a changeset update when a non-future date is provided and also ensure that a published changeset always gets set to the current date/time.

  • Also moves checks from customize_save Ajax handler to the underlying WP_Customize_Manager::save_changeset_post() call which plugins may invoke directly.
  • Ensures that customize_save_response filter is always passed an array, with error code available as code.

Props utkarshpatel, westonruter, sayedwp.
See #30937.
Fixes #38943.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp-customize-manager.php

    r39346 r39409  
    19621962
    19631963        $changeset_post_id = $this->changeset_post_id();
    1964         if ( $changeset_post_id && in_array( get_post_status( $changeset_post_id ), array( 'publish', 'trash' ) ) ) {
    1965             wp_send_json_error( 'changeset_already_published' );
    1966         }
    1967 
    19681964        if ( empty( $changeset_post_id ) ) {
    19691965            if ( ! current_user_can( get_post_type_object( 'customize_changeset' )->cap->create_posts ) ) {
     
    20001996            }
    20011997            $is_publish = ( 'publish' === $changeset_status || 'future' === $changeset_status );
    2002             if ( $is_publish ) {
    2003                 if ( ! current_user_can( get_post_type_object( 'customize_changeset' )->cap->publish_posts ) ) {
    2004                     wp_send_json_error( 'changeset_publish_unauthorized', 403 );
    2005                 }
    2006                 if ( false === has_action( 'transition_post_status', '_wp_customize_publish_changeset' ) ) {
    2007                     wp_send_json_error( 'missing_publish_callback', 500 );
    2008                 }
     1998            if ( $is_publish && ! current_user_can( get_post_type_object( 'customize_changeset' )->cap->publish_posts ) ) {
     1999                wp_send_json_error( 'changeset_publish_unauthorized', 403 );
    20092000            }
    20102001        }
     
    20352026                $changeset_date_gmt = gmdate( 'Y-m-d H:i:s', $timestamp );
    20362027            }
    2037             $now = gmdate( 'Y-m-d H:i:59' );
    2038 
    2039             $is_future_dated = ( mysql2date( 'U', $changeset_date_gmt, false ) > mysql2date( 'U', $now, false ) );
    2040             if ( ! $is_future_dated ) {
    2041                 wp_send_json_error( 'not_future_date', 400 ); // Only future dates are allowed.
    2042             }
    2043 
    2044             if ( ! $this->is_theme_active() && ( 'future' === $changeset_status || $is_future_dated ) ) {
    2045                 wp_send_json_error( 'cannot_schedule_theme_switches', 400 ); // This should be allowed in the future, when theme is a regular setting.
    2046             }
    2047             $will_remain_auto_draft = ( ! $changeset_status && ( ! $changeset_post_id || 'auto-draft' === get_post_status( $changeset_post_id ) ) );
    2048             if ( $changeset_date && $will_remain_auto_draft ) {
    2049                 wp_send_json_error( 'cannot_supply_date_for_auto_draft_changeset', 400 );
    2050             }
    20512028        }
    20522029
     
    20582035        ) );
    20592036        if ( is_wp_error( $r ) ) {
    2060             $response = $r->get_error_data();
     2037            $response = array(
     2038                'message' => $r->get_error_message(),
     2039                'code' => $r->get_error_code(),
     2040            );
     2041            if ( is_array( $r->get_error_data() ) ) {
     2042                $response = array_merge( $response, $r->get_error_data() );
     2043            } else {
     2044                $response['data'] = $r->get_error_data();
     2045            }
    20612046        } else {
    20622047            $response = $r;
     
    21332118        $existing_changeset_data = array();
    21342119        if ( $changeset_post_id ) {
     2120            $existing_status = get_post_status( $changeset_post_id );
     2121            if ( 'publish' === $existing_status || 'trash' === $existing_status ) {
     2122                return new WP_Error( 'changeset_already_published' );
     2123            }
     2124
    21352125            $existing_changeset_data = $this->get_changeset_post_data( $changeset_post_id );
     2126        }
     2127
     2128        // Fail if attempting to publish but publish hook is missing.
     2129        if ( 'publish' === $args['status'] && false === has_action( 'transition_post_status', '_wp_customize_publish_changeset' ) ) {
     2130            return new WP_Error( 'missing_publish_callback' );
     2131        }
     2132
     2133        // Validate date.
     2134        $now = gmdate( 'Y-m-d H:i:59' );
     2135        if ( $args['date_gmt'] ) {
     2136            $is_future_dated = ( mysql2date( 'U', $args['date_gmt'], false ) > mysql2date( 'U', $now, false ) );
     2137            if ( ! $is_future_dated ) {
     2138                return new WP_Error( 'not_future_date' ); // Only future dates are allowed.
     2139            }
     2140
     2141            if ( ! $this->is_theme_active() && ( 'future' === $args['status'] || $is_future_dated ) ) {
     2142                return new WP_Error( 'cannot_schedule_theme_switches' ); // This should be allowed in the future, when theme is a regular setting.
     2143            }
     2144            $will_remain_auto_draft = ( ! $args['status'] && ( ! $changeset_post_id || 'auto-draft' === get_post_status( $changeset_post_id ) ) );
     2145            if ( $will_remain_auto_draft ) {
     2146                return new WP_Error( 'cannot_supply_date_for_auto_draft_changeset' );
     2147            }
     2148        } elseif ( $changeset_post_id && 'future' === $args['status'] ) {
     2149
     2150            // Fail if the new status is future but the existing post's date is not in the future.
     2151            $changeset_post = get_post( $changeset_post_id );
     2152            if ( mysql2date( 'U', $changeset_post->post_date_gmt, false ) <= mysql2date( 'U', $now, false ) ) {
     2153                return new WP_Error( 'not_future_date' );
     2154            }
    21362155        }
    21372156
     
    23482367            $post_array['post_status'] = $args['status'];
    23492368        }
    2350         if ( $args['date_gmt'] ) {
     2369
     2370        // Reset post date to now if we are publishing, otherwise pass post_date_gmt and translate for post_date.
     2371        if ( 'publish' === $args['status'] ) {
     2372            $post_array['post_date_gmt'] = '0000-00-00 00:00:00';
     2373            $post_array['post_date'] = '0000-00-00 00:00:00';
     2374        } elseif ( $args['date_gmt'] ) {
    23512375            $post_array['post_date_gmt'] = $args['date_gmt'];
    23522376            $post_array['post_date'] = get_date_from_gmt( $args['date_gmt'] );
Note: See TracChangeset for help on using the changeset viewer.